Re: [HACKERS] New improved patch^N
От | Bruce Momjian |
---|---|
Тема | Re: [HACKERS] New improved patch^N |
Дата | |
Msg-id | 200002050931.EAA24979@candle.pha.pa.us обсуждение исходный текст |
Ответ на | New improved patch (Chris <chris@bitmead.com>) |
Список | pgsql-hackers |
> > Thanks Bruce! That suggestion with SearchSysCacheTuple makes a big > difference! I am no longer able to measure ANY performance difference > between inherited and > non-inherited while doing one million queries. > > The patch is too big to email, so it's up for ftp here... > > ftp://www.tech.com.au/pub/patch.only > Never mind. Got it. I am attaching it here for people to review. Let's see what people say now. I see documentation changes in there too. Great. Gee, I didn't know catalog.sgml existed. I wonder if it is up-to-date? No, pg_database doesn't show "encoding". Man, this is really old. I see pg_platter, which we have never had. I deals with jukebox platter inventory. pg_class shows things like relpreserved, which deals with time travel. I suggest we remove this file and tell people to look in include/catalog/*.h and use \dS. Comments? -- Bruce Momjian | http://www.op.net/~candle pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 ? pgsql/src/config.log ? pgsql/src/config.cache ? pgsql/src/config.status ? pgsql/src/GNUmakefile ? pgsql/src/Makefile.global ? pgsql/src/backend/fmgr.h ? pgsql/src/backend/parse.h ? pgsql/src/backend/postgres ? pgsql/src/backend/global1.bki.source ? pgsql/src/backend/local1_template1.bki.source ? pgsql/src/backend/global1.description ? pgsql/src/backend/local1_template1.description ? pgsql/src/backend/1 ? pgsql/src/backend/catalog/genbki.sh ? pgsql/src/backend/catalog/global1.bki.source ? pgsql/src/backend/catalog/global1.description ? pgsql/src/backend/catalog/local1_template1.bki.source ? pgsql/src/backend/catalog/local1_template1.description ? pgsql/src/backend/port/Makefile ? pgsql/src/backend/utils/Gen_fmgrtab.sh ? pgsql/src/backend/utils/fmgr.h ? pgsql/src/backend/utils/fmgrtab.c ? pgsql/src/bin/initdb/initdb ? pgsql/src/bin/initlocation/initlocation ? pgsql/src/bin/ipcclean/ipcclean ? pgsql/src/bin/pg_ctl/pg_ctl ? pgsql/src/bin/pg_dump/Makefile ? pgsql/src/bin/pg_dump/pg_dump ? pgsql/src/bin/pg_id/pg_id ? pgsql/src/bin/pg_passwd/pg_passwd ? pgsql/src/bin/pg_version/Makefile ? pgsql/src/bin/pg_version/pg_version ? pgsql/src/bin/pgtclsh/mkMakefile.tcldefs.sh ? pgsql/src/bin/pgtclsh/mkMakefile.tkdefs.sh ? pgsql/src/bin/psql/Makefile ? pgsql/src/bin/psql/psql ? pgsql/src/bin/scripts/createlang ? pgsql/src/include/version.h ? pgsql/src/include/config.h ? pgsql/src/interfaces/ecpg/lib/Makefile ? pgsql/src/interfaces/ecpg/lib/libecpg.so.3.0.10 ? pgsql/src/interfaces/ecpg/preproc/ecpg ? pgsql/src/interfaces/libpgeasy/Makefile ? pgsql/src/interfaces/libpgeasy/libpgeasy.so.2.1 ? pgsql/src/interfaces/libpgtcl/Makefile ? pgsql/src/interfaces/libpq/Makefile ? pgsql/src/interfaces/libpq/libpq.so.2.1 ? pgsql/src/interfaces/libpq++/Makefile ? pgsql/src/interfaces/libpq++/libpq++.so.3.1 ? pgsql/src/interfaces/odbc/GNUmakefile ? pgsql/src/interfaces/odbc/Makefile.global ? pgsql/src/pl/plpgsql/src/Makefile ? pgsql/src/pl/plpgsql/src/mklang.sql ? pgsql/src/pl/plpgsql/src/libplpgsql.so.1.0 ? pgsql/src/pl/tcl/mkMakefile.tcldefs.sh ? pgsql/src/test/regress/GNUmakefile Index: pgsql/doc/src/sgml/advanced.sgml =================================================================== RCS file: /usr/local/cvsroot/pgsql/doc/src/sgml/advanced.sgml,v retrieving revision 1.7 diff -c -r1.7 advanced.sgml *** pgsql/doc/src/sgml/advanced.sgml 1999/10/04 15:18:53 1.7 --- pgsql/doc/src/sgml/advanced.sgml 2000/02/05 08:24:35 *************** *** 56,93 **** </para> </note> ! For example, the following query finds ! all the cities that are situated at an attitude of 500ft or higher: ! ! <programlisting> ! SELECT name, altitude ! FROM cities ! WHERE altitude > 500; +----------+----------+ |name | altitude | +----------+----------+ |Las Vegas | 2174 | +----------+----------+ |Mariposa | 1953 | +----------+----------+ ! </programlisting> ! </para> ! <para> ! On the other hand, to find the names of all cities, ! including state capitals, that are located at an altitude ! over 500ft, the query is: ! ! <programlisting> ! SELECT c.name, c.altitude ! FROM cities* c ! WHERE c.altitude > 500; ! </programlisting> - which returns: - - <programlisting> +----------+----------+ |name | altitude | +----------+----------+ --- 56,97 ---- </para> </note> ! <para> ! For example, the following query finds the names of all cities, ! including state capitals, that are located at an altitude ! over 500ft, the query is: ! ! <programlisting> ! SELECT c.name, c.altitude ! FROM cities c ! WHERE c.altitude > 500; ! </programlisting> + which returns: + + <programlisting> +----------+----------+ |name | altitude | +----------+----------+ |Las Vegas | 2174 | +----------+----------+ |Mariposa | 1953 | + +----------+----------+ + |Madison | 845 | +----------+----------+ ! </programlisting> ! </para> ! <para> ! On the other hand, the following query finds ! all the cities, but not capital cities ! that are situated at an attitude of 500ft or higher: ! ! <programlisting> ! SELECT name, altitude ! FROM ONLY cities ! WHERE altitude > 500; +----------+----------+ |name | altitude | +----------+----------+ *************** *** 95,112 **** +----------+----------+ |Mariposa | 1953 | +----------+----------+ ! |Madison | 845 | ! +----------+----------+ ! </programlisting> ! Here the <quote>*</quote> after cities indicates that the query should ! be run over cities and all classes below cities in the ! inheritance hierarchy. Many of the commands that we ! have already discussed (<command>select</command>, ! <command>and>up</command>and> and <command>delete</command>) ! support this <quote>*</quote> notation, as do others, like ! <command>alter</command>. ! </para> </sect1> <sect1> --- 99,129 ---- +----------+----------+ |Mariposa | 1953 | +----------+----------+ ! </programlisting> ! </para> ! ! Here the <quote>ONLY</quote> before cities indicates that the query should ! be run over only cities and not classes below cities in the ! inheritance hierarchy. Many of the commands that we ! have already discussed -- <command>SELECT</command>, ! <command>UPDATE</command> and <command>DELETE</command> -- ! support this <quote>ONLY</quote> notation, as do others, like ! <command>ALTER TABLE</command>. ! </para> ! <para> ! Deprecated: In previous versions of postgres, the default was not to ! get access to child classes. By experience this was found to be error ! prone. Under the old syntax, to get the sub-classes you append "*" ! to the table name. For example ! <programlisting> ! SELECT * from cities*; ! </programlisting> ! This old behaviour is still available by using a SET command... ! <programlisting> ! SET EXAMINE_SUBCLASS TO 'on'; ! </programlisting> ! </para> </sect1> <sect1> Index: pgsql/doc/src/sgml/catalogs.sgml =================================================================== RCS file: /usr/local/cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v retrieving revision 2.3 diff -c -r2.3 catalogs.sgml *** pgsql/doc/src/sgml/catalogs.sgml 2000/01/22 23:50:08 2.3 --- pgsql/doc/src/sgml/catalogs.sgml 2000/02/05 08:24:37 *************** *** 192,197 **** --- 192,199 ---- 2=main memory */ int2vector relkey /* - unused */ oidvector relkeyop /* - unused */ + bool relhassubclass /* does the class have a subclass? + */ aclitem relacl[1] /* access control lists */ .fi .nf M Index: pgsql/doc/src/sgml/inherit.sgml =================================================================== RCS file: /usr/local/cvsroot/pgsql/doc/src/sgml/inherit.sgml,v retrieving revision 1.4 diff -c -r1.4 inherit.sgml *** pgsql/doc/src/sgml/inherit.sgml 1999/08/08 04:21:33 1.4 --- pgsql/doc/src/sgml/inherit.sgml 2000/02/05 08:24:37 *************** *** 37,50 **** </para> </note> ! For example, the following query finds ! all the cities that are situated at an attitude of 500ft or higher: <programlisting> ! SELECT name, altitude ! FROM cities ! WHERE altitude > 500; +----------+----------+ |name | altitude | +----------+----------+ --- 37,56 ---- </para> </note> ! <para> ! For example, the following query finds the names of all cities, ! including state capitals, that are located at an altitude ! over 500ft, the query is: <programlisting> ! SELECT c.name, c.altitude ! FROM cities c ! WHERE c.altitude > 500; ! </programlisting> ! ! which returns: + <programlisting> +----------+----------+ |name | altitude | +----------+----------+ *************** *** 52,92 **** +----------+----------+ |Mariposa | 1953 | +----------+----------+ ! </programlisting> </para> <para> ! On the other hand, to find the names of all cities, ! including state capitals, that are located at an altitude ! over 500ft, the query is: <programlisting> ! SELECT c.name, c.altitude ! FROM cities* c ! WHERE c.altitude > 500; ! </programlisting> ! ! which returns: - <programlisting> +----------+----------+ |name | altitude | +----------+----------+ |Las Vegas | 2174 | +----------+----------+ |Mariposa | 1953 | - +----------+----------+ - |Madison | 845 | +----------+----------+ ! </programlisting> ! Here the <quote>*</quote> after cities indicates that the query should ! be run over cities and all classes below cities in the inheritance hierarchy. Many of the commands that we have already discussed -- <command>SELECT</command>, <command>UPDATE</command> and <command>DELETE</command> -- ! support this <quote>*</quote> notation, as do others, like <command>ALTER TABLE</command>. </para> </chapter> --- 58,109 ---- +----------+----------+ |Mariposa | 1953 | +----------+----------+ ! |Madison | 845 | ! +----------+----------+ ! </programlisting> </para> <para> ! On the other hand, the following query finds ! all the cities, but not capital cities ! that are situated at an attitude of 500ft or higher: <programlisting> ! SELECT name, altitude ! FROM ONLY cities ! WHERE altitude > 500; +----------+----------+ |name | altitude | +----------+----------+ |Las Vegas | 2174 | +----------+----------+ |Mariposa | 1953 | +----------+----------+ ! </programlisting> ! </para> ! ! Here the <quote>ONLY</quote> before cities indicates that the query should ! be run over only cities and not classes below cities in the inheritance hierarchy. Many of the commands that we have already discussed -- <command>SELECT</command>, <command>UPDATE</command> and <command>DELETE</command> -- ! support this <quote>ONLY</quote> notation, as do others, like <command>ALTER TABLE</command>. + </para> + <para> + Deprecated: In previous versions of postgres, the default was not to + get access to child classes. By experience this was found to be error + prone. Under the old syntax, to get the sub-classes you append "*" + to the table name. For example + <programlisting> + SELECT * from cities*; + </programlisting> + This old behaviour is still available by using a SET command... + <programlisting> + SET EXAMINE_SUBCLASS TO 'on'; + </programlisting> </para> </chapter> Index: pgsql/doc/src/sgml/ref/alter_table.sgml =================================================================== RCS file: /usr/local/cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v retrieving revision 1.10 diff -c -r1.10 alter_table.sgml *** pgsql/doc/src/sgml/ref/alter_table.sgml 2000/01/29 16:58:27 1.10 --- pgsql/doc/src/sgml/ref/alter_table.sgml 2000/02/05 08:24:38 *************** *** 23,35 **** <date>1999-07-20</date> </refsynopsisdivinfo> <synopsis> ! ALTER TABLE <replaceable class="PARAMETER">table</replaceable> [ * ] ADD [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> <replaceable class="PARAMETER">type</replaceable> ! ALTER TABLE <replaceable class="PARAMETER">table</replaceable> [ * ] ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET DEFAULT <replaceable class="PARAMETER">value</replaceable> | DROP DEFAULT } ! ALTER TABLE <replaceable class="PARAMETER">table</replaceable> [ * ] RENAME [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> TO <replaceable class="PARAMETER">newcolumn</replaceable> ALTER TABLE <replaceable class="PARAMETER">table</replaceable> --- 23,35 ---- <date>1999-07-20</date> </refsynopsisdivinfo> <synopsis> ! ALTER TABLE [ ONLY ]<replaceable class="PARAMETER">table</replaceable> [ * ] ADD [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> <replaceable class="PARAMETER">type</replaceable> ! ALTER TABLE [ ONLY ]<replaceable class="PARAMETER">table</replaceable> [ * ] ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET DEFAULT <replaceable class="PARAMETER">value</replaceable> | DROP DEFAULT } ! ALTER TABLE [ ONLY ]<replaceable class="PARAMETER">table</replaceable> [ * ] RENAME [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> TO <replaceable class="PARAMETER">newcolumn</replaceable> ALTER TABLE <replaceable class="PARAMETER">table</replaceable> *************** *** 162,178 **** </para> <para> ! <quote>*</quote> following a name of a table indicates that the statement ! should be run over that table and all tables below it in the inheritance hierarchy; ! by default, the attribute will not be added to or renamed in any of the subclasses. ! This should always be done when adding or modifying an attribute in a ! superclass. If it is not, queries on the inheritance hierarchy such as <programlisting> ! SELECT <replaceable>NewColumn</replaceable> FROM <replaceable>SuperClass</replaceable>* </programlisting> will not work because the subclasses will be missing an attribute --- 162,178 ---- </para> <para> ! <quote>ONLY</quote> preceeding the name of a table indicates that the statement ! should be run over only that table and not tables below it in the inheritance hierarchy; ! by default, the attribute will be added to or renamed in any of the subclasses. ! It is recommended to never use the ONLY feature however. ! If it is, queries on the inheritance hierarchy such as <programlisting> ! SELECT <replaceable>NewColumn</replaceable> FROM <replaceable>SuperClass</replaceable> </programlisting> will not work because the subclasses will be missing an attribute Index: pgsql/doc/src/sgml/ref/select.sgml =================================================================== RCS file: /usr/local/cvsroot/pgsql/doc/src/sgml/ref/select.sgml,v retrieving revision 1.24 diff -c -r1.24 select.sgml *** pgsql/doc/src/sgml/ref/select.sgml 2000/01/27 18:11:25 1.24 --- pgsql/doc/src/sgml/ref/select.sgml 2000/02/05 08:24:40 *************** *** 25,31 **** SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replaceable> [, ...] ) ] ] <replaceable class="PARAMETER">expression</replaceable> [ AS <replaceable class="PARAMETER">name</replaceable> ] [,...] [ INTO [ TEMPORARY | TEMP ] [ TABLE ] <replaceable class="PARAMETER">new_table</replaceable> ] ! [ FROM <replaceable class="PARAMETER">table</replaceable> [ <replaceable class="PARAMETER">alias</replaceable> ] [,...] ] [ WHERE <replaceable class="PARAMETER">condition</replaceable> ] [ GROUP BY <replaceable class="PARAMETER">column</replaceable> [, ...] ] [ HAVING <replaceable class="PARAMETER">condition</replaceable> [, ...] ] --- 25,31 ---- SELECT [ ALL | DISTINCT [ ON ( <replaceable class="PARAMETER">expression</replaceable> [, ...] ) ] ] <replaceable class="PARAMETER">expression</replaceable> [ AS <replaceable class="PARAMETER">name</replaceable> ] [,...] [ INTO [ TEMPORARY | TEMP ] [ TABLE ] <replaceable class="PARAMETER">new_table</replaceable> ] ! [ FROM [ ONLY ]<replaceable class="PARAMETER">table</replaceable> [ <replaceable class="PARAMETER">alias</replaceable>] [, ...] ] [ WHERE <replaceable class="PARAMETER">condition</replaceable> ] [ GROUP BY <replaceable class="PARAMETER">column</replaceable> [, ...] ] [ HAVING <replaceable class="PARAMETER">condition</replaceable> [, ...] ] *************** *** 198,203 **** --- 198,210 ---- Candidates for selection are rows which satisfy the WHERE condition; if WHERE is omitted, all rows are candidates. (See <xref linkend="sql-where" endterm="sql-where-title">.) + </para> + <para> + <command>ONLY</command> will eliminate rows from subclasses of the table. + This was previously the default result, and getting subclasses was + obtained by appending <command>*</command> to the table name. + The old behaviour is available via the command + <command>SET EXAMINE_SUBCLASS TO 'on';</command> </para> <para> Index: pgsql/doc/src/sgml/ref/set.sgml =================================================================== RCS file: /usr/local/cvsroot/pgsql/doc/src/sgml/ref/set.sgml,v retrieving revision 1.28 diff -c -r1.28 set.sgml *** pgsql/doc/src/sgml/ref/set.sgml 1999/07/22 15:09:15 1.28 --- pgsql/doc/src/sgml/ref/set.sgml 2000/02/05 08:24:41 *************** *** 443,448 **** --- 443,482 ---- </listitem> </varlistentry> + <varlistentry> + <term>EXAMINE_SUBCLASS</term> + <listitem> + <para> + Sets the inheritance query syntax to the traditional postgres style. + + <variablelist> + <varlistentry> + <term><replaceable class="parameter">OFF</replaceable></term> + <listitem> + <para> + Changes the behaviour of SELECT so that it no longer automatically + examines sub-classes. (See SELECT). By default a SELECT on a table + will also return subclass tuples unless specifying ONLY tablename. + Setting this returns postgres to the traditional behaviour of + only returning subclasses when appending "*" to the tablename. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ON</term> + <listitem> + <para> + Returns SELECT to the behaviour of automatically returning + results from sub-classes. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </listitem> + </varlistentry> + <varlistentry> <term>OFF</term> <listitem> Index: pgsql/src/backend/commands/creatinh.c =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/backend/commands/creatinh.c,v retrieving revision 1.56 diff -c -r1.56 creatinh.c *** pgsql/src/backend/commands/creatinh.c 2000/01/29 16:58:34 1.56 --- pgsql/src/backend/commands/creatinh.c 2000/02/05 08:24:44 *************** *** 35,40 **** --- 35,43 ---- const char *attributeType, List *schema); static List *MergeAttributes(List *schema, List *supers, List **supconstr); static void StoreCatalogInheritance(Oid relationId, List *supers); + static void + setRelhassubclassInRelation(Oid relationId, bool relhassubclass); + /* ---------------------------------------------------------------- * DefineRelation *************** *** 323,328 **** --- 326,332 ---- TupleConstr *constr; relation = heap_openr(name, AccessShareLock); + setRelhassubclassInRelation(relation->rd_id, true); tupleDesc = RelationGetDescr(relation); constr = tupleDesc->constr; *************** *** 655,657 **** --- 659,698 ---- } return false; } + + + static void + setRelhassubclassInRelation(Oid relationId, bool relhassubclass) + { + Relation relationRelation; + HeapTuple tuple; + Relation idescs[Num_pg_class_indices]; + + /* + * Lock a relation given its Oid. Go to the RelationRelation (i.e. + * pg_relation), find the appropriate tuple, and add the specified + * lock to it. + */ + relationRelation = heap_openr(RelationRelationName, RowExclusiveLock); + tuple = SearchSysCacheTuple(RELOID, + ObjectIdGetDatum(relationId), + 0, 0, 0) + ; + Assert(HeapTupleIsValid(tuple)); + + ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass = relhassubclass; + heap_update(relationRelation, &tuple->t_self, tuple, NULL); + + /* keep the catalog indices up to date */ + CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation, tuple + ); + CatalogCloseIndices(Num_pg_class_indices, idescs); + + /* heap_freetuple(tuple); */ + heap_close(relationRelation, RowExclusiveLock); + } + + + + Index: pgsql/src/backend/commands/variable.c =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/backend/commands/variable.c,v retrieving revision 1.28 diff -c -r1.28 variable.c *** pgsql/src/backend/commands/variable.c 2000/01/22 23:50:10 1.28 --- pgsql/src/backend/commands/variable.c 2000/02/05 08:24:45 *************** *** 48,53 **** --- 48,56 ---- extern bool _use_keyset_query_optimizer; + #define examine_subclass_default true + bool examine_subclass = examine_subclass_default; + /* * * Get_Token *************** *** 228,233 **** --- 231,274 ---- geqo_rels = GEQO_RELS; return TRUE; } + /* + * + * EXAMINE_SUBCLASS + * + */ + #define EXAMINE_SUBCLASS "EXAMINE_SUBCLASS" + + static bool + parse_examine_subclass(const char *value) + { + if (strcasecmp(value, "on") == 0) + examine_subclass = true; + else if (strcasecmp(value, "off") == 0) + examine_subclass = false; + else if (strcasecmp(value, "default") == 0) + examine_subclass = examine_subclass_default; + else + elog(ERROR, "Bad value for %s (%s)", EXAMINE_SUBCLASS, value); + return TRUE; + } + + static bool + show_examine_subclass() + { + + if (examine_subclass) + elog(NOTICE, "%s is ON", EXAMINE_SUBCLASS); + else + elog(NOTICE, "%s is OFF", EXAMINE_SUBCLASS); + return TRUE; + } + + static bool + reset_examine_subclass(void) + { + examine_subclass = examine_subclass_default; + return TRUE; + } /* * *************** *** 600,605 **** --- 641,649 ---- { "pg_options", parse_pg_options, show_pg_options, reset_pg_options }, + { + EXAMINE_SUBCLASS, parse_examine_subclass, show_examine_subclass, reset_examine_subclass + }, { NULL, NULL, NULL, NULL } Index: pgsql/src/backend/optimizer/plan/planner.c =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v retrieving revision 1.74 diff -c -r1.74 planner.c *** pgsql/src/backend/optimizer/plan/planner.c 2000/01/27 18:11:31 1.74 --- pgsql/src/backend/optimizer/plan/planner.c 2000/02/05 08:24:48 *************** *** 35,40 **** --- 35,41 ---- #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/syscache.h" + #include "parser/parsetree.h" static List *make_subplanTargetList(Query *parse, List *tlist, AttrNumber **groupColIdx); *************** *** 140,146 **** * to change interface to plan_union_queries to pass that info back! */ } ! else if ((rt_index = first_inherit_rt_entry(rangetable)) != -1) { List *sub_tlist; --- 141,147 ---- * to change interface to plan_union_queries to pass that info back! */ } ! else if ((rt_index = first_inherit_rt_entry(rangetable)) != -1 && has_inheritors(rt_fetch(rt_index, parse->rtable)->relid)) { List *sub_tlist; Index: pgsql/src/backend/optimizer/prep/prepunion.c =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v retrieving revision 1.43 diff -c -r1.43 prepunion.c *** pgsql/src/backend/optimizer/prep/prepunion.c 2000/02/03 06:12:19 1.43 --- pgsql/src/backend/optimizer/prep/prepunion.c 2000/02/05 08:24:49 *************** *** 25,30 **** --- 25,33 ---- #include "parser/parse_clause.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" + #include "access/heapam.h" + #include "catalog/catname.h" + #include "utils/syscache.h" typedef struct { Index rt_index; *************** *** 45,50 **** --- 48,54 ---- static Append *make_append(List *appendplans, List *unionrtables, Index rt_index, List *inheritrtable, List *tlist); + bool has_inheritors(Oid relationId); /* *************** *** 352,357 **** --- 356,386 ---- *union_rtentriesPtr = union_rtentries; return union_plans; + } + + bool has_inheritors(Oid relationId) + { + bool rtn; + Relation relationRelation; + HeapTuple tuple; + + /* + * Lock a relation given its Oid. Go to the RelationRelation (i.e. + * pg_relation), find the appropriate tuple, and add the specified + * lock to it. + */ + relationRelation = heap_openr(RelationRelationName, NoLock); + tuple = SearchSysCacheTuple(RELOID, + ObjectIdGetDatum(relationId), + 0, 0, 0) + ; + /* Assert(HeapTupleIsValid(tuple)); */ + + rtn = ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass; + + /* heap_freetuple(tuple); */ + heap_close(relationRelation, NoLock); + return rtn; } /* Index: pgsql/src/backend/parser/gram.y =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/backend/parser/gram.y,v retrieving revision 2.139 diff -c -r2.139 gram.y *** pgsql/src/backend/parser/gram.y 2000/02/04 18:49:33 2.139 --- pgsql/src/backend/parser/gram.y 2000/02/05 08:25:00 *************** *** 811,868 **** AlterTableStmt: /* ALTER TABLE <name> ADD [COLUMN] <coldef> */ ALTER TABLE relation_name opt_inh_star ADD opt_column columnDef { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'A'; n->relname = $3; ! n->inh = $4; n->def = $7; $$ = (Node *)n; } /* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */ | ALTER TABLE relation_name opt_inh_star ALTER opt_column ColId alter_column_action { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'T'; n->relname = $3; ! n->inh = $4; n->name = $7; n->def = $8; $$ = (Node *)n; } /* ALTER TABLE <name> DROP [COLUMN] <name> {RESTRICT|CASCADE} */ | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId drop_behavior { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'D'; n->relname = $3; ! n->inh = $4; n->name = $7; n->behavior = $8; $$ = (Node *)n; } /* ALTER TABLE <name> ADD CONSTRAINT ... */ | ALTER TABLE relation_name opt_inh_star ADD TableConstraint { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'C'; n->relname = $3; ! n->inh = $4; n->def = $6; $$ = (Node *)n; } /* ALTER TABLE <name> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */ | ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'X'; n->relname = $3; ! n->inh = $4; n->name = $7; n->behavior = $8; $$ = (Node *)n; } ; alter_column_action: --- 811,926 ---- AlterTableStmt: /* ALTER TABLE <name> ADD [COLUMN] <coldef> */ + /* "*" deprecated */ ALTER TABLE relation_name opt_inh_star ADD opt_column columnDef { + extern bool examine_subclass; AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'A'; n->relname = $3; ! n->inh = $4 || examine_subclass; n->def = $7; $$ = (Node *)n; } + | ALTER TABLE ONLY relation_name ADD opt_column columnDef + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->subtype = 'A'; + n->relname = $4; + n->inh = FALSE; + n->def = $7; + $$ = (Node *)n; + } /* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */ + /* "*" deprecated */ | ALTER TABLE relation_name opt_inh_star ALTER opt_column ColId alter_column_action { + extern bool examine_subclass; AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'T'; n->relname = $3; ! n->inh = $4 || examine_subclass; n->name = $7; n->def = $8; $$ = (Node *)n; } + | ALTER TABLE ONLY relation_name ALTER opt_column ColId alter_column_action + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->subtype = 'T'; + n->relname = $4; + n->inh = FALSE; + n->name = $7; + n->def = $8; + $$ = (Node *)n; + } /* ALTER TABLE <name> DROP [COLUMN] <name> {RESTRICT|CASCADE} */ + /* "*" deprecated */ | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId drop_behavior { + extern bool examine_subclass; AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'D'; n->relname = $3; ! n->inh = $4 || examine_subclass; n->name = $7; n->behavior = $8; $$ = (Node *)n; } + | ALTER TABLE ONLY relation_name DROP opt_column ColId drop_behavior + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->subtype = 'D'; + n->relname = $4; + n->inh = FALSE; + n->name = $7; + n->behavior = $8; + $$ = (Node *)n; + } /* ALTER TABLE <name> ADD CONSTRAINT ... */ + /* "*" deprecated */ | ALTER TABLE relation_name opt_inh_star ADD TableConstraint { + extern bool examine_subclass; AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'C'; n->relname = $3; ! n->inh = $4 || examine_subclass; n->def = $6; $$ = (Node *)n; } + | ALTER TABLE ONLY relation_name ADD TableConstraint + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->subtype = 'C'; + n->relname = $4; + n->inh = FALSE; + n->def = $6; + $$ = (Node *)n; + } /* ALTER TABLE <name> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */ + /* "*" deprecated */ | ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior { + extern bool examine_subclass; AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'X'; n->relname = $3; ! n->inh = $4 || examine_subclass; n->name = $7; n->behavior = $8; $$ = (Node *)n; } + | ALTER TABLE ONLY relation_name DROP CONSTRAINT name drop_behavior + { + AlterTableStmt *n = makeNode(AlterTableStmt); + n->subtype = 'X'; + n->relname = $4; + n->inh = FALSE; + n->name = $7; + n->behavior = $8; + $$ = (Node *)n; + } ; alter_column_action: *************** *** 2380,2390 **** *****************************************************************************/ RenameStmt: ALTER TABLE relation_name opt_inh_star RENAME opt_column opt_name TO name { RenameStmt *n = makeNode(RenameStmt); n->relname = $3; ! n->inh = $4; n->column = $7; n->newname = $9; $$ = (Node *)n; --- 2438,2460 ---- *****************************************************************************/ RenameStmt: ALTER TABLE relation_name opt_inh_star + /* "*" deprecated */ RENAME opt_column opt_name TO name { + extern bool examine_subclass; RenameStmt *n = makeNode(RenameStmt); n->relname = $3; ! n->inh = $4 || examine_subclass; ! n->column = $7; ! n->newname = $9; ! $$ = (Node *)n; ! } ! | ALTER TABLE ONLY relation_name ! RENAME opt_column opt_name TO name ! { ! RenameStmt *n = makeNode(RenameStmt); ! n->relname = $4; ! n->inh = FALSE; n->column = $7; n->newname = $9; $$ = (Node *)n; *************** *** 3553,3562 **** relation_expr: relation_name { ! /* normal relations */ $$ = makeNode(RelExpr); $$->relname = $1; ! $$->inh = FALSE; } | relation_name '*' %prec '=' { --- 3623,3633 ---- relation_expr: relation_name { ! /* default inheritance */ ! extern bool examine_subclass; $$ = makeNode(RelExpr); $$->relname = $1; ! $$->inh = examine_subclass; } | relation_name '*' %prec '=' { *************** *** 3565,3570 **** --- 3636,3648 ---- $$->relname = $1; $$->inh = TRUE; } + | ONLY relation_name + { + /* no inheritance */ + $$ = makeNode(RelExpr); + $$->relname = $2; + $$->inh = FALSE; + } opt_array_bounds: '[' ']' opt_array_bounds { $$ = lcons(makeInteger(-1), $3); } Index: pgsql/src/include/catalog/catversion.h =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/include/catalog/catversion.h,v retrieving revision 1.13 diff -c -r1.13 catversion.h *** pgsql/src/include/catalog/catversion.h 2000/01/27 18:11:40 1.13 --- pgsql/src/include/catalog/catversion.h 2000/02/05 08:25:05 *************** *** 53,58 **** */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200001271 #endif --- 53,58 ---- */ /* yyyymmddN */ ! #define CATALOG_VERSION_NO 200002050 #endif Index: pgsql/src/include/catalog/pg_attribute.h =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/include/catalog/pg_attribute.h,v retrieving revision 1.53 diff -c -r1.53 pg_attribute.h *** pgsql/src/include/catalog/pg_attribute.h 2000/01/26 05:57:57 1.53 --- pgsql/src/include/catalog/pg_attribute.h 2000/02/05 08:25:09 *************** *** 402,408 **** { 1259, {"relrefs"}, 21, 0, 2, 16, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \ { 1259, {"relhaspkey"}, 16, 0, 1, 17, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \ { 1259, {"relhasrules"}, 16, 0, 1, 18, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \ ! { 1259, {"relacl"}, 1034, 0, -1, 19, 0, -1, -1, '\0', 'p', '\0', 'i', '\0', '\0' } DATA(insert OID = 0 ( 1259 relname 19 0 NAMEDATALEN 1 0 -1 -1 f p f i f f)); DATA(insert OID = 0 ( 1259 reltype 26 0 4 2 0 -1 -1 t p f i f f)); --- 402,409 ---- { 1259, {"relrefs"}, 21, 0, 2, 16, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \ { 1259, {"relhaspkey"}, 16, 0, 1, 17, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \ { 1259, {"relhasrules"}, 16, 0, 1, 18, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \ ! { 1259, {"relhassubclass"},16, 0, 1, 19, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \ ! { 1259, {"relacl"}, 1034, 0, -1, 20, 0, -1, -1, '\0', 'p', '\0', 'i', '\0', '\0' } DATA(insert OID = 0 ( 1259 relname 19 0 NAMEDATALEN 1 0 -1 -1 f p f i f f)); DATA(insert OID = 0 ( 1259 reltype 26 0 4 2 0 -1 -1 t p f i f f)); *************** *** 422,428 **** DATA(insert OID = 0 ( 1259 relrefs 21 0 2 16 0 -1 -1 t p f s f f)); DATA(insert OID = 0 ( 1259 relhaspkey 16 0 1 17 0 -1 -1 t p f c f f)); DATA(insert OID = 0 ( 1259 relhasrules 16 0 1 18 0 -1 -1 t p f c f f)); ! DATA(insert OID = 0 ( 1259 relacl 1034 0 -1 19 0 -1 -1 f p f i f f)); DATA(insert OID = 0 ( 1259 ctid 27 0 6 -1 0 -1 -1 f p f i f f)); DATA(insert OID = 0 ( 1259 oid 26 0 4 -2 0 -1 -1 t p f i f f)); DATA(insert OID = 0 ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i f f)); --- 423,430 ---- DATA(insert OID = 0 ( 1259 relrefs 21 0 2 16 0 -1 -1 t p f s f f)); DATA(insert OID = 0 ( 1259 relhaspkey 16 0 1 17 0 -1 -1 t p f c f f)); DATA(insert OID = 0 ( 1259 relhasrules 16 0 1 18 0 -1 -1 t p f c f f)); ! DATA(insert OID = 0 ( 1259 relhassubclass 16 0 1 19 0 -1 -1 t p f c f f)); ! DATA(insert OID = 0 ( 1259 relacl 1034 0 -1 20 0 -1 -1 f p f i f f)); DATA(insert OID = 0 ( 1259 ctid 27 0 6 -1 0 -1 -1 f p f i f f)); DATA(insert OID = 0 ( 1259 oid 26 0 4 -2 0 -1 -1 t p f i f f)); DATA(insert OID = 0 ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i f f)); Index: pgsql/src/include/catalog/pg_class.h =================================================================== RCS file: /usr/local/cvsroot/pgsql/src/include/catalog/pg_class.h,v retrieving revision 1.33 diff -c -r1.33 pg_class.h *** pgsql/src/include/catalog/pg_class.h 2000/01/26 05:57:57 1.33 --- pgsql/src/include/catalog/pg_class.h 2000/02/05 08:25:09 *************** *** 78,88 **** int2 relrefs; /* # of references to this relation */ bool relhaspkey; /* has PRIMARY KEY */ bool relhasrules; aclitem relacl[1]; /* this is here for the catalog */ } FormData_pg_class; #define CLASS_TUPLE_SIZE \ ! (offsetof(FormData_pg_class,relhasrules) + sizeof(bool)) /* ---------------- * Form_pg_class corresponds to a pointer to a tuple with --- 78,89 ---- int2 relrefs; /* # of references to this relation */ bool relhaspkey; /* has PRIMARY KEY */ bool relhasrules; + bool relhassubclass; aclitem relacl[1]; /* this is here for the catalog */ } FormData_pg_class; #define CLASS_TUPLE_SIZE \ ! (offsetof(FormData_pg_class,relhassubclass) + sizeof(bool)) /* ---------------- * Form_pg_class corresponds to a pointer to a tuple with *************** *** 102,109 **** * relacl field. * ---------------- */ ! #define Natts_pg_class_fixed 18 ! #define Natts_pg_class 19 #define Anum_pg_class_relname 1 #define Anum_pg_class_reltype 2 #define Anum_pg_class_relowner 3 --- 103,110 ---- * relacl field. * ---------------- */ ! #define Natts_pg_class_fixed 19 ! #define Natts_pg_class 20 #define Anum_pg_class_relname 1 #define Anum_pg_class_reltype 2 #define Anum_pg_class_relowner 3 *************** *** 122,128 **** #define Anum_pg_class_relrefs 16 #define Anum_pg_class_relhaspkey 17 #define Anum_pg_class_relhasrules 18 ! #define Anum_pg_class_relacl 19 /* ---------------- * initial contents of pg_class --- 123,130 ---- #define Anum_pg_class_relrefs 16 #define Anum_pg_class_relhaspkey 17 #define Anum_pg_class_relhasrules 18 ! #define Anum_pg_class_relhassubclass 19 ! #define Anum_pg_class_relacl 20 /* ---------------- * initial contents of pg_class *************** *** 135,141 **** DESCR(""); DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 0 0 0 f f r 16 0 0 0 0 0 f f _null_ )); DESCR(""); ! DATA(insert OID = 1259 ( pg_class 83 PGUID 0 0 0 0 f f r 19 0 0 0 0 0 f f _null_ )); DESCR(""); DATA(insert OID = 1260 ( pg_shadow 86 PGUID 0 0 0 0 f t r 8 0 0 0 0 0 f f _null_ )); DESCR(""); --- 137,143 ---- DESCR(""); DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 0 0 0 f f r 16 0 0 0 0 0 f f _null_ )); DESCR(""); ! DATA(insert OID = 1259 ( pg_class 83 PGUID 0 0 0 0 f f r 20 0 0 0 0 0 f f _null_ )); DESCR(""); DATA(insert OID = 1260 ( pg_shadow 86 PGUID 0 0 0 0 f t r 8 0 0 0 0 0 f f _null_ )); DESCR("");
В списке pgsql-hackers по дате отправления: