diff --git a/contrib/intarray/_int.sql.in b/contrib/intarray/_int.sql.in index 37530a9062..44efc85700 100644 --- a/contrib/intarray/_int.sql.in +++ b/contrib/intarray/_int.sql.in @@ -459,9 +459,9 @@ AS --GIN --mark built-in gin's _int4_ops as non default -update pg_opclass set opcdefault = 'f' where - pg_opclass.opcamid = (select pg_am.oid from pg_am where amname='gin') and - opcname = '_int4_ops'; +update pg_catalog.pg_opclass set opcdefault = 'f' +where opcmethod = (select oid from pg_catalog.pg_am where amname='gin') and + opcname = '_int4_ops'; CREATE FUNCTION ginint4_queryextract(internal, internal, int2) RETURNS internal diff --git a/contrib/intarray/uninstall__int.sql b/contrib/intarray/uninstall__int.sql index 6f5b863fea..2f3b20fda0 100644 --- a/contrib/intarray/uninstall__int.sql +++ b/contrib/intarray/uninstall__int.sql @@ -124,7 +124,7 @@ DROP FUNCTION querytree(query_int); DROP TYPE query_int CASCADE; -update pg_opclass set opcdefault = 't' where - pg_opclass.opcamid = (select pg_am.oid from pg_am where amname='gin') and - opcname = '_int4_ops'; - +--mark built-in gin's _int4_ops as default again +update pg_catalog.pg_opclass set opcdefault = 't' +where opcmethod = (select oid from pg_catalog.pg_am where amname='gin') and + opcname = '_int4_ops'; diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index ee5896b281..a906623ac9 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,4 +1,4 @@ - + @@ -160,7 +160,7 @@ pg_opclass - index access method operator classes + access method operator classes @@ -168,6 +168,11 @@ operators + + pg_opfamily + access method operator families + + pg_pltemplate template data for procedural languages @@ -516,9 +521,11 @@ - The catalog pg_amop stores information about operators - associated with index access method operator classes. There is one - row for each operator that is a member of an operator class. + The catalog pg_amop stores information about + operators associated with access method operator families. There is one + row for each operator that is a member of an operator family. An operator + can appear in more than one family, but may not appear in more than one + position within a family. @@ -536,18 +543,24 @@ - amopclaid + amopfamily oid - pg_opclass.oid - The index operator class this entry is for + pg_opfamily.oid + The operator family this entry is for - amopsubtype + amoplefttype oid pg_type.oid - Subtype to distinguish multiple entries for one strategy; - zero for default + Left-hand input data type of operator + + + + amoprighttype + oid + pg_type.oid + Right-hand input data type of operator @@ -571,10 +584,27 @@ OID of the operator + + amopmethod + oid + pg_am.oid + Index access method operator family is for + +
+ + An entry's amopmethod must match the + opfmethod of its containing operator family (including + amopmethod here is an intentional denormalization of the + catalog structure for performance reasons). Also, + amoplefttype and amoprighttype must match + the oprleft and oprright fields of the + referenced pg_operator entry. + + @@ -586,10 +616,9 @@ - The catalog pg_amproc stores information about support - procedures - associated with index access method operator classes. There is one - row for each support procedure belonging to an operator class. + The catalog pg_amproc stores information about + support procedures associated with access method operator families. There + is one row for each support procedure belonging to an operator family. @@ -607,17 +636,24 @@ - amopclaid + amprocfamily oid - pg_opclass.oid - The index operator class this entry is for + pg_opfamily.oid + The operator family this entry is for - amprocsubtype + amproclefttype oid pg_type.oid - Subtype, if cross-type routine, else zero + Left-hand input data type of associated operator + + + + amprocrighttype + oid + pg_type.oid + Right-hand input data type of associated operator @@ -638,6 +674,18 @@
+ + The usual interpretation of the + amproclefttype and amprocrighttype fields + is that they identify the left and right input types of the operator(s) + that a particular support procedure supports. For some access methods + these match the input data type(s) of the support procedure itself, for + others not. There is a notion of default support procedures for + an index, which are those with amproclefttype and + amprocrighttype both equal to the index opclass's + opcintype. + + @@ -2843,9 +2891,11 @@ The catalog pg_opclass defines index access method operator classes. Each operator class defines semantics for index columns of a particular data type and a particular - index access method. Note that there can be multiple operator classes - for a given data type/access method combination, thus supporting multiple - behaviors. + index access method. An operator class essentially specifies that a + particular operator family is applicable to a particular indexable column + data type. The set of operators from the family that are actually usable + with the indexed column are whichever ones accept the column's data type + as their lefthand input. @@ -2867,7 +2917,7 @@ - opcamid + opcmethod oid pg_am.oid Index access method operator class is for @@ -2894,6 +2944,13 @@ Owner of the operator class + + opcfamily + oid + pg_opfamily.oid + Operator family containing the operator class + + opcintype oid @@ -2920,14 +2977,11 @@ - The majority of the information defining an operator class is actually - not in its pg_opclass row, but in the associated - rows in pg_amop and - pg_amproc. Those rows are considered to be - part of the operator class definition — this is not unlike the way - that a relation is defined by a single pg_class - row plus associated rows in pg_attribute and - other tables. + An operator class's opcmethod must match the + opfmethod of its containing operator family. + Also, there must be no more than one pg_opclass + row having opcdefault true for any given combination of + opcmethod and opcintype. @@ -2993,6 +3047,13 @@ + + oprcanmerge + bool + + This operator supports merge joins + + oprcanhash bool @@ -3035,46 +3096,6 @@ Negator of this operator, if any - - oprlsortop - oid - pg_operator.oid - - If this operator supports merge joins, the operator that sorts - the type of the left-hand operand (L<L) - - - - - oprrsortop - oid - pg_operator.oid - - If this operator supports merge joins, the operator that sorts - the type of the right-hand operand (R<R) - - - - - oprltcmpop - oid - pg_operator.oid - - If this operator supports merge joins, the less-than operator that - compares the left and right operand types (L<R) - - - - - oprgtcmpop - oid - pg_operator.oid - - If this operator supports merge joins, the greater-than operator that - compares the left and right operand types (L>R) - - - oprcode regproc @@ -3107,6 +3128,86 @@ + + <structname>pg_opfamily</structname> + + + pg_opfamily + + + + The catalog pg_opfamily defines operator families. + Each operator family is a collection of operators and associated + support routines that implement the semantics specified for a particular + index access method. Furthermore, the operators in a family are all + compatible, in a way that depends on the access method. + The operator family concept allows cross-data-type operators to be used + with indexes and to be reasoned about using knowledge of access method + semantics. + + + + Operator families are described at length in . + + + + <structname>pg_opfamily</> Columns + + + + + Name + Type + References + Description + + + + + + opfmethod + oid + pg_am.oid + Index access method operator family is for + + + + opfname + name + + Name of this operator family + + + + opfnamespace + oid + pg_namespace.oid + Namespace of this operator family + + + + opfowner + oid + pg_authid.oid + Owner of the operator family + + + + +
+ + + The majority of the information defining an operator family is not in its + pg_opfamily row, but in the associated rows in + pg_amop, + pg_amproc, + and + pg_opclass. + + +
+ + <structname>pg_pltemplate</structname> diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml index 44dac1183e..658cdd7096 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -1,4 +1,4 @@ - + Index Access Method Interface Definition @@ -63,13 +63,15 @@ To be useful, an index access method must also have one or more + operator families and operator classes defined in + pg_opfamily, pg_opclass, pg_amop, and pg_amproc. These entries allow the planner to determine what kinds of query qualifications can be used with - indexes of this access method. Operator classes are described + indexes of this access method. Operator families and classes are described in , which is prerequisite material for reading this chapter. @@ -409,14 +411,14 @@ amrestrpos (IndexScanDesc scan); A scan key is the internal representation of a WHERE clause of the form index_key operator constant, where the index key is one of the columns of the - index and the operator is one of the members of the operator class + index and the operator is one of the members of the operator family associated with that index column. An index scan has zero or more scan keys, which are implicitly ANDed — the returned tuples are expected to satisfy all the indicated conditions.
- The operator class may indicate that the index is lossy for a + The operator family may indicate that the index is lossy for a particular operator; this implies that the index scan will return all the entries that pass the scan key, plus possibly additional entries that do not. The core system's index-scan machinery will then apply that operator @@ -429,7 +431,7 @@ amrestrpos (IndexScanDesc scan); Note that it is entirely up to the access method to ensure that it correctly finds all and only the entries passing all the given scan keys. Also, the core system will simply hand off all the WHERE - clauses that match the index keys and operator classes, without any + clauses that match the index keys and operator families, without any semantic analysis to determine whether they are redundant or contradictory. As an example, given WHERE x > 4 AND x > 14 where x is a b-tree diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml index 1edceebd2d..6ff9c4d4b4 100644 --- a/doc/src/sgml/indices.sgml +++ b/doc/src/sgml/indices.sgml @@ -1,4 +1,4 @@ - + Indexes @@ -784,12 +784,16 @@ CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) - Operator Classes + Operator Classes and Operator Families operator class + + operator family + + An index definition may specify an operator class for each column of an index. @@ -854,20 +858,32 @@ CREATE INDEX test_index ON test_table (col varchar_pattern_ops); SELECT am.amname AS index_method, opc.opcname AS opclass_name FROM pg_am am, pg_opclass opc - WHERE opc.opcamid = am.oid + WHERE opc.opcmethod = am.oid ORDER BY index_method, opclass_name; + - It can be extended to show all the operators included in each class: + + An operator class is actually just a subset of a larger structure called an + operator family. In cases where several data types have + similar behaviors, it is frequently useful to define cross-data-type + operators and allow these to work with indexes. To do this, the operator + classes for each of the types must be grouped into the same operator + family. The cross-type operators are members of the family, but are not + associated with any single class within the family. + + + + This query shows all defined operator families and all + the operators included in each family: SELECT am.amname AS index_method, - opc.opcname AS opclass_name, - opr.oid::regoperator AS opclass_operator - FROM pg_am am, pg_opclass opc, pg_amop amop, pg_operator opr - WHERE opc.opcamid = am.oid AND - amop.amopclaid = opc.oid AND - amop.amopopr = opr.oid - ORDER BY index_method, opclass_name, opclass_operator; + opf.opfname AS opfamily_name, + amop.amopopr::regoperator AS opfamily_operator + FROM pg_am am, pg_opfamily opf, pg_amop amop + WHERE opf.opfmethod = am.oid AND + amop.amopfamily = opf.oid + ORDER BY index_method, opfamily_name, opfamily_operator; diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml index 023a9e7cbe..955d9dbb2d 100644 --- a/doc/src/sgml/ref/create_operator.sgml +++ b/doc/src/sgml/ref/create_operator.sgml @@ -1,5 +1,5 @@ @@ -26,8 +26,6 @@ CREATE OPERATOR name ( [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ] [, RESTRICT = res_proc ] [, JOIN = join_proc ] [, HASHES ] [, MERGES ] - [, SORT1 = left_sort_op ] [, SORT2 = right_sort_op ] - [, LTCMP = less_than_op ] [, GTCMP = greater_than_op ] ) @@ -202,46 +200,6 @@ CREATE OPERATOR name ( - - - left_sort_op - - - If this operator can support a merge join, the less-than - operator that sorts the left-hand data type of this operator. - - - - - - right_sort_op - - - If this operator can support a merge join, the less-than - operator that sorts the right-hand data type of this operator. - - - - - - less_than_op - - - If this operator can support a merge join, the less-than - operator that compares the input data types of this operator. - - - - - - greater_than_op - - - If this operator can support a merge join, the greater-than - operator that compares the input data types of this operator. - - - @@ -261,6 +219,16 @@ COMMUTATOR = OPERATOR(myschema.===) , Refer to for further information. + + The obsolete options SORT1, SORT2, + LTCMP, and GTCMP were formerly used to + specify the names of sort operators associated with a mergejoinable + operator. This is no longer necessary, since information about + associated operators is found by looking at btree operator families + instead. If one of these options is given, it is ignored except + for implicitly setting MERGES true. + + Use to delete user-defined operators @@ -285,11 +253,7 @@ CREATE OPERATOR === ( NEGATOR = !==, RESTRICT = area_restriction_procedure, JOIN = area_join_procedure, - HASHES, - SORT1 = <<<, - SORT2 = <<< - -- Since sort operators were given, MERGES is implied. - -- LTCMP and GTCMP are assumed to be < and > respectively + HASHES, MERGES ); diff --git a/doc/src/sgml/xoper.sgml b/doc/src/sgml/xoper.sgml index 8a98018585..5f84393ed2 100644 --- a/doc/src/sgml/xoper.sgml +++ b/doc/src/sgml/xoper.sgml @@ -1,4 +1,4 @@ - + User-Defined Operators @@ -342,13 +342,13 @@ table1.column1 OP table2.column2 To be marked HASHES, the join operator must appear - in a hash index operator class. This is not enforced when you create - the operator, since of course the referencing operator class couldn't + in a hash index operator family. This is not enforced when you create + the operator, since of course the referencing operator family couldn't exist yet. But attempts to use the operator in hash joins will fail - at run time if no such operator class exists. The system needs the - operator class to find the data-type-specific hash function for the + at run time if no such operator family exists. The system needs the + operator family to find the data-type-specific hash function for the operator's input data type. Of course, you must also supply a suitable - hash function before you can create the operator class. + hash function before you can create the operator family. @@ -390,7 +390,7 @@ table1.column1 OP table2.column2 - <literal>MERGES</> (<literal>SORT1</>, <literal>SORT2</>, <literal>LTCMP</>, <literal>GTCMP</>) + <literal>MERGES</> The MERGES clause, if present, tells the system that @@ -418,36 +418,13 @@ table1.column1 OP table2.column2 - Execution of a merge join requires that the system be able to identify - four operators related to the merge-join equality operator: less-than - comparison for the left operand data type, less-than comparison for the - right operand data type, less-than comparison between the two data types, and - greater-than comparison between the two data types. (These are actually - four distinct operators if the merge-joinable operator has two different - operand data types; but when the operand types are the same the three - less-than operators are all the same operator.) - It is possible to - specify these operators individually by name, as the SORT1, - SORT2, LTCMP, and GTCMP options - respectively. The system will fill in the default names - <, <, <, > - respectively if any of these are omitted when MERGES is - specified. Also, MERGES will be assumed to be implied if any - of these four operator options appear, so it is possible to specify - just some of them and let the system fill in the rest. - - - - The operand data types of the four comparison operators can be deduced - from the operand types of the merge-joinable operator, so just as with - COMMUTATOR, only the operator names need be given in these - clauses. Unless you are using peculiar choices of operator names, - it's sufficient to write MERGES and let the system fill in - the details. - (As with COMMUTATOR and NEGATOR, the system is - able to make dummy - operator entries if you happen to define the equality operator before - the other ones.) + To be marked MERGES, the join operator must appear + in a btree index operator family. This is not enforced when you create + the operator, since of course the referencing operator family couldn't + exist yet. But the operator will not actually be used for merge joins + unless a matching operator family can be found. The + MERGES flag thus acts as a hint to the planner that + it's worth looking for a matching operator family. @@ -474,13 +451,6 @@ table1.column1 OP table2.column2 be transitive. - - - - Bizarre results will ensue at run time if the four comparison - operators you name do not sort the data values compatibly. - - @@ -491,17 +461,5 @@ table1.column1 OP table2.column2 attempt to use the operator for a merge join. - - - - In PostgreSQL versions before 7.3, - the MERGES shorthand was not available: to make a - merge-joinable operator one had to write both SORT1 and - SORT2 explicitly. Also, the LTCMP and - GTCMP - options did not exist; the names of those operators were hardwired as - < and > respectively. - - diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index 1e2d779a14..f6b39bada2 100644 --- a/src/backend/access/hash/hashfunc.c +++ b/src/backend/access/hash/hashfunc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.48 2006/10/04 00:29:48 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/hash/hashfunc.c,v 1.49 2006/12/23 00:43:08 tgl Exp $ * * NOTES * These functions are stored in pg_amproc. For each operator class @@ -46,11 +46,11 @@ hashint8(PG_FUNCTION_ARGS) { /* * The idea here is to produce a hash value compatible with the values - * produced by hashint4 and hashint2 for logically equivalent inputs; this - * is necessary if we ever hope to support cross-type hash joins across - * these input types. Since all three types are signed, we can xor the - * high half of the int8 value if the sign is positive, or the complement - * of the high half when the sign is negative. + * produced by hashint4 and hashint2 for logically equal inputs; this is + * necessary to support cross-type hash joins across these input types. + * Since all three types are signed, we can xor the high half of the int8 + * value if the sign is positive, or the complement of the high half when + * the sign is negative. */ #ifndef INT64_IS_BUSTED int64 val = PG_GETARG_INT64(0); @@ -76,16 +76,26 @@ Datum hashfloat4(PG_FUNCTION_ARGS) { float4 key = PG_GETARG_FLOAT4(0); + float8 key8; /* * On IEEE-float machines, minus zero and zero have different bit patterns * but should compare as equal. We must ensure that they have the same - * hash value, which is most easily done this way: + * hash value, which is most reliably done this way: */ if (key == (float4) 0) PG_RETURN_UINT32(0); - return hash_any((unsigned char *) &key, sizeof(key)); + /* + * To support cross-type hashing of float8 and float4, we want to return + * the same hash value hashfloat8 would produce for an equal float8 value. + * So, widen the value to float8 and hash that. (We must do this rather + * than have hashfloat8 try to narrow its value to float4; that could + * fail on overflow.) + */ + key8 = key; + + return hash_any((unsigned char *) &key8, sizeof(key8)); } Datum @@ -96,7 +106,7 @@ hashfloat8(PG_FUNCTION_ARGS) /* * On IEEE-float machines, minus zero and zero have different bit patterns * but should compare as equal. We must ensure that they have the same - * hash value, which is most easily done this way: + * hash value, which is most reliably done this way: */ if (key == (float8) 0) PG_RETURN_UINT32(0); diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 493e9f0ad0..6d60f46178 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.95 2006/10/04 00:29:48 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.96 2006/12/23 00:43:08 tgl Exp $ * * INTERFACE ROUTINES * index_open - open an index relation by relation OID @@ -608,17 +608,27 @@ index_vacuum_cleanup(IndexVacuumInfo *info, /* ---------------- * index_getprocid * - * Some indexed access methods may require support routines that are - * not in the operator class/operator model imposed by pg_am. These - * access methods may store the OIDs of registered procedures they - * need in pg_amproc. These registered procedure OIDs are ordered in - * a way that makes sense to the access method, and used only by the - * access method. The general index code doesn't know anything about - * the routines involved; it just builds an ordered list of them for + * Index access methods typically require support routines that are + * not directly the implementation of any WHERE-clause query operator + * and so cannot be kept in pg_amop. Instead, such routines are kept + * in pg_amproc. These registered procedure OIDs are assigned numbers + * according to a convention established by the access method. + * The general index code doesn't know anything about the routines + * involved; it just builds an ordered list of them for * each attribute on which an index is defined. * - * This routine returns the requested procedure OID for a particular - * indexed attribute. + * As of Postgres 8.3, support routines within an operator family + * are further subdivided by the "left type" and "right type" of the + * query operator(s) that they support. The "default" functions for a + * particular indexed attribute are those with both types equal to + * the index opclass' opcintype (note that this is subtly different + * from the indexed attribute's own type: it may be a binary-compatible + * type instead). Only the default functions are stored in relcache + * entries --- access methods can use the syscache to look up non-default + * functions. + * + * This routine returns the requested default procedure OID for a + * particular indexed attribute. * ---------------- */ RegProcedure @@ -647,7 +657,8 @@ index_getprocid(Relation irel, * index_getprocinfo * * This routine allows index AMs to keep fmgr lookup info for - * support procs in the relcache. + * support procs in the relcache. As above, only the "default" + * functions for any particular indexed attribute are cached. * * Note: the return value points into cached data that will be lost during * any relcache rebuild! Therefore, either use the callinfo right away, diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 6d9be1b017..284b92e0d2 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.107 2006/10/04 00:29:49 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.108 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -658,11 +658,14 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) * to an insertion scan key by replacing the sk_func with the * appropriate btree comparison function. * - * If scankey operator is of default subtype, we can use the - * cached comparison function; otherwise gotta look it up in the - * catalogs. + * If scankey operator is of the default type for the index, we + * can use the cached comparison function; otherwise gotta look it + * up in the catalogs. Also, we support the convention that + * sk_subtype == 0 means the default type; this is a hack to + * simplify life for ScanKeyInit(). */ - if (cur->sk_subtype == InvalidOid) + if (cur->sk_subtype == rel->rd_opcintype[i] || + cur->sk_subtype == InvalidOid) { FmgrInfo *procinfo; @@ -671,7 +674,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) cur->sk_flags, cur->sk_attno, InvalidStrategy, - InvalidOid, + cur->sk_subtype, procinfo, cur->sk_argument); } @@ -679,9 +682,14 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) { RegProcedure cmp_proc; - cmp_proc = get_opclass_proc(rel->rd_indclass->values[i], - cur->sk_subtype, - BTORDER_PROC); + cmp_proc = get_opfamily_proc(rel->rd_opfamily[i], + rel->rd_opcintype[i], + cur->sk_subtype, + BTORDER_PROC); + if (!RegProcedureIsValid(cmp_proc)) + elog(ERROR, "missing support function %d(%u,%u) for attribute %d of index \"%s\"", + BTORDER_PROC, rel->rd_opcintype[i], cur->sk_subtype, + cur->sk_attno, RelationGetRelationName(rel)); ScanKeyEntryInitialize(scankeys + i, cur->sk_flags, cur->sk_attno, diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index 2e2d885f89..110619425b 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/catalog # -# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.60 2006/07/31 01:16:36 tgl Exp $ +# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.61 2006/12/23 00:43:09 tgl Exp $ # #------------------------------------------------------------------------- @@ -28,8 +28,8 @@ SUBSYS.o: $(OBJS) POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_autovacuum.h \ - pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h \ - pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ + pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \ + pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \ pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \ pg_namespace.h pg_conversion.h pg_depend.h \ diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index cab4f1006b..770b189606 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.60 2006/10/04 00:29:50 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.61 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,6 +22,8 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/pg_amop.h" +#include "catalog/pg_amproc.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_authid.h" #include "catalog/pg_cast.h" @@ -33,6 +35,7 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_proc.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_tablespace.h" @@ -78,19 +81,25 @@ typedef struct * See also getObjectClass(). */ static const Oid object_classes[MAX_OCLASS] = { - RelationRelationId, /* OCLASS_CLASS */ - ProcedureRelationId, /* OCLASS_PROC */ - TypeRelationId, /* OCLASS_TYPE */ - CastRelationId, /* OCLASS_CAST */ - ConstraintRelationId, /* OCLASS_CONSTRAINT */ - ConversionRelationId, /* OCLASS_CONVERSION */ - AttrDefaultRelationId, /* OCLASS_DEFAULT */ - LanguageRelationId, /* OCLASS_LANGUAGE */ - OperatorRelationId, /* OCLASS_OPERATOR */ - OperatorClassRelationId, /* OCLASS_OPCLASS */ - RewriteRelationId, /* OCLASS_REWRITE */ - TriggerRelationId, /* OCLASS_TRIGGER */ - NamespaceRelationId /* OCLASS_SCHEMA */ + RelationRelationId, /* OCLASS_CLASS */ + ProcedureRelationId, /* OCLASS_PROC */ + TypeRelationId, /* OCLASS_TYPE */ + CastRelationId, /* OCLASS_CAST */ + ConstraintRelationId, /* OCLASS_CONSTRAINT */ + ConversionRelationId, /* OCLASS_CONVERSION */ + AttrDefaultRelationId, /* OCLASS_DEFAULT */ + LanguageRelationId, /* OCLASS_LANGUAGE */ + OperatorRelationId, /* OCLASS_OPERATOR */ + OperatorClassRelationId, /* OCLASS_OPCLASS */ + OperatorFamilyRelationId, /* OCLASS_OPFAMILY */ + AccessMethodOperatorRelationId, /* OCLASS_AMOP */ + AccessMethodProcedureRelationId, /* OCLASS_AMPROC */ + RewriteRelationId, /* OCLASS_REWRITE */ + TriggerRelationId, /* OCLASS_TRIGGER */ + NamespaceRelationId, /* OCLASS_SCHEMA */ + AuthIdRelationId, /* OCLASS_ROLE */ + DatabaseRelationId, /* OCLASS_DATABASE */ + TableSpaceRelationId /* OCLASS_TBLSPACE */ }; @@ -122,6 +131,7 @@ static int object_address_comparator(const void *a, const void *b); static void add_object_address(ObjectClass oclass, Oid objectId, int32 subId, ObjectAddresses *addrs); static void getRelationDescription(StringInfo buffer, Oid relid); +static void getOpFamilyDescription(StringInfo buffer, Oid opfid); /* @@ -185,7 +195,7 @@ performDeletion(const ObjectAddress *object, * filled with some objects. Also, the deleted objects are saved in the * alreadyDeleted list. * - * XXX performDeletion could be refactored to be a thin wrapper to this + * XXX performDeletion could be refactored to be a thin wrapper around this * function. */ static void @@ -954,6 +964,18 @@ doDeletion(const ObjectAddress *object) RemoveOpClassById(object->objectId); break; + case OCLASS_OPFAMILY: + RemoveOpFamilyById(object->objectId); + break; + + case OCLASS_AMOP: + RemoveAmOpEntryById(object->objectId); + break; + + case OCLASS_AMPROC: + RemoveAmProcEntryById(object->objectId); + break; + case OCLASS_REWRITE: RemoveRewriteRuleById(object->objectId); break; @@ -966,6 +988,8 @@ doDeletion(const ObjectAddress *object) RemoveSchemaById(object->objectId); break; + /* OCLASS_ROLE, OCLASS_DATABASE, OCLASS_TBLSPACE not handled */ + default: elog(ERROR, "unrecognized object class: %u", object->classId); @@ -1316,9 +1340,9 @@ find_expr_references_walker(Node *node, add_object_address(OCLASS_OPERATOR, lfirst_oid(l), 0, context->addrs); } - foreach(l, rcexpr->opclasses) + foreach(l, rcexpr->opfamilies) { - add_object_address(OCLASS_OPCLASS, lfirst_oid(l), 0, + add_object_address(OCLASS_OPFAMILY, lfirst_oid(l), 0, context->addrs); } /* fall through to examine arguments */ @@ -1623,6 +1647,18 @@ getObjectClass(const ObjectAddress *object) Assert(object->objectSubId == 0); return OCLASS_OPCLASS; + case OperatorFamilyRelationId: + Assert(object->objectSubId == 0); + return OCLASS_OPFAMILY; + + case AccessMethodOperatorRelationId: + Assert(object->objectSubId == 0); + return OCLASS_AMOP; + + case AccessMethodProcedureRelationId: + Assert(object->objectSubId == 0); + return OCLASS_AMPROC; + case RewriteRelationId: Assert(object->objectSubId == 0); return OCLASS_REWRITE; @@ -1856,11 +1892,11 @@ getObjectDescription(const ObjectAddress *object) opcForm = (Form_pg_opclass) GETSTRUCT(opcTup); amTup = SearchSysCache(AMOID, - ObjectIdGetDatum(opcForm->opcamid), + ObjectIdGetDatum(opcForm->opcmethod), 0, 0, 0); if (!HeapTupleIsValid(amTup)) elog(ERROR, "cache lookup failed for access method %u", - opcForm->opcamid); + opcForm->opcmethod); amForm = (Form_pg_am) GETSTRUCT(amTup); /* Qualify the name if not visible in search path */ @@ -1879,6 +1915,84 @@ getObjectDescription(const ObjectAddress *object) break; } + case OCLASS_OPFAMILY: + getOpFamilyDescription(&buffer, object->objectId); + break; + + case OCLASS_AMOP: + { + Relation amopDesc; + ScanKeyData skey[1]; + SysScanDesc amscan; + HeapTuple tup; + Form_pg_amop amopForm; + + amopDesc = heap_open(AccessMethodOperatorRelationId, + AccessShareLock); + + ScanKeyInit(&skey[0], + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId)); + + amscan = systable_beginscan(amopDesc, AccessMethodOperatorOidIndexId, true, + SnapshotNow, 1, skey); + + tup = systable_getnext(amscan); + + if (!HeapTupleIsValid(tup)) + elog(ERROR, "could not find tuple for amop entry %u", + object->objectId); + + amopForm = (Form_pg_amop) GETSTRUCT(tup); + + appendStringInfo(&buffer, _("operator %d %s of "), + amopForm->amopstrategy, + format_operator(amopForm->amopopr)); + getOpFamilyDescription(&buffer, amopForm->amopfamily); + + systable_endscan(amscan); + heap_close(amopDesc, AccessShareLock); + break; + } + + case OCLASS_AMPROC: + { + Relation amprocDesc; + ScanKeyData skey[1]; + SysScanDesc amscan; + HeapTuple tup; + Form_pg_amproc amprocForm; + + amprocDesc = heap_open(AccessMethodProcedureRelationId, + AccessShareLock); + + ScanKeyInit(&skey[0], + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId)); + + amscan = systable_beginscan(amprocDesc, AccessMethodProcedureOidIndexId, true, + SnapshotNow, 1, skey); + + tup = systable_getnext(amscan); + + if (!HeapTupleIsValid(tup)) + elog(ERROR, "could not find tuple for amproc entry %u", + object->objectId); + + amprocForm = (Form_pg_amproc) GETSTRUCT(tup); + + appendStringInfo(&buffer, _("function %d %s of "), + amprocForm->amprocnum, + format_procedure(amprocForm->amproc)); + getOpFamilyDescription(&buffer, amprocForm->amprocfamily); + + systable_endscan(amscan); + heap_close(amprocDesc, AccessShareLock); + break; + } + case OCLASS_REWRITE: { Relation ruleDesc; @@ -2068,3 +2182,45 @@ getRelationDescription(StringInfo buffer, Oid relid) ReleaseSysCache(relTup); } + +/* + * subroutine for getObjectDescription: describe an operator family + */ +static void +getOpFamilyDescription(StringInfo buffer, Oid opfid) +{ + HeapTuple opfTup; + Form_pg_opfamily opfForm; + HeapTuple amTup; + Form_pg_am amForm; + char *nspname; + + opfTup = SearchSysCache(OPFAMILYOID, + ObjectIdGetDatum(opfid), + 0, 0, 0); + if (!HeapTupleIsValid(opfTup)) + elog(ERROR, "cache lookup failed for opfamily %u", opfid); + opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup); + + amTup = SearchSysCache(AMOID, + ObjectIdGetDatum(opfForm->opfmethod), + 0, 0, 0); + if (!HeapTupleIsValid(amTup)) + elog(ERROR, "cache lookup failed for access method %u", + opfForm->opfmethod); + amForm = (Form_pg_am) GETSTRUCT(amTup); + + /* Qualify the name if not visible in search path */ + if (OpfamilyIsVisible(opfid)) + nspname = NULL; + else + nspname = get_namespace_name(opfForm->opfnamespace); + + appendStringInfo(buffer, _("operator family %s for access method %s"), + quote_qualified_identifier(nspname, + NameStr(opfForm->opfname)), + NameStr(amForm->amname)); + + ReleaseSysCache(amTup); + ReleaseSysCache(opfTup); +} diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 1d6162ca12..5c661a098b 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.88 2006/10/04 00:29:50 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.89 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" @@ -1062,7 +1063,7 @@ OpclassIsVisible(Oid opcid) */ char *opcname = NameStr(opcform->opcname); - visible = (OpclassnameGetOpcid(opcform->opcamid, opcname) == opcid); + visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid); } ReleaseSysCache(opctup); @@ -1070,6 +1071,89 @@ OpclassIsVisible(Oid opcid) return visible; } +/* + * OpfamilynameGetOpfid + * Try to resolve an unqualified index opfamily name. + * Returns OID if opfamily found in search path, else InvalidOid. + * + * This is essentially the same as TypenameGetTypid, but we have to have + * an extra argument for the index AM OID. + */ +Oid +OpfamilynameGetOpfid(Oid amid, const char *opfname) +{ + Oid opfid; + ListCell *l; + + recomputeNamespacePath(); + + foreach(l, namespaceSearchPath) + { + Oid namespaceId = lfirst_oid(l); + + opfid = GetSysCacheOid(OPFAMILYAMNAMENSP, + ObjectIdGetDatum(amid), + PointerGetDatum(opfname), + ObjectIdGetDatum(namespaceId), + 0); + if (OidIsValid(opfid)) + return opfid; + } + + /* Not found in path */ + return InvalidOid; +} + +/* + * OpfamilyIsVisible + * Determine whether an opfamily (identified by OID) is visible in the + * current search path. Visible means "would be found by searching + * for the unqualified opfamily name". + */ +bool +OpfamilyIsVisible(Oid opfid) +{ + HeapTuple opftup; + Form_pg_opfamily opfform; + Oid opfnamespace; + bool visible; + + opftup = SearchSysCache(OPFAMILYOID, + ObjectIdGetDatum(opfid), + 0, 0, 0); + if (!HeapTupleIsValid(opftup)) + elog(ERROR, "cache lookup failed for opfamily %u", opfid); + opfform = (Form_pg_opfamily) GETSTRUCT(opftup); + + recomputeNamespacePath(); + + /* + * Quick check: if it ain't in the path at all, it ain't visible. Items in + * the system namespace are surely in the path and so we needn't even do + * list_member_oid() for them. + */ + opfnamespace = opfform->opfnamespace; + if (opfnamespace != PG_CATALOG_NAMESPACE && + !list_member_oid(namespaceSearchPath, opfnamespace)) + visible = false; + else + { + /* + * If it is in the path, it might still not be visible; it could be + * hidden by another opfamily of the same name earlier in the path. So + * we must do a slow check to see if this opfamily would be found by + * OpfamilynameGetOpfid. + */ + char *opfname = NameStr(opfform->opfname); + + visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid); + } + + ReleaseSysCache(opftup); + + return visible; +} + /* * ConversionGetConid * Try to resolve an unqualified conversion name. diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 13efb7227a..65ecb65b92 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.98 2006/07/14 14:52:18 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.99 2006/12/23 00:43:09 tgl Exp $ * * NOTES * these routines moved here from commands/define.c and somewhat cleaned up. @@ -238,16 +238,13 @@ OperatorShellMake(const char *operatorName, values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */ values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */ values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */ + values[i++] = BoolGetDatum(false); /* oprcanmerge */ values[i++] = BoolGetDatum(false); /* oprcanhash */ values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */ values[i++] = ObjectIdGetDatum(rightTypeId); /* oprright */ values[i++] = ObjectIdGetDatum(InvalidOid); /* oprresult */ values[i++] = ObjectIdGetDatum(InvalidOid); /* oprcom */ values[i++] = ObjectIdGetDatum(InvalidOid); /* oprnegate */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* oprlsortop */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* oprrsortop */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* oprltcmpop */ - values[i++] = ObjectIdGetDatum(InvalidOid); /* oprgtcmpop */ values[i++] = ObjectIdGetDatum(InvalidOid); /* oprcode */ values[i++] = ObjectIdGetDatum(InvalidOid); /* oprrest */ values[i++] = ObjectIdGetDatum(InvalidOid); /* oprjoin */ @@ -296,11 +293,8 @@ OperatorShellMake(const char *operatorName, * negatorName X negator operator * restrictionName X restriction sel. procedure * joinName X join sel. procedure + * canMerge merge join can be used with this operator * canHash hash join can be used with this operator - * leftSortName X left sort operator (for merge join) - * rightSortName X right sort operator (for merge join) - * ltCompareName X LR compare operator (for merge join) * * This routine gets complicated because it allows the user to * specify operators that do not exist. For example, if operator @@ -326,6 +320,7 @@ OperatorShellMake(const char *operatorName, * operatorName * owner id (simply the user id of the caller) * operator "kind" either "b" for binary or "l" for left unary + * canMerge boolean * canHash boolean * leftTypeObjectId -- type must already be defined * rightTypeObjectId -- this is optional, enter ObjectId=0 if none specified @@ -341,8 +336,6 @@ OperatorShellMake(const char *operatorName, * (We are creating a self-commutating operator.) * The link will be fixed later by OperatorUpd. * negatorObjectId -- same as for commutatorObjectId - * leftSortObjectId -- same as for commutatorObjectId - * rightSortObjectId -- same as for commutatorObjectId * operatorProcedure -- must access the pg_procedure catalog to get the * ObjectId of the procedure that actually does the operator * actions this is required. Do a lookup to find out the @@ -369,11 +362,8 @@ OperatorCreate(const char *operatorName, List *negatorName, List *restrictionName, List *joinName, - bool canHash, - List *leftSortName, - List *rightSortName, - List *ltCompareName, - List *gtCompareName) + bool canMerge, + bool canHash) { Relation pg_operator_desc; HeapTuple tup; @@ -386,10 +376,6 @@ OperatorCreate(const char *operatorName, Oid operResultType; Oid commutatorId, negatorId, - leftSortId, - rightSortId, - ltCompareId, - gtCompareId, restOid, joinOid; bool selfCommutator = false; @@ -424,14 +410,14 @@ OperatorCreate(const char *operatorName, ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("only binary operators can have join selectivity"))); + if (canMerge) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only binary operators can merge join"))); if (canHash) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("only binary operators can hash"))); - if (leftSortName || rightSortName || ltCompareName || gtCompareName) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only binary operators can merge join"))); } operatorObjectId = OperatorGet(operatorName, @@ -522,6 +508,7 @@ OperatorCreate(const char *operatorName, values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */ values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */ values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */ + values[i++] = BoolGetDatum(canMerge); /* oprcanmerge */ values[i++] = BoolGetDatum(canHash); /* oprcanhash */ values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */ values[i++] = ObjectIdGetDatum(rightTypeId); /* oprright */ @@ -565,58 +552,6 @@ OperatorCreate(const char *operatorName, negatorId = InvalidOid; values[i++] = ObjectIdGetDatum(negatorId); /* oprnegate */ - if (leftSortName) - { - /* left sort op takes left-side data type */ - leftSortId = get_other_operator(leftSortName, - leftTypeId, leftTypeId, - operatorName, operatorNamespace, - leftTypeId, rightTypeId, - false); - } - else - leftSortId = InvalidOid; - values[i++] = ObjectIdGetDatum(leftSortId); /* oprlsortop */ - - if (rightSortName) - { - /* right sort op takes right-side data type */ - rightSortId = get_other_operator(rightSortName, - rightTypeId, rightTypeId, - operatorName, operatorNamespace, - leftTypeId, rightTypeId, - false); - } - else - rightSortId = InvalidOid; - values[i++] = ObjectIdGetDatum(rightSortId); /* oprrsortop */ - - if (ltCompareName) - { - /* comparator has same arg types */ - ltCompareId = get_other_operator(ltCompareName, - leftTypeId, rightTypeId, - operatorName, operatorNamespace, - leftTypeId, rightTypeId, - false); - } - else - ltCompareId = InvalidOid; - values[i++] = ObjectIdGetDatum(ltCompareId); /* oprltcmpop */ - - if (gtCompareName) - { - /* comparator has same arg types */ - gtCompareId = get_other_operator(gtCompareName, - leftTypeId, rightTypeId, - operatorName, operatorNamespace, - leftTypeId, rightTypeId, - false); - } - else - gtCompareId = InvalidOid; - values[i++] = ObjectIdGetDatum(gtCompareId); /* oprgtcmpop */ - values[i++] = ObjectIdGetDatum(procOid); /* oprcode */ values[i++] = ObjectIdGetDatum(restOid); /* oprrest */ values[i++] = ObjectIdGetDatum(joinOid); /* oprjoin */ @@ -930,12 +865,11 @@ makeOperatorDependencies(HeapTuple tuple) /* * NOTE: we do not consider the operator to depend on the associated - * operators oprcom, oprnegate, oprlsortop, oprrsortop, oprltcmpop, - * oprgtcmpop. We would not want to delete this operator if those go - * away, but only reset the link fields; which is not a function that the - * dependency code can presently handle. (Something could perhaps be done - * with objectSubId though.) For now, it's okay to let those links dangle - * if a referenced operator is removed. + * operators oprcom and oprnegate. We would not want to delete this + * operator if those go away, but only reset the link fields; which is not + * a function that the dependency code can presently handle. (Something + * could perhaps be done with objectSubId though.) For now, it's okay to + * let those links dangle if a referenced operator is removed. */ /* Dependency on implementation function */ diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 5f54f66f59..a5cc047c69 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.149 2006/10/04 00:29:51 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.150 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -802,31 +802,37 @@ GetIndexOpClass(List *opclass, Oid attrType, Oid GetDefaultOpClass(Oid type_id, Oid am_id) { + Oid result = InvalidOid; int nexact = 0; int ncompatible = 0; - Oid exactOid = InvalidOid; - Oid compatibleOid = InvalidOid; + int ncompatiblepreferred = 0; Relation rel; ScanKeyData skey[1]; SysScanDesc scan; HeapTuple tup; + CATEGORY tcategory; /* If it's a domain, look at the base type instead */ type_id = getBaseType(type_id); + tcategory = TypeCategory(type_id); + /* * We scan through all the opclasses available for the access method, * looking for one that is marked default and matches the target type * (either exactly or binary-compatibly, but prefer an exact match). * - * We could find more than one binary-compatible match, in which case we - * require the user to specify which one he wants. If we find more than - * one exact match, then someone put bogus entries in pg_opclass. + * We could find more than one binary-compatible match. If just one is + * for a preferred type, use that one; otherwise we fail, forcing the user + * to specify which one he wants. (The preferred-type special case is a + * kluge for varchar: it's binary-compatible to both text and bpchar, so + * we need a tiebreaker.) If we find more than one exact match, then + * someone put bogus entries in pg_opclass. */ rel = heap_open(OperatorClassRelationId, AccessShareLock); ScanKeyInit(&skey[0], - Anum_pg_opclass_opcamid, + Anum_pg_opclass_opcmethod, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(am_id)); @@ -837,17 +843,26 @@ GetDefaultOpClass(Oid type_id, Oid am_id) { Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tup); - if (opclass->opcdefault) + /* ignore altogether if not a default opclass */ + if (!opclass->opcdefault) + continue; + if (opclass->opcintype == type_id) { - if (opclass->opcintype == type_id) + nexact++; + result = HeapTupleGetOid(tup); + } + else if (nexact == 0 && + IsBinaryCoercible(type_id, opclass->opcintype)) + { + if (IsPreferredType(tcategory, opclass->opcintype)) { - nexact++; - exactOid = HeapTupleGetOid(tup); + ncompatiblepreferred++; + result = HeapTupleGetOid(tup); } - else if (IsBinaryCoercible(type_id, opclass->opcintype)) + else if (ncompatiblepreferred == 0) { ncompatible++; - compatibleOid = HeapTupleGetOid(tup); + result = HeapTupleGetOid(tup); } } } @@ -856,15 +871,17 @@ GetDefaultOpClass(Oid type_id, Oid am_id) heap_close(rel, AccessShareLock); - if (nexact == 1) - return exactOid; - if (nexact != 0) + /* raise error if pg_opclass contains inconsistent data */ + if (nexact > 1) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("there are multiple default operator classes for data type %s", format_type_be(type_id)))); - if (ncompatible == 1) - return compatibleOid; + + if (nexact == 1 || + ncompatiblepreferred == 1 || + (ncompatiblepreferred == 0 && ncompatible == 1)) + return result; return InvalidOid; } diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index d4dec74650..8b1b27ef3e 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -2,14 +2,14 @@ * * opclasscmds.c * - * Routines for opclass manipulation commands + * Routines for opclass (and opfamily) manipulation commands * * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.50 2006/12/18 18:56:28 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.51 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,6 +26,7 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "commands/defrem.h" @@ -42,26 +43,186 @@ /* * We use lists of this struct type to keep track of both operators and - * procedures during DefineOpClass. + * procedures while building or adding to an opfamily. */ typedef struct { Oid object; /* operator or support proc's OID */ int number; /* strategy or support proc number */ - Oid subtype; /* subtype */ + Oid lefttype; /* lefttype */ + Oid righttype; /* righttype */ bool recheck; /* oper recheck flag (unused for proc) */ -} OpClassMember; +} OpFamilyMember; -static Oid assignOperSubtype(Oid amoid, Oid typeoid, Oid operOid); -static Oid assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid); -static void addClassMember(List **list, OpClassMember *member, bool isProc); -static void storeOperators(Oid opclassoid, List *operators); -static void storeProcedures(Oid opclassoid, List *procedures); +static void assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid); +static void assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid); +static void addFamilyMember(List **list, OpFamilyMember *member, bool isProc); +static void storeOperators(Oid amoid, Oid opfamilyoid, Oid opclassoid, + List *operators); +static void storeProcedures(Oid amoid, Oid opfamilyoid, Oid opclassoid, + List *procedures); static void AlterOpClassOwner_internal(Relation rel, HeapTuple tuple, Oid newOwnerId); +/* + * OpFamilyCacheLookup + * Look up an existing opfamily by name. + * + * Returns a syscache tuple reference, or NULL if not found. + */ +static HeapTuple +OpFamilyCacheLookup(Oid amID, List *opfamilyname) +{ + char *schemaname; + char *opfname; + + /* deconstruct the name list */ + DeconstructQualifiedName(opfamilyname, &schemaname, &opfname); + + if (schemaname) + { + /* Look in specific schema only */ + Oid namespaceId; + + namespaceId = LookupExplicitNamespace(schemaname); + return SearchSysCache(OPFAMILYAMNAMENSP, + ObjectIdGetDatum(amID), + PointerGetDatum(opfname), + ObjectIdGetDatum(namespaceId), + 0); + } + else + { + /* Unqualified opfamily name, so search the search path */ + Oid opfID = OpfamilynameGetOpfid(amID, opfname); + + if (!OidIsValid(opfID)) + return NULL; + return SearchSysCache(OPFAMILYOID, + ObjectIdGetDatum(opfID), + 0, 0, 0); + } +} + +/* + * OpClassCacheLookup + * Look up an existing opclass by name. + * + * Returns a syscache tuple reference, or NULL if not found. + */ +static HeapTuple +OpClassCacheLookup(Oid amID, List *opclassname) +{ + char *schemaname; + char *opcname; + + /* deconstruct the name list */ + DeconstructQualifiedName(opclassname, &schemaname, &opcname); + + if (schemaname) + { + /* Look in specific schema only */ + Oid namespaceId; + + namespaceId = LookupExplicitNamespace(schemaname); + return SearchSysCache(CLAAMNAMENSP, + ObjectIdGetDatum(amID), + PointerGetDatum(opcname), + ObjectIdGetDatum(namespaceId), + 0); + } + else + { + /* Unqualified opclass name, so search the search path */ + Oid opcID = OpclassnameGetOpcid(amID, opcname); + + if (!OidIsValid(opcID)) + return NULL; + return SearchSysCache(CLAOID, + ObjectIdGetDatum(opcID), + 0, 0, 0); + } +} + +/* + * CreateOpFamily + * Internal routine to make the catalog entry for a new operator family. + * + * Caller must have done permissions checks etc. already. + */ +static Oid +CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid) +{ + Oid opfamilyoid; + Relation rel; + HeapTuple tup; + Datum values[Natts_pg_opfamily]; + char nulls[Natts_pg_opfamily]; + NameData opfName; + ObjectAddress myself, + referenced; + + rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock); + + /* + * Make sure there is no existing opfamily of this name (this is just to + * give a more friendly error message than "duplicate key"). + */ + if (SearchSysCacheExists(OPFAMILYAMNAMENSP, + ObjectIdGetDatum(amoid), + CStringGetDatum(opfname), + ObjectIdGetDatum(namespaceoid), + 0)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("operator family \"%s\" for access method \"%s\" already exists", + opfname, amname))); + + /* + * Okay, let's create the pg_opfamily entry. + */ + memset(values, 0, sizeof(values)); + memset(nulls, ' ', sizeof(nulls)); + + values[Anum_pg_opfamily_opfmethod - 1] = ObjectIdGetDatum(amoid); + namestrcpy(&opfName, opfname); + values[Anum_pg_opfamily_opfname - 1] = NameGetDatum(&opfName); + values[Anum_pg_opfamily_opfnamespace - 1] = ObjectIdGetDatum(namespaceoid); + values[Anum_pg_opfamily_opfowner - 1] = ObjectIdGetDatum(GetUserId()); + + tup = heap_formtuple(rel->rd_att, values, nulls); + + opfamilyoid = simple_heap_insert(rel, tup); + + CatalogUpdateIndexes(rel, tup); + + heap_freetuple(tup); + + /* + * Create dependencies for the opfamily proper. Note: we do not create a + * dependency link to the AM, because we don't currently support DROP + * ACCESS METHOD. + */ + myself.classId = OperatorFamilyRelationId; + myself.objectId = opfamilyoid; + myself.objectSubId = 0; + + /* dependency on namespace */ + referenced.classId = NamespaceRelationId; + referenced.objectId = namespaceoid; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + + /* dependency on owner */ + recordDependencyOnOwner(OperatorFamilyRelationId, opfamilyoid, GetUserId()); + + heap_close(rel, RowExclusiveLock); + + return opfamilyoid; +} + /* * DefineOpClass * Define a new index operator class. @@ -74,12 +235,13 @@ DefineOpClass(CreateOpClassStmt *stmt) typeoid, /* indexable datatype oid */ storageoid, /* storage datatype oid, if any */ namespaceoid, /* namespace to create opclass in */ + opfamilyoid, /* oid of containing opfamily */ opclassoid; /* oid of opclass we create */ int maxOpNumber, /* amstrategies value */ maxProcNumber; /* amsupport value */ bool amstorage; /* amstorage flag */ - List *operators; /* OpClassMember list for operators */ - List *procedures; /* OpClassMember list for support procs */ + List *operators; /* OpFamilyMember list for operators */ + List *procedures; /* OpFamilyMember list for support procs */ ListCell *l; Relation rel; HeapTuple tup; @@ -88,7 +250,6 @@ DefineOpClass(CreateOpClassStmt *stmt) char nulls[Natts_pg_opclass]; AclResult aclresult; NameData opcName; - int i; ObjectAddress myself, referenced; @@ -161,6 +322,52 @@ DefineOpClass(CreateOpClassStmt *stmt) format_type_be(typeoid)); #endif + /* + * Look up the containing operator family, or create one if FAMILY option + * was omitted and there's not a match already. + */ + if (stmt->opfamilyname) + { + tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname); + if (!HeapTupleIsValid(tup)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("operator family \"%s\" does not exist for access method \"%s\"", + NameListToString(stmt->opfamilyname), stmt->amname))); + opfamilyoid = HeapTupleGetOid(tup); + /* + * XXX given the superuser check above, there's no need for an + * ownership check here + */ + ReleaseSysCache(tup); + } + else + { + /* Lookup existing family of same name and namespace */ + tup = SearchSysCache(OPFAMILYAMNAMENSP, + ObjectIdGetDatum(amoid), + PointerGetDatum(opcname), + ObjectIdGetDatum(namespaceoid), + 0); + if (HeapTupleIsValid(tup)) + { + opfamilyoid = HeapTupleGetOid(tup); + /* + * XXX given the superuser check above, there's no need for an + * ownership check here + */ + ReleaseSysCache(tup); + } + else + { + /* + * Create it ... again no need for more permissions ... + */ + opfamilyoid = CreateOpFamily(stmt->amname, opcname, + namespaceoid, amoid); + } + } + operators = NIL; procedures = NIL; @@ -175,7 +382,7 @@ DefineOpClass(CreateOpClassStmt *stmt) CreateOpClassItem *item = lfirst(l); Oid operOid; Oid funcOid; - OpClassMember *member; + OpFamilyMember *member; Assert(IsA(item, CreateOpClassItem)); switch (item->itemtype) @@ -217,12 +424,12 @@ DefineOpClass(CreateOpClassStmt *stmt) #endif /* Save the info */ - member = (OpClassMember *) palloc0(sizeof(OpClassMember)); + member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); member->object = operOid; member->number = item->number; - member->subtype = assignOperSubtype(amoid, typeoid, operOid); member->recheck = item->recheck; - addClassMember(&operators, member, false); + assignOperTypes(member, amoid, typeoid); + addFamilyMember(&operators, member, false); break; case OPCLASS_ITEM_FUNCTION: if (item->number <= 0 || item->number > maxProcNumber) @@ -242,11 +449,11 @@ DefineOpClass(CreateOpClassStmt *stmt) #endif /* Save the info */ - member = (OpClassMember *) palloc0(sizeof(OpClassMember)); + member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); member->object = funcOid; member->number = item->number; - member->subtype = assignProcSubtype(amoid, typeoid, funcOid); - addClassMember(&procedures, member, true); + assignProcTypes(member, amoid, typeoid); + addFamilyMember(&procedures, member, true); break; case OPCLASS_ITEM_STORAGETYPE: if (OidIsValid(storageoid)) @@ -311,7 +518,7 @@ DefineOpClass(CreateOpClassStmt *stmt) SysScanDesc scan; ScanKeyInit(&skey[0], - Anum_pg_opclass_opcamid, + Anum_pg_opclass_opcmethod, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(amoid)); @@ -338,21 +545,18 @@ DefineOpClass(CreateOpClassStmt *stmt) /* * Okay, let's create the pg_opclass entry. */ - for (i = 0; i < Natts_pg_opclass; ++i) - { - nulls[i] = ' '; - values[i] = (Datum) NULL; /* redundant, but safe */ - } + memset(values, 0, sizeof(values)); + memset(nulls, ' ', sizeof(nulls)); - i = 0; - values[i++] = ObjectIdGetDatum(amoid); /* opcamid */ + values[Anum_pg_opclass_opcmethod - 1] = ObjectIdGetDatum(amoid); namestrcpy(&opcName, opcname); - values[i++] = NameGetDatum(&opcName); /* opcname */ - values[i++] = ObjectIdGetDatum(namespaceoid); /* opcnamespace */ - values[i++] = ObjectIdGetDatum(GetUserId()); /* opcowner */ - values[i++] = ObjectIdGetDatum(typeoid); /* opcintype */ - values[i++] = BoolGetDatum(stmt->isDefault); /* opcdefault */ - values[i++] = ObjectIdGetDatum(storageoid); /* opckeytype */ + values[Anum_pg_opclass_opcname - 1] = NameGetDatum(&opcName); + values[Anum_pg_opclass_opcnamespace - 1] = ObjectIdGetDatum(namespaceoid); + values[Anum_pg_opclass_opcowner - 1] = ObjectIdGetDatum(GetUserId()); + values[Anum_pg_opclass_opcfamily - 1] = ObjectIdGetDatum(opfamilyoid); + values[Anum_pg_opclass_opcintype - 1] = ObjectIdGetDatum(typeoid); + values[Anum_pg_opclass_opcdefault - 1] = BoolGetDatum(stmt->isDefault); + values[Anum_pg_opclass_opckeytype - 1] = ObjectIdGetDatum(storageoid); tup = heap_formtuple(rel->rd_att, values, nulls); @@ -364,14 +568,15 @@ DefineOpClass(CreateOpClassStmt *stmt) /* * Now add tuples to pg_amop and pg_amproc tying in the operators and - * functions. + * functions. Dependencies on them are inserted, too. */ - storeOperators(opclassoid, operators); - storeProcedures(opclassoid, procedures); + storeOperators(amoid, opfamilyoid, opclassoid, operators); + storeProcedures(amoid, opfamilyoid, opclassoid, procedures); /* - * Create dependencies. Note: we do not create a dependency link to the - * AM, because we don't currently support DROP ACCESS METHOD. + * Create dependencies for the opclass proper. Note: we do not create a + * dependency link to the AM, because we don't currently support DROP + * ACCESS METHOD. */ myself.classId = OperatorClassRelationId; myself.objectId = opclassoid; @@ -383,6 +588,12 @@ DefineOpClass(CreateOpClassStmt *stmt) referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + /* dependency on opfamily */ + referenced.classId = OperatorFamilyRelationId; + referenced.objectId = opfamilyoid; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + /* dependency on indexed datatype */ referenced.classId = TypeRelationId; referenced.objectId = typeoid; @@ -398,28 +609,6 @@ DefineOpClass(CreateOpClassStmt *stmt) recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - /* dependencies on operators */ - foreach(l, operators) - { - OpClassMember *op = (OpClassMember *) lfirst(l); - - referenced.classId = OperatorRelationId; - referenced.objectId = op->object; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); - } - - /* dependencies on procedures */ - foreach(l, procedures) - { - OpClassMember *proc = (OpClassMember *) lfirst(l); - - referenced.classId = ProcedureRelationId; - referenced.objectId = proc->object; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); - } - /* dependency on owner */ recordDependencyOnOwner(OperatorClassRelationId, opclassoid, GetUserId()); @@ -427,139 +616,158 @@ DefineOpClass(CreateOpClassStmt *stmt) } /* - * Determine the subtype to assign to an operator, and do any validity - * checking we can manage - * - * Currently this is done using hardwired rules; we don't let the user - * specify it directly. + * Determine the lefttype/righttype to assign to an operator, + * and do any validity checking we can manage. */ -static Oid -assignOperSubtype(Oid amoid, Oid typeoid, Oid operOid) +static void +assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) { - Oid subtype; Operator optup; Form_pg_operator opform; - /* Subtypes are currently only supported by btree, others use 0 */ - if (amoid != BTREE_AM_OID) - return InvalidOid; - + /* Fetch the operator definition */ optup = SearchSysCache(OPEROID, - ObjectIdGetDatum(operOid), + ObjectIdGetDatum(member->object), 0, 0, 0); if (optup == NULL) - elog(ERROR, "cache lookup failed for operator %u", operOid); + elog(ERROR, "cache lookup failed for operator %u", member->object); opform = (Form_pg_operator) GETSTRUCT(optup); /* - * btree operators must be binary ops returning boolean, and the left-side - * input type must match the operator class' input type. + * Opfamily operators must be binary ops returning boolean. */ if (opform->oprkind != 'b') ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree operators must be binary"))); + errmsg("index operators must be binary"))); if (opform->oprresult != BOOLOID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree operators must return boolean"))); - if (opform->oprleft != typeoid) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree operators must have index type as left input"))); + errmsg("index operators must return boolean"))); /* - * The subtype is "default" (0) if oprright matches the operator class, - * otherwise it is oprright. + * If lefttype/righttype isn't specified, use the operator's input types */ - if (opform->oprright == typeoid) - subtype = InvalidOid; - else - subtype = opform->oprright; + if (!OidIsValid(member->lefttype)) + member->lefttype = opform->oprleft; + if (!OidIsValid(member->righttype)) + member->righttype = opform->oprright; + ReleaseSysCache(optup); - return subtype; } /* - * Determine the subtype to assign to a support procedure, and do any validity - * checking we can manage - * - * Currently this is done using hardwired rules; we don't let the user - * specify it directly. + * Determine the lefttype/righttype to assign to a support procedure, + * and do any validity checking we can manage. */ -static Oid -assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid) +static void +assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) { - Oid subtype; HeapTuple proctup; Form_pg_proc procform; - /* Subtypes are currently only supported by btree, others use 0 */ - if (amoid != BTREE_AM_OID) - return InvalidOid; - + /* Fetch the procedure definition */ proctup = SearchSysCache(PROCOID, - ObjectIdGetDatum(procOid), + ObjectIdGetDatum(member->object), 0, 0, 0); if (proctup == NULL) - elog(ERROR, "cache lookup failed for function %u", procOid); + elog(ERROR, "cache lookup failed for function %u", member->object); procform = (Form_pg_proc) GETSTRUCT(proctup); /* - * btree support procs must be 2-arg procs returning int4, and the first - * input type must match the operator class' input type. + * btree support procs must be 2-arg procs returning int4; hash support + * procs must be 1-arg procs returning int4; otherwise we don't know. */ - if (procform->pronargs != 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree procedures must have two arguments"))); - if (procform->prorettype != INT4OID) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree procedures must return integer"))); - if (procform->proargtypes.values[0] != typeoid) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree procedures must have index type as first input"))); + if (amoid == BTREE_AM_OID) + { + if (procform->pronargs != 2) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("btree procedures must have two arguments"))); + if (procform->prorettype != INT4OID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("btree procedures must return integer"))); - /* - * The subtype is "default" (0) if second input type matches the operator - * class, otherwise it is the second input type. - */ - if (procform->proargtypes.values[1] == typeoid) - subtype = InvalidOid; + /* + * If lefttype/righttype isn't specified, use the proc's input types + */ + if (!OidIsValid(member->lefttype)) + member->lefttype = procform->proargtypes.values[0]; + if (!OidIsValid(member->righttype)) + member->righttype = procform->proargtypes.values[1]; + } + else if (amoid == HASH_AM_OID) + { + if (procform->pronargs != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("hash procedures must have one argument"))); + if (procform->prorettype != INT4OID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("hash procedures must return integer"))); + + /* + * If lefttype/righttype isn't specified, use the proc's input type + */ + if (!OidIsValid(member->lefttype)) + member->lefttype = procform->proargtypes.values[0]; + if (!OidIsValid(member->righttype)) + member->righttype = procform->proargtypes.values[0]; + } else - subtype = procform->proargtypes.values[1]; + { + /* + * The default for GiST and GIN in CREATE OPERATOR CLASS is to use + * the class' opcintype as lefttype and righttype. In CREATE or + * ALTER OPERATOR FAMILY, opcintype isn't available, so make the + * user specify the types. + */ + if (!OidIsValid(member->lefttype)) + member->lefttype = typeoid; + if (!OidIsValid(member->righttype)) + member->righttype = typeoid; + if (!OidIsValid(member->lefttype) || !OidIsValid(member->righttype)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("associated data types must be specified for index support procedure"))); + } + ReleaseSysCache(proctup); - return subtype; } /* - * Add a new class member to the appropriate list, after checking for + * Add a new family member to the appropriate list, after checking for * duplicated strategy or proc number. */ static void -addClassMember(List **list, OpClassMember *member, bool isProc) +addFamilyMember(List **list, OpFamilyMember *member, bool isProc) { ListCell *l; foreach(l, *list) { - OpClassMember *old = (OpClassMember *) lfirst(l); + OpFamilyMember *old = (OpFamilyMember *) lfirst(l); if (old->number == member->number && - old->subtype == member->subtype) + old->lefttype == member->lefttype && + old->righttype == member->righttype) { if (isProc) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("procedure number %d appears more than once", - member->number))); + errmsg("procedure number %d for (%s,%s) appears more than once", + member->number, + format_type_be(member->lefttype), + format_type_be(member->righttype)))); else ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator number %d appears more than once", - member->number))); + errmsg("operator number %d for (%s,%s) appears more than once", + member->number, + format_type_be(member->lefttype), + format_type_be(member->righttype)))); } } *list = lappend(*list, member); @@ -567,43 +775,80 @@ addClassMember(List **list, OpClassMember *member, bool isProc) /* * Dump the operators to pg_amop + * + * We also make dependency entries in pg_depend for the opfamily entries. + * If opclassoid is valid then make an INTERNAL dependency on that opclass, + * else make an AUTO dependency on the opfamily. */ static void -storeOperators(Oid opclassoid, List *operators) +storeOperators(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *operators) { Relation rel; Datum values[Natts_pg_amop]; char nulls[Natts_pg_amop]; HeapTuple tup; + Oid entryoid; + ObjectAddress myself, + referenced; ListCell *l; - int i; rel = heap_open(AccessMethodOperatorRelationId, RowExclusiveLock); foreach(l, operators) { - OpClassMember *op = (OpClassMember *) lfirst(l); + OpFamilyMember *op = (OpFamilyMember *) lfirst(l); - for (i = 0; i < Natts_pg_amop; ++i) - { - nulls[i] = ' '; - values[i] = (Datum) NULL; - } + /* Create the pg_amop entry */ + memset(values, 0, sizeof(values)); + memset(nulls, ' ', sizeof(nulls)); - i = 0; - values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */ - values[i++] = ObjectIdGetDatum(op->subtype); /* amopsubtype */ - values[i++] = Int16GetDatum(op->number); /* amopstrategy */ - values[i++] = BoolGetDatum(op->recheck); /* amopreqcheck */ - values[i++] = ObjectIdGetDatum(op->object); /* amopopr */ + values[Anum_pg_amop_amopfamily - 1] = ObjectIdGetDatum(opfamilyoid); + values[Anum_pg_amop_amoplefttype - 1] = ObjectIdGetDatum(op->lefttype); + values[Anum_pg_amop_amoprighttype - 1] = ObjectIdGetDatum(op->righttype); + values[Anum_pg_amop_amopstrategy - 1] = Int16GetDatum(op->number); + values[Anum_pg_amop_amopreqcheck - 1] = BoolGetDatum(op->recheck); + values[Anum_pg_amop_amopopr - 1] = ObjectIdGetDatum(op->object); + values[Anum_pg_amop_amopmethod - 1] = ObjectIdGetDatum(amoid); tup = heap_formtuple(rel->rd_att, values, nulls); - simple_heap_insert(rel, tup); + entryoid = simple_heap_insert(rel, tup); CatalogUpdateIndexes(rel, tup); heap_freetuple(tup); + + /* Make its dependencies */ + myself.classId = AccessMethodOperatorRelationId; + myself.objectId = entryoid; + myself.objectSubId = 0; + + referenced.classId = OperatorRelationId; + referenced.objectId = op->object; + referenced.objectSubId = 0; + + if (OidIsValid(opclassoid)) + { + /* if contained in an opclass, use a NORMAL dep on operator */ + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + + /* ... and an INTERNAL dep on the opclass */ + referenced.classId = OperatorClassRelationId; + referenced.objectId = opclassoid; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + } + else + { + /* if "loose" in the opfamily, use a AUTO dep on operator */ + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + + /* ... and an AUTO dep on the opfamily */ + referenced.classId = OperatorFamilyRelationId; + referenced.objectId = opfamilyoid; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + } } heap_close(rel, RowExclusiveLock); @@ -611,42 +856,78 @@ storeOperators(Oid opclassoid, List *operators) /* * Dump the procedures (support routines) to pg_amproc + * + * We also make dependency entries in pg_depend for the opfamily entries. + * If opclassoid is valid then make an INTERNAL dependency on that opclass, + * else make an AUTO dependency on the opfamily. */ static void -storeProcedures(Oid opclassoid, List *procedures) +storeProcedures(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *procedures) { Relation rel; Datum values[Natts_pg_amproc]; char nulls[Natts_pg_amproc]; HeapTuple tup; + Oid entryoid; + ObjectAddress myself, + referenced; ListCell *l; - int i; rel = heap_open(AccessMethodProcedureRelationId, RowExclusiveLock); foreach(l, procedures) { - OpClassMember *proc = (OpClassMember *) lfirst(l); + OpFamilyMember *proc = (OpFamilyMember *) lfirst(l); - for (i = 0; i < Natts_pg_amproc; ++i) - { - nulls[i] = ' '; - values[i] = (Datum) NULL; - } + /* Create the pg_amproc entry */ + memset(values, 0, sizeof(values)); + memset(nulls, ' ', sizeof(nulls)); - i = 0; - values[i++] = ObjectIdGetDatum(opclassoid); /* amopclaid */ - values[i++] = ObjectIdGetDatum(proc->subtype); /* amprocsubtype */ - values[i++] = Int16GetDatum(proc->number); /* amprocnum */ - values[i++] = ObjectIdGetDatum(proc->object); /* amproc */ + values[Anum_pg_amproc_amprocfamily - 1] = ObjectIdGetDatum(opfamilyoid); + values[Anum_pg_amproc_amproclefttype - 1] = ObjectIdGetDatum(proc->lefttype); + values[Anum_pg_amproc_amprocrighttype - 1] = ObjectIdGetDatum(proc->righttype); + values[Anum_pg_amproc_amprocnum - 1] = Int16GetDatum(proc->number); + values[Anum_pg_amproc_amproc - 1] = ObjectIdGetDatum(proc->object); tup = heap_formtuple(rel->rd_att, values, nulls); - simple_heap_insert(rel, tup); + entryoid = simple_heap_insert(rel, tup); CatalogUpdateIndexes(rel, tup); heap_freetuple(tup); + + /* Make its dependencies */ + myself.classId = AccessMethodProcedureRelationId; + myself.objectId = entryoid; + myself.objectSubId = 0; + + referenced.classId = ProcedureRelationId; + referenced.objectId = proc->object; + referenced.objectSubId = 0; + + if (OidIsValid(opclassoid)) + { + /* if contained in an opclass, use a NORMAL dep on procedure */ + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + + /* ... and an INTERNAL dep on the opclass */ + referenced.classId = OperatorClassRelationId; + referenced.objectId = opclassoid; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + } + else + { + /* if "loose" in the opfamily, use a AUTO dep on procedure */ + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + + /* ... and an AUTO dep on the opfamily */ + referenced.classId = OperatorFamilyRelationId; + referenced.objectId = opfamilyoid; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + } } heap_close(rel, RowExclusiveLock); @@ -662,8 +943,6 @@ RemoveOpClass(RemoveOpClassStmt *stmt) { Oid amID, opcID; - char *schemaname; - char *opcname; HeapTuple tuple; ObjectAddress object; @@ -682,49 +961,9 @@ RemoveOpClass(RemoveOpClassStmt *stmt) /* * Look up the opclass. */ - - /* deconstruct the name list */ - DeconstructQualifiedName(stmt->opclassname, &schemaname, &opcname); - - if (schemaname) - { - /* Look in specific schema only */ - Oid namespaceId; - - namespaceId = LookupExplicitNamespace(schemaname); - tuple = SearchSysCache(CLAAMNAMENSP, - ObjectIdGetDatum(amID), - PointerGetDatum(opcname), - ObjectIdGetDatum(namespaceId), - 0); - } - else - { - /* Unqualified opclass name, so search the search path */ - opcID = OpclassnameGetOpcid(amID, opcname); - if (!OidIsValid(opcID)) - { - if (!stmt->missing_ok) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("operator class \"%s\" does not exist for access method \"%s\"", - opcname, stmt->amname))); - else - ereport(NOTICE, - (errmsg("operator class \"%s\" does not exist for access method \"%s\"", - opcname, stmt->amname))); - - return; - } - - tuple = SearchSysCache(CLAOID, - ObjectIdGetDatum(opcID), - 0, 0, 0); - } - + tuple = OpClassCacheLookup(amID, stmt->opclassname); if (!HeapTupleIsValid(tuple)) { - if (!stmt->missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -759,19 +998,35 @@ RemoveOpClass(RemoveOpClassStmt *stmt) } /* - * Guts of opclass deletion. + * Deletion subroutines for use by dependency.c. */ +void +RemoveOpFamilyById(Oid opfamilyOid) +{ + Relation rel; + HeapTuple tup; + + rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock); + + tup = SearchSysCache(OPFAMILYOID, + ObjectIdGetDatum(opfamilyOid), + 0, 0, 0); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for opfamily %u", opfamilyOid); + + simple_heap_delete(rel, &tup->t_self); + + ReleaseSysCache(tup); + + heap_close(rel, RowExclusiveLock); +} + void RemoveOpClassById(Oid opclassOid) { Relation rel; HeapTuple tup; - ScanKeyData skey[1]; - SysScanDesc scan; - /* - * First remove the pg_opclass entry itself. - */ rel = heap_open(OperatorClassRelationId, RowExclusiveLock); tup = SearchSysCache(CLAOID, @@ -785,41 +1040,61 @@ RemoveOpClassById(Oid opclassOid) ReleaseSysCache(tup); heap_close(rel, RowExclusiveLock); +} + +void +RemoveAmOpEntryById(Oid entryOid) +{ + Relation rel; + HeapTuple tup; + ScanKeyData skey[1]; + SysScanDesc scan; - /* - * Remove associated entries in pg_amop. - */ ScanKeyInit(&skey[0], - Anum_pg_amop_amopclaid, + ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(opclassOid)); + ObjectIdGetDatum(entryOid)); rel = heap_open(AccessMethodOperatorRelationId, RowExclusiveLock); - scan = systable_beginscan(rel, AccessMethodStrategyIndexId, true, + scan = systable_beginscan(rel, AccessMethodOperatorOidIndexId, true, SnapshotNow, 1, skey); - while (HeapTupleIsValid(tup = systable_getnext(scan))) - simple_heap_delete(rel, &tup->t_self); + /* we expect exactly one match */ + tup = systable_getnext(scan); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "could not find tuple for amop entry %u", entryOid); + + simple_heap_delete(rel, &tup->t_self); systable_endscan(scan); heap_close(rel, RowExclusiveLock); +} + +void +RemoveAmProcEntryById(Oid entryOid) +{ + Relation rel; + HeapTuple tup; + ScanKeyData skey[1]; + SysScanDesc scan; - /* - * Remove associated entries in pg_amproc. - */ ScanKeyInit(&skey[0], - Anum_pg_amproc_amopclaid, + ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(opclassOid)); + ObjectIdGetDatum(entryOid)); rel = heap_open(AccessMethodProcedureRelationId, RowExclusiveLock); - scan = systable_beginscan(rel, AccessMethodProcedureIndexId, true, + scan = systable_beginscan(rel, AccessMethodProcedureOidIndexId, true, SnapshotNow, 1, skey); - while (HeapTupleIsValid(tup = systable_getnext(scan))) - simple_heap_delete(rel, &tup->t_self); + /* we expect exactly one match */ + tup = systable_getnext(scan); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "could not find tuple for amproc entry %u", entryOid); + + simple_heap_delete(rel, &tup->t_self); systable_endscan(scan); heap_close(rel, RowExclusiveLock); @@ -1022,7 +1297,7 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId) /* * The first parameter is pg_opclass, opened and suitably locked. The second - * parameter is the tuple from pg_opclass we want to modify. + * parameter is a copy of the tuple from pg_opclass we want to modify. */ static void AlterOpClassOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 76884e8cd8..a84feee2a7 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.33 2006/10/04 00:29:51 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.34 2006/12/23 00:43:09 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -64,8 +64,8 @@ DefineOperator(List *names, List *parameters) char *oprName; Oid oprNamespace; AclResult aclresult; - bool canHash = false; /* operator hashes */ bool canMerge = false; /* operator merges */ + bool canHash = false; /* operator hashes */ List *functionName = NIL; /* function for operator */ TypeName *typeName1 = NULL; /* first type name */ TypeName *typeName2 = NULL; /* second type name */ @@ -75,10 +75,6 @@ DefineOperator(List *names, List *parameters) List *negatorName = NIL; /* optional negator operator name */ List *restrictionName = NIL; /* optional restrict. sel. procedure */ List *joinName = NIL; /* optional join sel. procedure */ - List *leftSortName = NIL; /* optional left sort operator */ - List *rightSortName = NIL; /* optional right sort operator */ - List *ltCompareName = NIL; /* optional < compare operator */ - List *gtCompareName = NIL; /* optional > compare operator */ ListCell *pl; /* Convert list of names to a name and namespace */ @@ -127,14 +123,15 @@ DefineOperator(List *names, List *parameters) canHash = defGetBoolean(defel); else if (pg_strcasecmp(defel->defname, "merges") == 0) canMerge = defGetBoolean(defel); + /* These obsolete options are taken as meaning canMerge */ else if (pg_strcasecmp(defel->defname, "sort1") == 0) - leftSortName = defGetQualifiedName(defel); + canMerge = true; else if (pg_strcasecmp(defel->defname, "sort2") == 0) - rightSortName = defGetQualifiedName(defel); + canMerge = true; else if (pg_strcasecmp(defel->defname, "ltcmp") == 0) - ltCompareName = defGetQualifiedName(defel); + canMerge = true; else if (pg_strcasecmp(defel->defname, "gtcmp") == 0) - gtCompareName = defGetQualifiedName(defel); + canMerge = true; else ereport(WARNING, (errcode(ERRCODE_SYNTAX_ERROR), @@ -156,26 +153,6 @@ DefineOperator(List *names, List *parameters) if (typeName2) typeId2 = typenameTypeId(NULL, typeName2); - /* - * If any of the mergejoin support operators were given, then canMerge is - * implicit. If canMerge is specified or implicit, fill in default - * operator names for any missing mergejoin support operators. - */ - if (leftSortName || rightSortName || ltCompareName || gtCompareName) - canMerge = true; - - if (canMerge) - { - if (!leftSortName) - leftSortName = list_make1(makeString("<")); - if (!rightSortName) - rightSortName = list_make1(makeString("<")); - if (!ltCompareName) - ltCompareName = list_make1(makeString("<")); - if (!gtCompareName) - gtCompareName = list_make1(makeString(">")); - } - /* * now have OperatorCreate do all the work.. */ @@ -188,11 +165,8 @@ DefineOperator(List *names, List *parameters) negatorName, /* optional negator operator name */ restrictionName, /* optional restrict. sel. procedure */ joinName, /* optional join sel. procedure name */ - canHash, /* operator hashes */ - leftSortName, /* optional left sort operator */ - rightSortName, /* optional right sort operator */ - ltCompareName, /* optional < comparison op */ - gtCompareName); /* optional < comparison op */ + canMerge, /* operator merges */ + canHash); /* operator hashes */ } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index ea80c4e828..2a1116f758 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.206 2006/10/13 21:43:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.207 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4145,7 +4145,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, * generate a warning if not, since otherwise costly seqscans will be * incurred to check FK validity. */ - if (!op_in_opclass(oprid(o), opclasses[i])) + if (!op_in_opfamily(oprid(o), get_opclass_family(opclasses[i]))) ereport(WARNING, (errmsg("foreign key constraint \"%s\" " "will require costly sequential scans", diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 10b02b4a3e..1e9865c300 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.200 2006/12/21 16:05:13 petere Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.201 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -3700,21 +3700,28 @@ ExecInitExpr(Expr *node, PlanState *parent) outlist = lappend(outlist, estate); } rstate->rargs = outlist; - Assert(list_length(rcexpr->opclasses) == nopers); + Assert(list_length(rcexpr->opfamilies) == nopers); rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo)); i = 0; - forboth(l, rcexpr->opnos, l2, rcexpr->opclasses) + forboth(l, rcexpr->opnos, l2, rcexpr->opfamilies) { Oid opno = lfirst_oid(l); - Oid opclass = lfirst_oid(l2); + Oid opfamily = lfirst_oid(l2); int strategy; - Oid subtype; + Oid lefttype; + Oid righttype; bool recheck; Oid proc; - get_op_opclass_properties(opno, opclass, - &strategy, &subtype, &recheck); - proc = get_opclass_proc(opclass, subtype, BTORDER_PROC); + get_op_opfamily_properties(opno, opfamily, + &strategy, + &lefttype, + &righttype, + &recheck); + proc = get_opfamily_proc(opfamily, + lefttype, + righttype, + BTORDER_PROC); /* * If we enforced permissions checks on index support diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 9773f2341e..4371fc1a28 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.117 2006/10/04 00:29:52 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.118 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -797,9 +797,10 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, int flags = SK_ROW_MEMBER; Datum scanvalue; Oid opno; - Oid opclass; + Oid opfamily; int op_strategy; - Oid op_subtype; + Oid op_lefttype; + Oid op_righttype; bool op_recheck; /* @@ -857,15 +858,21 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, if (index->rd_rel->relam != BTREE_AM_OID || varattno < 1 || varattno > index->rd_index->indnatts) elog(ERROR, "bogus RowCompare index qualification"); - opclass = index->rd_indclass->values[varattno - 1]; + opfamily = index->rd_opfamily[varattno - 1]; - get_op_opclass_properties(opno, opclass, - &op_strategy, &op_subtype, &op_recheck); + get_op_opfamily_properties(opno, opfamily, + &op_strategy, + &op_lefttype, + &op_righttype, + &op_recheck); if (op_strategy != rc->rctype) elog(ERROR, "RowCompare index qualification contains wrong operator"); - opfuncid = get_opclass_proc(opclass, op_subtype, BTORDER_PROC); + opfuncid = get_opfamily_proc(opfamily, + op_lefttype, + op_righttype, + BTORDER_PROC); /* * initialize the subsidiary scan key's fields appropriately @@ -874,7 +881,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, flags, varattno, /* attribute number */ op_strategy, /* op's strategy */ - op_subtype, /* strategy subtype */ + op_righttype, /* strategy subtype */ opfuncid, /* reg proc to use */ scanvalue); /* constant */ extra_scan_keys++; diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index 8a9f6fe230..97824920d6 100644 --- a/src/backend/executor/nodeMergejoin.c +++ b/src/backend/executor/nodeMergejoin.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.82 2006/10/04 00:29:52 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.83 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -106,14 +106,14 @@ /* * Comparison strategies supported by MJCompare * - * XXX eventually should extend these to support descending-order sorts. + * XXX eventually should extend MJCompare to support descending-order sorts. * There are some tricky issues however about being sure we are on the same * page as the underlying sort or index as to which end NULLs sort to. */ typedef enum { - MERGEFUNC_LT, /* raw "<" operator */ - MERGEFUNC_CMP /* -1 / 0 / 1 three-way comparator */ + MERGEFUNC_CMP, /* -1 / 0 / 1 three-way comparator */ + MERGEFUNC_REV_CMP /* same, reversing the sense of the result */ } MergeFunctionKind; /* Runtime data for each mergejoin clause */ @@ -132,20 +132,11 @@ typedef struct MergeJoinClauseData bool lisnull; /* and their isnull flags */ bool risnull; - /* - * Remember whether mergejoin operator is strict (usually it will be). - * NOTE: if it's not strict, we still assume it cannot return true for one - * null and one non-null input. - */ - bool mergestrict; - /* * The comparison strategy in use, and the lookup info to let us call the - * needed comparison routines. eqfinfo is the "=" operator itself. - * cmpfinfo is either the btree comparator or the "<" operator. + * btree comparison support function. */ MergeFunctionKind cmpstrategy; - FmgrInfo eqfinfo; FmgrInfo cmpfinfo; } MergeJoinClauseData; @@ -164,34 +155,51 @@ typedef struct MergeJoinClauseData * we will need at runtime. Each struct essentially tells us how to compare * the two expressions from the original clause. * - * The best, most efficient way to compare two expressions is to use a btree - * comparison support routine, since that requires only one function call - * per comparison. Hence we try to find a btree opclass that matches the - * mergejoinable operator. If we cannot find one, we'll have to call both - * the "=" and (often) the "<" operator for each comparison. + * In addition to the expressions themselves, the planner passes the btree + * opfamily OID and btree strategy number (BTLessStrategyNumber or + * BTGreaterStrategyNumber) that identify the intended merge semantics for + * each merge key. The mergejoinable operator is an equality operator in + * this opfamily, and the two inputs are guaranteed to be ordered in either + * increasing or decreasing (respectively) order according to this opfamily. + * This allows us to obtain the needed comparison functions from the opfamily. */ static MergeJoinClause -MJExamineQuals(List *qualList, PlanState *parent) +MJExamineQuals(List *mergeclauses, List *mergefamilies, List *mergestrategies, + PlanState *parent) { MergeJoinClause clauses; - int nClauses = list_length(qualList); + int nClauses = list_length(mergeclauses); int iClause; - ListCell *l; + ListCell *cl; + ListCell *cf; + ListCell *cs; clauses = (MergeJoinClause) palloc0(nClauses * sizeof(MergeJoinClauseData)); iClause = 0; - foreach(l, qualList) + cf = list_head(mergefamilies); + cs = list_head(mergestrategies); + foreach(cl, mergeclauses) { - OpExpr *qual = (OpExpr *) lfirst(l); + OpExpr *qual = (OpExpr *) lfirst(cl); MergeJoinClause clause = &clauses[iClause]; - Oid ltop; - Oid gtop; - RegProcedure ltproc; - RegProcedure gtproc; + Oid opfamily; + StrategyNumber opstrategy; + int op_strategy; + Oid op_lefttype; + Oid op_righttype; + bool op_recheck; + RegProcedure cmpproc; AclResult aclresult; - CatCList *catlist; - int i; + + opfamily = lfirst_oid(cf); + cf = lnext(cf); + opstrategy = lfirst_int(cs); + cs = lnext(cs); + + /* Later we'll support both ascending and descending sort... */ + Assert(opstrategy == BTLessStrategyNumber); + clause->cmpstrategy = MERGEFUNC_CMP; if (!IsA(qual, OpExpr)) elog(ERROR, "mergejoin clause is not an OpExpr"); @@ -202,77 +210,30 @@ MJExamineQuals(List *qualList, PlanState *parent) clause->lexpr = ExecInitExpr((Expr *) linitial(qual->args), parent); clause->rexpr = ExecInitExpr((Expr *) lsecond(qual->args), parent); - /* - * Check permission to call the mergejoinable operator. For - * predictability, we check this even if we end up not using it. - */ - aclresult = pg_proc_aclcheck(qual->opfuncid, GetUserId(), ACL_EXECUTE); + /* Extract the operator's declared left/right datatypes */ + get_op_opfamily_properties(qual->opno, opfamily, + &op_strategy, + &op_lefttype, + &op_righttype, + &op_recheck); + Assert(op_strategy == BTEqualStrategyNumber); + Assert(!op_recheck); + + /* And get the matching support procedure (comparison function) */ + cmpproc = get_opfamily_proc(opfamily, + op_lefttype, + op_righttype, + BTORDER_PROC); + Assert(RegProcedureIsValid(cmpproc)); + + /* Check permission to call cmp function */ + aclresult = pg_proc_aclcheck(cmpproc, GetUserId(), ACL_EXECUTE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_PROC, - get_func_name(qual->opfuncid)); + get_func_name(cmpproc)); /* Set up the fmgr lookup information */ - fmgr_info(qual->opfuncid, &(clause->eqfinfo)); - - /* And remember strictness */ - clause->mergestrict = clause->eqfinfo.fn_strict; - - /* - * Lookup the comparison operators that go with the mergejoinable - * top-level operator. (This will elog if the operator isn't - * mergejoinable, which would be the planner's mistake.) - */ - op_mergejoin_crossops(qual->opno, - <op, - >op, - <proc, - >proc); - - clause->cmpstrategy = MERGEFUNC_LT; - - /* - * Look for a btree opclass including all three operators. This is - * much like SelectSortFunction except we insist on matching all the - * operators provided, and it can be a cross-type opclass. - * - * XXX for now, insist on forward sort so that NULLs can be counted on - * to be high. - */ - catlist = SearchSysCacheList(AMOPOPID, 1, - ObjectIdGetDatum(qual->opno), - 0, 0, 0); - - for (i = 0; i < catlist->n_members; i++) - { - HeapTuple tuple = &catlist->members[i]->tuple; - Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple); - Oid opcid = aform->amopclaid; - - if (aform->amopstrategy != BTEqualStrategyNumber) - continue; - if (!opclass_is_btree(opcid)) - continue; - if (get_op_opclass_strategy(ltop, opcid) == BTLessStrategyNumber && - get_op_opclass_strategy(gtop, opcid) == BTGreaterStrategyNumber) - { - clause->cmpstrategy = MERGEFUNC_CMP; - ltproc = get_opclass_proc(opcid, aform->amopsubtype, - BTORDER_PROC); - Assert(RegProcedureIsValid(ltproc)); - break; /* done looking */ - } - } - - ReleaseSysCacheList(catlist); - - /* Check permission to call "<" operator or cmp function */ - aclresult = pg_proc_aclcheck(ltproc, GetUserId(), ACL_EXECUTE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_PROC, - get_func_name(ltproc)); - - /* Set up the fmgr lookup information */ - fmgr_info(ltproc, &(clause->cmpfinfo)); + fmgr_info(cmpproc, &(clause->cmpfinfo)); iClause++; } @@ -286,7 +247,7 @@ MJExamineQuals(List *qualList, PlanState *parent) * Compute the values of the mergejoined expressions for the current * outer tuple. We also detect whether it's impossible for the current * outer tuple to match anything --- this is true if it yields a NULL - * input for any strict mergejoin operator. + * input, since we assume mergejoin operators are strict. * * We evaluate the values in OuterEContext, which can be reset each * time we move to a new tuple. @@ -311,7 +272,7 @@ MJEvalOuterValues(MergeJoinState *mergestate) clause->ldatum = ExecEvalExpr(clause->lexpr, econtext, &clause->lisnull, NULL); - if (clause->lisnull && clause->mergestrict) + if (clause->lisnull) canmatch = false; } @@ -347,7 +308,7 @@ MJEvalInnerValues(MergeJoinState *mergestate, TupleTableSlot *innerslot) clause->rdatum = ExecEvalExpr(clause->rexpr, econtext, &clause->risnull, NULL); - if (clause->risnull && clause->mergestrict) + if (clause->risnull) canmatch = false; } @@ -391,32 +352,11 @@ MJCompare(MergeJoinState *mergestate) /* * Deal with null inputs. We treat NULL as sorting after non-NULL. - * - * If both inputs are NULL, and the comparison function isn't strict, - * then we call it and check for a true result (this allows operators - * that behave like IS NOT DISTINCT to be mergejoinable). If the - * function is strict or returns false, we temporarily pretend NULL == - * NULL and contine checking remaining columns. */ if (clause->lisnull) { if (clause->risnull) { - if (!clause->eqfinfo.fn_strict) - { - InitFunctionCallInfoData(fcinfo, &(clause->eqfinfo), 2, - NULL, NULL); - fcinfo.arg[0] = clause->ldatum; - fcinfo.arg[1] = clause->rdatum; - fcinfo.argnull[0] = true; - fcinfo.argnull[1] = true; - fresult = FunctionCallInvoke(&fcinfo); - if (!fcinfo.isnull && DatumGetBool(fresult)) - { - /* treat nulls as really equal */ - continue; - } - } nulleqnull = true; continue; } @@ -431,38 +371,26 @@ MJCompare(MergeJoinState *mergestate) break; } - if (clause->cmpstrategy == MERGEFUNC_LT) + InitFunctionCallInfoData(fcinfo, &(clause->cmpfinfo), 2, + NULL, NULL); + fcinfo.arg[0] = clause->ldatum; + fcinfo.arg[1] = clause->rdatum; + fcinfo.argnull[0] = false; + fcinfo.argnull[1] = false; + fresult = FunctionCallInvoke(&fcinfo); + if (fcinfo.isnull) { - InitFunctionCallInfoData(fcinfo, &(clause->eqfinfo), 2, - NULL, NULL); - fcinfo.arg[0] = clause->ldatum; - fcinfo.arg[1] = clause->rdatum; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fresult = FunctionCallInvoke(&fcinfo); - if (fcinfo.isnull) - { - nulleqnull = true; - continue; - } - else if (DatumGetBool(fresult)) - { - /* equal */ - continue; - } - InitFunctionCallInfoData(fcinfo, &(clause->cmpfinfo), 2, - NULL, NULL); - fcinfo.arg[0] = clause->ldatum; - fcinfo.arg[1] = clause->rdatum; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fresult = FunctionCallInvoke(&fcinfo); - if (fcinfo.isnull) - { - nulleqnull = true; - continue; - } - else if (DatumGetBool(fresult)) + nulleqnull = true; + continue; + } + if (DatumGetInt32(fresult) == 0) + { + /* equal */ + continue; + } + if (clause->cmpstrategy == MERGEFUNC_CMP) + { + if (DatumGetInt32(fresult) < 0) { /* less than */ result = -1; @@ -476,26 +404,9 @@ MJCompare(MergeJoinState *mergestate) } } else - /* must be MERGEFUNC_CMP */ { - InitFunctionCallInfoData(fcinfo, &(clause->cmpfinfo), 2, - NULL, NULL); - fcinfo.arg[0] = clause->ldatum; - fcinfo.arg[1] = clause->rdatum; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fresult = FunctionCallInvoke(&fcinfo); - if (fcinfo.isnull) - { - nulleqnull = true; - continue; - } - else if (DatumGetInt32(fresult) == 0) - { - /* equal */ - continue; - } - else if (DatumGetInt32(fresult) < 0) + /* reverse the sort order */ + if (DatumGetInt32(fresult) > 0) { /* less than */ result = -1; @@ -1614,6 +1525,8 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) */ mergestate->mj_NumClauses = list_length(node->mergeclauses); mergestate->mj_Clauses = MJExamineQuals(node->mergeclauses, + node->mergefamilies, + node->mergestrategies, (PlanState *) mergestate); /* diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 3bb95b658d..ca841cb181 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.355 2006/12/21 16:05:13 petere Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.356 2006/12/23 00:43:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -449,6 +449,8 @@ _copyMergeJoin(MergeJoin *from) * copy remainder of node */ COPY_NODE_FIELD(mergeclauses); + COPY_NODE_FIELD(mergefamilies); + COPY_NODE_FIELD(mergestrategies); return newnode; } @@ -1055,7 +1057,7 @@ _copyRowCompareExpr(RowCompareExpr *from) COPY_SCALAR_FIELD(rctype); COPY_NODE_FIELD(opnos); - COPY_NODE_FIELD(opclasses); + COPY_NODE_FIELD(opfamilies); COPY_NODE_FIELD(largs); COPY_NODE_FIELD(rargs); @@ -1307,6 +1309,7 @@ _copyRestrictInfo(RestrictInfo *from) COPY_SCALAR_FIELD(mergejoinoperator); COPY_SCALAR_FIELD(left_sortop); COPY_SCALAR_FIELD(right_sortop); + COPY_SCALAR_FIELD(mergeopfamily); /* * Do not copy pathkeys, since they'd not be canonical in a copied query @@ -2291,6 +2294,7 @@ _copyCreateOpClassStmt(CreateOpClassStmt *from) CreateOpClassStmt *newnode = makeNode(CreateOpClassStmt); COPY_NODE_FIELD(opclassname); + COPY_NODE_FIELD(opfamilyname); COPY_STRING_FIELD(amname); COPY_NODE_FIELD(datatype); COPY_NODE_FIELD(items); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index ef21e67faf..a7c4ef4e2a 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.289 2006/12/21 16:05:13 petere Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.290 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -428,7 +428,7 @@ _equalRowCompareExpr(RowCompareExpr *a, RowCompareExpr *b) { COMPARE_SCALAR_FIELD(rctype); COMPARE_NODE_FIELD(opnos); - COMPARE_NODE_FIELD(opclasses); + COMPARE_NODE_FIELD(opfamilies); COMPARE_NODE_FIELD(largs); COMPARE_NODE_FIELD(rargs); @@ -1163,6 +1163,7 @@ static bool _equalCreateOpClassStmt(CreateOpClassStmt *a, CreateOpClassStmt *b) { COMPARE_NODE_FIELD(opclassname); + COMPARE_NODE_FIELD(opfamilyname); COMPARE_STRING_FIELD(amname); COMPARE_NODE_FIELD(datatype); COMPARE_NODE_FIELD(items); diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 5ddf60dbbb..b18b6988cf 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.287 2006/12/21 16:05:13 petere Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.288 2006/12/23 00:43:10 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -442,6 +442,8 @@ _outMergeJoin(StringInfo str, MergeJoin *node) _outJoinPlanInfo(str, (Join *) node); WRITE_NODE_FIELD(mergeclauses); + WRITE_NODE_FIELD(mergefamilies); + WRITE_NODE_FIELD(mergestrategies); } static void @@ -866,7 +868,7 @@ _outRowCompareExpr(StringInfo str, RowCompareExpr *node) WRITE_ENUM_FIELD(rctype, RowCompareType); WRITE_NODE_FIELD(opnos); - WRITE_NODE_FIELD(opclasses); + WRITE_NODE_FIELD(opfamilies); WRITE_NODE_FIELD(largs); WRITE_NODE_FIELD(rargs); } @@ -1167,6 +1169,8 @@ _outMergePath(StringInfo str, MergePath *node) _outJoinPathInfo(str, (JoinPath *) node); WRITE_NODE_FIELD(path_mergeclauses); + WRITE_NODE_FIELD(path_mergefamilies); + WRITE_NODE_FIELD(path_mergestrategies); WRITE_NODE_FIELD(outersortkeys); WRITE_NODE_FIELD(innersortkeys); } @@ -1281,6 +1285,7 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node) WRITE_OID_FIELD(mergejoinoperator); WRITE_OID_FIELD(left_sortop); WRITE_OID_FIELD(right_sortop); + WRITE_OID_FIELD(mergeopfamily); WRITE_NODE_FIELD(left_pathkey); WRITE_NODE_FIELD(right_pathkey); WRITE_OID_FIELD(hashjoinoperator); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 689cef3edf..37b39439eb 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.197 2006/12/21 16:05:13 petere Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.198 2006/12/23 00:43:10 tgl Exp $ * * NOTES * Path and Plan nodes do not have any readfuncs support, because we @@ -672,7 +672,7 @@ _readRowCompareExpr(void) READ_ENUM_FIELD(rctype, RowCompareType); READ_NODE_FIELD(opnos); - READ_NODE_FIELD(opclasses); + READ_NODE_FIELD(opfamilies); READ_NODE_FIELD(largs); READ_NODE_FIELD(rargs); diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 71685643ef..fbcf7d2b5f 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -54,7 +54,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.170 2006/12/15 18:42:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.171 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1258,6 +1258,8 @@ cost_mergejoin(MergePath *path, PlannerInfo *root) Path *outer_path = path->jpath.outerjoinpath; Path *inner_path = path->jpath.innerjoinpath; List *mergeclauses = path->path_mergeclauses; + List *mergefamilies = path->path_mergefamilies; + List *mergestrategies = path->path_mergestrategies; List *outersortkeys = path->outersortkeys; List *innersortkeys = path->innersortkeys; Cost startup_cost = 0; @@ -1347,13 +1349,16 @@ cost_mergejoin(MergePath *path, PlannerInfo *root) * * Since this calculation is somewhat expensive, and will be the same for * all mergejoin paths associated with the merge clause, we cache the - * results in the RestrictInfo node. + * results in the RestrictInfo node. XXX that won't work anymore once + * we support multiple possible orderings! */ if (mergeclauses && path->jpath.jointype != JOIN_FULL) { firstclause = (RestrictInfo *) linitial(mergeclauses); if (firstclause->left_mergescansel < 0) /* not computed yet? */ mergejoinscansel(root, (Node *) firstclause->clause, + linitial_oid(mergefamilies), + linitial_int(mergestrategies), &firstclause->left_mergescansel, &firstclause->right_mergescansel); diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index b15affa54d..af081b82c8 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.212 2006/10/04 00:29:54 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.213 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,8 +19,8 @@ #include "access/skey.h" #include "catalog/pg_am.h" -#include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "optimizer/clauses.h" @@ -40,10 +40,10 @@ /* * DoneMatchingIndexKeys() - MACRO */ -#define DoneMatchingIndexKeys(classes) (classes[0] == InvalidOid) +#define DoneMatchingIndexKeys(families) (families[0] == InvalidOid) -#define IsBooleanOpclass(opclass) \ - ((opclass) == BOOL_BTREE_OPS_OID || (opclass) == BOOL_HASH_OPS_OID) +#define IsBooleanOpfamily(opfamily) \ + ((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID) static List *find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, @@ -61,15 +61,15 @@ static Cost bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, static List *pull_indexpath_quals(Path *bitmapqual); static bool lists_intersect_ptr(List *list1, List *list2); static bool match_clause_to_indexcol(IndexOptInfo *index, - int indexcol, Oid opclass, + int indexcol, Oid opfamily, RestrictInfo *rinfo, Relids outer_relids, SaOpControl saop_control); -static bool is_indexable_operator(Oid expr_op, Oid opclass, +static bool is_indexable_operator(Oid expr_op, Oid opfamily, bool indexkey_on_left); static bool match_rowcompare_to_indexcol(IndexOptInfo *index, int indexcol, - Oid opclass, + Oid opfamily, RowCompareExpr *clause, Relids outer_relids); static Relids indexable_outerrelids(RelOptInfo *rel); @@ -89,17 +89,17 @@ static bool match_index_to_query_keys(PlannerInfo *root, List *ignorables); static bool match_boolean_index_clause(Node *clause, int indexcol, IndexOptInfo *index); -static bool match_special_index_operator(Expr *clause, Oid opclass, +static bool match_special_index_operator(Expr *clause, Oid opfamily, bool indexkey_on_left); static Expr *expand_boolean_index_clause(Node *clause, int indexcol, IndexOptInfo *index); -static List *expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass); +static List *expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily); static RestrictInfo *expand_indexqual_rowcompare(RestrictInfo *rinfo, IndexOptInfo *index, int indexcol); -static List *prefix_quals(Node *leftop, Oid opclass, +static List *prefix_quals(Node *leftop, Oid opfamily, Const *prefix, Pattern_Prefix_Status pstatus); -static List *network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, +static List *network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop); static Datum string_to_datum(const char *str, Oid datatype); static Const *string_to_const(const char *str, Oid datatype); @@ -858,7 +858,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, List *clausegroup_list = NIL; bool found_outer_clause = false; int indexcol = 0; - Oid *classes = index->classlist; + Oid *families = index->opfamily; *found_clause = false; /* default result */ @@ -867,7 +867,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, do { - Oid curClass = classes[0]; + Oid curFamily = families[0]; List *clausegroup = NIL; ListCell *l; @@ -879,7 +879,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, Assert(IsA(rinfo, RestrictInfo)); if (match_clause_to_indexcol(index, indexcol, - curClass, + curFamily, rinfo, outer_relids, saop_control)) @@ -899,7 +899,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, Assert(IsA(rinfo, RestrictInfo)); if (match_clause_to_indexcol(index, indexcol, - curClass, + curFamily, rinfo, outer_relids, saop_control)) @@ -918,9 +918,9 @@ group_clauses_by_indexkey(IndexOptInfo *index, clausegroup_list = lappend(clausegroup_list, clausegroup); indexcol++; - classes++; + families++; - } while (!DoneMatchingIndexKeys(classes)); + } while (!DoneMatchingIndexKeys(families)); if (!*found_clause && !found_outer_clause) return NIL; /* no indexable clauses anywhere */ @@ -937,7 +937,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, * * (1) must be in the form (indexkey op const) or (const op indexkey); * and - * (2) must contain an operator which is in the same class as the index + * (2) must contain an operator which is in the same family as the index * operator for this column, or is a "special" operator as recognized * by match_special_index_operator(). * @@ -978,7 +978,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, * * 'index' is the index of interest. * 'indexcol' is a column number of 'index' (counting from 0). - * 'opclass' is the corresponding operator class. + * 'opfamily' is the corresponding operator family. * 'rinfo' is the clause to be tested (as a RestrictInfo node). * 'saop_control' indicates whether ScalarArrayOpExpr clauses can be used. * @@ -990,7 +990,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, static bool match_clause_to_indexcol(IndexOptInfo *index, int indexcol, - Oid opclass, + Oid opfamily, RestrictInfo *rinfo, Relids outer_relids, SaOpControl saop_control) @@ -1013,7 +1013,7 @@ match_clause_to_indexcol(IndexOptInfo *index, return false; /* First check for boolean-index cases. */ - if (IsBooleanOpclass(opclass)) + if (IsBooleanOpfamily(opfamily)) { if (match_boolean_index_clause((Node *) clause, indexcol, index)) return true; @@ -1052,7 +1052,7 @@ match_clause_to_indexcol(IndexOptInfo *index, } else if (clause && IsA(clause, RowCompareExpr)) { - return match_rowcompare_to_indexcol(index, indexcol, opclass, + return match_rowcompare_to_indexcol(index, indexcol, opfamily, (RowCompareExpr *) clause, outer_relids); } @@ -1067,15 +1067,15 @@ match_clause_to_indexcol(IndexOptInfo *index, bms_is_subset(right_relids, outer_relids) && !contain_volatile_functions(rightop)) { - if (is_indexable_operator(expr_op, opclass, true)) + if (is_indexable_operator(expr_op, opfamily, true)) return true; /* - * If we didn't find a member of the index's opclass, see whether it + * If we didn't find a member of the index's opfamily, see whether it * is a "special" indexable operator. */ if (plain_op && - match_special_index_operator(clause, opclass, true)) + match_special_index_operator(clause, opfamily, true)) return true; return false; } @@ -1085,14 +1085,14 @@ match_clause_to_indexcol(IndexOptInfo *index, bms_is_subset(left_relids, outer_relids) && !contain_volatile_functions(leftop)) { - if (is_indexable_operator(expr_op, opclass, false)) + if (is_indexable_operator(expr_op, opfamily, false)) return true; /* - * If we didn't find a member of the index's opclass, see whether it + * If we didn't find a member of the index's opfamily, see whether it * is a "special" indexable operator. */ - if (match_special_index_operator(clause, opclass, false)) + if (match_special_index_operator(clause, opfamily, false)) return true; return false; } @@ -1102,14 +1102,14 @@ match_clause_to_indexcol(IndexOptInfo *index, /* * is_indexable_operator - * Does the operator match the specified index opclass? + * Does the operator match the specified index opfamily? * * If the indexkey is on the right, what we actually want to know * is whether the operator has a commutator operator that matches - * the opclass. + * the opfamily. */ static bool -is_indexable_operator(Oid expr_op, Oid opclass, bool indexkey_on_left) +is_indexable_operator(Oid expr_op, Oid opfamily, bool indexkey_on_left) { /* Get the commuted operator if necessary */ if (!indexkey_on_left) @@ -1119,8 +1119,8 @@ is_indexable_operator(Oid expr_op, Oid opclass, bool indexkey_on_left) return false; } - /* OK if the (commuted) operator is a member of the index's opclass */ - return op_in_opclass(expr_op, opclass); + /* OK if the (commuted) operator is a member of the index's opfamily */ + return op_in_opfamily(expr_op, opfamily); } /* @@ -1131,7 +1131,7 @@ is_indexable_operator(Oid expr_op, Oid opclass, bool indexkey_on_left) static bool match_rowcompare_to_indexcol(IndexOptInfo *index, int indexcol, - Oid opclass, + Oid opfamily, RowCompareExpr *clause, Relids outer_relids) { @@ -1144,13 +1144,14 @@ match_rowcompare_to_indexcol(IndexOptInfo *index, return false; /* - * We could do the matching on the basis of insisting that the opclass - * shown in the RowCompareExpr be the same as the index column's opclass, - * but that does not work well for cross-type comparisons (the opclass - * could be for the other datatype). Also it would fail to handle indexes - * using reverse-sort opclasses. Instead, match if the operator listed in - * the RowCompareExpr is the < <= > or >= member of the index opclass - * (after commutation, if the indexkey is on the right). + * We could do the matching on the basis of insisting that the opfamily + * shown in the RowCompareExpr be the same as the index column's opfamily, + * but that could fail in the presence of reverse-sort opfamilies: it'd + * be a matter of chance whether RowCompareExpr had picked the forward + * or reverse-sort family. So look only at the operator, and match + * if it is a member of the index's opfamily (after commutation, if the + * indexkey is on the right). We'll worry later about whether any + * additional operators are matchable to the index. */ leftop = (Node *) linitial(clause->largs); rightop = (Node *) linitial(clause->rargs); @@ -1177,8 +1178,8 @@ match_rowcompare_to_indexcol(IndexOptInfo *index, else return false; - /* We're good if the operator is the right type of opclass member */ - switch (get_op_opclass_strategy(expr_op, opclass)) + /* We're good if the operator is the right type of opfamily member */ + switch (get_op_opfamily_strategy(expr_op, opfamily)) { case BTLessStrategyNumber: case BTLessEqualStrategyNumber: @@ -1316,23 +1317,23 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids) { IndexOptInfo *index = (IndexOptInfo *) lfirst(l); int indexcol = 0; - Oid *classes = index->classlist; + Oid *families = index->opfamily; do { - Oid curClass = classes[0]; + Oid curFamily = families[0]; if (match_clause_to_indexcol(index, indexcol, - curClass, + curFamily, rinfo, outer_relids, SAOP_ALLOW)) return true; indexcol++; - classes++; - } while (!DoneMatchingIndexKeys(classes)); + families++; + } while (!DoneMatchingIndexKeys(families)); } return false; @@ -1601,11 +1602,11 @@ find_clauses_for_join(PlannerInfo *root, RelOptInfo *rel, * Note: it would be possible to similarly ignore useless ORDER BY items; * that is, an index on just y could be considered to match the ordering of * ... WHERE x = 42 ORDER BY x, y; - * But proving that this is safe would require finding a btree opclass + * But proving that this is safe would require finding a btree opfamily * containing both the = operator and the < or > operator in the ORDER BY * item. That's significantly more expensive than what we do here, since * we'd have to look at restriction clauses unrelated to the current index - * and search for opclasses without any hint from the index. The practical + * and search for opfamilies without any hint from the index. The practical * use-cases seem to be mostly covered by ignoring index columns, so that's * all we do for now. * @@ -1627,7 +1628,7 @@ match_variant_ordering(PlannerInfo *root, /* * Forget the whole thing if not a btree index; our check for ignorable - * columns assumes we are dealing with btree opclasses. (It'd be possible + * columns assumes we are dealing with btree opfamilies. (It'd be possible * to factor out just the try for backwards indexscan, but considering * that we presently have no orderable indexes except btrees anyway, it's * hardly worth contorting this code for that case.) @@ -1685,7 +1686,7 @@ identify_ignorable_ordering_cols(PlannerInfo *root, foreach(l, restrictclauses) { List *sublist = (List *) lfirst(l); - Oid opclass = index->classlist[indexcol]; + Oid opfamily = index->opfamily[indexcol]; ListCell *l2; foreach(l2, sublist) @@ -1698,7 +1699,7 @@ identify_ignorable_ordering_cols(PlannerInfo *root, bool ispc; /* First check for boolean-index cases. */ - if (IsBooleanOpclass(opclass)) + if (IsBooleanOpfamily(opfamily)) { if (match_boolean_index_clause((Node *) clause, indexcol, index)) @@ -1729,18 +1730,18 @@ identify_ignorable_ordering_cols(PlannerInfo *root, { Assert(match_index_to_operand(lsecond(clause->args), indexcol, index)); - /* Must flip operator to get the opclass member */ + /* Must flip operator to get the opfamily member */ clause_op = get_commutator(clause_op); varonleft = false; } if (!OidIsValid(clause_op)) continue; /* ignore non match, per next comment */ - op_strategy = get_op_opclass_strategy(clause_op, opclass); + op_strategy = get_op_opfamily_strategy(clause_op, opfamily); /* * You might expect to see Assert(op_strategy != 0) here, but you * won't: the clause might contain a special indexable operator - * rather than an ordinary opclass member. Currently none of the + * rather than an ordinary opfamily member. Currently none of the * special operators are very likely to expand to an equality * operator; we do not bother to check, but just assume no match. */ @@ -1968,7 +1969,7 @@ match_index_to_operand(Node *operand, * * match_special_index_operator() is just an auxiliary function for * match_clause_to_indexcol(); after the latter fails to recognize a - * restriction opclause's operator as a member of an index's opclass, + * restriction opclause's operator as a member of an index's opfamily, * it asks match_special_index_operator() whether the clause should be * considered an indexqual anyway. * @@ -1978,7 +1979,7 @@ match_index_to_operand(Node *operand, * expand_indexqual_conditions() converts a list of lists of RestrictInfo * nodes (with implicit AND semantics across list elements) into * a list of clauses that the executor can actually handle. For operators - * that are members of the index's opclass this transformation is a no-op, + * that are members of the index's opfamily this transformation is a no-op, * but clauses recognized by match_special_index_operator() or * match_boolean_index_clause() must be converted into one or more "regular" * indexqual conditions. @@ -1989,8 +1990,8 @@ match_index_to_operand(Node *operand, * match_boolean_index_clause * Recognize restriction clauses that can be matched to a boolean index. * - * This should be called only when IsBooleanOpclass() recognizes the - * index's operator class. We check to see if the clause matches the + * This should be called only when IsBooleanOpfamily() recognizes the + * index's operator family. We check to see if the clause matches the * index's key. */ static bool @@ -2034,11 +2035,11 @@ match_boolean_index_clause(Node *clause, * * The given clause is already known to be a binary opclause having * the form (indexkey OP pseudoconst) or (pseudoconst OP indexkey), - * but the OP proved not to be one of the index's opclass operators. + * but the OP proved not to be one of the index's opfamily operators. * Return 'true' if we can do something with it anyway. */ static bool -match_special_index_operator(Expr *clause, Oid opclass, +match_special_index_operator(Expr *clause, Oid opfamily, bool indexkey_on_left) { bool isIndexable = false; @@ -2122,12 +2123,12 @@ match_special_index_operator(Expr *clause, Oid opclass, return false; /* - * Must also check that index's opclass supports the operators we will + * Must also check that index's opfamily supports the operators we will * want to apply. (A hash index, for example, will not support ">=".) * Currently, only btree supports the operators we need. * - * We insist on the opclass being the specific one we expect, else we'd do - * the wrong thing if someone were to make a reverse-sort opclass with the + * We insist on the opfamily being the specific one we expect, else we'd do + * the wrong thing if someone were to make a reverse-sort opfamily with the * same operators. */ switch (expr_op) @@ -2136,12 +2137,9 @@ match_special_index_operator(Expr *clause, Oid opclass, case OID_TEXT_ICLIKE_OP: case OID_TEXT_REGEXEQ_OP: case OID_TEXT_ICREGEXEQ_OP: - /* text operators will be used for varchar inputs, too */ isIndexable = - (opclass == TEXT_PATTERN_BTREE_OPS_OID) || - (opclass == TEXT_BTREE_OPS_OID && lc_collate_is_c()) || - (opclass == VARCHAR_PATTERN_BTREE_OPS_OID) || - (opclass == VARCHAR_BTREE_OPS_OID && lc_collate_is_c()); + (opfamily == TEXT_PATTERN_BTREE_FAM_OID) || + (opfamily == TEXT_BTREE_FAM_OID && lc_collate_is_c()); break; case OID_BPCHAR_LIKE_OP: @@ -2149,8 +2147,8 @@ match_special_index_operator(Expr *clause, Oid opclass, case OID_BPCHAR_REGEXEQ_OP: case OID_BPCHAR_ICREGEXEQ_OP: isIndexable = - (opclass == BPCHAR_PATTERN_BTREE_OPS_OID) || - (opclass == BPCHAR_BTREE_OPS_OID && lc_collate_is_c()); + (opfamily == BPCHAR_PATTERN_BTREE_FAM_OID) || + (opfamily == BPCHAR_BTREE_FAM_OID && lc_collate_is_c()); break; case OID_NAME_LIKE_OP: @@ -2158,18 +2156,17 @@ match_special_index_operator(Expr *clause, Oid opclass, case OID_NAME_REGEXEQ_OP: case OID_NAME_ICREGEXEQ_OP: isIndexable = - (opclass == NAME_PATTERN_BTREE_OPS_OID) || - (opclass == NAME_BTREE_OPS_OID && lc_collate_is_c()); + (opfamily == NAME_PATTERN_BTREE_FAM_OID) || + (opfamily == NAME_BTREE_FAM_OID && lc_collate_is_c()); break; case OID_BYTEA_LIKE_OP: - isIndexable = (opclass == BYTEA_BTREE_OPS_OID); + isIndexable = (opfamily == BYTEA_BTREE_FAM_OID); break; case OID_INET_SUB_OP: case OID_INET_SUBEQ_OP: - isIndexable = (opclass == INET_BTREE_OPS_OID || - opclass == CIDR_BTREE_OPS_OID); + isIndexable = (opfamily == NETWORK_BTREE_FAM_OID); break; } @@ -2180,7 +2177,7 @@ match_special_index_operator(Expr *clause, Oid opclass, * expand_indexqual_conditions * Given a list of sublists of RestrictInfo nodes, produce a flat list * of index qual clauses. Standard qual clauses (those in the index's - * opclass) are passed through unchanged. Boolean clauses and "special" + * opfamily) are passed through unchanged. Boolean clauses and "special" * index operators are expanded into clauses that the indexscan machinery * will know what to do with. RowCompare clauses are simplified if * necessary to create a clause that is fully checkable by the index. @@ -2196,7 +2193,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) List *resultquals = NIL; ListCell *clausegroup_item; int indexcol = 0; - Oid *classes = index->classlist; + Oid *families = index->opfamily; if (clausegroups == NIL) return NIL; @@ -2204,7 +2201,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) clausegroup_item = list_head(clausegroups); do { - Oid curClass = classes[0]; + Oid curFamily = families[0]; ListCell *l; foreach(l, (List *) lfirst(clausegroup_item)) @@ -2213,7 +2210,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) Expr *clause = rinfo->clause; /* First check for boolean cases */ - if (IsBooleanOpclass(curClass)) + if (IsBooleanOpfamily(curFamily)) { Expr *boolqual; @@ -2240,7 +2237,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) { resultquals = list_concat(resultquals, expand_indexqual_opclause(rinfo, - curClass)); + curFamily)); } else if (IsA(clause, ScalarArrayOpExpr)) { @@ -2262,8 +2259,8 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) clausegroup_item = lnext(clausegroup_item); indexcol++; - classes++; - } while (clausegroup_item != NULL && !DoneMatchingIndexKeys(classes)); + families++; + } while (clausegroup_item != NULL && !DoneMatchingIndexKeys(families)); Assert(clausegroup_item == NULL); /* else more groups than indexkeys */ @@ -2337,7 +2334,7 @@ expand_boolean_index_clause(Node *clause, * The input is a single RestrictInfo, the output a list of RestrictInfos */ static List * -expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) +expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily) { Expr *clause = rinfo->clause; @@ -2354,7 +2351,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) switch (expr_op) { /* - * LIKE and regex operators are not members of any index opclass, + * LIKE and regex operators are not members of any index opfamily, * so if we find one in an indexqual list we can assume that it * was accepted by match_special_index_operator(). */ @@ -2364,7 +2361,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) case OID_BYTEA_LIKE_OP: pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like, &prefix, &rest); - result = prefix_quals(leftop, opclass, prefix, pstatus); + result = prefix_quals(leftop, opfamily, prefix, pstatus); break; case OID_TEXT_ICLIKE_OP: @@ -2373,7 +2370,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) /* the right-hand const is type text for all of these */ pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like_IC, &prefix, &rest); - result = prefix_quals(leftop, opclass, prefix, pstatus); + result = prefix_quals(leftop, opfamily, prefix, pstatus); break; case OID_TEXT_REGEXEQ_OP: @@ -2382,7 +2379,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) /* the right-hand const is type text for all of these */ pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex, &prefix, &rest); - result = prefix_quals(leftop, opclass, prefix, pstatus); + result = prefix_quals(leftop, opfamily, prefix, pstatus); break; case OID_TEXT_ICREGEXEQ_OP: @@ -2391,12 +2388,12 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) /* the right-hand const is type text for all of these */ pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC, &prefix, &rest); - result = prefix_quals(leftop, opclass, prefix, pstatus); + result = prefix_quals(leftop, opfamily, prefix, pstatus); break; case OID_INET_SUB_OP: case OID_INET_SUBEQ_OP: - result = network_prefix_quals(leftop, expr_op, opclass, + result = network_prefix_quals(leftop, expr_op, opfamily, patt->constvalue); break; @@ -2416,7 +2413,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opclass) * the specified column of the index. We can use additional columns of the * row comparison as index qualifications, so long as they match the index * in the "same direction", ie, the indexkeys are all on the same side of the - * clause and the operators are all the same-type members of the opclasses. + * clause and the operators are all the same-type members of the opfamilies. * If all the columns of the RowCompareExpr match in this way, we just use it * as-is. Otherwise, we build a shortened RowCompareExpr (if more than one * column matches) or a simple OpExpr (if the first-column match is all @@ -2433,12 +2430,14 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, RowCompareExpr *clause = (RowCompareExpr *) rinfo->clause; bool var_on_left; int op_strategy; - Oid op_subtype; + Oid op_lefttype; + Oid op_righttype; bool op_recheck; int matching_cols; Oid expr_op; - List *opclasses; - List *subtypes; + List *opfamilies; + List *lefttypes; + List *righttypes; List *new_ops; ListCell *largs_cell; ListCell *rargs_cell; @@ -2453,11 +2452,15 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, expr_op = linitial_oid(clause->opnos); if (!var_on_left) expr_op = get_commutator(expr_op); - get_op_opclass_properties(expr_op, index->classlist[indexcol], - &op_strategy, &op_subtype, &op_recheck); - /* Build lists of the opclasses and operator subtypes in case needed */ - opclasses = list_make1_oid(index->classlist[indexcol]); - subtypes = list_make1_oid(op_subtype); + get_op_opfamily_properties(expr_op, index->opfamily[indexcol], + &op_strategy, + &op_lefttype, + &op_righttype, + &op_recheck); + /* Build lists of the opfamilies and operator datatypes in case needed */ + opfamilies = list_make1_oid(index->opfamily[indexcol]); + lefttypes = list_make1_oid(op_lefttype); + righttypes = list_make1_oid(op_righttype); /* * See how many of the remaining columns match some index column in the @@ -2513,15 +2516,19 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, break; /* no match found */ /* Now, do we have the right operator for this column? */ - if (get_op_opclass_strategy(expr_op, index->classlist[i]) + if (get_op_opfamily_strategy(expr_op, index->opfamily[i]) != op_strategy) break; - /* Add opclass and subtype to lists */ - get_op_opclass_properties(expr_op, index->classlist[i], - &op_strategy, &op_subtype, &op_recheck); - opclasses = lappend_oid(opclasses, index->classlist[i]); - subtypes = lappend_oid(subtypes, op_subtype); + /* Add opfamily and datatypes to lists */ + get_op_opfamily_properties(expr_op, index->opfamily[i], + &op_strategy, + &op_lefttype, + &op_righttype, + &op_recheck); + opfamilies = lappend_oid(opfamilies, index->opfamily[i]); + lefttypes = lappend_oid(lefttypes, op_lefttype); + righttypes = lappend_oid(righttypes, op_righttype); /* This column matches, keep scanning */ matching_cols++; @@ -2547,8 +2554,9 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, } else { - ListCell *opclasses_cell; - ListCell *subtypes_cell; + ListCell *opfamilies_cell; + ListCell *lefttypes_cell; + ListCell *righttypes_cell; if (op_strategy == BTLessStrategyNumber) op_strategy = BTLessEqualStrategyNumber; @@ -2557,23 +2565,30 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, else elog(ERROR, "unexpected strategy number %d", op_strategy); new_ops = NIL; - forboth(opclasses_cell, opclasses, subtypes_cell, subtypes) + lefttypes_cell = list_head(lefttypes); + righttypes_cell = list_head(righttypes); + foreach(opfamilies_cell, opfamilies) { - expr_op = get_opclass_member(lfirst_oid(opclasses_cell), - lfirst_oid(subtypes_cell), - op_strategy); + Oid opfam = lfirst_oid(opfamilies_cell); + Oid lefttype = lfirst_oid(lefttypes_cell); + Oid righttype = lfirst_oid(righttypes_cell); + + expr_op = get_opfamily_member(opfam, lefttype, righttype, + op_strategy); if (!OidIsValid(expr_op)) /* should not happen */ - elog(ERROR, "could not find member %d of opclass %u", - op_strategy, lfirst_oid(opclasses_cell)); + elog(ERROR, "could not find member %d(%u,%u) of opfamily %u", + op_strategy, lefttype, righttype, opfam); if (!var_on_left) { expr_op = get_commutator(expr_op); if (!OidIsValid(expr_op)) /* should not happen */ - elog(ERROR, "could not find commutator of member %d of opclass %u", - op_strategy, lfirst_oid(opclasses_cell)); + elog(ERROR, "could not find commutator of member %d(%u,%u) of opfamily %u", + op_strategy, lefttype, righttype, opfam); } new_ops = lappend_oid(new_ops, expr_op); } + lefttypes_cell = lnext(lefttypes_cell); + righttypes_cell = lnext(righttypes_cell); } /* If we have more than one matching col, create a subset rowcompare */ @@ -2587,8 +2602,8 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, rc->rctype = (op_strategy == BTLessEqualStrategyNumber) ? ROWCOMPARE_GE : ROWCOMPARE_LE; rc->opnos = new_ops; - rc->opclasses = list_truncate(list_copy(clause->opclasses), - matching_cols); + rc->opfamilies = list_truncate(list_copy(clause->opfamilies), + matching_cols); rc->largs = list_truncate((List *) copyObject(clause->largs), matching_cols); rc->rargs = list_truncate((List *) copyObject(clause->rargs), @@ -2608,12 +2623,12 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, /* * Given a fixed prefix that all the "leftop" values must have, - * generate suitable indexqual condition(s). opclass is the index - * operator class; we use it to deduce the appropriate comparison + * generate suitable indexqual condition(s). opfamily is the index + * operator family; we use it to deduce the appropriate comparison * operators and operand datatypes. */ static List * -prefix_quals(Node *leftop, Oid opclass, +prefix_quals(Node *leftop, Oid opfamily, Const *prefix_const, Pattern_Prefix_Status pstatus) { List *result; @@ -2624,35 +2639,30 @@ prefix_quals(Node *leftop, Oid opclass, Assert(pstatus != Pattern_Prefix_None); - switch (opclass) + switch (opfamily) { - case TEXT_BTREE_OPS_OID: - case TEXT_PATTERN_BTREE_OPS_OID: + case TEXT_BTREE_FAM_OID: + case TEXT_PATTERN_BTREE_FAM_OID: datatype = TEXTOID; break; - case VARCHAR_BTREE_OPS_OID: - case VARCHAR_PATTERN_BTREE_OPS_OID: - datatype = VARCHAROID; - break; - - case BPCHAR_BTREE_OPS_OID: - case BPCHAR_PATTERN_BTREE_OPS_OID: + case BPCHAR_BTREE_FAM_OID: + case BPCHAR_PATTERN_BTREE_FAM_OID: datatype = BPCHAROID; break; - case NAME_BTREE_OPS_OID: - case NAME_PATTERN_BTREE_OPS_OID: + case NAME_BTREE_FAM_OID: + case NAME_PATTERN_BTREE_FAM_OID: datatype = NAMEOID; break; - case BYTEA_BTREE_OPS_OID: + case BYTEA_BTREE_FAM_OID: datatype = BYTEAOID; break; default: /* shouldn't get here */ - elog(ERROR, "unexpected opclass: %u", opclass); + elog(ERROR, "unexpected opfamily: %u", opfamily); return NIL; } @@ -2688,10 +2698,10 @@ prefix_quals(Node *leftop, Oid opclass, */ if (pstatus == Pattern_Prefix_Exact) { - oproid = get_opclass_member(opclass, InvalidOid, - BTEqualStrategyNumber); + oproid = get_opfamily_member(opfamily, datatype, datatype, + BTEqualStrategyNumber); if (oproid == InvalidOid) - elog(ERROR, "no = operator for opclass %u", opclass); + elog(ERROR, "no = operator for opfamily %u", opfamily); expr = make_opclause(oproid, BOOLOID, false, (Expr *) leftop, (Expr *) prefix_const); result = list_make1(make_restrictinfo(expr, true, false, false, NULL)); @@ -2703,10 +2713,10 @@ prefix_quals(Node *leftop, Oid opclass, * * We can always say "x >= prefix". */ - oproid = get_opclass_member(opclass, InvalidOid, - BTGreaterEqualStrategyNumber); + oproid = get_opfamily_member(opfamily, datatype, datatype, + BTGreaterEqualStrategyNumber); if (oproid == InvalidOid) - elog(ERROR, "no >= operator for opclass %u", opclass); + elog(ERROR, "no >= operator for opfamily %u", opfamily); expr = make_opclause(oproid, BOOLOID, false, (Expr *) leftop, (Expr *) prefix_const); result = list_make1(make_restrictinfo(expr, true, false, false, NULL)); @@ -2719,10 +2729,10 @@ prefix_quals(Node *leftop, Oid opclass, greaterstr = make_greater_string(prefix_const); if (greaterstr) { - oproid = get_opclass_member(opclass, InvalidOid, - BTLessStrategyNumber); + oproid = get_opfamily_member(opfamily, datatype, datatype, + BTLessStrategyNumber); if (oproid == InvalidOid) - elog(ERROR, "no < operator for opclass %u", opclass); + elog(ERROR, "no < operator for opfamily %u", opfamily); expr = make_opclause(oproid, BOOLOID, false, (Expr *) leftop, (Expr *) greaterstr); result = lappend(result, @@ -2733,12 +2743,12 @@ prefix_quals(Node *leftop, Oid opclass, } /* - * Given a leftop and a rightop, and a inet-class sup/sub operator, + * Given a leftop and a rightop, and a inet-family sup/sub operator, * generate suitable indexqual condition(s). expr_op is the original - * operator, and opclass is the index opclass. + * operator, and opfamily is the index opfamily. */ static List * -network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop) +network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop) { bool is_eq; Oid datatype; @@ -2770,17 +2780,17 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop) */ if (is_eq) { - opr1oid = get_opclass_member(opclass, InvalidOid, - BTGreaterEqualStrategyNumber); + opr1oid = get_opfamily_member(opfamily, datatype, datatype, + BTGreaterEqualStrategyNumber); if (opr1oid == InvalidOid) - elog(ERROR, "no >= operator for opclass %u", opclass); + elog(ERROR, "no >= operator for opfamily %u", opfamily); } else { - opr1oid = get_opclass_member(opclass, InvalidOid, - BTGreaterStrategyNumber); + opr1oid = get_opfamily_member(opfamily, datatype, datatype, + BTGreaterStrategyNumber); if (opr1oid == InvalidOid) - elog(ERROR, "no > operator for opclass %u", opclass); + elog(ERROR, "no > operator for opfamily %u", opfamily); } opr1right = network_scan_first(rightop); @@ -2793,10 +2803,10 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop) /* create clause "key <= network_scan_last( rightop )" */ - opr2oid = get_opclass_member(opclass, InvalidOid, - BTLessEqualStrategyNumber); + opr2oid = get_opfamily_member(opfamily, datatype, datatype, + BTLessEqualStrategyNumber); if (opr2oid == InvalidOid) - elog(ERROR, "no <= operator for opclass %u", opclass); + elog(ERROR, "no <= operator for opfamily %u", opfamily); opr2right = network_scan_last(rightop); diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 6882439ca3..06022b373b 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.107 2006/10/04 00:29:54 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.108 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,6 +16,7 @@ #include +#include "access/skey.h" #include "optimizer/cost.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" @@ -39,6 +40,8 @@ static List *select_mergejoin_clauses(RelOptInfo *joinrel, RelOptInfo *innerrel, List *restrictlist, JoinType jointype); +static void build_mergejoin_strat_lists(List *mergeclauses, + List **mergefamilies, List **mergestrategies); /* @@ -225,6 +228,8 @@ sort_inner_and_outer(PlannerInfo *root, List *front_pathkey = (List *) lfirst(l); List *cur_pathkeys; List *cur_mergeclauses; + List *mergefamilies; + List *mergestrategies; List *outerkeys; List *innerkeys; List *merge_pathkeys; @@ -269,6 +274,10 @@ sort_inner_and_outer(PlannerInfo *root, merge_pathkeys = build_join_pathkeys(root, joinrel, jointype, outerkeys); + /* Build opfamily info for execution */ + build_mergejoin_strat_lists(cur_mergeclauses, + &mergefamilies, &mergestrategies); + /* * And now we can make the path. */ @@ -281,6 +290,8 @@ sort_inner_and_outer(PlannerInfo *root, restrictlist, merge_pathkeys, cur_mergeclauses, + mergefamilies, + mergestrategies, outerkeys, innerkeys)); } @@ -410,6 +421,8 @@ match_unsorted_outer(PlannerInfo *root, Path *outerpath = (Path *) lfirst(l); List *merge_pathkeys; List *mergeclauses; + List *mergefamilies; + List *mergestrategies; List *innersortkeys; List *trialsortkeys; Path *cheapest_startup_inner; @@ -516,6 +529,10 @@ match_unsorted_outer(PlannerInfo *root, mergeclauses, innerrel); + /* Build opfamily info for execution */ + build_mergejoin_strat_lists(mergeclauses, + &mergefamilies, &mergestrategies); + /* * Generate a mergejoin on the basis of sorting the cheapest inner. * Since a sort will be needed, only cheapest total cost matters. (But @@ -531,6 +548,8 @@ match_unsorted_outer(PlannerInfo *root, restrictlist, merge_pathkeys, mergeclauses, + mergefamilies, + mergestrategies, NIL, innersortkeys)); @@ -589,6 +608,11 @@ match_unsorted_outer(PlannerInfo *root, } else newclauses = mergeclauses; + + /* Build opfamily info for execution */ + build_mergejoin_strat_lists(newclauses, + &mergefamilies, &mergestrategies); + add_path(joinrel, (Path *) create_mergejoin_path(root, joinrel, @@ -598,6 +622,8 @@ match_unsorted_outer(PlannerInfo *root, restrictlist, merge_pathkeys, newclauses, + mergefamilies, + mergestrategies, NIL, NIL)); cheapest_total_inner = innerpath; @@ -633,6 +659,11 @@ match_unsorted_outer(PlannerInfo *root, else newclauses = mergeclauses; } + + /* Build opfamily info for execution */ + build_mergejoin_strat_lists(newclauses, + &mergefamilies, &mergestrategies); + add_path(joinrel, (Path *) create_mergejoin_path(root, joinrel, @@ -642,6 +673,8 @@ match_unsorted_outer(PlannerInfo *root, restrictlist, merge_pathkeys, newclauses, + mergefamilies, + mergestrategies, NIL, NIL)); } @@ -946,3 +979,35 @@ select_mergejoin_clauses(RelOptInfo *joinrel, return result_list; } + +/* + * Temporary hack to build opfamily and strategy lists needed for mergejoin + * by the executor. We need to rethink the planner's handling of merge + * planning so that it can deal with multiple possible merge orders, but + * that's not done yet. + */ +static void +build_mergejoin_strat_lists(List *mergeclauses, + List **mergefamilies, List **mergestrategies) +{ + ListCell *l; + + *mergefamilies = NIL; + *mergestrategies = NIL; + + foreach(l, mergeclauses) + { + RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l); + + /* + * We do not need to worry about whether the mergeclause will be + * commuted at runtime --- it's the same opfamily either way. + */ + *mergefamilies = lappend_oid(*mergefamilies, restrictinfo->mergeopfamily); + /* + * For the moment, strategy must always be LessThan --- see + * hack version of get_op_mergejoin_info + */ + *mergestrategies = lappend_int(*mergestrategies, BTLessStrategyNumber); + } +} diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 14f1f1a10f..f924994480 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.217 2006/10/04 00:29:54 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.218 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -73,7 +73,7 @@ static void fix_indexqual_references(List *indexquals, IndexPath *index_path, List **indexstrategy, List **indexsubtype); static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, - Oid *opclass); + Oid *opfamily); static List *get_switched_clauses(List *clauses, Relids outerrelids); static List *order_qual_clauses(PlannerInfo *root, List *clauses); static void copy_path_costsize(Plan *dest, Path *src); @@ -113,7 +113,7 @@ static HashJoin *make_hashjoin(List *tlist, static Hash *make_hash(Plan *lefttree); static MergeJoin *make_mergejoin(List *tlist, List *joinclauses, List *otherclauses, - List *mergeclauses, + List *mergeclauses, List *mergefamilies, List *mergestrategies, Plan *lefttree, Plan *righttree, JoinType jointype); static Sort *make_sort(PlannerInfo *root, Plan *lefttree, int numCols, @@ -1540,6 +1540,8 @@ create_mergejoin_plan(PlannerInfo *root, joinclauses, otherclauses, mergeclauses, + best_path->path_mergefamilies, + best_path->path_mergestrategies, outer_plan, inner_plan, best_path->jpath.jointype); @@ -1676,9 +1678,10 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); Expr *clause; Oid clause_op; - Oid opclass; + Oid opfamily; int stratno; - Oid stratsubtype; + Oid stratlefttype; + Oid stratrighttype; bool recheck; Assert(IsA(rinfo, RestrictInfo)); @@ -1709,11 +1712,11 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, /* * Now, determine which index attribute this is, change the - * indexkey operand as needed, and get the index opclass. + * indexkey operand as needed, and get the index opfamily. */ linitial(op->args) = fix_indexqual_operand(linitial(op->args), index, - &opclass); + &opfamily); clause_op = op->opno; } else if (IsA(clause, RowCompareExpr)) @@ -1734,20 +1737,20 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, * For each column in the row comparison, determine which index * attribute this is and change the indexkey operand as needed. * - * Save the index opclass for only the first column. We will - * return the operator and opclass info for just the first column + * Save the index opfamily for only the first column. We will + * return the operator and opfamily info for just the first column * of the row comparison; the executor will have to look up the * rest if it needs them. */ foreach(lc, rc->largs) { - Oid tmp_opclass; + Oid tmp_opfamily; lfirst(lc) = fix_indexqual_operand(lfirst(lc), index, - &tmp_opclass); + &tmp_opfamily); if (lc == list_head(rc->largs)) - opclass = tmp_opclass; + opfamily = tmp_opfamily; } clause_op = linitial_oid(rc->opnos); } @@ -1759,11 +1762,11 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, /* * Now, determine which index attribute this is, change the - * indexkey operand as needed, and get the index opclass. + * indexkey operand as needed, and get the index opfamily. */ linitial(saop->args) = fix_indexqual_operand(linitial(saop->args), index, - &opclass); + &opfamily); clause_op = saop->opno; } else @@ -1776,15 +1779,18 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, *fixed_indexquals = lappend(*fixed_indexquals, clause); /* - * Look up the (possibly commuted) operator in the operator class to - * get its strategy numbers and the recheck indicator. This also + * Look up the (possibly commuted) operator in the operator family to + * get its strategy number and the recheck indicator. This also * double-checks that we found an operator matching the index. */ - get_op_opclass_properties(clause_op, opclass, - &stratno, &stratsubtype, &recheck); + get_op_opfamily_properties(clause_op, opfamily, + &stratno, + &stratlefttype, + &stratrighttype, + &recheck); *indexstrategy = lappend_int(*indexstrategy, stratno); - *indexsubtype = lappend_oid(*indexsubtype, stratsubtype); + *indexsubtype = lappend_oid(*indexsubtype, stratrighttype); /* If it's not lossy, add to nonlossy_indexquals */ if (!recheck) @@ -1793,7 +1799,7 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, } static Node * -fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass) +fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opfamily) { /* * We represent index keys by Var nodes having the varno of the base table @@ -1826,8 +1832,8 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass) { result = (Var *) copyObject(node); result->varattno = pos + 1; - /* return the correct opclass, too */ - *opclass = index->classlist[pos]; + /* return the correct opfamily, too */ + *opfamily = index->opfamily[pos]; return (Node *) result; } } @@ -1853,8 +1859,8 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass) result = makeVar(index->rel->relid, pos + 1, exprType(lfirst(indexpr_item)), -1, 0); - /* return the correct opclass, too */ - *opclass = index->classlist[pos]; + /* return the correct opfamily, too */ + *opfamily = index->opfamily[pos]; return (Node *) result; } indexpr_item = lnext(indexpr_item); @@ -1863,7 +1869,7 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, Oid *opclass) /* Ooops... */ elog(ERROR, "node is not an index attribute"); - *opclass = InvalidOid; /* keep compiler quiet */ + *opfamily = InvalidOid; /* keep compiler quiet */ return NULL; } @@ -2327,6 +2333,8 @@ make_mergejoin(List *tlist, List *joinclauses, List *otherclauses, List *mergeclauses, + List *mergefamilies, + List *mergestrategies, Plan *lefttree, Plan *righttree, JoinType jointype) @@ -2340,6 +2348,8 @@ make_mergejoin(List *tlist, plan->lefttree = lefttree; plan->righttree = righttree; node->mergeclauses = mergeclauses; + node->mergefamilies = mergefamilies; + node->mergestrategies = mergestrategies; node->join.jointype = jointype; node->join.joinqual = joinclauses; diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index da321a637b..229b779af0 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.124 2006/12/07 19:33:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.125 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1109,10 +1109,10 @@ process_implied_equality(PlannerInfo *root, /* * Let's just make sure this appears to be a compatible operator. + * + * XXX needs work */ - if (pgopform->oprlsortop != sortop1 || - pgopform->oprrsortop != sortop2 || - pgopform->oprresult != BOOLOID) + if (pgopform->oprresult != BOOLOID) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("equality operator for types %s and %s should be merge-joinable, but isn't", @@ -1276,6 +1276,7 @@ check_mergejoinable(RestrictInfo *restrictinfo) Oid opno, leftOp, rightOp; + Oid opfamily; if (restrictinfo->pseudoconstant) return; @@ -1286,14 +1287,17 @@ check_mergejoinable(RestrictInfo *restrictinfo) opno = ((OpExpr *) clause)->opno; - if (op_mergejoinable(opno, - &leftOp, - &rightOp) && + if (op_mergejoinable(opno) && !contain_volatile_functions((Node *) clause)) { - restrictinfo->mergejoinoperator = opno; - restrictinfo->left_sortop = leftOp; - restrictinfo->right_sortop = rightOp; + /* XXX for the moment, continue to force use of particular sortops */ + if (get_op_mergejoin_info(opno, &leftOp, &rightOp, &opfamily)) + { + restrictinfo->mergejoinoperator = opno; + restrictinfo->left_sortop = leftOp; + restrictinfo->right_sortop = rightOp; + restrictinfo->mergeopfamily = opfamily; + } } } diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c index e64340ed21..fcc8d51078 100644 --- a/src/backend/optimizer/plan/planagg.c +++ b/src/backend/optimizer/plan/planagg.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.22 2006/10/04 00:29:54 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.23 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -340,8 +340,8 @@ build_minmax_path(PlannerInfo *root, RelOptInfo *rel, MinMaxAggInfo *info) Assert(is_opclause(rinfo->clause)); strategy = - get_op_opclass_strategy(((OpExpr *) rinfo->clause)->opno, - index->classlist[prevcol]); + get_op_opfamily_strategy(((OpExpr *) rinfo->clause)->opno, + index->opfamily[prevcol]); if (strategy == BTEqualStrategyNumber) break; } @@ -390,10 +390,10 @@ build_minmax_path(PlannerInfo *root, RelOptInfo *rel, MinMaxAggInfo *info) * Does an aggregate match an index column? * * It matches if its argument is equal to the index column's data and its - * sortop is either the LessThan or GreaterThan member of the column's opclass. + * sortop is either a LessThan or GreaterThan member of the column's opfamily. * - * We return ForwardScanDirection if match the LessThan member, - * BackwardScanDirection if match the GreaterThan member, + * We return ForwardScanDirection if match a LessThan member, + * BackwardScanDirection if match a GreaterThan member, * and NoMovementScanDirection if there's no match. */ static ScanDirection @@ -405,9 +405,9 @@ match_agg_to_index_col(MinMaxAggInfo *info, IndexOptInfo *index, int indexcol) if (!match_index_to_operand((Node *) info->target, indexcol, index)) return NoMovementScanDirection; - /* Look up the operator in the opclass */ - strategy = get_op_opclass_strategy(info->aggsortop, - index->classlist[indexcol]); + /* Look up the operator in the opfamily */ + strategy = get_op_opfamily_strategy(info->aggsortop, + index->opfamily[indexcol]); if (strategy == BTLessStrategyNumber) return ForwardScanDirection; if (strategy == BTGreaterStrategyNumber) diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 7793d071cd..f42a28cddd 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.114 2006/12/10 22:13:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.115 2006/12/23 00:43:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -689,11 +689,11 @@ convert_IN_to_join(PlannerInfo *root, SubLink *sublink) return NULL; if (sublink->testexpr && IsA(sublink->testexpr, OpExpr)) { - List *opclasses; + List *opfamilies; List *opstrats; get_op_btree_interpretation(((OpExpr *) sublink->testexpr)->opno, - &opclasses, &opstrats); + &opfamilies, &opstrats); if (!list_member_int(opstrats, ROWCOMPARE_EQ)) return NULL; } diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 73ad926418..0f720c40e9 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.224 2006/12/21 16:05:13 petere Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.225 2006/12/23 00:43:10 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -1294,13 +1294,9 @@ CommuteRowCompareExpr(RowCompareExpr *clause) clause->opnos = newops; /* - * Note: we don't bother to update the opclasses list, but just set it to - * empty. This is OK since this routine is currently only used for index - * quals, and the index machinery won't use the opclass information. The - * original opclass list is NOT valid if we have commuted any cross-type - * comparisons, so don't leave it in place. + * Note: we need not change the opfamilies list; we assume any btree + * opfamily containing an operator will also contain its commutator. */ - clause->opclasses = NIL; /* XXX */ temp = clause->largs; clause->largs = clause->rargs; diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 01f3151bee..5042a3ff56 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.133 2006/10/04 00:29:55 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.134 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1152,6 +1152,10 @@ create_nestloop_path(PlannerInfo *root, * 'pathkeys' are the path keys of the new join path * 'mergeclauses' are the RestrictInfo nodes to use as merge clauses * (this should be a subset of the restrict_clauses list) + * 'mergefamilies' are the btree opfamily OIDs identifying the merge + * ordering for each merge clause + * 'mergestrategies' are the btree operator strategies identifying the merge + * ordering for each merge clause * 'outersortkeys' are the sort varkeys for the outer relation * 'innersortkeys' are the sort varkeys for the inner relation */ @@ -1164,6 +1168,8 @@ create_mergejoin_path(PlannerInfo *root, List *restrict_clauses, List *pathkeys, List *mergeclauses, + List *mergefamilies, + List *mergestrategies, List *outersortkeys, List *innersortkeys) { @@ -1204,6 +1210,8 @@ create_mergejoin_path(PlannerInfo *root, pathnode->jpath.joinrestrictinfo = restrict_clauses; pathnode->jpath.path.pathkeys = pathkeys; pathnode->path_mergeclauses = mergeclauses; + pathnode->path_mergefamilies = mergefamilies; + pathnode->path_mergestrategies = mergestrategies; pathnode->outersortkeys = outersortkeys; pathnode->innersortkeys = innersortkeys; diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 70a77bd3bd..5b80991aef 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.128 2006/12/18 18:56:28 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.129 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -169,16 +169,16 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, info->ncolumns = ncolumns = index->indnatts; /* - * Need to make classlist and ordering arrays large enough to put + * Need to make opfamily and ordering arrays large enough to put * a terminating 0 at the end of each one. */ info->indexkeys = (int *) palloc(sizeof(int) * ncolumns); - info->classlist = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1)); + info->opfamily = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1)); info->ordering = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1)); for (i = 0; i < ncolumns; i++) { - info->classlist[i] = indexRelation->rd_indclass->values[i]; + info->opfamily[i] = indexRelation->rd_opfamily[i]; info->indexkeys[i] = index->indkey.values[i]; } diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c index 4a2609a4ab..5f81cae4e8 100644 --- a/src/backend/optimizer/util/predtest.c +++ b/src/backend/optimizer/util/predtest.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.10 2006/10/04 00:29:55 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.11 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -939,7 +939,7 @@ arrayexpr_cleanup_fn(PredIterInfo info) * already known immutable, so the clause will certainly always fail.) * * Finally, we may be able to deduce something using knowledge about btree - * operator classes; this is encapsulated in btree_predicate_proof(). + * operator families; this is encapsulated in btree_predicate_proof(). *---------- */ static bool @@ -989,7 +989,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause) * that has "foo" as an input. See notes for implication case. * * Finally, we may be able to deduce something using knowledge about btree - * operator classes; this is encapsulated in btree_predicate_proof(). + * operator families; this is encapsulated in btree_predicate_proof(). *---------- */ static bool @@ -1062,8 +1062,8 @@ extract_not_arg(Node *clause) * The strategy numbers defined by btree indexes (see access/skey.h) are: * (1) < (2) <= (3) = (4) >= (5) > * and in addition we use (6) to represent <>. <> is not a btree-indexable - * operator, but we assume here that if the equality operator of a btree - * opclass has a negator operator, the negator behaves as <> for the opclass. + * operator, but we assume here that if an equality operator of a btree + * opfamily has a negator operator, the negator behaves as <> for the opfamily. * * The interpretation of: * @@ -1146,10 +1146,10 @@ static const StrategyNumber BT_refute_table[6][6] = { * What we look for here is binary boolean opclauses of the form * "foo op constant", where "foo" is the same in both clauses. The operators * and constants can be different but the operators must be in the same btree - * operator class. We use the above operator implication tables to + * operator family. We use the above operator implication tables to * derive implications between nonidentical clauses. (Note: "foo" is known * immutable, and constants are surely immutable, but we have to check that - * the operators are too. As of 8.0 it's possible for opclasses to contain + * the operators are too. As of 8.0 it's possible for opfamilies to contain * operators that are merely stable, and we dare not make deductions with * these.) *---------- @@ -1171,12 +1171,12 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it) pred_op_negator, clause_op_negator, test_op = InvalidOid; - Oid opclass_id; + Oid opfamily_id; bool found = false; StrategyNumber pred_strategy, clause_strategy, test_strategy; - Oid clause_subtype; + Oid clause_righttype; Expr *test_expr; ExprState *test_exprstate; Datum test_result; @@ -1272,28 +1272,30 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it) } /* - * Try to find a btree opclass containing the needed operators. + * Try to find a btree opfamily containing the needed operators. * - * We must find a btree opclass that contains both operators, else the + * XXX this needs work!!!!!!!!!!!!!!!!!!!!!!! + * + * We must find a btree opfamily that contains both operators, else the * implication can't be determined. Also, the pred_op has to be of * default subtype (implying left and right input datatypes are the same); * otherwise it's unsafe to put the pred_const on the left side of the - * test. Also, the opclass must contain a suitable test operator matching + * test. Also, the opfamily must contain a suitable test operator matching * the clause_const's type (which we take to mean that it has the same * subtype as the original clause_operator). * - * If there are multiple matching opclasses, assume we can use any one to + * If there are multiple matching opfamilies, assume we can use any one to * determine the logical relationship of the two operators and the correct * corresponding test operator. This should work for any logically - * consistent opclasses. + * consistent opfamilies. */ catlist = SearchSysCacheList(AMOPOPID, 1, ObjectIdGetDatum(pred_op), 0, 0, 0); /* - * If we couldn't find any opclass containing the pred_op, perhaps it is a - * <> operator. See if it has a negator that is in an opclass. + * If we couldn't find any opfamily containing the pred_op, perhaps it is a + * <> operator. See if it has a negator that is in an opfamily. */ pred_op_negated = false; if (catlist->n_members == 0) @@ -1312,23 +1314,22 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it) /* Also may need the clause_op's negator */ clause_op_negator = get_negator(clause_op); - /* Now search the opclasses */ + /* Now search the opfamilies */ for (i = 0; i < catlist->n_members; i++) { HeapTuple pred_tuple = &catlist->members[i]->tuple; Form_pg_amop pred_form = (Form_pg_amop) GETSTRUCT(pred_tuple); HeapTuple clause_tuple; - opclass_id = pred_form->amopclaid; - /* must be btree */ - if (!opclass_is_btree(opclass_id)) + if (pred_form->amopmethod != BTREE_AM_OID) continue; - /* predicate operator must be default within this opclass */ - if (pred_form->amopsubtype != InvalidOid) + /* predicate operator must be default within this opfamily */ + if (pred_form->amoplefttype != pred_form->amoprighttype) continue; /* Get the predicate operator's btree strategy number */ + opfamily_id = pred_form->amopfamily; pred_strategy = (StrategyNumber) pred_form->amopstrategy; Assert(pred_strategy >= 1 && pred_strategy <= 5); @@ -1341,37 +1342,39 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it) } /* - * From the same opclass, find a strategy number for the clause_op, if - * possible + * From the same opfamily, find a strategy number for the clause_op, + * if possible */ clause_tuple = SearchSysCache(AMOPOPID, ObjectIdGetDatum(clause_op), - ObjectIdGetDatum(opclass_id), + ObjectIdGetDatum(opfamily_id), 0, 0); if (HeapTupleIsValid(clause_tuple)) { Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple); - /* Get the restriction clause operator's strategy/subtype */ + /* Get the restriction clause operator's strategy/datatype */ clause_strategy = (StrategyNumber) clause_form->amopstrategy; Assert(clause_strategy >= 1 && clause_strategy <= 5); - clause_subtype = clause_form->amopsubtype; + Assert(clause_form->amoplefttype == pred_form->amoplefttype); + clause_righttype = clause_form->amoprighttype; ReleaseSysCache(clause_tuple); } else if (OidIsValid(clause_op_negator)) { clause_tuple = SearchSysCache(AMOPOPID, ObjectIdGetDatum(clause_op_negator), - ObjectIdGetDatum(opclass_id), + ObjectIdGetDatum(opfamily_id), 0, 0); if (HeapTupleIsValid(clause_tuple)) { Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple); - /* Get the restriction clause operator's strategy/subtype */ + /* Get the restriction clause operator's strategy/datatype */ clause_strategy = (StrategyNumber) clause_form->amopstrategy; Assert(clause_strategy >= 1 && clause_strategy <= 5); - clause_subtype = clause_form->amopsubtype; + Assert(clause_form->amoplefttype == pred_form->amoplefttype); + clause_righttype = clause_form->amoprighttype; ReleaseSysCache(clause_tuple); /* Only consider negators that are = */ @@ -1400,20 +1403,24 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it) } /* - * See if opclass has an operator for the test strategy and the clause - * datatype. + * See if opfamily has an operator for the test strategy and the + * datatypes. */ if (test_strategy == BTNE) { - test_op = get_opclass_member(opclass_id, clause_subtype, - BTEqualStrategyNumber); + test_op = get_opfamily_member(opfamily_id, + pred_form->amoprighttype, + clause_righttype, + BTEqualStrategyNumber); if (OidIsValid(test_op)) test_op = get_negator(test_op); } else { - test_op = get_opclass_member(opclass_id, clause_subtype, - test_strategy); + test_op = get_opfamily_member(opfamily_id, + pred_form->amoprighttype, + clause_righttype, + test_strategy); } if (OidIsValid(test_op)) { @@ -1423,7 +1430,7 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it) * Note that we require only the test_op to be immutable, not the * original clause_op. (pred_op is assumed to have been checked * immutable by the caller.) Essentially we are assuming that the - * opclass is consistent even if it contains operators that are + * opfamily is consistent even if it contains operators that are * merely stable. */ if (op_volatile(test_op) == PROVOLATILE_IMMUTABLE) @@ -1438,7 +1445,7 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it) if (!found) { - /* couldn't find a btree opclass to interpret the operators */ + /* couldn't find a btree opfamily to interpret the operators */ return false; } diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index 9176ae1680..adfd9e4785 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.49 2006/10/04 00:29:55 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.50 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -342,6 +342,7 @@ make_restrictinfo_internal(Expr *clause, restrictinfo->mergejoinoperator = InvalidOid; restrictinfo->left_sortop = InvalidOid; restrictinfo->right_sortop = InvalidOid; + restrictinfo->mergeopfamily = InvalidOid; restrictinfo->left_pathkey = NIL; restrictinfo->right_pathkey = NIL; diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 234a15b6af..2a48741b3a 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.200 2006/12/21 16:05:14 petere Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.201 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2014,10 +2014,10 @@ make_row_comparison_op(ParseState *pstate, List *opname, RowCompareType rctype; List *opexprs; List *opnos; - List *opclasses; + List *opfamilies; ListCell *l, *r; - List **opclass_lists; + List **opfamily_lists; List **opstrat_lists; Bitmapset *strats; int nopers; @@ -2057,7 +2057,7 @@ make_row_comparison_op(ParseState *pstate, List *opname, /* * We don't use coerce_to_boolean here because we insist on the * operator yielding boolean directly, not via coercion. If it - * doesn't yield bool it won't be in any index opclasses... + * doesn't yield bool it won't be in any index opfamilies... */ if (cmp->opresulttype != BOOLOID) ereport(ERROR, @@ -2084,21 +2084,22 @@ make_row_comparison_op(ParseState *pstate, List *opname, /* * Now we must determine which row comparison semantics (= <> < <= > >=) - * apply to this set of operators. We look for btree opclasses containing + * apply to this set of operators. We look for btree opfamilies containing * the operators, and see which interpretations (strategy numbers) exist * for each operator. */ - opclass_lists = (List **) palloc(nopers * sizeof(List *)); + opfamily_lists = (List **) palloc(nopers * sizeof(List *)); opstrat_lists = (List **) palloc(nopers * sizeof(List *)); strats = NULL; i = 0; foreach(l, opexprs) { + Oid opno = ((OpExpr *) lfirst(l))->opno; Bitmapset *this_strats; ListCell *j; - get_op_btree_interpretation(((OpExpr *) lfirst(l))->opno, - &opclass_lists[i], &opstrat_lists[i]); + get_op_btree_interpretation(opno, + &opfamily_lists[i], &opstrat_lists[i]); /* * convert strategy number list to a Bitmapset to make the @@ -2116,68 +2117,23 @@ make_row_comparison_op(ParseState *pstate, List *opname, i++; } - switch (bms_membership(strats)) + /* + * If there are multiple common interpretations, we may use any one of + * them ... this coding arbitrarily picks the lowest btree strategy + * number. + */ + i = bms_first_member(strats); + if (i < 0) { - case BMS_EMPTY_SET: - /* No common interpretation, so fail */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("could not determine interpretation of row comparison operator %s", - strVal(llast(opname))), - errhint("Row comparison operators must be associated with btree operator classes."), - parser_errposition(pstate, location))); - rctype = 0; /* keep compiler quiet */ - break; - case BMS_SINGLETON: - /* Simple case: just one possible interpretation */ - rctype = bms_singleton_member(strats); - break; - case BMS_MULTIPLE: - default: /* keep compiler quiet */ - { - /* - * Prefer the interpretation with the most default opclasses. - */ - int best_defaults = 0; - bool multiple_best = false; - int this_rctype; - - rctype = 0; /* keep compiler quiet */ - while ((this_rctype = bms_first_member(strats)) >= 0) - { - int ndefaults = 0; - - for (i = 0; i < nopers; i++) - { - forboth(l, opclass_lists[i], r, opstrat_lists[i]) - { - Oid opclass = lfirst_oid(l); - int opstrat = lfirst_int(r); - - if (opstrat == this_rctype && - opclass_is_default(opclass)) - ndefaults++; - } - } - if (ndefaults > best_defaults) - { - best_defaults = ndefaults; - rctype = this_rctype; - multiple_best = false; - } - else if (ndefaults == best_defaults) - multiple_best = true; - } - if (best_defaults == 0 || multiple_best) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("could not determine interpretation of row comparison operator %s", - strVal(llast(opname))), - errdetail("There are multiple equally-plausible candidates."), - parser_errposition(pstate, location))); - break; - } + /* No common interpretation, so fail */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("could not determine interpretation of row comparison operator %s", + strVal(llast(opname))), + errhint("Row comparison operators must be associated with btree operator families."), + parser_errposition(pstate, location))); } + rctype = (RowCompareType) i; /* * For = and <> cases, we just combine the pairwise operators with AND or @@ -2193,34 +2149,27 @@ make_row_comparison_op(ParseState *pstate, List *opname, return (Node *) makeBoolExpr(OR_EXPR, opexprs); /* - * Otherwise we need to determine exactly which opclass to associate with + * Otherwise we need to choose exactly which opfamily to associate with * each operator. */ - opclasses = NIL; + opfamilies = NIL; for (i = 0; i < nopers; i++) { - Oid best_opclass = 0; - int ndefault = 0; - int nmatch = 0; + Oid opfamily = InvalidOid; - forboth(l, opclass_lists[i], r, opstrat_lists[i]) + forboth(l, opfamily_lists[i], r, opstrat_lists[i]) { - Oid opclass = lfirst_oid(l); int opstrat = lfirst_int(r); if (opstrat == rctype) { - if (ndefault == 0) - best_opclass = opclass; - if (opclass_is_default(opclass)) - ndefault++; - else - nmatch++; + opfamily = lfirst_oid(l); + break; } } - if (ndefault == 1 || (ndefault == 0 && nmatch == 1)) - opclasses = lappend_oid(opclasses, best_opclass); - else + if (OidIsValid(opfamily)) + opfamilies = lappend_oid(opfamilies, opfamily); + else /* should not happen */ ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("could not determine interpretation of row comparison operator %s", @@ -2250,7 +2199,7 @@ make_row_comparison_op(ParseState *pstate, List *opname, rcexpr = makeNode(RowCompareExpr); rcexpr->rctype = rctype; rcexpr->opnos = opnos; - rcexpr->opclasses = opclasses; + rcexpr->opfamilies = opfamilies; rcexpr->largs = largs; rcexpr->rargs = rargs; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a99942010b..b2ff95f457 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -2,7 +2,7 @@ * ruleutils.c - Functions to convert stored expressions/querytrees * back to source text * - * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.236 2006/12/21 16:05:15 petere Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.237 2006/12/23 00:43:11 tgl Exp $ **********************************************************************/ #include "postgres.h" @@ -19,6 +19,7 @@ #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_trigger.h" +#include "commands/defrem.h" #include "executor/spi.h" #include "funcapi.h" #include "nodes/makefuncs.h" @@ -4717,11 +4718,6 @@ get_opclass_name(Oid opclass, Oid actual_datatype, Form_pg_opclass opcrec; char *opcname; char *nspname; - bool isvisible; - - /* Domains use their base type's default opclass */ - if (OidIsValid(actual_datatype)) - actual_datatype = getBaseType(actual_datatype); ht_opc = SearchSysCache(CLAOID, ObjectIdGetDatum(opclass), @@ -4730,25 +4726,12 @@ get_opclass_name(Oid opclass, Oid actual_datatype, elog(ERROR, "cache lookup failed for opclass %u", opclass); opcrec = (Form_pg_opclass) GETSTRUCT(ht_opc); - /* - * Special case for ARRAY_OPS: pretend it is default for any array type - */ - if (OidIsValid(actual_datatype)) - { - if (opcrec->opcintype == ANYARRAYOID && - OidIsValid(get_element_type(actual_datatype))) - actual_datatype = opcrec->opcintype; - } - - /* Must force use of opclass name if not in search path */ - isvisible = OpclassIsVisible(opclass); - - if (actual_datatype != opcrec->opcintype || !opcrec->opcdefault || - !isvisible) + if (!OidIsValid(actual_datatype) || + GetDefaultOpClass(actual_datatype, opcrec->opcmethod) != opclass) { /* Okay, we need the opclass name. Do we need to qualify it? */ opcname = NameStr(opcrec->opcname); - if (isvisible) + if (OpclassIsVisible(opclass)) appendStringInfo(buf, " %s", quote_identifier(opcname)); else { diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 230ce549f3..73e82cd5e0 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.215 2006/12/15 18:42:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.216 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -76,7 +76,7 @@ #include #include -#include "catalog/pg_opclass.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "mb/pg_wchar.h" @@ -128,7 +128,7 @@ static double convert_timevalue_to_scalar(Datum value, Oid typid); static bool get_variable_maximum(PlannerInfo *root, VariableStatData *vardata, Oid sortop, Datum *max); static Selectivity prefix_selectivity(VariableStatData *vardata, - Oid opclass, Const *prefixcon); + Oid vartype, Oid opfamily, Const *prefixcon); static Selectivity pattern_selectivity(Const *patt, Pattern_Type ptype); static Datum string_to_datum(const char *str, Oid datatype); static Const *string_to_const(const char *str, Oid datatype); @@ -911,7 +911,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) Datum constval; Oid consttype; Oid vartype; - Oid opclass; + Oid opfamily; Pattern_Prefix_Status pstatus; Const *patt = NULL; Const *prefix = NULL; @@ -960,9 +960,9 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) * Similarly, the exposed type of the left-hand side should be one of * those we know. (Do not look at vardata.atttype, which might be * something binary-compatible but different.) We can use it to choose - * the index opclass from which we must draw the comparison operators. + * the index opfamily from which we must draw the comparison operators. * - * NOTE: It would be more correct to use the PATTERN opclasses than the + * NOTE: It would be more correct to use the PATTERN opfamilies than the * simple ones, but at the moment ANALYZE will not generate statistics for * the PATTERN operators. But our results are so approximate anyway that * it probably hardly matters. @@ -972,19 +972,16 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) switch (vartype) { case TEXTOID: - opclass = TEXT_BTREE_OPS_OID; - break; - case VARCHAROID: - opclass = VARCHAR_BTREE_OPS_OID; + opfamily = TEXT_BTREE_FAM_OID; break; case BPCHAROID: - opclass = BPCHAR_BTREE_OPS_OID; + opfamily = BPCHAR_BTREE_FAM_OID; break; case NAMEOID: - opclass = NAME_BTREE_OPS_OID; + opfamily = NAME_BTREE_FAM_OID; break; case BYTEAOID: - opclass = BYTEA_BTREE_OPS_OID; + opfamily = BYTEA_BTREE_FAM_OID; break; default: ReleaseVariableStats(vardata); @@ -1028,12 +1025,12 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) /* * Pattern specifies an exact match, so pretend operator is '=' */ - Oid eqopr = get_opclass_member(opclass, InvalidOid, - BTEqualStrategyNumber); + Oid eqopr = get_opfamily_member(opfamily, vartype, vartype, + BTEqualStrategyNumber); List *eqargs; if (eqopr == InvalidOid) - elog(ERROR, "no = operator for opclass %u", opclass); + elog(ERROR, "no = operator for opfamily %u", opfamily); eqargs = list_make2(variable, prefix); result = DatumGetFloat8(DirectFunctionCall4(eqsel, PointerGetDatum(root), @@ -1074,7 +1071,8 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype) Selectivity restsel; if (pstatus == Pattern_Prefix_Partial) - prefixsel = prefix_selectivity(&vardata, opclass, prefix); + prefixsel = prefix_selectivity(&vardata, vartype, + opfamily, prefix); else prefixsel = 1.0; restsel = pattern_selectivity(rest, ptype); @@ -2114,7 +2112,8 @@ icnlikejoinsel(PG_FUNCTION_ARGS) * we can estimate how much of the input will actually be read. This * can have a considerable impact on the cost when using indexscans. * - * clause should be a clause already known to be mergejoinable. + * clause should be a clause already known to be mergejoinable. opfamily and + * strategy specify the sort ordering being used. * * *leftscan is set to the fraction of the left-hand variable expected * to be scanned (0 to 1), and similarly *rightscan for the right-hand @@ -2122,6 +2121,7 @@ icnlikejoinsel(PG_FUNCTION_ARGS) */ void mergejoinscansel(PlannerInfo *root, Node *clause, + Oid opfamily, int strategy, Selectivity *leftscan, Selectivity *rightscan) { @@ -2129,15 +2129,14 @@ mergejoinscansel(PlannerInfo *root, Node *clause, *right; VariableStatData leftvar, rightvar; - Oid lefttype, - righttype; + int op_strategy; + Oid op_lefttype; + Oid op_righttype; + bool op_recheck; Oid opno, lsortop, rsortop, - ltop, - gtop, leop, - revgtop, revleop; Datum leftmax, rightmax; @@ -2159,15 +2158,51 @@ mergejoinscansel(PlannerInfo *root, Node *clause, examine_variable(root, left, 0, &leftvar); examine_variable(root, right, 0, &rightvar); - /* Get the direct input types of the operator */ - lefttype = exprType(left); - righttype = exprType(right); + /* Extract the operator's declared left/right datatypes */ + get_op_opfamily_properties(opno, opfamily, + &op_strategy, + &op_lefttype, + &op_righttype, + &op_recheck); + Assert(op_strategy == BTEqualStrategyNumber); + Assert(!op_recheck); - /* Verify mergejoinability and get left and right "<" operators */ - if (!op_mergejoinable(opno, - &lsortop, - &rsortop)) - goto fail; /* shouldn't happen */ + /* + * Look up the various operators we need. If we don't find them all, + * it probably means the opfamily is broken, but we cope anyway. + */ + switch (strategy) + { + case BTLessStrategyNumber: + lsortop = get_opfamily_member(opfamily, op_lefttype, op_lefttype, + BTLessStrategyNumber); + rsortop = get_opfamily_member(opfamily, op_righttype, op_righttype, + BTLessStrategyNumber); + leop = get_opfamily_member(opfamily, op_lefttype, op_righttype, + BTLessEqualStrategyNumber); + revleop = get_opfamily_member(opfamily, op_righttype, op_lefttype, + BTLessEqualStrategyNumber); + break; + case BTGreaterStrategyNumber: + /* descending-order case */ + lsortop = get_opfamily_member(opfamily, op_lefttype, op_lefttype, + BTGreaterStrategyNumber); + rsortop = get_opfamily_member(opfamily, op_righttype, op_righttype, + BTGreaterStrategyNumber); + leop = get_opfamily_member(opfamily, op_lefttype, op_righttype, + BTGreaterEqualStrategyNumber); + revleop = get_opfamily_member(opfamily, op_righttype, op_lefttype, + BTGreaterEqualStrategyNumber); + break; + default: + goto fail; /* shouldn't get here */ + } + + if (!OidIsValid(lsortop) || + !OidIsValid(rsortop) || + !OidIsValid(leop) || + !OidIsValid(revleop)) + goto fail; /* insufficient info in catalogs */ /* Try to get maximum values of both inputs */ if (!get_variable_maximum(root, &leftvar, lsortop, &leftmax)) @@ -2176,37 +2211,19 @@ mergejoinscansel(PlannerInfo *root, Node *clause, if (!get_variable_maximum(root, &rightvar, rsortop, &rightmax)) goto fail; /* no max available from stats */ - /* Look up the "left < right" and "left > right" operators */ - op_mergejoin_crossops(opno, <op, >op, NULL, NULL); - - /* Look up the "left <= right" operator */ - leop = get_negator(gtop); - if (!OidIsValid(leop)) - goto fail; /* insufficient info in catalogs */ - - /* Look up the "right > left" operator */ - revgtop = get_commutator(ltop); - if (!OidIsValid(revgtop)) - goto fail; /* insufficient info in catalogs */ - - /* Look up the "right <= left" operator */ - revleop = get_negator(revgtop); - if (!OidIsValid(revleop)) - goto fail; /* insufficient info in catalogs */ - /* * Now, the fraction of the left variable that will be scanned is the * fraction that's <= the right-side maximum value. But only believe * non-default estimates, else stick with our 1.0. */ selec = scalarineqsel(root, leop, false, &leftvar, - rightmax, righttype); + rightmax, op_righttype); if (selec != DEFAULT_INEQ_SEL) *leftscan = selec; /* And similarly for the right variable. */ selec = scalarineqsel(root, revleop, false, &rightvar, - leftmax, lefttype); + leftmax, op_lefttype); if (selec != DEFAULT_INEQ_SEL) *rightscan = selec; @@ -3486,7 +3503,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, * statistics. * * XXX it's conceivable that there are multiple matches with different - * index opclasses; if so, we need to pick one that matches the + * index opfamilies; if so, we need to pick one that matches the * operator we are estimating for. FIXME later. */ ListCell *ilist; @@ -4100,7 +4117,7 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype, * population represented by the histogram --- the caller must fold this * together with info about MCVs and NULLs. * - * We use the >= and < operators from the specified btree opclass to do the + * We use the >= and < operators from the specified btree opfamily to do the * estimation. The given variable and Const must be of the associated * datatype. * @@ -4110,17 +4127,18 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype, * more useful to use the upper-bound code than not. */ static Selectivity -prefix_selectivity(VariableStatData *vardata, Oid opclass, Const *prefixcon) +prefix_selectivity(VariableStatData *vardata, + Oid vartype, Oid opfamily, Const *prefixcon) { Selectivity prefixsel; Oid cmpopr; FmgrInfo opproc; Const *greaterstrcon; - cmpopr = get_opclass_member(opclass, InvalidOid, - BTGreaterEqualStrategyNumber); + cmpopr = get_opfamily_member(opfamily, vartype, vartype, + BTGreaterEqualStrategyNumber); if (cmpopr == InvalidOid) - elog(ERROR, "no >= operator for opclass %u", opclass); + elog(ERROR, "no >= operator for opfamily %u", opfamily); fmgr_info(get_opcode(cmpopr), &opproc); prefixsel = ineq_histogram_selectivity(vardata, &opproc, true, @@ -4143,10 +4161,10 @@ prefix_selectivity(VariableStatData *vardata, Oid opclass, Const *prefixcon) { Selectivity topsel; - cmpopr = get_opclass_member(opclass, InvalidOid, - BTLessStrategyNumber); + cmpopr = get_opfamily_member(opfamily, vartype, vartype, + BTLessStrategyNumber); if (cmpopr == InvalidOid) - elog(ERROR, "no < operator for opclass %u", opclass); + elog(ERROR, "no < operator for opfamily %u", opfamily); fmgr_info(get_opcode(cmpopr), &opproc); topsel = ineq_histogram_selectivity(vardata, &opproc, false, @@ -4921,7 +4939,7 @@ btcostestimate(PG_FUNCTION_ARGS) } else if (match_index_to_operand(rightop, indexcol, index)) { - /* Must flip operator to get the opclass member */ + /* Must flip operator to get the opfamily member */ clause_op = get_commutator(clause_op); } else @@ -4937,7 +4955,7 @@ btcostestimate(PG_FUNCTION_ARGS) } else if (match_index_to_operand(rightop, indexcol, index)) { - /* Must flip operator to get the opclass member */ + /* Must flip operator to get the opfamily member */ clause_op = get_commutator(clause_op); } else @@ -4946,9 +4964,9 @@ btcostestimate(PG_FUNCTION_ARGS) break; } } - op_strategy = get_op_opclass_strategy(clause_op, - index->classlist[indexcol]); - Assert(op_strategy != 0); /* not a member of opclass?? */ + op_strategy = get_op_opfamily_strategy(clause_op, + index->opfamily[indexcol]); + Assert(op_strategy != 0); /* not a member of opfamily?? */ if (op_strategy == BTEqualStrategyNumber) eqQualHere = true; /* count up number of SA scans induced by indexBoundQuals only */ diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 55b9d5baf0..1a1d19f399 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.134 2006/10/06 18:23:35 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.135 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1033,9 +1033,10 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey) if (cache->id == INDEXRELID) { /* - * Since the OIDs of indexes aren't hardwired, it's painful to figure - * out which is which. Just force all pg_index searches to be heap - * scans while building the relcaches. + * Rather than tracking exactly which indexes have to be loaded + * before we can use indexscans (which changes from time to time), + * just force all pg_index searches to be heap scans until we've + * built the critical relcaches. */ if (!criticalRelcachesBuilt) return false; @@ -1051,17 +1052,6 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey) */ return false; } - else if (cache->id == OPEROID) - { - if (!criticalRelcachesBuilt) - { - /* Looking for an OID comparison function? */ - Oid lookup_oid = DatumGetObjectId(cur_skey[0].sk_argument); - - if (lookup_oid >= MIN_OIDCMP && lookup_oid <= MAX_OIDCMP) - return false; - } - } /* Normal case, allow index scan */ return true; diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index fdc31e0d97..824ef4a1ef 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.138 2006/10/04 00:30:00 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.139 2006/12/23 00:43:11 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -37,27 +37,27 @@ /* ---------- AMOP CACHES ---------- */ /* - * op_in_opclass + * op_in_opfamily * - * Return t iff operator 'opno' is in operator class 'opclass'. + * Return t iff operator 'opno' is in operator family 'opfamily'. */ bool -op_in_opclass(Oid opno, Oid opclass) +op_in_opfamily(Oid opno, Oid opfamily) { return SearchSysCacheExists(AMOPOPID, ObjectIdGetDatum(opno), - ObjectIdGetDatum(opclass), + ObjectIdGetDatum(opfamily), 0, 0); } /* - * get_op_opclass_strategy + * get_op_opfamily_strategy * - * Get the operator's strategy number within the specified opclass, - * or 0 if it's not a member of the opclass. + * Get the operator's strategy number within the specified opfamily, + * or 0 if it's not a member of the opfamily. */ int -get_op_opclass_strategy(Oid opno, Oid opclass) +get_op_opfamily_strategy(Oid opno, Oid opfamily) { HeapTuple tp; Form_pg_amop amop_tup; @@ -65,7 +65,7 @@ get_op_opclass_strategy(Oid opno, Oid opclass) tp = SearchSysCache(AMOPOPID, ObjectIdGetDatum(opno), - ObjectIdGetDatum(opclass), + ObjectIdGetDatum(opfamily), 0, 0); if (!HeapTupleIsValid(tp)) return 0; @@ -76,54 +76,59 @@ get_op_opclass_strategy(Oid opno, Oid opclass) } /* - * get_op_opclass_properties + * get_op_opfamily_properties * - * Get the operator's strategy number, subtype, and recheck (lossy) flag - * within the specified opclass. + * Get the operator's strategy number, input types, and recheck (lossy) + * flag within the specified opfamily. * - * Caller should already have verified that opno is a member of opclass, + * Caller should already have verified that opno is a member of opfamily, * therefore we raise an error if the tuple is not found. */ void -get_op_opclass_properties(Oid opno, Oid opclass, - int *strategy, Oid *subtype, bool *recheck) +get_op_opfamily_properties(Oid opno, Oid opfamily, + int *strategy, + Oid *lefttype, + Oid *righttype, + bool *recheck) { HeapTuple tp; Form_pg_amop amop_tup; tp = SearchSysCache(AMOPOPID, ObjectIdGetDatum(opno), - ObjectIdGetDatum(opclass), + ObjectIdGetDatum(opfamily), 0, 0); if (!HeapTupleIsValid(tp)) - elog(ERROR, "operator %u is not a member of opclass %u", - opno, opclass); + elog(ERROR, "operator %u is not a member of opfamily %u", + opno, opfamily); amop_tup = (Form_pg_amop) GETSTRUCT(tp); *strategy = amop_tup->amopstrategy; - *subtype = amop_tup->amopsubtype; + *lefttype = amop_tup->amoplefttype; + *righttype = amop_tup->amoprighttype; *recheck = amop_tup->amopreqcheck; ReleaseSysCache(tp); } /* - * get_opclass_member + * get_opfamily_member * Get the OID of the operator that implements the specified strategy - * with the specified subtype for the specified opclass. + * with the specified datatypes for the specified opfamily. * * Returns InvalidOid if there is no pg_amop entry for the given keys. */ Oid -get_opclass_member(Oid opclass, Oid subtype, int16 strategy) +get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, + int16 strategy) { HeapTuple tp; Form_pg_amop amop_tup; Oid result; tp = SearchSysCache(AMOPSTRATEGY, - ObjectIdGetDatum(opclass), - ObjectIdGetDatum(subtype), - Int16GetDatum(strategy), - 0); + ObjectIdGetDatum(opfamily), + ObjectIdGetDatum(lefttype), + ObjectIdGetDatum(righttype), + Int16GetDatum(strategy)); if (!HeapTupleIsValid(tp)) return InvalidOid; amop_tup = (Form_pg_amop) GETSTRUCT(tp); @@ -132,11 +137,161 @@ get_opclass_member(Oid opclass, Oid subtype, int16 strategy) return result; } +/* + * get_op_mergejoin_info + * Given the OIDs of a (putatively) mergejoinable equality operator + * and a sortop defining the sort ordering of the lefthand input of + * the merge clause, determine whether this sort ordering is actually + * usable for merging. If so, return the required sort ordering op + * for the righthand input, as well as the btree opfamily OID containing + * these operators and the operator strategy number of the two sortops + * (either BTLessStrategyNumber or BTGreaterStrategyNumber). + * + * We can mergejoin if we find the two operators in the same opfamily as + * equality and either less-than or greater-than respectively. If there + * are multiple such opfamilies, assume we can use any one. + */ +#ifdef NOT_YET +/* eventually should look like this */ +bool +get_op_mergejoin_info(Oid eq_op, Oid left_sortop, + Oid *right_sortop, Oid *opfamily, int *opstrategy) +{ + bool result = false; + Oid lefttype; + Oid righttype; + CatCList *catlist; + int i; + + /* Make sure output args are initialized even on failure */ + *right_sortop = InvalidOid; + *opfamily = InvalidOid; + *opstrategy = 0; + + /* Need the righthand input datatype */ + op_input_types(eq_op, &lefttype, &righttype); + + /* + * Search through all the pg_amop entries containing the equality operator + */ + catlist = SearchSysCacheList(AMOPOPID, 1, + ObjectIdGetDatum(eq_op), + 0, 0, 0); + + for (i = 0; i < catlist->n_members; i++) + { + HeapTuple op_tuple = &catlist->members[i]->tuple; + Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple); + Oid opfamily_id; + StrategyNumber op_strategy; + + /* must be btree */ + if (op_form->amopmethod != BTREE_AM_OID) + continue; + /* must use the operator as equality */ + if (op_form->amopstrategy != BTEqualStrategyNumber) + continue; + + /* See if sort operator is also in this opclass with OK semantics */ + opfamily_id = op_form->amopfamily; + op_strategy = get_op_opfamily_strategy(left_sortop, opfamily_id); + if (op_strategy == BTLessStrategyNumber || + op_strategy == BTGreaterStrategyNumber) + { + /* Yes, so find the corresponding righthand sortop */ + *right_sortop = get_opfamily_member(opfamily_id, + righttype, + righttype, + op_strategy); + if (OidIsValid(*right_sortop)) + { + /* Found a workable mergejoin semantics */ + *opfamily = opfamily_id; + *opstrategy = op_strategy; + result = true; + break; + } + } + } + + ReleaseSysCacheList(catlist); + + return result; +} +#else +/* temp implementation until planner gets smarter: left_sortop is output */ +bool +get_op_mergejoin_info(Oid eq_op, Oid *left_sortop, + Oid *right_sortop, Oid *opfamily) +{ + bool result = false; + Oid lefttype; + Oid righttype; + CatCList *catlist; + int i; + + /* Make sure output args are initialized even on failure */ + *left_sortop = InvalidOid; + *right_sortop = InvalidOid; + *opfamily = InvalidOid; + + /* Need the input datatypes */ + op_input_types(eq_op, &lefttype, &righttype); + + /* + * Search through all the pg_amop entries containing the equality operator + */ + catlist = SearchSysCacheList(AMOPOPID, 1, + ObjectIdGetDatum(eq_op), + 0, 0, 0); + + for (i = 0; i < catlist->n_members; i++) + { + HeapTuple op_tuple = &catlist->members[i]->tuple; + Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple); + Oid opfamily_id; + + /* must be btree */ + if (op_form->amopmethod != BTREE_AM_OID) + continue; + /* must use the operator as equality */ + if (op_form->amopstrategy != BTEqualStrategyNumber) + continue; + + opfamily_id = op_form->amopfamily; + + /* Find the matching sortops */ + *left_sortop = get_opfamily_member(opfamily_id, + lefttype, + lefttype, + BTLessStrategyNumber); + *right_sortop = get_opfamily_member(opfamily_id, + righttype, + righttype, + BTLessStrategyNumber); + if (OidIsValid(*left_sortop) && OidIsValid(*right_sortop)) + { + /* Found a workable mergejoin semantics */ + *opfamily = opfamily_id; + result = true; + break; + } + } + + ReleaseSysCacheList(catlist); + + return result; +} +#endif + /* * get_op_hash_function * Get the OID of the datatype-specific hash function associated with * a hashable equality operator. * + * XXX API needs to be generalized for the case of different left and right + * datatypes. + * * Returns InvalidOid if no hash function can be found. (This indicates * that the operator should not have been marked oprcanhash.) */ @@ -145,12 +300,12 @@ get_op_hash_function(Oid opno) { CatCList *catlist; int i; - Oid opclass = InvalidOid; + Oid result = InvalidOid; /* * Search pg_amop to see if the target operator is registered as the "=" - * operator of any hash opclass. If the operator is registered in - * multiple opclasses, assume we can use the associated hash function from + * operator of any hash opfamily. If the operator is registered in + * multiple opfamilies, assume we can use the associated hash function from * any one. */ catlist = SearchSysCacheList(AMOPOPID, 1, @@ -162,57 +317,43 @@ get_op_hash_function(Oid opno) HeapTuple tuple = &catlist->members[i]->tuple; Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple); - if (aform->amopstrategy == HTEqualStrategyNumber && - opclass_is_hash(aform->amopclaid)) + if (aform->amopmethod == HASH_AM_OID && + aform->amopstrategy == HTEqualStrategyNumber) { - opclass = aform->amopclaid; + /* Found a suitable opfamily, get matching hash support function */ + result = get_opfamily_proc(aform->amopfamily, + aform->amoplefttype, + aform->amoprighttype, + HASHPROC); break; } } ReleaseSysCacheList(catlist); - if (OidIsValid(opclass)) - { - /* Found a suitable opclass, get its default hash support function */ - return get_opclass_proc(opclass, InvalidOid, HASHPROC); - } - - /* Didn't find a match... */ - return InvalidOid; + return result; } /* * get_op_btree_interpretation - * Given an operator's OID, find out which btree opclasses it belongs to, + * Given an operator's OID, find out which btree opfamilies it belongs to, * and what strategy number it has within each one. The results are * returned as an OID list and a parallel integer list. * * In addition to the normal btree operators, we consider a <> operator to be - * a "member" of an opclass if its negator is the opclass' equality operator. - * ROWCOMPARE_NE is returned as the strategy number for this case. + * a "member" of an opfamily if its negator is an equality operator of the + * opfamily. ROWCOMPARE_NE is returned as the strategy number for this case. */ void -get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats) +get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats) { - Oid lefttype, - righttype; CatCList *catlist; bool op_negated; int i; - *opclasses = NIL; + *opfamilies = NIL; *opstrats = NIL; - /* - * Get the nominal left-hand input type of the operator; we will ignore - * opclasses that don't have that as the expected input datatype. This is - * a kluge to avoid being confused by binary-compatible opclasses (such as - * text_ops and varchar_ops, which share the same operators). - */ - op_input_types(opno, &lefttype, &righttype); - Assert(OidIsValid(lefttype)); - /* * Find all the pg_amop entries containing the operator. */ @@ -221,8 +362,8 @@ get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats) 0, 0, 0); /* - * If we can't find any opclass containing the op, perhaps it is a <> - * operator. See if it has a negator that is in an opclass. + * If we can't find any opfamily containing the op, perhaps it is a <> + * operator. See if it has a negator that is in an opfamily. */ op_negated = false; if (catlist->n_members == 0) @@ -239,25 +380,20 @@ get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats) } } - /* Now search the opclasses */ + /* Now search the opfamilies */ for (i = 0; i < catlist->n_members; i++) { HeapTuple op_tuple = &catlist->members[i]->tuple; Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple); - Oid opclass_id; + Oid opfamily_id; StrategyNumber op_strategy; - opclass_id = op_form->amopclaid; - /* must be btree */ - if (!opclass_is_btree(opclass_id)) - continue; - - /* must match operator input type exactly */ - if (get_opclass_input_type(opclass_id) != lefttype) + if (op_form->amopmethod != BTREE_AM_OID) continue; /* Get the operator's btree strategy number */ + opfamily_id = op_form->amopfamily; op_strategy = (StrategyNumber) op_form->amopstrategy; Assert(op_strategy >= 1 && op_strategy <= 5); @@ -269,7 +405,7 @@ get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats) op_strategy = ROWCOMPARE_NE; } - *opclasses = lappend_oid(*opclasses, opclass_id); + *opfamilies = lappend_oid(*opfamilies, opfamily_id); *opstrats = lappend_int(*opstrats, op_strategy); } @@ -280,24 +416,24 @@ get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats) /* ---------- AMPROC CACHES ---------- */ /* - * get_opclass_proc + * get_opfamily_proc * Get the OID of the specified support function - * for the specified opclass and subtype. + * for the specified opfamily and datatypes. * * Returns InvalidOid if there is no pg_amproc entry for the given keys. */ Oid -get_opclass_proc(Oid opclass, Oid subtype, int16 procnum) +get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum) { HeapTuple tp; Form_pg_amproc amproc_tup; RegProcedure result; tp = SearchSysCache(AMPROCNUM, - ObjectIdGetDatum(opclass), - ObjectIdGetDatum(subtype), - Int16GetDatum(procnum), - 0); + ObjectIdGetDatum(opfamily), + ObjectIdGetDatum(lefttype), + ObjectIdGetDatum(righttype), + Int16GetDatum(procnum)); if (!HeapTupleIsValid(tp)) return InvalidOid; amproc_tup = (Form_pg_amproc) GETSTRUCT(tp); @@ -477,17 +613,16 @@ get_atttypetypmod(Oid relid, AttrNumber attnum, /* ---------- OPCLASS CACHE ---------- */ /* - * opclass_is_btree + * get_opclass_family * - * Returns TRUE iff the specified opclass is associated with the - * btree index access method. + * Returns the OID of the operator family the opclass belongs to. */ -bool -opclass_is_btree(Oid opclass) +Oid +get_opclass_family(Oid opclass) { HeapTuple tp; Form_pg_opclass cla_tup; - bool result; + Oid result; tp = SearchSysCache(CLAOID, ObjectIdGetDatum(opclass), @@ -496,57 +631,7 @@ opclass_is_btree(Oid opclass) elog(ERROR, "cache lookup failed for opclass %u", opclass); cla_tup = (Form_pg_opclass) GETSTRUCT(tp); - result = (cla_tup->opcamid == BTREE_AM_OID); - ReleaseSysCache(tp); - return result; -} - -/* - * opclass_is_hash - * - * Returns TRUE iff the specified opclass is associated with the - * hash index access method. - */ -bool -opclass_is_hash(Oid opclass) -{ - HeapTuple tp; - Form_pg_opclass cla_tup; - bool result; - - tp = SearchSysCache(CLAOID, - ObjectIdGetDatum(opclass), - 0, 0, 0); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for opclass %u", opclass); - cla_tup = (Form_pg_opclass) GETSTRUCT(tp); - - result = (cla_tup->opcamid == HASH_AM_OID); - ReleaseSysCache(tp); - return result; -} - -/* - * opclass_is_default - * - * Returns TRUE iff the specified opclass is the default for its - * index access method and input data type. - */ -bool -opclass_is_default(Oid opclass) -{ - HeapTuple tp; - Form_pg_opclass cla_tup; - bool result; - - tp = SearchSysCache(CLAOID, - ObjectIdGetDatum(opclass), - 0, 0, 0); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for opclass %u", opclass); - cla_tup = (Form_pg_opclass) GETSTRUCT(tp); - - result = cla_tup->opcdefault; + result = cla_tup->opcfamily; ReleaseSysCache(tp); return result; } @@ -657,11 +742,13 @@ op_input_types(Oid opno, Oid *lefttype, Oid *righttype) /* * op_mergejoinable * - * Returns the left and right sort operators corresponding to a - * mergejoinable operator, or false if the operator is not mergejoinable. + * Returns true if the operator is potentially mergejoinable. (The planner + * will fail to find any mergejoin plans unless there are suitable btree + * opfamily entries for this operator and associated sortops. The pg_operator + * flag is just a hint to tell the planner whether to bother looking.) */ bool -op_mergejoinable(Oid opno, Oid *leftOp, Oid *rightOp) +op_mergejoinable(Oid opno) { HeapTuple tp; bool result = false; @@ -673,65 +760,17 @@ op_mergejoinable(Oid opno, Oid *leftOp, Oid *rightOp) { Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp); - if (optup->oprlsortop && - optup->oprrsortop) - { - *leftOp = optup->oprlsortop; - *rightOp = optup->oprrsortop; - result = true; - } + result = optup->oprcanmerge; ReleaseSysCache(tp); } return result; } -/* - * op_mergejoin_crossops - * - * Returns the cross-type comparison operators (ltype "<" rtype and - * ltype ">" rtype) for an operator previously determined to be - * mergejoinable. Optionally, fetches the regproc ids of these - * operators, as well as their operator OIDs. - */ -void -op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop, - RegProcedure *ltproc, RegProcedure *gtproc) -{ - HeapTuple tp; - Form_pg_operator optup; - - /* - * Get the declared comparison operators of the operator. - */ - tp = SearchSysCache(OPEROID, - ObjectIdGetDatum(opno), - 0, 0, 0); - if (!HeapTupleIsValid(tp)) /* shouldn't happen */ - elog(ERROR, "cache lookup failed for operator %u", opno); - optup = (Form_pg_operator) GETSTRUCT(tp); - *ltop = optup->oprltcmpop; - *gtop = optup->oprgtcmpop; - ReleaseSysCache(tp); - - /* Check < op provided */ - if (!OidIsValid(*ltop)) - elog(ERROR, "mergejoin operator %u has no matching < operator", - opno); - if (ltproc) - *ltproc = get_opcode(*ltop); - - /* Check > op provided */ - if (!OidIsValid(*gtop)) - elog(ERROR, "mergejoin operator %u has no matching > operator", - opno); - if (gtproc) - *gtproc = get_opcode(*gtop); -} - /* * op_hashjoinable * - * Returns true if the operator is hashjoinable. + * Returns true if the operator is hashjoinable. (There must be a suitable + * hash opfamily entry for this operator if it is so marked.) */ bool op_hashjoinable(Oid opno) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 65cd1e7290..be5fb60dc8 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.250 2006/11/05 23:40:30 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.251 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -69,7 +69,7 @@ */ #define RELCACHE_INIT_FILENAME "pg_internal.init" -#define RELCACHE_INIT_FILEMAGIC 0x573263 /* version ID value */ +#define RELCACHE_INIT_FILEMAGIC 0x573264 /* version ID value */ /* * hardcoded tuple descriptors. see include/catalog/pg_attribute.h @@ -159,7 +159,8 @@ do { \ /* * Special cache for opclass-related information * - * Note: only default-subtype operators and support procs get cached + * Note: only default operators and support procs get cached, ie, those with + * lefttype = righttype = opcintype. */ typedef struct opclasscacheent { @@ -167,6 +168,8 @@ typedef struct opclasscacheent bool valid; /* set TRUE after successful fill-in */ StrategyNumber numStrats; /* max # of strategies (from pg_am) */ StrategyNumber numSupport; /* max # of support procs (from pg_am) */ + Oid opcfamily; /* OID of opclass's family */ + Oid opcintype; /* OID of opclass's declared input type */ Oid *operatorOids; /* strategy operators' OIDs */ RegProcedure *supportProcs; /* support procs */ } OpClassCacheEnt; @@ -201,6 +204,8 @@ static List *insert_ordered_oid(List *list, Oid datum); static void IndexSupportInitialize(oidvector *indclass, Oid *indexOperator, RegProcedure *indexSupport, + Oid *opFamily, + Oid *opcInType, StrategyNumber maxStrategyNumber, StrategyNumber maxSupportNumber, AttrNumber maxAttributeNumber); @@ -921,11 +926,9 @@ RelationInitIndexAccessInfo(Relation relation) Form_pg_am aform; Datum indclassDatum; bool isnull; + oidvector *indclass; MemoryContext indexcxt; MemoryContext oldcontext; - Oid *operator; - RegProcedure *support; - FmgrInfo *supportinfo; int natts; uint16 amstrategies; uint16 amsupport; @@ -947,18 +950,6 @@ RelationInitIndexAccessInfo(Relation relation) MemoryContextSwitchTo(oldcontext); ReleaseSysCache(tuple); - /* - * indclass cannot be referenced directly through the C struct, because it - * is after the variable-width indkey field. Therefore we extract the - * datum the hard way and provide a direct link in the relcache. - */ - indclassDatum = fastgetattr(relation->rd_indextuple, - Anum_pg_index_indclass, - GetPgIndexDescriptor(), - &isnull); - Assert(!isnull); - relation->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum); - /* * Make a copy of the pg_am entry for the index's access method */ @@ -1001,38 +992,53 @@ RelationInitIndexAccessInfo(Relation relation) relation->rd_aminfo = (RelationAmInfo *) MemoryContextAllocZero(indexcxt, sizeof(RelationAmInfo)); + relation->rd_opfamily = (Oid *) + MemoryContextAllocZero(indexcxt, natts * sizeof(Oid)); + relation->rd_opcintype = (Oid *) + MemoryContextAllocZero(indexcxt, natts * sizeof(Oid)); + if (amstrategies > 0) - operator = (Oid *) + relation->rd_operator = (Oid *) MemoryContextAllocZero(indexcxt, natts * amstrategies * sizeof(Oid)); else - operator = NULL; + relation->rd_operator = NULL; if (amsupport > 0) { int nsupport = natts * amsupport; - support = (RegProcedure *) + relation->rd_support = (RegProcedure *) MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure)); - supportinfo = (FmgrInfo *) + relation->rd_supportinfo = (FmgrInfo *) MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo)); } else { - support = NULL; - supportinfo = NULL; + relation->rd_support = NULL; + relation->rd_supportinfo = NULL; } - relation->rd_operator = operator; - relation->rd_support = support; - relation->rd_supportinfo = supportinfo; + /* + * indclass cannot be referenced directly through the C struct, because it + * comes after the variable-width indkey field. Must extract the + * datum the hard way... + */ + indclassDatum = fastgetattr(relation->rd_indextuple, + Anum_pg_index_indclass, + GetPgIndexDescriptor(), + &isnull); + Assert(!isnull); + indclass = (oidvector *) DatumGetPointer(indclassDatum); /* - * Fill the operator and support procedure OID arrays. (aminfo and + * Fill the operator and support procedure OID arrays, as well as the + * info about opfamilies and opclass input types. (aminfo and * supportinfo are left as zeroes, and are filled on-the-fly when used) */ - IndexSupportInitialize(relation->rd_indclass, - operator, support, + IndexSupportInitialize(indclass, + relation->rd_operator, relation->rd_support, + relation->rd_opfamily, relation->rd_opcintype, amstrategies, amsupport, natts); /* @@ -1048,8 +1054,8 @@ RelationInitIndexAccessInfo(Relation relation) * Initializes an index's cached opclass information, * given the index's pg_index.indclass entry. * - * Data is returned into *indexOperator and *indexSupport, which are arrays - * allocated by the caller. + * Data is returned into *indexOperator, *indexSupport, *opFamily, and + * *opcInType, which are arrays allocated by the caller. * * The caller also passes maxStrategyNumber, maxSupportNumber, and * maxAttributeNumber, since these indicate the size of the arrays @@ -1061,6 +1067,8 @@ static void IndexSupportInitialize(oidvector *indclass, Oid *indexOperator, RegProcedure *indexSupport, + Oid *opFamily, + Oid *opcInType, StrategyNumber maxStrategyNumber, StrategyNumber maxSupportNumber, AttrNumber maxAttributeNumber) @@ -1080,6 +1088,8 @@ IndexSupportInitialize(oidvector *indclass, maxSupportNumber); /* copy cached data into relcache entry */ + opFamily[attIndex] = opcentry->opcfamily; + opcInType[attIndex] = opcentry->opcintype; if (maxStrategyNumber > 0) memcpy(&indexOperator[attIndex * maxStrategyNumber], opcentry->operatorOids, @@ -1116,7 +1126,7 @@ LookupOpclassInfo(Oid operatorClassOid, bool found; Relation rel; SysScanDesc scan; - ScanKeyData skey[2]; + ScanKeyData skey[3]; HeapTuple htup; bool indexOK; @@ -1176,23 +1186,55 @@ LookupOpclassInfo(Oid operatorClassOid, (operatorClassOid != OID_BTREE_OPS_OID && operatorClassOid != INT2_BTREE_OPS_OID); + /* + * We have to fetch the pg_opclass row to determine its opfamily and + * opcintype, which are needed to look up the operators and functions. + * It'd be convenient to use the syscache here, but that probably doesn't + * work while bootstrapping. + */ + ScanKeyInit(&skey[0], + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(operatorClassOid)); + rel = heap_open(OperatorClassRelationId, AccessShareLock); + scan = systable_beginscan(rel, OpclassOidIndexId, indexOK, + SnapshotNow, 1, skey); + + if (HeapTupleIsValid(htup = systable_getnext(scan))) + { + Form_pg_opclass opclassform = (Form_pg_opclass) GETSTRUCT(htup); + + opcentry->opcfamily = opclassform->opcfamily; + opcentry->opcintype = opclassform->opcintype; + } + else + elog(ERROR, "could not find tuple for opclass %u", operatorClassOid); + + systable_endscan(scan); + heap_close(rel, AccessShareLock); + + /* * Scan pg_amop to obtain operators for the opclass. We only fetch the - * default ones (those with subtype zero). + * default ones (those with lefttype = righttype = opcintype). */ if (numStrats > 0) { ScanKeyInit(&skey[0], - Anum_pg_amop_amopclaid, + Anum_pg_amop_amopfamily, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(operatorClassOid)); + ObjectIdGetDatum(opcentry->opcfamily)); ScanKeyInit(&skey[1], - Anum_pg_amop_amopsubtype, + Anum_pg_amop_amoplefttype, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(InvalidOid)); + ObjectIdGetDatum(opcentry->opcintype)); + ScanKeyInit(&skey[2], + Anum_pg_amop_amoprighttype, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(opcentry->opcintype)); rel = heap_open(AccessMethodOperatorRelationId, AccessShareLock); scan = systable_beginscan(rel, AccessMethodStrategyIndexId, indexOK, - SnapshotNow, 2, skey); + SnapshotNow, 3, skey); while (HeapTupleIsValid(htup = systable_getnext(scan))) { @@ -1212,21 +1254,25 @@ LookupOpclassInfo(Oid operatorClassOid, /* * Scan pg_amproc to obtain support procs for the opclass. We only fetch - * the default ones (those with subtype zero). + * the default ones (those with lefttype = righttype = opcintype). */ if (numSupport > 0) { ScanKeyInit(&skey[0], - Anum_pg_amproc_amopclaid, + Anum_pg_amproc_amprocfamily, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(operatorClassOid)); + ObjectIdGetDatum(opcentry->opcfamily)); ScanKeyInit(&skey[1], - Anum_pg_amproc_amprocsubtype, + Anum_pg_amproc_amproclefttype, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(InvalidOid)); + ObjectIdGetDatum(opcentry->opcintype)); + ScanKeyInit(&skey[2], + Anum_pg_amproc_amprocrighttype, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(opcentry->opcintype)); rel = heap_open(AccessMethodProcedureRelationId, AccessShareLock); scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK, - SnapshotNow, 2, skey); + SnapshotNow, 3, skey); while (HeapTupleIsValid(htup = systable_getnext(scan))) { @@ -3097,8 +3143,6 @@ load_relcache_init_file(void) Relation rel; Form_pg_class relform; bool has_not_null; - Datum indclassDatum; - bool isnull; /* first read the relation descriptor length */ if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len)) @@ -3187,6 +3231,8 @@ load_relcache_init_file(void) { Form_pg_am am; MemoryContext indexcxt; + Oid *opfamily; + Oid *opcintype; Oid *operator; RegProcedure *support; int nsupport; @@ -3207,14 +3253,6 @@ load_relcache_init_file(void) rel->rd_indextuple->t_data = (HeapTupleHeader) ((char *) rel->rd_indextuple + HEAPTUPLESIZE); rel->rd_index = (Form_pg_index) GETSTRUCT(rel->rd_indextuple); - /* fix up indclass pointer too */ - indclassDatum = fastgetattr(rel->rd_indextuple, - Anum_pg_index_indclass, - GetPgIndexDescriptor(), - &isnull); - Assert(!isnull); - rel->rd_indclass = (oidvector *) DatumGetPointer(indclassDatum); - /* next, read the access method tuple form */ if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len)) goto read_failed; @@ -3235,6 +3273,26 @@ load_relcache_init_file(void) ALLOCSET_SMALL_MAXSIZE); rel->rd_indexcxt = indexcxt; + /* next, read the vector of opfamily OIDs */ + if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len)) + goto read_failed; + + opfamily = (Oid *) MemoryContextAlloc(indexcxt, len); + if ((nread = fread(opfamily, 1, len, fp)) != len) + goto read_failed; + + rel->rd_opfamily = opfamily; + + /* next, read the vector of opcintype OIDs */ + if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len)) + goto read_failed; + + opcintype = (Oid *) MemoryContextAlloc(indexcxt, len); + if ((nread = fread(opcintype, 1, len, fp)) != len) + goto read_failed; + + rel->rd_opcintype = opcintype; + /* next, read the vector of operator OIDs */ if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len)) goto read_failed; @@ -3269,10 +3327,11 @@ load_relcache_init_file(void) Assert(rel->rd_index == NULL); Assert(rel->rd_indextuple == NULL); - Assert(rel->rd_indclass == NULL); Assert(rel->rd_am == NULL); Assert(rel->rd_indexcxt == NULL); Assert(rel->rd_aminfo == NULL); + Assert(rel->rd_opfamily == NULL); + Assert(rel->rd_opcintype == NULL); Assert(rel->rd_operator == NULL); Assert(rel->rd_support == NULL); Assert(rel->rd_supportinfo == NULL); @@ -3450,6 +3509,16 @@ write_relcache_init_file(void) /* next, write the access method tuple form */ write_item(am, sizeof(FormData_pg_am), fp); + /* next, write the vector of opfamily OIDs */ + write_item(rel->rd_opfamily, + relform->relnatts * sizeof(Oid), + fp); + + /* next, write the vector of opcintype OIDs */ + write_item(rel->rd_opcintype, + relform->relnatts * sizeof(Oid), + fp); + /* next, write the vector of operator OIDs */ write_item(rel->rd_operator, relform->relnatts * (am->amstrategies * sizeof(Oid)), diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index e19fba0584..f2fb0796cb 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.108 2006/10/06 18:23:35 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.109 2006/12/23 00:43:11 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -30,11 +30,11 @@ #include "catalog/pg_cast.h" #include "catalog/pg_conversion.h" #include "catalog/pg_database.h" -#include "catalog/pg_inherits.h" #include "catalog/pg_language.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_proc.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_statistic.h" @@ -135,7 +135,7 @@ static const struct cachedesc cacheinfo[] = { 2, { Anum_pg_amop_amopopr, - Anum_pg_amop_amopclaid, + Anum_pg_amop_amopfamily, 0, 0 }, @@ -144,24 +144,24 @@ static const struct cachedesc cacheinfo[] = { {AccessMethodOperatorRelationId, /* AMOPSTRATEGY */ AccessMethodStrategyIndexId, 0, - 3, + 4, { - Anum_pg_amop_amopclaid, - Anum_pg_amop_amopsubtype, - Anum_pg_amop_amopstrategy, - 0 + Anum_pg_amop_amopfamily, + Anum_pg_amop_amoplefttype, + Anum_pg_amop_amoprighttype, + Anum_pg_amop_amopstrategy }, 64 }, {AccessMethodProcedureRelationId, /* AMPROCNUM */ AccessMethodProcedureIndexId, 0, - 3, + 4, { - Anum_pg_amproc_amopclaid, - Anum_pg_amproc_amprocsubtype, - Anum_pg_amproc_amprocnum, - 0 + Anum_pg_amproc_amprocfamily, + Anum_pg_amproc_amproclefttype, + Anum_pg_amproc_amprocrighttype, + Anum_pg_amproc_amprocnum }, 64 }, @@ -255,7 +255,7 @@ static const struct cachedesc cacheinfo[] = { 0, 3, { - Anum_pg_opclass_opcamid, + Anum_pg_opclass_opcmethod, Anum_pg_opclass_opcname, Anum_pg_opclass_opcnamespace, 0 @@ -334,18 +334,6 @@ static const struct cachedesc cacheinfo[] = { }, 1024 }, - {InheritsRelationId, /* INHRELID */ - InheritsRelidSeqnoIndexId, - Anum_pg_inherits_inhrelid, - 2, - { - Anum_pg_inherits_inhrelid, - Anum_pg_inherits_inhseqno, - 0, - 0 - }, - 256 - }, {LanguageRelationId, /* LANGNAME */ LanguageNameIndexId, 0, @@ -418,6 +406,30 @@ static const struct cachedesc cacheinfo[] = { }, 1024 }, + {OperatorFamilyRelationId, /* OPFAMILYAMNAMENSP */ + OpfamilyAmNameNspIndexId, + 0, + 3, + { + Anum_pg_opfamily_opfmethod, + Anum_pg_opfamily_opfname, + Anum_pg_opfamily_opfnamespace, + 0 + }, + 64 + }, + {OperatorFamilyRelationId, /* OPFAMILYOID */ + OpfamilyOidIndexId, + 0, + 1, + { + ObjectIdAttributeNumber, + 0, + 0, + 0 + }, + 64 + }, {ProcedureRelationId, /* PROCNAMEARGSNSP */ ProcedureNameArgsNspIndexId, 0, diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index c5a0272414..192675c95e 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -36,7 +36,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.22 2006/10/04 00:30:01 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.23 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -165,17 +165,30 @@ lookup_type_cache(Oid type_id, int flags) /* If we haven't already found the opclass, try to do so */ if ((flags & (TYPECACHE_EQ_OPR | TYPECACHE_LT_OPR | TYPECACHE_GT_OPR | TYPECACHE_CMP_PROC | - TYPECACHE_EQ_OPR_FINFO | TYPECACHE_CMP_PROC_FINFO)) && - typentry->btree_opc == InvalidOid) + TYPECACHE_EQ_OPR_FINFO | TYPECACHE_CMP_PROC_FINFO | + TYPECACHE_BTREE_OPFAMILY)) && + typentry->btree_opf == InvalidOid) { - typentry->btree_opc = GetDefaultOpClass(type_id, - BTREE_AM_OID); - /* Only care about hash opclass if no btree opclass... */ - if (typentry->btree_opc == InvalidOid) + Oid opclass; + + opclass = GetDefaultOpClass(type_id, BTREE_AM_OID); + if (OidIsValid(opclass)) { - if (typentry->hash_opc == InvalidOid) - typentry->hash_opc = GetDefaultOpClass(type_id, - HASH_AM_OID); + typentry->btree_opf = get_opclass_family(opclass); + typentry->btree_opintype = get_opclass_input_type(opclass); + } + /* Only care about hash opclass if no btree opclass... */ + if (typentry->btree_opf == InvalidOid) + { + if (typentry->hash_opf == InvalidOid) + { + opclass = GetDefaultOpClass(type_id, HASH_AM_OID); + if (OidIsValid(opclass)) + { + typentry->hash_opf = get_opclass_family(opclass); + typentry->hash_opintype = get_opclass_input_type(opclass); + } + } } else { @@ -193,37 +206,42 @@ lookup_type_cache(Oid type_id, int flags) if ((flags & (TYPECACHE_EQ_OPR | TYPECACHE_EQ_OPR_FINFO)) && typentry->eq_opr == InvalidOid) { - if (typentry->btree_opc != InvalidOid) - typentry->eq_opr = get_opclass_member(typentry->btree_opc, - InvalidOid, - BTEqualStrategyNumber); + if (typentry->btree_opf != InvalidOid) + typentry->eq_opr = get_opfamily_member(typentry->btree_opf, + typentry->btree_opintype, + typentry->btree_opintype, + BTEqualStrategyNumber); if (typentry->eq_opr == InvalidOid && - typentry->hash_opc != InvalidOid) - typentry->eq_opr = get_opclass_member(typentry->hash_opc, - InvalidOid, - HTEqualStrategyNumber); + typentry->hash_opf != InvalidOid) + typentry->eq_opr = get_opfamily_member(typentry->hash_opf, + typentry->hash_opintype, + typentry->hash_opintype, + HTEqualStrategyNumber); } if ((flags & TYPECACHE_LT_OPR) && typentry->lt_opr == InvalidOid) { - if (typentry->btree_opc != InvalidOid) - typentry->lt_opr = get_opclass_member(typentry->btree_opc, - InvalidOid, - BTLessStrategyNumber); + if (typentry->btree_opf != InvalidOid) + typentry->lt_opr = get_opfamily_member(typentry->btree_opf, + typentry->btree_opintype, + typentry->btree_opintype, + BTLessStrategyNumber); } if ((flags & TYPECACHE_GT_OPR) && typentry->gt_opr == InvalidOid) { - if (typentry->btree_opc != InvalidOid) - typentry->gt_opr = get_opclass_member(typentry->btree_opc, - InvalidOid, - BTGreaterStrategyNumber); + if (typentry->btree_opf != InvalidOid) + typentry->gt_opr = get_opfamily_member(typentry->btree_opf, + typentry->btree_opintype, + typentry->btree_opintype, + BTGreaterStrategyNumber); } if ((flags & (TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO)) && typentry->cmp_proc == InvalidOid) { - if (typentry->btree_opc != InvalidOid) - typentry->cmp_proc = get_opclass_proc(typentry->btree_opc, - InvalidOid, - BTORDER_PROC); + if (typentry->btree_opf != InvalidOid) + typentry->cmp_proc = get_opfamily_proc(typentry->btree_opf, + typentry->btree_opintype, + typentry->btree_opintype, + BTORDER_PROC); } /* diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 652f9a2ff4..dceaf5a655 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -91,7 +91,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.70 2006/10/04 00:30:04 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.71 2006/12/23 00:43:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2104,15 +2104,16 @@ SelectSortFunction(Oid sortOperator, int i; HeapTuple tuple; Form_pg_operator optup; - Oid opclass = InvalidOid; + Oid opfamily = InvalidOid; + Oid opinputtype = InvalidOid; /* - * Search pg_amop to see if the target operator is registered as the "<" - * or ">" operator of any btree opclass. It's possible that it might be + * Search pg_amop to see if the target operator is registered as a "<" + * or ">" operator of any btree opfamily. It's possible that it might be * registered both ways (eg, if someone were to build a "reverse sort" - * opclass for some reason); prefer the "<" case if so. If the operator is - * registered the same way in multiple opclasses, assume we can use the - * associated comparator function from any one. + * opfamily); prefer the "<" case if so. If the operator is registered the + * same way in multiple opfamilies, assume we can use the associated + * comparator function from any one. */ catlist = SearchSysCacheList(AMOPOPID, 1, ObjectIdGetDatum(sortOperator), @@ -2125,21 +2126,24 @@ SelectSortFunction(Oid sortOperator, tuple = &catlist->members[i]->tuple; aform = (Form_pg_amop) GETSTRUCT(tuple); - if (!opclass_is_btree(aform->amopclaid)) + /* must be btree */ + if (aform->amopmethod != BTREE_AM_OID) continue; - /* must be of default subtype, too */ - if (aform->amopsubtype != InvalidOid) + /* mustn't be cross-datatype, either */ + if (aform->amoplefttype != aform->amoprighttype) continue; if (aform->amopstrategy == BTLessStrategyNumber) { - opclass = aform->amopclaid; + opfamily = aform->amopfamily; + opinputtype = aform->amoplefttype; *kind = SORTFUNC_CMP; break; /* done looking */ } else if (aform->amopstrategy == BTGreaterStrategyNumber) { - opclass = aform->amopclaid; + opfamily = aform->amopfamily; + opinputtype = aform->amoplefttype; *kind = SORTFUNC_REVCMP; /* keep scanning in hopes of finding a BTLess entry */ } @@ -2147,10 +2151,13 @@ SelectSortFunction(Oid sortOperator, ReleaseSysCacheList(catlist); - if (OidIsValid(opclass)) + if (OidIsValid(opfamily)) { - /* Found a suitable opclass, get its default comparator function */ - *sortFunction = get_opclass_proc(opclass, InvalidOid, BTORDER_PROC); + /* Found a suitable opfamily, get the matching comparator function */ + *sortFunction = get_opfamily_proc(opfamily, + opinputtype, + opinputtype, + BTORDER_PROC); Assert(RegProcedureIsValid(*sortFunction)); return; } diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index ce5439a1dd..cd31e135de 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * Portions taken from FreeBSD. * - * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.125 2006/10/04 18:58:08 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.126 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1590,7 +1590,8 @@ setup_depend(void) * dependencies seems hard. * * Note that we deliberately do not pin the system views, which - * haven't been created yet. + * haven't been created yet. Also, no conversions, databases, + * or tablespaces are pinned. * * First delete any already-made entries; PINs override all else, and * must be the only entries for their objects. @@ -1619,6 +1620,12 @@ setup_depend(void) "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_opclass;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " + " FROM pg_opfamily;\n", + "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " + " FROM pg_amop;\n", + "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " + " FROM pg_amproc;\n", + "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_rewrite;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_trigger;\n", diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c4df03083e..ae8d54936f 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -12,7 +12,7 @@ * by PostgreSQL * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.453 2006/10/09 23:36:59 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.454 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -6219,11 +6219,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) int i_oprnegate; int i_oprrest; int i_oprjoin; + int i_oprcanmerge; int i_oprcanhash; - int i_oprlsortop; - int i_oprrsortop; - int i_oprltcmpop; - int i_oprgtcmpop; char *oprkind; char *oprcode; char *oprleft; @@ -6232,11 +6229,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) char *oprnegate; char *oprrest; char *oprjoin; + char *oprcanmerge; char *oprcanhash; - char *oprlsortop; - char *oprrsortop; - char *oprltcmpop; - char *oprgtcmpop; /* Skip if not to be dumped */ if (!oprinfo->dobj.dump || dataOnly) @@ -6258,7 +6252,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) /* Make sure we are in proper schema so regoperator works correctly */ selectSourceSchema(oprinfo->dobj.namespace->dobj.name); - if (g_fout->remoteVersion >= 70300) + if (g_fout->remoteVersion >= 80300) { appendPQExpBuffer(query, "SELECT oprkind, " "oprcode::pg_catalog.regprocedure, " @@ -6268,11 +6262,23 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) "oprnegate::pg_catalog.regoperator, " "oprrest::pg_catalog.regprocedure, " "oprjoin::pg_catalog.regprocedure, " - "oprcanhash, " - "oprlsortop::pg_catalog.regoperator, " - "oprrsortop::pg_catalog.regoperator, " - "oprltcmpop::pg_catalog.regoperator, " - "oprgtcmpop::pg_catalog.regoperator " + "oprcanmerge, oprcanhash " + "from pg_catalog.pg_operator " + "where oid = '%u'::pg_catalog.oid", + oprinfo->dobj.catId.oid); + } + else if (g_fout->remoteVersion >= 70300) + { + appendPQExpBuffer(query, "SELECT oprkind, " + "oprcode::pg_catalog.regprocedure, " + "oprleft::pg_catalog.regtype, " + "oprright::pg_catalog.regtype, " + "oprcom::pg_catalog.regoperator, " + "oprnegate::pg_catalog.regoperator, " + "oprrest::pg_catalog.regprocedure, " + "oprjoin::pg_catalog.regprocedure, " + "(oprlsortop != 0) as oprcanmerge, " + "oprcanhash " "from pg_catalog.pg_operator " "where oid = '%u'::pg_catalog.oid", oprinfo->dobj.catId.oid); @@ -6285,8 +6291,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) "CASE WHEN oprright = 0 THEN '-' " "ELSE format_type(oprright, NULL) END as oprright, " "oprcom, oprnegate, oprrest, oprjoin, " - "oprcanhash, oprlsortop, oprrsortop, " - "0 as oprltcmpop, 0 as oprgtcmpop " + "(oprlsortop != 0) as oprcanmerge, " + "oprcanhash " "from pg_operator " "where oid = '%u'::oid", oprinfo->dobj.catId.oid); @@ -6299,8 +6305,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) "CASE WHEN oprright = 0 THEN '-'::name " "ELSE (select typname from pg_type where oid = oprright) END as oprright, " "oprcom, oprnegate, oprrest, oprjoin, " - "oprcanhash, oprlsortop, oprrsortop, " - "0 as oprltcmpop, 0 as oprgtcmpop " + "(oprlsortop != 0) as oprcanmerge, " + "oprcanhash " "from pg_operator " "where oid = '%u'::oid", oprinfo->dobj.catId.oid); @@ -6326,11 +6332,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) i_oprnegate = PQfnumber(res, "oprnegate"); i_oprrest = PQfnumber(res, "oprrest"); i_oprjoin = PQfnumber(res, "oprjoin"); + i_oprcanmerge = PQfnumber(res, "oprcanmerge"); i_oprcanhash = PQfnumber(res, "oprcanhash"); - i_oprlsortop = PQfnumber(res, "oprlsortop"); - i_oprrsortop = PQfnumber(res, "oprrsortop"); - i_oprltcmpop = PQfnumber(res, "oprltcmpop"); - i_oprgtcmpop = PQfnumber(res, "oprgtcmpop"); oprkind = PQgetvalue(res, 0, i_oprkind); oprcode = PQgetvalue(res, 0, i_oprcode); @@ -6340,11 +6343,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) oprnegate = PQgetvalue(res, 0, i_oprnegate); oprrest = PQgetvalue(res, 0, i_oprrest); oprjoin = PQgetvalue(res, 0, i_oprjoin); + oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge); oprcanhash = PQgetvalue(res, 0, i_oprcanhash); - oprlsortop = PQgetvalue(res, 0, i_oprlsortop); - oprrsortop = PQgetvalue(res, 0, i_oprrsortop); - oprltcmpop = PQgetvalue(res, 0, i_oprltcmpop); - oprgtcmpop = PQgetvalue(res, 0, i_oprgtcmpop); appendPQExpBuffer(details, " PROCEDURE = %s", convertRegProcReference(oprcode)); @@ -6390,6 +6390,9 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) if (name) appendPQExpBuffer(details, ",\n NEGATOR = %s", name); + if (strcmp(oprcanmerge, "t") == 0) + appendPQExpBuffer(details, ",\n MERGES"); + if (strcmp(oprcanhash, "t") == 0) appendPQExpBuffer(details, ",\n HASHES"); @@ -6401,22 +6404,6 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) if (name) appendPQExpBuffer(details, ",\n JOIN = %s", name); - name = convertOperatorReference(oprlsortop); - if (name) - appendPQExpBuffer(details, ",\n SORT1 = %s", name); - - name = convertOperatorReference(oprrsortop); - if (name) - appendPQExpBuffer(details, ",\n SORT2 = %s", name); - - name = convertOperatorReference(oprltcmpop); - if (name) - appendPQExpBuffer(details, ",\n LTCMP = %s", name); - - name = convertOperatorReference(oprgtcmpop); - if (name) - appendPQExpBuffer(details, ",\n GTCMP = %s", name); - /* * DROP must be fully qualified in case same name appears in pg_catalog */ @@ -6608,13 +6595,26 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) selectSourceSchema(opcinfo->dobj.namespace->dobj.name); /* Get additional fields from the pg_opclass row */ - appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, " - "opckeytype::pg_catalog.regtype, " - "opcdefault, " - "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname " - "FROM pg_catalog.pg_opclass " - "WHERE oid = '%u'::pg_catalog.oid", - opcinfo->dobj.catId.oid); + if (g_fout->remoteVersion >= 80300) + { + appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, " + "opckeytype::pg_catalog.regtype, " + "opcdefault, " + "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname " + "FROM pg_catalog.pg_opclass " + "WHERE oid = '%u'::pg_catalog.oid", + opcinfo->dobj.catId.oid); + } + else + { + appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, " + "opckeytype::pg_catalog.regtype, " + "opcdefault, " + "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname " + "FROM pg_catalog.pg_opclass " + "WHERE oid = '%u'::pg_catalog.oid", + opcinfo->dobj.catId.oid); + } res = PQexec(g_conn, query->data); check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); @@ -6674,12 +6674,31 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) */ resetPQExpBuffer(query); - appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, " - "amopopr::pg_catalog.regoperator " - "FROM pg_catalog.pg_amop " - "WHERE amopclaid = '%u'::pg_catalog.oid " - "ORDER BY amopstrategy", - opcinfo->dobj.catId.oid); + if (g_fout->remoteVersion >= 80300) + { + /* + * Print only those opfamily members that are tied to the opclass + * by pg_depend entries. + */ + appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, " + "amopopr::pg_catalog.regoperator " + "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend " + "WHERE refclassid = 'pg_catalog.pg_opclass'::regclass " + "AND refobjid = '%u'::pg_catalog.oid " + "AND classid = 'pg_catalog.pg_amop'::regclass " + "AND objid = ao.oid " + "ORDER BY amopstrategy", + opcinfo->dobj.catId.oid); + } + else + { + appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, " + "amopopr::pg_catalog.regoperator " + "FROM pg_catalog.pg_amop " + "WHERE amopclaid = '%u'::pg_catalog.oid " + "ORDER BY amopstrategy", + opcinfo->dobj.catId.oid); + } res = PQexec(g_conn, query->data); check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); @@ -6714,12 +6733,31 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) */ resetPQExpBuffer(query); - appendPQExpBuffer(query, "SELECT amprocnum, " - "amproc::pg_catalog.regprocedure " - "FROM pg_catalog.pg_amproc " - "WHERE amopclaid = '%u'::pg_catalog.oid " - "ORDER BY amprocnum", - opcinfo->dobj.catId.oid); + if (g_fout->remoteVersion >= 80300) + { + /* + * Print only those opfamily members that are tied to the opclass + * by pg_depend entries. + */ + appendPQExpBuffer(query, "SELECT amprocnum, " + "amproc::pg_catalog.regprocedure " + "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend " + "WHERE refclassid = 'pg_catalog.pg_opclass'::regclass " + "AND refobjid = '%u'::pg_catalog.oid " + "AND classid = 'pg_catalog.pg_amproc'::regclass " + "AND objid = ap.oid " + "ORDER BY amprocnum", + opcinfo->dobj.catId.oid); + } + else + { + appendPQExpBuffer(query, "SELECT amprocnum, " + "amproc::pg_catalog.regprocedure " + "FROM pg_catalog.pg_amproc " + "WHERE amopclaid = '%u'::pg_catalog.oid " + "ORDER BY amprocnum", + opcinfo->dobj.catId.oid); + } res = PQexec(g_conn, query->data); check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 945c9a1b22..f0a840a3dd 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.364 2006/12/21 18:32:56 petere Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.365 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200612201 +#define CATALOG_VERSION_NO 200612221 #endif diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index da7d7ac8e4..b3ec0ccf2c 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.27 2006/08/21 00:57:26 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.28 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -131,6 +131,9 @@ typedef enum ObjectClass OCLASS_LANGUAGE, /* pg_language */ OCLASS_OPERATOR, /* pg_operator */ OCLASS_OPCLASS, /* pg_opclass */ + OCLASS_OPFAMILY, /* pg_opfamily */ + OCLASS_AMOP, /* pg_amop */ + OCLASS_AMPROC, /* pg_amproc */ OCLASS_REWRITE, /* pg_rewrite */ OCLASS_TRIGGER, /* pg_trigger */ OCLASS_SCHEMA, /* pg_namespace */ diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 6587b34db7..215119afd0 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.95 2006/07/13 17:47:01 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.96 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -65,13 +65,17 @@ DECLARE_UNIQUE_INDEX(pg_am_name_index, 2651, on pg_am using btree(amname name_op DECLARE_UNIQUE_INDEX(pg_am_oid_index, 2652, on pg_am using btree(oid oid_ops)); #define AmOidIndexId 2652 -DECLARE_UNIQUE_INDEX(pg_amop_opc_strat_index, 2653, on pg_amop using btree(amopclaid oid_ops, amopsubtype oid_ops, amopstrategy int2_ops)); +DECLARE_UNIQUE_INDEX(pg_amop_fam_strat_index, 2653, on pg_amop using btree(amopfamily oid_ops, amoplefttype oid_ops, amoprighttype oid_ops, amopstrategy int2_ops)); #define AccessMethodStrategyIndexId 2653 -DECLARE_UNIQUE_INDEX(pg_amop_opr_opc_index, 2654, on pg_amop using btree(amopopr oid_ops, amopclaid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_amop_opr_fam_index, 2654, on pg_amop using btree(amopopr oid_ops, amopfamily oid_ops)); #define AccessMethodOperatorIndexId 2654 +DECLARE_UNIQUE_INDEX(pg_amop_oid_index, 2756, on pg_amop using btree(oid oid_ops)); +#define AccessMethodOperatorOidIndexId 2756 -DECLARE_UNIQUE_INDEX(pg_amproc_opc_proc_index, 2655, on pg_amproc using btree(amopclaid oid_ops, amprocsubtype oid_ops, amprocnum int2_ops)); +DECLARE_UNIQUE_INDEX(pg_amproc_fam_proc_index, 2655, on pg_amproc using btree(amprocfamily oid_ops, amproclefttype oid_ops, amprocrighttype oid_ops, amprocnum int2_ops)); #define AccessMethodProcedureIndexId 2655 +DECLARE_UNIQUE_INDEX(pg_amproc_oid_index, 2757, on pg_amproc using btree(oid oid_ops)); +#define AccessMethodProcedureOidIndexId 2757 DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index, 2656, on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops)); #define AttrDefaultIndexId 2656 @@ -164,7 +168,7 @@ DECLARE_UNIQUE_INDEX(pg_namespace_nspname_index, 2684, on pg_namespace using btr DECLARE_UNIQUE_INDEX(pg_namespace_oid_index, 2685, on pg_namespace using btree(oid oid_ops)); #define NamespaceOidIndexId 2685 -DECLARE_UNIQUE_INDEX(pg_opclass_am_name_nsp_index, 2686, on pg_opclass using btree(opcamid oid_ops, opcname name_ops, opcnamespace oid_ops)); +DECLARE_UNIQUE_INDEX(pg_opclass_am_name_nsp_index, 2686, on pg_opclass using btree(opcmethod oid_ops, opcname name_ops, opcnamespace oid_ops)); #define OpclassAmNameNspIndexId 2686 DECLARE_UNIQUE_INDEX(pg_opclass_oid_index, 2687, on pg_opclass using btree(oid oid_ops)); #define OpclassOidIndexId 2687 @@ -174,6 +178,11 @@ DECLARE_UNIQUE_INDEX(pg_operator_oid_index, 2688, on pg_operator using btree(oid DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_n_index, 2689, on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprnamespace oid_ops)); #define OperatorNameNspIndexId 2689 +DECLARE_UNIQUE_INDEX(pg_opfamily_am_name_nsp_index, 2754, on pg_opfamily using btree(opfmethod oid_ops, opfname name_ops, opfnamespace oid_ops)); +#define OpfamilyAmNameNspIndexId 2754 +DECLARE_UNIQUE_INDEX(pg_opfamily_oid_index, 2755, on pg_opfamily using btree(oid oid_ops)); +#define OpfamilyOidIndexId 2755 + DECLARE_UNIQUE_INDEX(pg_pltemplate_name_index, 1137, on pg_pltemplate using btree(tmplname name_ops)); #define PLTemplateNameIndexId 1137 diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index ab354f53ac..e1d9b190f2 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.42 2006/05/01 23:22:43 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.43 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -51,6 +51,9 @@ extern bool OperatorIsVisible(Oid oprid); extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname); extern bool OpclassIsVisible(Oid opcid); +extern Oid OpfamilynameGetOpfid(Oid amid, const char *opfname); +extern bool OpfamilyIsVisible(Oid opfid); + extern Oid ConversionGetConid(const char *conname); extern bool ConversionIsVisible(Oid conid); diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index 1203434727..6907547eef 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -4,26 +4,32 @@ * definition of the system "amop" relation (pg_amop) * along with the relation's initial contents. * - * The amop table identifies the operators associated with each index opclass. + * The amop table identifies the operators associated with each index operator + * family and operator class (classes are subsets of families). * - * The primary key for this table is . - * amopsubtype is equal to zero for an opclass's "default" operators - * (which normally are those that accept the opclass's opcintype on both - * left and right sides). Some index AMs allow nondefault operators to - * exist for a single strategy --- for example, in the btree AM nondefault - * operators can have right-hand input data types different from opcintype, - * and their amopsubtype is equal to the right-hand input data type. + * The primary key for this table is . amoplefttype and amoprighttype are just copies of the + * operator's oprleft/oprright, ie its declared input data types. The + * "default" operators for a particular opclass within the family are those + * with amoplefttype = amoprighttype = opclass's opcintype. An opfamily may + * also contain other operators, typically cross-data-type operators. All the + * operators within a family are supposed to be compatible, in a way that is + * defined by each individual index AM. * - * We also keep a unique index on , so that we can - * use a syscache to quickly answer questions of the form "is this operator - * in this opclass?". This implies that the same operator cannot be listed - * for multiple subtypes or strategy numbers of a single opclass. + * We also keep a unique index on , so that we can use a + * syscache to quickly answer questions of the form "is this operator in this + * opfamily, and if so what are its semantics with respect to the family?" + * This implies that the same operator cannot be listed for multiple strategy + * numbers within a single opfamily. + * + * amopmethod is a copy of the owning opfamily's opfmethod field. This is an + * intentional denormalization of the catalogs to buy lookup speed. * * * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.75 2006/10/04 00:30:07 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.76 2006/12/23 00:43:12 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -48,13 +54,15 @@ */ #define AccessMethodOperatorRelationId 2602 -CATALOG(pg_amop,2602) BKI_WITHOUT_OIDS +CATALOG(pg_amop,2602) { - Oid amopclaid; /* the index opclass this entry is for */ - Oid amopsubtype; /* operator subtype, or zero if default */ + Oid amopfamily; /* the index opfamily this entry is for */ + Oid amoplefttype; /* operator's left input data type */ + Oid amoprighttype; /* operator's right input data type */ int2 amopstrategy; /* operator strategy number */ bool amopreqcheck; /* index hit must be rechecked */ Oid amopopr; /* the operator's pg_operator OID */ + Oid amopmethod; /* the index access method this entry is for */ } FormData_pg_amop; /* ---------------- @@ -68,12 +76,14 @@ typedef FormData_pg_amop *Form_pg_amop; * compiler constants for pg_amop * ---------------- */ -#define Natts_pg_amop 5 -#define Anum_pg_amop_amopclaid 1 -#define Anum_pg_amop_amopsubtype 2 -#define Anum_pg_amop_amopstrategy 3 -#define Anum_pg_amop_amopreqcheck 4 -#define Anum_pg_amop_amopopr 5 +#define Natts_pg_amop 7 +#define Anum_pg_amop_amopfamily 1 +#define Anum_pg_amop_amoplefttype 2 +#define Anum_pg_amop_amoprighttype 3 +#define Anum_pg_amop_amopstrategy 4 +#define Anum_pg_amop_amopreqcheck 5 +#define Anum_pg_amop_amopopr 6 +#define Anum_pg_amop_amopmethod 7 /* ---------------- * initial contents of pg_amop @@ -81,815 +91,528 @@ typedef FormData_pg_amop *Form_pg_amop; */ /* - * btree int2_ops + * btree integer_ops */ -DATA(insert ( 1976 0 1 f 95 )); -DATA(insert ( 1976 0 2 f 522 )); -DATA(insert ( 1976 0 3 f 94 )); -DATA(insert ( 1976 0 4 f 524 )); -DATA(insert ( 1976 0 5 f 520 )); +/* default operators int2 */ +DATA(insert ( 1976 21 21 1 f 95 403 )); +DATA(insert ( 1976 21 21 2 f 522 403 )); +DATA(insert ( 1976 21 21 3 f 94 403 )); +DATA(insert ( 1976 21 21 4 f 524 403 )); +DATA(insert ( 1976 21 21 5 f 520 403 )); /* crosstype operators int24 */ -DATA(insert ( 1976 23 1 f 534 )); -DATA(insert ( 1976 23 2 f 540 )); -DATA(insert ( 1976 23 3 f 532 )); -DATA(insert ( 1976 23 4 f 542 )); -DATA(insert ( 1976 23 5 f 536 )); +DATA(insert ( 1976 21 23 1 f 534 403 )); +DATA(insert ( 1976 21 23 2 f 540 403 )); +DATA(insert ( 1976 21 23 3 f 532 403 )); +DATA(insert ( 1976 21 23 4 f 542 403 )); +DATA(insert ( 1976 21 23 5 f 536 403 )); /* crosstype operators int28 */ -DATA(insert ( 1976 20 1 f 1864 )); -DATA(insert ( 1976 20 2 f 1866 )); -DATA(insert ( 1976 20 3 f 1862 )); -DATA(insert ( 1976 20 4 f 1867 )); -DATA(insert ( 1976 20 5 f 1865 )); - -/* - * btree int4_ops - */ - -DATA(insert ( 1978 0 1 f 97 )); -DATA(insert ( 1978 0 2 f 523 )); -DATA(insert ( 1978 0 3 f 96 )); -DATA(insert ( 1978 0 4 f 525 )); -DATA(insert ( 1978 0 5 f 521 )); +DATA(insert ( 1976 21 20 1 f 1864 403 )); +DATA(insert ( 1976 21 20 2 f 1866 403 )); +DATA(insert ( 1976 21 20 3 f 1862 403 )); +DATA(insert ( 1976 21 20 4 f 1867 403 )); +DATA(insert ( 1976 21 20 5 f 1865 403 )); +/* default operators int4 */ +DATA(insert ( 1976 23 23 1 f 97 403 )); +DATA(insert ( 1976 23 23 2 f 523 403 )); +DATA(insert ( 1976 23 23 3 f 96 403 )); +DATA(insert ( 1976 23 23 4 f 525 403 )); +DATA(insert ( 1976 23 23 5 f 521 403 )); /* crosstype operators int42 */ -DATA(insert ( 1978 21 1 f 535 )); -DATA(insert ( 1978 21 2 f 541 )); -DATA(insert ( 1978 21 3 f 533 )); -DATA(insert ( 1978 21 4 f 543 )); -DATA(insert ( 1978 21 5 f 537 )); +DATA(insert ( 1976 23 21 1 f 535 403 )); +DATA(insert ( 1976 23 21 2 f 541 403 )); +DATA(insert ( 1976 23 21 3 f 533 403 )); +DATA(insert ( 1976 23 21 4 f 543 403 )); +DATA(insert ( 1976 23 21 5 f 537 403 )); /* crosstype operators int48 */ -DATA(insert ( 1978 20 1 f 37 )); -DATA(insert ( 1978 20 2 f 80 )); -DATA(insert ( 1978 20 3 f 15 )); -DATA(insert ( 1978 20 4 f 82 )); -DATA(insert ( 1978 20 5 f 76 )); - -/* - * btree int8_ops - */ - -DATA(insert ( 1980 0 1 f 412 )); -DATA(insert ( 1980 0 2 f 414 )); -DATA(insert ( 1980 0 3 f 410 )); -DATA(insert ( 1980 0 4 f 415 )); -DATA(insert ( 1980 0 5 f 413 )); +DATA(insert ( 1976 23 20 1 f 37 403 )); +DATA(insert ( 1976 23 20 2 f 80 403 )); +DATA(insert ( 1976 23 20 3 f 15 403 )); +DATA(insert ( 1976 23 20 4 f 82 403 )); +DATA(insert ( 1976 23 20 5 f 76 403 )); +/* default operators int8 */ +DATA(insert ( 1976 20 20 1 f 412 403 )); +DATA(insert ( 1976 20 20 2 f 414 403 )); +DATA(insert ( 1976 20 20 3 f 410 403 )); +DATA(insert ( 1976 20 20 4 f 415 403 )); +DATA(insert ( 1976 20 20 5 f 413 403 )); /* crosstype operators int82 */ -DATA(insert ( 1980 21 1 f 1870 )); -DATA(insert ( 1980 21 2 f 1872 )); -DATA(insert ( 1980 21 3 f 1868 )); -DATA(insert ( 1980 21 4 f 1873 )); -DATA(insert ( 1980 21 5 f 1871 )); +DATA(insert ( 1976 20 21 1 f 1870 403 )); +DATA(insert ( 1976 20 21 2 f 1872 403 )); +DATA(insert ( 1976 20 21 3 f 1868 403 )); +DATA(insert ( 1976 20 21 4 f 1873 403 )); +DATA(insert ( 1976 20 21 5 f 1871 403 )); /* crosstype operators int84 */ -DATA(insert ( 1980 23 1 f 418 )); -DATA(insert ( 1980 23 2 f 420 )); -DATA(insert ( 1980 23 3 f 416 )); -DATA(insert ( 1980 23 4 f 430 )); -DATA(insert ( 1980 23 5 f 419 )); +DATA(insert ( 1976 20 23 1 f 418 403 )); +DATA(insert ( 1976 20 23 2 f 420 403 )); +DATA(insert ( 1976 20 23 3 f 416 403 )); +DATA(insert ( 1976 20 23 4 f 430 403 )); +DATA(insert ( 1976 20 23 5 f 419 403 )); /* * btree oid_ops */ -DATA(insert ( 1989 0 1 f 609 )); -DATA(insert ( 1989 0 2 f 611 )); -DATA(insert ( 1989 0 3 f 607 )); -DATA(insert ( 1989 0 4 f 612 )); -DATA(insert ( 1989 0 5 f 610 )); +DATA(insert ( 1989 26 26 1 f 609 403 )); +DATA(insert ( 1989 26 26 2 f 611 403 )); +DATA(insert ( 1989 26 26 3 f 607 403 )); +DATA(insert ( 1989 26 26 4 f 612 403 )); +DATA(insert ( 1989 26 26 5 f 610 403 )); /* * btree tid_ops */ -DATA(insert ( 2789 0 1 f 2799 )); -DATA(insert ( 2789 0 2 f 2801 )); -DATA(insert ( 2789 0 3 f 387 )); -DATA(insert ( 2789 0 4 f 2802 )); -DATA(insert ( 2789 0 5 f 2800 )); +DATA(insert ( 2789 27 27 1 f 2799 403 )); +DATA(insert ( 2789 27 27 2 f 2801 403 )); +DATA(insert ( 2789 27 27 3 f 387 403 )); +DATA(insert ( 2789 27 27 4 f 2802 403 )); +DATA(insert ( 2789 27 27 5 f 2800 403 )); /* * btree oidvector_ops */ -DATA(insert ( 1991 0 1 f 645 )); -DATA(insert ( 1991 0 2 f 647 )); -DATA(insert ( 1991 0 3 f 649 )); -DATA(insert ( 1991 0 4 f 648 )); -DATA(insert ( 1991 0 5 f 646 )); +DATA(insert ( 1991 30 30 1 f 645 403 )); +DATA(insert ( 1991 30 30 2 f 647 403 )); +DATA(insert ( 1991 30 30 3 f 649 403 )); +DATA(insert ( 1991 30 30 4 f 648 403 )); +DATA(insert ( 1991 30 30 5 f 646 403 )); /* - * btree float4_ops + * btree float_ops */ -DATA(insert ( 1970 0 1 f 622 )); -DATA(insert ( 1970 0 2 f 624 )); -DATA(insert ( 1970 0 3 f 620 )); -DATA(insert ( 1970 0 4 f 625 )); -DATA(insert ( 1970 0 5 f 623 )); +/* default operators float4 */ +DATA(insert ( 1970 700 700 1 f 622 403 )); +DATA(insert ( 1970 700 700 2 f 624 403 )); +DATA(insert ( 1970 700 700 3 f 620 403 )); +DATA(insert ( 1970 700 700 4 f 625 403 )); +DATA(insert ( 1970 700 700 5 f 623 403 )); /* crosstype operators float48 */ -DATA(insert ( 1970 701 1 f 1122 )); -DATA(insert ( 1970 701 2 f 1124 )); -DATA(insert ( 1970 701 3 f 1120 )); -DATA(insert ( 1970 701 4 f 1125 )); -DATA(insert ( 1970 701 5 f 1123 )); - -/* - * btree float8_ops - */ - -DATA(insert ( 1972 0 1 f 672 )); -DATA(insert ( 1972 0 2 f 673 )); -DATA(insert ( 1972 0 3 f 670 )); -DATA(insert ( 1972 0 4 f 675 )); -DATA(insert ( 1972 0 5 f 674 )); +DATA(insert ( 1970 700 701 1 f 1122 403 )); +DATA(insert ( 1970 700 701 2 f 1124 403 )); +DATA(insert ( 1970 700 701 3 f 1120 403 )); +DATA(insert ( 1970 700 701 4 f 1125 403 )); +DATA(insert ( 1970 700 701 5 f 1123 403 )); +/* default operators float8 */ +DATA(insert ( 1970 701 701 1 f 672 403 )); +DATA(insert ( 1970 701 701 2 f 673 403 )); +DATA(insert ( 1970 701 701 3 f 670 403 )); +DATA(insert ( 1970 701 701 4 f 675 403 )); +DATA(insert ( 1970 701 701 5 f 674 403 )); /* crosstype operators float84 */ -DATA(insert ( 1972 700 1 f 1132 )); -DATA(insert ( 1972 700 2 f 1134 )); -DATA(insert ( 1972 700 3 f 1130 )); -DATA(insert ( 1972 700 4 f 1135 )); -DATA(insert ( 1972 700 5 f 1133 )); +DATA(insert ( 1970 701 700 1 f 1132 403 )); +DATA(insert ( 1970 701 700 2 f 1134 403 )); +DATA(insert ( 1970 701 700 3 f 1130 403 )); +DATA(insert ( 1970 701 700 4 f 1135 403 )); +DATA(insert ( 1970 701 700 5 f 1133 403 )); /* * btree char_ops */ -DATA(insert ( 429 0 1 f 631 )); -DATA(insert ( 429 0 2 f 632 )); -DATA(insert ( 429 0 3 f 92 )); -DATA(insert ( 429 0 4 f 634 )); -DATA(insert ( 429 0 5 f 633 )); +DATA(insert ( 429 18 18 1 f 631 403 )); +DATA(insert ( 429 18 18 2 f 632 403 )); +DATA(insert ( 429 18 18 3 f 92 403 )); +DATA(insert ( 429 18 18 4 f 634 403 )); +DATA(insert ( 429 18 18 5 f 633 403 )); /* * btree name_ops */ -DATA(insert ( 1986 0 1 f 660 )); -DATA(insert ( 1986 0 2 f 661 )); -DATA(insert ( 1986 0 3 f 93 )); -DATA(insert ( 1986 0 4 f 663 )); -DATA(insert ( 1986 0 5 f 662 )); +DATA(insert ( 1986 19 19 1 f 660 403 )); +DATA(insert ( 1986 19 19 2 f 661 403 )); +DATA(insert ( 1986 19 19 3 f 93 403 )); +DATA(insert ( 1986 19 19 4 f 663 403 )); +DATA(insert ( 1986 19 19 5 f 662 403 )); /* * btree text_ops */ -DATA(insert ( 1994 0 1 f 664 )); -DATA(insert ( 1994 0 2 f 665 )); -DATA(insert ( 1994 0 3 f 98 )); -DATA(insert ( 1994 0 4 f 667 )); -DATA(insert ( 1994 0 5 f 666 )); +DATA(insert ( 1994 25 25 1 f 664 403 )); +DATA(insert ( 1994 25 25 2 f 665 403 )); +DATA(insert ( 1994 25 25 3 f 98 403 )); +DATA(insert ( 1994 25 25 4 f 667 403 )); +DATA(insert ( 1994 25 25 5 f 666 403 )); /* * btree bpchar_ops */ -DATA(insert ( 426 0 1 f 1058 )); -DATA(insert ( 426 0 2 f 1059 )); -DATA(insert ( 426 0 3 f 1054 )); -DATA(insert ( 426 0 4 f 1061 )); -DATA(insert ( 426 0 5 f 1060 )); - -/* - * btree varchar_ops (same operators as text_ops) - */ - -DATA(insert ( 2003 0 1 f 664 )); -DATA(insert ( 2003 0 2 f 665 )); -DATA(insert ( 2003 0 3 f 98 )); -DATA(insert ( 2003 0 4 f 667 )); -DATA(insert ( 2003 0 5 f 666 )); +DATA(insert ( 426 1042 1042 1 f 1058 403 )); +DATA(insert ( 426 1042 1042 2 f 1059 403 )); +DATA(insert ( 426 1042 1042 3 f 1054 403 )); +DATA(insert ( 426 1042 1042 4 f 1061 403 )); +DATA(insert ( 426 1042 1042 5 f 1060 403 )); /* * btree bytea_ops */ -DATA(insert ( 428 0 1 f 1957 )); -DATA(insert ( 428 0 2 f 1958 )); -DATA(insert ( 428 0 3 f 1955 )); -DATA(insert ( 428 0 4 f 1960 )); -DATA(insert ( 428 0 5 f 1959 )); +DATA(insert ( 428 17 17 1 f 1957 403 )); +DATA(insert ( 428 17 17 2 f 1958 403 )); +DATA(insert ( 428 17 17 3 f 1955 403 )); +DATA(insert ( 428 17 17 4 f 1960 403 )); +DATA(insert ( 428 17 17 5 f 1959 403 )); /* * btree abstime_ops */ -DATA(insert ( 421 0 1 f 562 )); -DATA(insert ( 421 0 2 f 564 )); -DATA(insert ( 421 0 3 f 560 )); -DATA(insert ( 421 0 4 f 565 )); -DATA(insert ( 421 0 5 f 563 )); +DATA(insert ( 421 702 702 1 f 562 403 )); +DATA(insert ( 421 702 702 2 f 564 403 )); +DATA(insert ( 421 702 702 3 f 560 403 )); +DATA(insert ( 421 702 702 4 f 565 403 )); +DATA(insert ( 421 702 702 5 f 563 403 )); /* - * btree date_ops + * btree datetime_ops */ -DATA(insert ( 434 0 1 f 1095 )); -DATA(insert ( 434 0 2 f 1096 )); -DATA(insert ( 434 0 3 f 1093 )); -DATA(insert ( 434 0 4 f 1098 )); -DATA(insert ( 434 0 5 f 1097 )); +/* default operators date */ +DATA(insert ( 434 1082 1082 1 f 1095 403 )); +DATA(insert ( 434 1082 1082 2 f 1096 403 )); +DATA(insert ( 434 1082 1082 3 f 1093 403 )); +DATA(insert ( 434 1082 1082 4 f 1098 403 )); +DATA(insert ( 434 1082 1082 5 f 1097 403 )); /* crosstype operators vs timestamp */ -DATA(insert ( 434 1114 1 f 2345 )); -DATA(insert ( 434 1114 2 f 2346 )); -DATA(insert ( 434 1114 3 f 2347 )); -DATA(insert ( 434 1114 4 f 2348 )); -DATA(insert ( 434 1114 5 f 2349 )); +DATA(insert ( 434 1082 1114 1 f 2345 403 )); +DATA(insert ( 434 1082 1114 2 f 2346 403 )); +DATA(insert ( 434 1082 1114 3 f 2347 403 )); +DATA(insert ( 434 1082 1114 4 f 2348 403 )); +DATA(insert ( 434 1082 1114 5 f 2349 403 )); /* crosstype operators vs timestamptz */ -DATA(insert ( 434 1184 1 f 2358 )); -DATA(insert ( 434 1184 2 f 2359 )); -DATA(insert ( 434 1184 3 f 2360 )); -DATA(insert ( 434 1184 4 f 2361 )); -DATA(insert ( 434 1184 5 f 2362 )); +DATA(insert ( 434 1082 1184 1 f 2358 403 )); +DATA(insert ( 434 1082 1184 2 f 2359 403 )); +DATA(insert ( 434 1082 1184 3 f 2360 403 )); +DATA(insert ( 434 1082 1184 4 f 2361 403 )); +DATA(insert ( 434 1082 1184 5 f 2362 403 )); +/* default operators timestamp */ +DATA(insert ( 434 1114 1114 1 f 2062 403 )); +DATA(insert ( 434 1114 1114 2 f 2063 403 )); +DATA(insert ( 434 1114 1114 3 f 2060 403 )); +DATA(insert ( 434 1114 1114 4 f 2065 403 )); +DATA(insert ( 434 1114 1114 5 f 2064 403 )); +/* crosstype operators vs date */ +DATA(insert ( 434 1114 1082 1 f 2371 403 )); +DATA(insert ( 434 1114 1082 2 f 2372 403 )); +DATA(insert ( 434 1114 1082 3 f 2373 403 )); +DATA(insert ( 434 1114 1082 4 f 2374 403 )); +DATA(insert ( 434 1114 1082 5 f 2375 403 )); +/* crosstype operators vs timestamptz */ +DATA(insert ( 434 1114 1184 1 f 2534 403 )); +DATA(insert ( 434 1114 1184 2 f 2535 403 )); +DATA(insert ( 434 1114 1184 3 f 2536 403 )); +DATA(insert ( 434 1114 1184 4 f 2537 403 )); +DATA(insert ( 434 1114 1184 5 f 2538 403 )); +/* default operators timestamptz */ +DATA(insert ( 434 1184 1184 1 f 1322 403 )); +DATA(insert ( 434 1184 1184 2 f 1323 403 )); +DATA(insert ( 434 1184 1184 3 f 1320 403 )); +DATA(insert ( 434 1184 1184 4 f 1325 403 )); +DATA(insert ( 434 1184 1184 5 f 1324 403 )); +/* crosstype operators vs date */ +DATA(insert ( 434 1184 1082 1 f 2384 403 )); +DATA(insert ( 434 1184 1082 2 f 2385 403 )); +DATA(insert ( 434 1184 1082 3 f 2386 403 )); +DATA(insert ( 434 1184 1082 4 f 2387 403 )); +DATA(insert ( 434 1184 1082 5 f 2388 403 )); +/* crosstype operators vs timestamp */ +DATA(insert ( 434 1184 1114 1 f 2540 403 )); +DATA(insert ( 434 1184 1114 2 f 2541 403 )); +DATA(insert ( 434 1184 1114 3 f 2542 403 )); +DATA(insert ( 434 1184 1114 4 f 2543 403 )); +DATA(insert ( 434 1184 1114 5 f 2544 403 )); /* * btree time_ops */ -DATA(insert ( 1996 0 1 f 1110 )); -DATA(insert ( 1996 0 2 f 1111 )); -DATA(insert ( 1996 0 3 f 1108 )); -DATA(insert ( 1996 0 4 f 1113 )); -DATA(insert ( 1996 0 5 f 1112 )); +DATA(insert ( 1996 1083 1083 1 f 1110 403 )); +DATA(insert ( 1996 1083 1083 2 f 1111 403 )); +DATA(insert ( 1996 1083 1083 3 f 1108 403 )); +DATA(insert ( 1996 1083 1083 4 f 1113 403 )); +DATA(insert ( 1996 1083 1083 5 f 1112 403 )); /* * btree timetz_ops */ -DATA(insert ( 2000 0 1 f 1552 )); -DATA(insert ( 2000 0 2 f 1553 )); -DATA(insert ( 2000 0 3 f 1550 )); -DATA(insert ( 2000 0 4 f 1555 )); -DATA(insert ( 2000 0 5 f 1554 )); - -/* - * btree timestamp_ops - */ - -DATA(insert ( 2039 0 1 f 2062 )); -DATA(insert ( 2039 0 2 f 2063 )); -DATA(insert ( 2039 0 3 f 2060 )); -DATA(insert ( 2039 0 4 f 2065 )); -DATA(insert ( 2039 0 5 f 2064 )); -/* crosstype operators vs date */ -DATA(insert ( 2039 1082 1 f 2371 )); -DATA(insert ( 2039 1082 2 f 2372 )); -DATA(insert ( 2039 1082 3 f 2373 )); -DATA(insert ( 2039 1082 4 f 2374 )); -DATA(insert ( 2039 1082 5 f 2375 )); -/* crosstype operators vs timestamptz */ -DATA(insert ( 2039 1184 1 f 2534 )); -DATA(insert ( 2039 1184 2 f 2535 )); -DATA(insert ( 2039 1184 3 f 2536 )); -DATA(insert ( 2039 1184 4 f 2537 )); -DATA(insert ( 2039 1184 5 f 2538 )); - -/* - * btree timestamptz_ops - */ - -DATA(insert ( 1998 0 1 f 1322 )); -DATA(insert ( 1998 0 2 f 1323 )); -DATA(insert ( 1998 0 3 f 1320 )); -DATA(insert ( 1998 0 4 f 1325 )); -DATA(insert ( 1998 0 5 f 1324 )); -/* crosstype operators vs date */ -DATA(insert ( 1998 1082 1 f 2384 )); -DATA(insert ( 1998 1082 2 f 2385 )); -DATA(insert ( 1998 1082 3 f 2386 )); -DATA(insert ( 1998 1082 4 f 2387 )); -DATA(insert ( 1998 1082 5 f 2388 )); -/* crosstype operators vs timestamp */ -DATA(insert ( 1998 1114 1 f 2540 )); -DATA(insert ( 1998 1114 2 f 2541 )); -DATA(insert ( 1998 1114 3 f 2542 )); -DATA(insert ( 1998 1114 4 f 2543 )); -DATA(insert ( 1998 1114 5 f 2544 )); +DATA(insert ( 2000 1266 1266 1 f 1552 403 )); +DATA(insert ( 2000 1266 1266 2 f 1553 403 )); +DATA(insert ( 2000 1266 1266 3 f 1550 403 )); +DATA(insert ( 2000 1266 1266 4 f 1555 403 )); +DATA(insert ( 2000 1266 1266 5 f 1554 403 )); /* * btree interval_ops */ -DATA(insert ( 1982 0 1 f 1332 )); -DATA(insert ( 1982 0 2 f 1333 )); -DATA(insert ( 1982 0 3 f 1330 )); -DATA(insert ( 1982 0 4 f 1335 )); -DATA(insert ( 1982 0 5 f 1334 )); +DATA(insert ( 1982 1186 1186 1 f 1332 403 )); +DATA(insert ( 1982 1186 1186 2 f 1333 403 )); +DATA(insert ( 1982 1186 1186 3 f 1330 403 )); +DATA(insert ( 1982 1186 1186 4 f 1335 403 )); +DATA(insert ( 1982 1186 1186 5 f 1334 403 )); /* * btree macaddr */ -DATA(insert ( 1984 0 1 f 1222 )); -DATA(insert ( 1984 0 2 f 1223 )); -DATA(insert ( 1984 0 3 f 1220 )); -DATA(insert ( 1984 0 4 f 1225 )); -DATA(insert ( 1984 0 5 f 1224 )); +DATA(insert ( 1984 829 829 1 f 1222 403 )); +DATA(insert ( 1984 829 829 2 f 1223 403 )); +DATA(insert ( 1984 829 829 3 f 1220 403 )); +DATA(insert ( 1984 829 829 4 f 1225 403 )); +DATA(insert ( 1984 829 829 5 f 1224 403 )); /* - * btree inet + * btree network */ -DATA(insert ( 1974 0 1 f 1203 )); -DATA(insert ( 1974 0 2 f 1204 )); -DATA(insert ( 1974 0 3 f 1201 )); -DATA(insert ( 1974 0 4 f 1206 )); -DATA(insert ( 1974 0 5 f 1205 )); - -/* - * btree cidr - */ - -DATA(insert ( 432 0 1 f 1203 )); -DATA(insert ( 432 0 2 f 1204 )); -DATA(insert ( 432 0 3 f 1201 )); -DATA(insert ( 432 0 4 f 1206 )); -DATA(insert ( 432 0 5 f 1205 )); +DATA(insert ( 1974 869 869 1 f 1203 403 )); +DATA(insert ( 1974 869 869 2 f 1204 403 )); +DATA(insert ( 1974 869 869 3 f 1201 403 )); +DATA(insert ( 1974 869 869 4 f 1206 403 )); +DATA(insert ( 1974 869 869 5 f 1205 403 )); /* * btree numeric */ -DATA(insert ( 1988 0 1 f 1754 )); -DATA(insert ( 1988 0 2 f 1755 )); -DATA(insert ( 1988 0 3 f 1752 )); -DATA(insert ( 1988 0 4 f 1757 )); -DATA(insert ( 1988 0 5 f 1756 )); +DATA(insert ( 1988 1700 1700 1 f 1754 403 )); +DATA(insert ( 1988 1700 1700 2 f 1755 403 )); +DATA(insert ( 1988 1700 1700 3 f 1752 403 )); +DATA(insert ( 1988 1700 1700 4 f 1757 403 )); +DATA(insert ( 1988 1700 1700 5 f 1756 403 )); /* * btree bool */ -DATA(insert ( 424 0 1 f 58 )); -DATA(insert ( 424 0 2 f 1694 )); -DATA(insert ( 424 0 3 f 91 )); -DATA(insert ( 424 0 4 f 1695 )); -DATA(insert ( 424 0 5 f 59 )); +DATA(insert ( 424 16 16 1 f 58 403 )); +DATA(insert ( 424 16 16 2 f 1694 403 )); +DATA(insert ( 424 16 16 3 f 91 403 )); +DATA(insert ( 424 16 16 4 f 1695 403 )); +DATA(insert ( 424 16 16 5 f 59 403 )); /* * btree bit */ -DATA(insert ( 423 0 1 f 1786 )); -DATA(insert ( 423 0 2 f 1788 )); -DATA(insert ( 423 0 3 f 1784 )); -DATA(insert ( 423 0 4 f 1789 )); -DATA(insert ( 423 0 5 f 1787 )); +DATA(insert ( 423 1560 1560 1 f 1786 403 )); +DATA(insert ( 423 1560 1560 2 f 1788 403 )); +DATA(insert ( 423 1560 1560 3 f 1784 403 )); +DATA(insert ( 423 1560 1560 4 f 1789 403 )); +DATA(insert ( 423 1560 1560 5 f 1787 403 )); /* * btree varbit */ -DATA(insert ( 2002 0 1 f 1806 )); -DATA(insert ( 2002 0 2 f 1808 )); -DATA(insert ( 2002 0 3 f 1804 )); -DATA(insert ( 2002 0 4 f 1809 )); -DATA(insert ( 2002 0 5 f 1807 )); +DATA(insert ( 2002 1562 1562 1 f 1806 403 )); +DATA(insert ( 2002 1562 1562 2 f 1808 403 )); +DATA(insert ( 2002 1562 1562 3 f 1804 403 )); +DATA(insert ( 2002 1562 1562 4 f 1809 403 )); +DATA(insert ( 2002 1562 1562 5 f 1807 403 )); /* * btree text pattern */ -DATA(insert ( 2095 0 1 f 2314 )); -DATA(insert ( 2095 0 2 f 2315 )); -DATA(insert ( 2095 0 3 f 2316 )); -DATA(insert ( 2095 0 4 f 2317 )); -DATA(insert ( 2095 0 5 f 2318 )); - -/* - * btree varchar pattern (same operators as text) - */ - -DATA(insert ( 2096 0 1 f 2314 )); -DATA(insert ( 2096 0 2 f 2315 )); -DATA(insert ( 2096 0 3 f 2316 )); -DATA(insert ( 2096 0 4 f 2317 )); -DATA(insert ( 2096 0 5 f 2318 )); +DATA(insert ( 2095 25 25 1 f 2314 403 )); +DATA(insert ( 2095 25 25 2 f 2315 403 )); +DATA(insert ( 2095 25 25 3 f 2316 403 )); +DATA(insert ( 2095 25 25 4 f 2317 403 )); +DATA(insert ( 2095 25 25 5 f 2318 403 )); /* * btree bpchar pattern */ -DATA(insert ( 2097 0 1 f 2326 )); -DATA(insert ( 2097 0 2 f 2327 )); -DATA(insert ( 2097 0 3 f 2328 )); -DATA(insert ( 2097 0 4 f 2329 )); -DATA(insert ( 2097 0 5 f 2330 )); +DATA(insert ( 2097 1042 1042 1 f 2326 403 )); +DATA(insert ( 2097 1042 1042 2 f 2327 403 )); +DATA(insert ( 2097 1042 1042 3 f 2328 403 )); +DATA(insert ( 2097 1042 1042 4 f 2329 403 )); +DATA(insert ( 2097 1042 1042 5 f 2330 403 )); /* * btree name pattern */ -DATA(insert ( 2098 0 1 f 2332 )); -DATA(insert ( 2098 0 2 f 2333 )); -DATA(insert ( 2098 0 3 f 2334 )); -DATA(insert ( 2098 0 4 f 2335 )); -DATA(insert ( 2098 0 5 f 2336 )); +DATA(insert ( 2098 19 19 1 f 2332 403 )); +DATA(insert ( 2098 19 19 2 f 2333 403 )); +DATA(insert ( 2098 19 19 3 f 2334 403 )); +DATA(insert ( 2098 19 19 4 f 2335 403 )); +DATA(insert ( 2098 19 19 5 f 2336 403 )); /* * btree money_ops */ -DATA(insert ( 2099 0 1 f 902 )); -DATA(insert ( 2099 0 2 f 904 )); -DATA(insert ( 2099 0 3 f 900 )); -DATA(insert ( 2099 0 4 f 905 )); -DATA(insert ( 2099 0 5 f 903 )); +DATA(insert ( 2099 790 790 1 f 902 403 )); +DATA(insert ( 2099 790 790 2 f 904 403 )); +DATA(insert ( 2099 790 790 3 f 900 403 )); +DATA(insert ( 2099 790 790 4 f 905 403 )); +DATA(insert ( 2099 790 790 5 f 903 403 )); /* * btree reltime_ops */ -DATA(insert ( 2233 0 1 f 568 )); -DATA(insert ( 2233 0 2 f 570 )); -DATA(insert ( 2233 0 3 f 566 )); -DATA(insert ( 2233 0 4 f 571 )); -DATA(insert ( 2233 0 5 f 569 )); +DATA(insert ( 2233 703 703 1 f 568 403 )); +DATA(insert ( 2233 703 703 2 f 570 403 )); +DATA(insert ( 2233 703 703 3 f 566 403 )); +DATA(insert ( 2233 703 703 4 f 571 403 )); +DATA(insert ( 2233 703 703 5 f 569 403 )); /* * btree tinterval_ops */ -DATA(insert ( 2234 0 1 f 813 )); -DATA(insert ( 2234 0 2 f 815 )); -DATA(insert ( 2234 0 3 f 811 )); -DATA(insert ( 2234 0 4 f 816 )); -DATA(insert ( 2234 0 5 f 814 )); +DATA(insert ( 2234 704 704 1 f 813 403 )); +DATA(insert ( 2234 704 704 2 f 815 403 )); +DATA(insert ( 2234 704 704 3 f 811 403 )); +DATA(insert ( 2234 704 704 4 f 816 403 )); +DATA(insert ( 2234 704 704 5 f 814 403 )); /* * btree array_ops */ -DATA(insert ( 397 0 1 f 1072 )); -DATA(insert ( 397 0 2 f 1074 )); -DATA(insert ( 397 0 3 f 1070 )); -DATA(insert ( 397 0 4 f 1075 )); -DATA(insert ( 397 0 5 f 1073 )); +DATA(insert ( 397 2277 2277 1 f 1072 403 )); +DATA(insert ( 397 2277 2277 2 f 1074 403 )); +DATA(insert ( 397 2277 2277 3 f 1070 403 )); +DATA(insert ( 397 2277 2277 4 f 1075 403 )); +DATA(insert ( 397 2277 2277 5 f 1073 403 )); /* * hash index _ops */ /* bpchar_ops */ -DATA(insert ( 427 0 1 f 1054 )); +DATA(insert ( 427 1042 1042 1 f 1054 405 )); /* char_ops */ -DATA(insert ( 431 0 1 f 92 )); -/* cidr_ops */ -DATA(insert ( 433 0 1 f 1201 )); +DATA(insert ( 431 18 18 1 f 92 405 )); /* date_ops */ -DATA(insert ( 435 0 1 f 1093 )); -/* float4_ops */ -DATA(insert ( 1971 0 1 f 620 )); -/* float8_ops */ -DATA(insert ( 1973 0 1 f 670 )); -/* inet_ops */ -DATA(insert ( 1975 0 1 f 1201 )); -/* int2_ops */ -DATA(insert ( 1977 0 1 f 94 )); -/* int4_ops */ -DATA(insert ( 1979 0 1 f 96 )); -/* int8_ops */ -DATA(insert ( 1981 0 1 f 410 )); +DATA(insert ( 435 1082 1082 1 f 1093 405 )); +/* float_ops */ +DATA(insert ( 1971 700 700 1 f 620 405 )); +DATA(insert ( 1971 701 701 1 f 670 405 )); +/* network_ops */ +DATA(insert ( 1975 869 869 1 f 1201 405 )); +/* integer_ops */ +DATA(insert ( 1977 21 21 1 f 94 405 )); +DATA(insert ( 1977 23 23 1 f 96 405 )); +DATA(insert ( 1977 20 20 1 f 410 405 )); /* interval_ops */ -DATA(insert ( 1983 0 1 f 1330 )); +DATA(insert ( 1983 1186 1186 1 f 1330 405 )); /* macaddr_ops */ -DATA(insert ( 1985 0 1 f 1220 )); +DATA(insert ( 1985 829 829 1 f 1220 405 )); /* name_ops */ -DATA(insert ( 1987 0 1 f 93 )); +DATA(insert ( 1987 19 19 1 f 93 405 )); /* oid_ops */ -DATA(insert ( 1990 0 1 f 607 )); +DATA(insert ( 1990 26 26 1 f 607 405 )); /* oidvector_ops */ -DATA(insert ( 1992 0 1 f 649 )); +DATA(insert ( 1992 30 30 1 f 649 405 )); /* text_ops */ -DATA(insert ( 1995 0 1 f 98 )); +DATA(insert ( 1995 25 25 1 f 98 405 )); /* time_ops */ -DATA(insert ( 1997 0 1 f 1108 )); +DATA(insert ( 1997 1083 1083 1 f 1108 405 )); /* timestamptz_ops */ -DATA(insert ( 1999 0 1 f 1320 )); +DATA(insert ( 1999 1184 1184 1 f 1320 405 )); /* timetz_ops */ -DATA(insert ( 2001 0 1 f 1550 )); -/* varchar_ops */ -DATA(insert ( 2004 0 1 f 98 )); +DATA(insert ( 2001 1266 1266 1 f 1550 405 )); /* timestamp_ops */ -DATA(insert ( 2040 0 1 f 2060 )); +DATA(insert ( 2040 1114 1114 1 f 2060 405 )); /* bool_ops */ -DATA(insert ( 2222 0 1 f 91 )); +DATA(insert ( 2222 16 16 1 f 91 405 )); /* bytea_ops */ -DATA(insert ( 2223 0 1 f 1955 )); +DATA(insert ( 2223 17 17 1 f 1955 405 )); /* int2vector_ops */ -DATA(insert ( 2224 0 1 f 386 )); +DATA(insert ( 2224 22 22 1 f 386 405 )); /* xid_ops */ -DATA(insert ( 2225 0 1 f 352 )); +DATA(insert ( 2225 28 28 1 f 352 405 )); /* cid_ops */ -DATA(insert ( 2226 0 1 f 385 )); +DATA(insert ( 2226 29 29 1 f 385 405 )); /* abstime_ops */ -DATA(insert ( 2227 0 1 f 560 )); +DATA(insert ( 2227 702 702 1 f 560 405 )); /* reltime_ops */ -DATA(insert ( 2228 0 1 f 566 )); +DATA(insert ( 2228 703 703 1 f 566 405 )); /* text_pattern_ops */ -DATA(insert ( 2229 0 1 f 2316 )); -/* varchar_pattern_ops */ -DATA(insert ( 2230 0 1 f 2316 )); +DATA(insert ( 2229 25 25 1 f 2316 405 )); /* bpchar_pattern_ops */ -DATA(insert ( 2231 0 1 f 2328 )); +DATA(insert ( 2231 1042 1042 1 f 2328 405 )); /* name_pattern_ops */ -DATA(insert ( 2232 0 1 f 2334 )); +DATA(insert ( 2232 19 19 1 f 2334 405 )); /* aclitem_ops */ -DATA(insert ( 2235 0 1 f 974 )); +DATA(insert ( 2235 1033 1033 1 f 974 405 )); /* * gist box_ops */ -DATA(insert ( 2593 0 1 f 493 )); -DATA(insert ( 2593 0 2 f 494 )); -DATA(insert ( 2593 0 3 f 500 )); -DATA(insert ( 2593 0 4 f 495 )); -DATA(insert ( 2593 0 5 f 496 )); -DATA(insert ( 2593 0 6 f 499 )); -DATA(insert ( 2593 0 7 f 498 )); -DATA(insert ( 2593 0 8 f 497 )); -DATA(insert ( 2593 0 9 f 2571 )); -DATA(insert ( 2593 0 10 f 2570 )); -DATA(insert ( 2593 0 11 f 2573 )); -DATA(insert ( 2593 0 12 f 2572 )); -DATA(insert ( 2593 0 13 f 2863 )); -DATA(insert ( 2593 0 14 f 2862 )); +DATA(insert ( 2593 603 603 1 f 493 783 )); +DATA(insert ( 2593 603 603 2 f 494 783 )); +DATA(insert ( 2593 603 603 3 f 500 783 )); +DATA(insert ( 2593 603 603 4 f 495 783 )); +DATA(insert ( 2593 603 603 5 f 496 783 )); +DATA(insert ( 2593 603 603 6 f 499 783 )); +DATA(insert ( 2593 603 603 7 f 498 783 )); +DATA(insert ( 2593 603 603 8 f 497 783 )); +DATA(insert ( 2593 603 603 9 f 2571 783 )); +DATA(insert ( 2593 603 603 10 f 2570 783 )); +DATA(insert ( 2593 603 603 11 f 2573 783 )); +DATA(insert ( 2593 603 603 12 f 2572 783 )); +DATA(insert ( 2593 603 603 13 f 2863 783 )); +DATA(insert ( 2593 603 603 14 f 2862 783 )); /* * gist poly_ops (supports polygons) */ -DATA(insert ( 2594 0 1 t 485 )); -DATA(insert ( 2594 0 2 t 486 )); -DATA(insert ( 2594 0 3 t 492 )); -DATA(insert ( 2594 0 4 t 487 )); -DATA(insert ( 2594 0 5 t 488 )); -DATA(insert ( 2594 0 6 t 491 )); -DATA(insert ( 2594 0 7 t 490 )); -DATA(insert ( 2594 0 8 t 489 )); -DATA(insert ( 2594 0 9 t 2575 )); -DATA(insert ( 2594 0 10 t 2574 )); -DATA(insert ( 2594 0 11 t 2577 )); -DATA(insert ( 2594 0 12 t 2576 )); -DATA(insert ( 2594 0 13 t 2861 )); -DATA(insert ( 2594 0 14 t 2860 )); +DATA(insert ( 2594 604 604 1 t 485 783 )); +DATA(insert ( 2594 604 604 2 t 486 783 )); +DATA(insert ( 2594 604 604 3 t 492 783 )); +DATA(insert ( 2594 604 604 4 t 487 783 )); +DATA(insert ( 2594 604 604 5 t 488 783 )); +DATA(insert ( 2594 604 604 6 t 491 783 )); +DATA(insert ( 2594 604 604 7 t 490 783 )); +DATA(insert ( 2594 604 604 8 t 489 783 )); +DATA(insert ( 2594 604 604 9 t 2575 783 )); +DATA(insert ( 2594 604 604 10 t 2574 783 )); +DATA(insert ( 2594 604 604 11 t 2577 783 )); +DATA(insert ( 2594 604 604 12 t 2576 783 )); +DATA(insert ( 2594 604 604 13 t 2861 783 )); +DATA(insert ( 2594 604 604 14 t 2860 783 )); /* * gist circle_ops */ -DATA(insert ( 2595 0 1 t 1506 )); -DATA(insert ( 2595 0 2 t 1507 )); -DATA(insert ( 2595 0 3 t 1513 )); -DATA(insert ( 2595 0 4 t 1508 )); -DATA(insert ( 2595 0 5 t 1509 )); -DATA(insert ( 2595 0 6 t 1512 )); -DATA(insert ( 2595 0 7 t 1511 )); -DATA(insert ( 2595 0 8 t 1510 )); -DATA(insert ( 2595 0 9 t 2589 )); -DATA(insert ( 2595 0 10 t 1515 )); -DATA(insert ( 2595 0 11 t 1514 )); -DATA(insert ( 2595 0 12 t 2590 )); -DATA(insert ( 2595 0 13 t 2865 )); -DATA(insert ( 2595 0 14 t 2864 )); +DATA(insert ( 2595 718 718 1 t 1506 783 )); +DATA(insert ( 2595 718 718 2 t 1507 783 )); +DATA(insert ( 2595 718 718 3 t 1513 783 )); +DATA(insert ( 2595 718 718 4 t 1508 783 )); +DATA(insert ( 2595 718 718 5 t 1509 783 )); +DATA(insert ( 2595 718 718 6 t 1512 783 )); +DATA(insert ( 2595 718 718 7 t 1511 783 )); +DATA(insert ( 2595 718 718 8 t 1510 783 )); +DATA(insert ( 2595 718 718 9 t 2589 783 )); +DATA(insert ( 2595 718 718 10 t 1515 783 )); +DATA(insert ( 2595 718 718 11 t 1514 783 )); +DATA(insert ( 2595 718 718 12 t 2590 783 )); +DATA(insert ( 2595 718 718 13 t 2865 783 )); +DATA(insert ( 2595 718 718 14 t 2864 783 )); /* - * gin _int4_ops + * gin array_ops (these anyarray operators are used with all the opclasses + * of the family) */ -DATA(insert ( 2745 0 1 f 2750 )); -DATA(insert ( 2745 0 2 f 2751 )); -DATA(insert ( 2745 0 3 t 2752 )); -DATA(insert ( 2745 0 4 t 1070 )); - -/* - * gin _text_ops - */ -DATA(insert ( 2746 0 1 f 2750 )); -DATA(insert ( 2746 0 2 f 2751 )); -DATA(insert ( 2746 0 3 t 2752 )); -DATA(insert ( 2746 0 4 t 1070 )); - -/* - * gin _abstime_ops - */ -DATA(insert ( 2753 0 1 f 2750 )); -DATA(insert ( 2753 0 2 f 2751 )); -DATA(insert ( 2753 0 3 t 2752 )); -DATA(insert ( 2753 0 4 t 1070 )); - -/* - * gin _bit_ops - */ -DATA(insert ( 2754 0 1 f 2750 )); -DATA(insert ( 2754 0 2 f 2751 )); -DATA(insert ( 2754 0 3 t 2752 )); -DATA(insert ( 2754 0 4 t 1070 )); - -/* - * gin _bool_ops - */ -DATA(insert ( 2755 0 1 f 2750 )); -DATA(insert ( 2755 0 2 f 2751 )); -DATA(insert ( 2755 0 3 t 2752 )); -DATA(insert ( 2755 0 4 t 1070 )); - -/* - * gin _bpchar_ops - */ -DATA(insert ( 2756 0 1 f 2750 )); -DATA(insert ( 2756 0 2 f 2751 )); -DATA(insert ( 2756 0 3 t 2752 )); -DATA(insert ( 2756 0 4 t 1070 )); - -/* - * gin _bytea_ops - */ -DATA(insert ( 2757 0 1 f 2750 )); -DATA(insert ( 2757 0 2 f 2751 )); -DATA(insert ( 2757 0 3 t 2752 )); -DATA(insert ( 2757 0 4 t 1070 )); - -/* - * gin _char_ops - */ -DATA(insert ( 2758 0 1 f 2750 )); -DATA(insert ( 2758 0 2 f 2751 )); -DATA(insert ( 2758 0 3 t 2752 )); -DATA(insert ( 2758 0 4 t 1070 )); - -/* - * gin _cidr_ops - */ -DATA(insert ( 2759 0 1 f 2750 )); -DATA(insert ( 2759 0 2 f 2751 )); -DATA(insert ( 2759 0 3 t 2752 )); -DATA(insert ( 2759 0 4 t 1070 )); - -/* - * gin _date_ops - */ -DATA(insert ( 2760 0 1 f 2750 )); -DATA(insert ( 2760 0 2 f 2751 )); -DATA(insert ( 2760 0 3 t 2752 )); -DATA(insert ( 2760 0 4 t 1070 )); - -/* - * gin _float4_ops - */ -DATA(insert ( 2761 0 1 f 2750 )); -DATA(insert ( 2761 0 2 f 2751 )); -DATA(insert ( 2761 0 3 t 2752 )); -DATA(insert ( 2761 0 4 t 1070 )); - -/* - * gin _float8_ops - */ -DATA(insert ( 2762 0 1 f 2750 )); -DATA(insert ( 2762 0 2 f 2751 )); -DATA(insert ( 2762 0 3 t 2752 )); -DATA(insert ( 2762 0 4 t 1070 )); - -/* - * gin _inet_ops - */ -DATA(insert ( 2763 0 1 f 2750 )); -DATA(insert ( 2763 0 2 f 2751 )); -DATA(insert ( 2763 0 3 t 2752 )); -DATA(insert ( 2763 0 4 t 1070 )); - -/* - * gin _int2_ops - */ -DATA(insert ( 2764 0 1 f 2750 )); -DATA(insert ( 2764 0 2 f 2751 )); -DATA(insert ( 2764 0 3 t 2752 )); -DATA(insert ( 2764 0 4 t 1070 )); - -/* - * gin _int8_ops - */ -DATA(insert ( 2765 0 1 f 2750 )); -DATA(insert ( 2765 0 2 f 2751 )); -DATA(insert ( 2765 0 3 t 2752 )); -DATA(insert ( 2765 0 4 t 1070 )); - -/* - * gin _interval_ops - */ -DATA(insert ( 2766 0 1 f 2750 )); -DATA(insert ( 2766 0 2 f 2751 )); -DATA(insert ( 2766 0 3 t 2752 )); -DATA(insert ( 2766 0 4 t 1070 )); - -/* - * gin _macaddr_ops - */ -DATA(insert ( 2767 0 1 f 2750 )); -DATA(insert ( 2767 0 2 f 2751 )); -DATA(insert ( 2767 0 3 t 2752 )); -DATA(insert ( 2767 0 4 t 1070 )); - -/* - * gin _name_ops - */ -DATA(insert ( 2768 0 1 f 2750 )); -DATA(insert ( 2768 0 2 f 2751 )); -DATA(insert ( 2768 0 3 t 2752 )); -DATA(insert ( 2768 0 4 t 1070 )); - -/* - * gin _numeric_ops - */ -DATA(insert ( 2769 0 1 f 2750 )); -DATA(insert ( 2769 0 2 f 2751 )); -DATA(insert ( 2769 0 3 t 2752 )); -DATA(insert ( 2769 0 4 t 1070 )); - -/* - * gin _oid_ops - */ -DATA(insert ( 2770 0 1 f 2750 )); -DATA(insert ( 2770 0 2 f 2751 )); -DATA(insert ( 2770 0 3 t 2752 )); -DATA(insert ( 2770 0 4 t 1070 )); - -/* - * gin _oidvector_ops - */ -DATA(insert ( 2771 0 1 f 2750 )); -DATA(insert ( 2771 0 2 f 2751 )); -DATA(insert ( 2771 0 3 t 2752 )); -DATA(insert ( 2771 0 4 t 1070 )); - -/* - * gin _time_ops - */ -DATA(insert ( 2772 0 1 f 2750 )); -DATA(insert ( 2772 0 2 f 2751 )); -DATA(insert ( 2772 0 3 t 2752 )); -DATA(insert ( 2772 0 4 t 1070 )); - -/* - * gin _timestamptz_ops - */ -DATA(insert ( 2773 0 1 f 2750 )); -DATA(insert ( 2773 0 2 f 2751 )); -DATA(insert ( 2773 0 3 t 2752 )); -DATA(insert ( 2773 0 4 t 1070 )); - -/* - * gin _timetz_ops - */ -DATA(insert ( 2774 0 1 f 2750 )); -DATA(insert ( 2774 0 2 f 2751 )); -DATA(insert ( 2774 0 3 t 2752 )); -DATA(insert ( 2774 0 4 t 1070 )); - -/* - * gin _varbit_ops - */ -DATA(insert ( 2775 0 1 f 2750 )); -DATA(insert ( 2775 0 2 f 2751 )); -DATA(insert ( 2775 0 3 t 2752 )); -DATA(insert ( 2775 0 4 t 1070 )); - -/* - * gin _varchar_ops - */ -DATA(insert ( 2776 0 1 f 2750 )); -DATA(insert ( 2776 0 2 f 2751 )); -DATA(insert ( 2776 0 3 t 2752 )); -DATA(insert ( 2776 0 4 t 1070 )); - -/* - * gin _timestamp_ops - */ -DATA(insert ( 2777 0 1 f 2750 )); -DATA(insert ( 2777 0 2 f 2751 )); -DATA(insert ( 2777 0 3 t 2752 )); -DATA(insert ( 2777 0 4 t 1070 )); - -/* - * gin _money_ops - */ -DATA(insert ( 2778 0 1 f 2750 )); -DATA(insert ( 2778 0 2 f 2751 )); -DATA(insert ( 2778 0 3 t 2752 )); -DATA(insert ( 2778 0 4 t 1070 )); - -/* - * gin _reltime_ops - */ -DATA(insert ( 2779 0 1 f 2750 )); -DATA(insert ( 2779 0 2 f 2751 )); -DATA(insert ( 2779 0 3 t 2752 )); -DATA(insert ( 2779 0 4 t 1070 )); - -/* - * gin _tinterval_ops - */ -DATA(insert ( 2780 0 1 f 2750 )); -DATA(insert ( 2780 0 2 f 2751 )); -DATA(insert ( 2780 0 3 t 2752 )); -DATA(insert ( 2780 0 4 t 1070 )); +DATA(insert ( 2745 2277 2277 1 f 2750 2742 )); +DATA(insert ( 2745 2277 2277 2 f 2751 2742 )); +DATA(insert ( 2745 2277 2277 3 t 2752 2742 )); +DATA(insert ( 2745 2277 2277 4 t 1070 2742 )); #endif /* PG_AMOP_H */ diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 291931b707..1f81ff7830 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -5,21 +5,24 @@ * along with the relation's initial contents. * * The amproc table identifies support procedures associated with index - * opclasses. These procedures can't be listed in pg_amop since they are - * not the implementation of any indexable operator for the opclass. + * operator families and classes. These procedures can't be listed in pg_amop + * since they are not the implementation of any indexable operator. * - * The primary key for this table is . - * amprocsubtype is equal to zero for an opclass's "default" procedures. - * Usually a nondefault amprocsubtype indicates a support procedure to be - * used with operators having the same nondefault amopsubtype. The exact - * behavior depends on the index AM, however, and some don't pay attention - * to subtype at all. + * The primary key for this table is . The "default" support functions for a + * particular opclass within the family are those with amproclefttype = + * amprocrighttype = opclass's opcintype. These are the ones loaded into the + * relcache for an index and typically used for internal index operations. + * Other support functions are typically used to handle cross-type indexable + * operators with oprleft/oprright matching the entry's amproclefttype and + * amprocrighttype. The exact behavior depends on the index AM, however, and + * some don't pay attention to non-default functions at all. * * * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.60 2006/10/04 00:30:07 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.61 2006/12/23 00:43:12 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -44,12 +47,13 @@ */ #define AccessMethodProcedureRelationId 2603 -CATALOG(pg_amproc,2603) BKI_WITHOUT_OIDS +CATALOG(pg_amproc,2603) { - Oid amopclaid; /* the index opclass this entry is for */ - Oid amprocsubtype; /* procedure subtype, or zero if default */ - int2 amprocnum; /* support procedure index */ - regproc amproc; /* OID of the proc */ + Oid amprocfamily; /* the index opfamily this entry is for */ + Oid amproclefttype; /* procedure's left input data type */ + Oid amprocrighttype; /* procedure's right input data type */ + int2 amprocnum; /* support procedure index */ + regproc amproc; /* OID of the proc */ } FormData_pg_amproc; /* ---------------- @@ -63,11 +67,12 @@ typedef FormData_pg_amproc *Form_pg_amproc; * compiler constants for pg_amproc * ---------------- */ -#define Natts_pg_amproc 4 -#define Anum_pg_amproc_amopclaid 1 -#define Anum_pg_amproc_amprocsubtype 2 -#define Anum_pg_amproc_amprocnum 3 -#define Anum_pg_amproc_amproc 4 +#define Natts_pg_amproc 5 +#define Anum_pg_amproc_amprocfamily 1 +#define Anum_pg_amproc_amproclefttype 2 +#define Anum_pg_amproc_amprocrighttype 3 +#define Anum_pg_amproc_amprocnum 4 +#define Anum_pg_amproc_amproc 5 /* ---------------- * initial contents of pg_amproc @@ -75,237 +80,223 @@ typedef FormData_pg_amproc *Form_pg_amproc; */ /* btree */ -DATA(insert ( 397 0 1 382 )); -DATA(insert ( 421 0 1 357 )); -DATA(insert ( 423 0 1 1596 )); -DATA(insert ( 424 0 1 1693 )); -DATA(insert ( 426 0 1 1078 )); -DATA(insert ( 428 0 1 1954 )); -DATA(insert ( 429 0 1 358 )); -DATA(insert ( 432 0 1 926 )); -DATA(insert ( 434 0 1 1092 )); -DATA(insert ( 434 1114 1 2344 )); -DATA(insert ( 434 1184 1 2357 )); -DATA(insert ( 1970 0 1 354 )); -DATA(insert ( 1970 701 1 2194 )); -DATA(insert ( 1972 0 1 355 )); -DATA(insert ( 1972 700 1 2195 )); -DATA(insert ( 1974 0 1 926 )); -DATA(insert ( 1976 0 1 350 )); -DATA(insert ( 1976 23 1 2190 )); -DATA(insert ( 1976 20 1 2192 )); -DATA(insert ( 1978 0 1 351 )); -DATA(insert ( 1978 20 1 2188 )); -DATA(insert ( 1978 21 1 2191 )); -DATA(insert ( 1980 0 1 842 )); -DATA(insert ( 1980 23 1 2189 )); -DATA(insert ( 1980 21 1 2193 )); -DATA(insert ( 1982 0 1 1315 )); -DATA(insert ( 1984 0 1 836 )); -DATA(insert ( 1986 0 1 359 )); -DATA(insert ( 1988 0 1 1769 )); -DATA(insert ( 1989 0 1 356 )); -DATA(insert ( 1991 0 1 404 )); -DATA(insert ( 1994 0 1 360 )); -DATA(insert ( 1996 0 1 1107 )); -DATA(insert ( 1998 0 1 1314 )); -DATA(insert ( 1998 1082 1 2383 )); -DATA(insert ( 1998 1114 1 2533 )); -DATA(insert ( 2000 0 1 1358 )); -DATA(insert ( 2002 0 1 1672 )); -DATA(insert ( 2003 0 1 360 )); -DATA(insert ( 2039 0 1 2045 )); -DATA(insert ( 2039 1082 1 2370 )); -DATA(insert ( 2039 1184 1 2526 )); -DATA(insert ( 2095 0 1 2166 )); -DATA(insert ( 2096 0 1 2166 )); -DATA(insert ( 2097 0 1 2180 )); -DATA(insert ( 2098 0 1 2187 )); -DATA(insert ( 2099 0 1 377 )); -DATA(insert ( 2233 0 1 380 )); -DATA(insert ( 2234 0 1 381 )); -DATA(insert ( 2789 0 1 2794 )); +DATA(insert ( 397 2277 2277 1 382 )); +DATA(insert ( 421 702 702 1 357 )); +DATA(insert ( 423 1560 1560 1 1596 )); +DATA(insert ( 424 16 16 1 1693 )); +DATA(insert ( 426 1042 1042 1 1078 )); +DATA(insert ( 428 17 17 1 1954 )); +DATA(insert ( 429 18 18 1 358 )); +DATA(insert ( 434 1082 1082 1 1092 )); +DATA(insert ( 434 1082 1114 1 2344 )); +DATA(insert ( 434 1082 1184 1 2357 )); +DATA(insert ( 434 1114 1114 1 2045 )); +DATA(insert ( 434 1114 1082 1 2370 )); +DATA(insert ( 434 1114 1184 1 2526 )); +DATA(insert ( 434 1184 1184 1 1314 )); +DATA(insert ( 434 1184 1082 1 2383 )); +DATA(insert ( 434 1184 1114 1 2533 )); +DATA(insert ( 1970 700 700 1 354 )); +DATA(insert ( 1970 700 701 1 2194 )); +DATA(insert ( 1970 701 701 1 355 )); +DATA(insert ( 1970 701 700 1 2195 )); +DATA(insert ( 1974 869 869 1 926 )); +DATA(insert ( 1976 21 21 1 350 )); +DATA(insert ( 1976 21 23 1 2190 )); +DATA(insert ( 1976 21 20 1 2192 )); +DATA(insert ( 1976 23 23 1 351 )); +DATA(insert ( 1976 23 20 1 2188 )); +DATA(insert ( 1976 23 21 1 2191 )); +DATA(insert ( 1976 20 20 1 842 )); +DATA(insert ( 1976 20 23 1 2189 )); +DATA(insert ( 1976 20 21 1 2193 )); +DATA(insert ( 1982 1186 1186 1 1315 )); +DATA(insert ( 1984 829 829 1 836 )); +DATA(insert ( 1986 19 19 1 359 )); +DATA(insert ( 1988 1700 1700 1 1769 )); +DATA(insert ( 1989 26 26 1 356 )); +DATA(insert ( 1991 30 30 1 404 )); +DATA(insert ( 1994 25 25 1 360 )); +DATA(insert ( 1996 1083 1083 1 1107 )); +DATA(insert ( 2000 1266 1266 1 1358 )); +DATA(insert ( 2002 1562 1562 1 1672 )); +DATA(insert ( 2095 25 25 1 2166 )); +DATA(insert ( 2097 1042 1042 1 2180 )); +DATA(insert ( 2098 19 19 1 2187 )); +DATA(insert ( 2099 790 790 1 377 )); +DATA(insert ( 2233 703 703 1 380 )); +DATA(insert ( 2234 704 704 1 381 )); +DATA(insert ( 2789 27 27 1 2794 )); /* hash */ -DATA(insert ( 427 0 1 1080 )); -DATA(insert ( 431 0 1 454 )); -DATA(insert ( 433 0 1 422 )); -DATA(insert ( 435 0 1 450 )); -DATA(insert ( 1971 0 1 451 )); -DATA(insert ( 1973 0 1 452 )); -DATA(insert ( 1975 0 1 422 )); -DATA(insert ( 1977 0 1 449 )); -DATA(insert ( 1979 0 1 450 )); -DATA(insert ( 1981 0 1 949 )); -DATA(insert ( 1983 0 1 1697 )); -DATA(insert ( 1985 0 1 399 )); -DATA(insert ( 1987 0 1 455 )); -DATA(insert ( 1990 0 1 453 )); -DATA(insert ( 1992 0 1 457 )); -DATA(insert ( 1995 0 1 400 )); -DATA(insert ( 1997 0 1 452 )); -DATA(insert ( 1999 0 1 452 )); -DATA(insert ( 2001 0 1 1696 )); -DATA(insert ( 2004 0 1 400 )); -DATA(insert ( 2040 0 1 452 )); -DATA(insert ( 2222 0 1 454 )); -DATA(insert ( 2223 0 1 456 )); -DATA(insert ( 2224 0 1 398 )); -DATA(insert ( 2225 0 1 450 )); -DATA(insert ( 2226 0 1 450 )); -DATA(insert ( 2227 0 1 450 )); -DATA(insert ( 2228 0 1 450 )); -DATA(insert ( 2229 0 1 456 )); -DATA(insert ( 2230 0 1 456 )); -DATA(insert ( 2231 0 1 456 )); -DATA(insert ( 2232 0 1 455 )); -DATA(insert ( 2235 0 1 329 )); +DATA(insert ( 427 1042 1042 1 1080 )); +DATA(insert ( 431 18 18 1 454 )); +DATA(insert ( 435 1082 1082 1 450 )); +DATA(insert ( 1971 700 700 1 451 )); +DATA(insert ( 1971 701 701 1 452 )); +DATA(insert ( 1975 869 869 1 422 )); +DATA(insert ( 1977 21 21 1 449 )); +DATA(insert ( 1977 23 23 1 450 )); +DATA(insert ( 1977 20 20 1 949 )); +DATA(insert ( 1983 1186 1186 1 1697 )); +DATA(insert ( 1985 829 829 1 399 )); +DATA(insert ( 1987 19 19 1 455 )); +DATA(insert ( 1990 26 26 1 453 )); +DATA(insert ( 1992 30 30 1 457 )); +DATA(insert ( 1995 25 25 1 400 )); +DATA(insert ( 1997 1083 1083 1 452 )); +DATA(insert ( 1999 1184 1184 1 452 )); +DATA(insert ( 2001 1266 1266 1 1696 )); +DATA(insert ( 2040 1114 1114 1 452 )); +DATA(insert ( 2222 16 16 1 454 )); +DATA(insert ( 2223 17 17 1 456 )); +DATA(insert ( 2224 22 22 1 398 )); +DATA(insert ( 2225 28 28 1 450 )); +DATA(insert ( 2226 29 29 1 450 )); +DATA(insert ( 2227 702 702 1 450 )); +DATA(insert ( 2228 703 703 1 450 )); +DATA(insert ( 2229 25 25 1 456 )); +DATA(insert ( 2231 1042 1042 1 456 )); +DATA(insert ( 2232 19 19 1 455 )); +DATA(insert ( 2235 1033 1033 1 329 )); /* gist */ -DATA(insert ( 2593 0 1 2578 )); -DATA(insert ( 2593 0 2 2583 )); -DATA(insert ( 2593 0 3 2579 )); -DATA(insert ( 2593 0 4 2580 )); -DATA(insert ( 2593 0 5 2581 )); -DATA(insert ( 2593 0 6 2582 )); -DATA(insert ( 2593 0 7 2584 )); -DATA(insert ( 2594 0 1 2585 )); -DATA(insert ( 2594 0 2 2583 )); -DATA(insert ( 2594 0 3 2586 )); -DATA(insert ( 2594 0 4 2580 )); -DATA(insert ( 2594 0 5 2581 )); -DATA(insert ( 2594 0 6 2582 )); -DATA(insert ( 2594 0 7 2584 )); -DATA(insert ( 2595 0 1 2591 )); -DATA(insert ( 2595 0 2 2583 )); -DATA(insert ( 2595 0 3 2592 )); -DATA(insert ( 2595 0 4 2580 )); -DATA(insert ( 2595 0 5 2581 )); -DATA(insert ( 2595 0 6 2582 )); -DATA(insert ( 2595 0 7 2584 )); +DATA(insert ( 2593 603 603 1 2578 )); +DATA(insert ( 2593 603 603 2 2583 )); +DATA(insert ( 2593 603 603 3 2579 )); +DATA(insert ( 2593 603 603 4 2580 )); +DATA(insert ( 2593 603 603 5 2581 )); +DATA(insert ( 2593 603 603 6 2582 )); +DATA(insert ( 2593 603 603 7 2584 )); +DATA(insert ( 2594 604 604 1 2585 )); +DATA(insert ( 2594 604 604 2 2583 )); +DATA(insert ( 2594 604 604 3 2586 )); +DATA(insert ( 2594 604 604 4 2580 )); +DATA(insert ( 2594 604 604 5 2581 )); +DATA(insert ( 2594 604 604 6 2582 )); +DATA(insert ( 2594 604 604 7 2584 )); +DATA(insert ( 2595 718 718 1 2591 )); +DATA(insert ( 2595 718 718 2 2583 )); +DATA(insert ( 2595 718 718 3 2592 )); +DATA(insert ( 2595 718 718 4 2580 )); +DATA(insert ( 2595 718 718 5 2581 )); +DATA(insert ( 2595 718 718 6 2582 )); +DATA(insert ( 2595 718 718 7 2584 )); /* gin */ -DATA(insert ( 2745 0 1 351 )); -DATA(insert ( 2745 0 2 2743 )); -DATA(insert ( 2745 0 3 2743 )); -DATA(insert ( 2745 0 4 2744 )); -DATA(insert ( 2746 0 1 360 )); -DATA(insert ( 2746 0 2 2743 )); -DATA(insert ( 2746 0 3 2743 )); -DATA(insert ( 2746 0 4 2744 )); -DATA(insert ( 2753 0 1 357 )); -DATA(insert ( 2753 0 2 2743 )); -DATA(insert ( 2753 0 3 2743 )); -DATA(insert ( 2753 0 4 2744 )); -DATA(insert ( 2754 0 1 1596 )); -DATA(insert ( 2754 0 2 2743 )); -DATA(insert ( 2754 0 3 2743 )); -DATA(insert ( 2754 0 4 2744 )); -DATA(insert ( 2755 0 1 1693 )); -DATA(insert ( 2755 0 2 2743 )); -DATA(insert ( 2755 0 3 2743 )); -DATA(insert ( 2755 0 4 2744 )); -DATA(insert ( 2756 0 1 1078 )); -DATA(insert ( 2756 0 2 2743 )); -DATA(insert ( 2756 0 3 2743 )); -DATA(insert ( 2756 0 4 2744 )); -DATA(insert ( 2757 0 1 1954 )); -DATA(insert ( 2757 0 2 2743 )); -DATA(insert ( 2757 0 3 2743 )); -DATA(insert ( 2757 0 4 2744 )); -DATA(insert ( 2758 0 1 358 )); -DATA(insert ( 2758 0 2 2743 )); -DATA(insert ( 2758 0 3 2743 )); -DATA(insert ( 2758 0 4 2744 )); -DATA(insert ( 2759 0 1 926 )); -DATA(insert ( 2759 0 2 2743 )); -DATA(insert ( 2759 0 3 2743 )); -DATA(insert ( 2759 0 4 2744 )); -DATA(insert ( 2760 0 1 1092 )); -DATA(insert ( 2760 0 2 2743 )); -DATA(insert ( 2760 0 3 2743 )); -DATA(insert ( 2760 0 4 2744 )); -DATA(insert ( 2761 0 1 354 )); -DATA(insert ( 2761 0 2 2743 )); -DATA(insert ( 2761 0 3 2743 )); -DATA(insert ( 2761 0 4 2744 )); -DATA(insert ( 2762 0 1 355 )); -DATA(insert ( 2762 0 2 2743 )); -DATA(insert ( 2762 0 3 2743 )); -DATA(insert ( 2762 0 4 2744 )); -DATA(insert ( 2763 0 1 926 )); -DATA(insert ( 2763 0 2 2743 )); -DATA(insert ( 2763 0 3 2743 )); -DATA(insert ( 2763 0 4 2744 )); -DATA(insert ( 2764 0 1 350 )); -DATA(insert ( 2764 0 2 2743 )); -DATA(insert ( 2764 0 3 2743 )); -DATA(insert ( 2764 0 4 2744 )); -DATA(insert ( 2765 0 1 842 )); -DATA(insert ( 2765 0 2 2743 )); -DATA(insert ( 2765 0 3 2743 )); -DATA(insert ( 2765 0 4 2744 )); -DATA(insert ( 2766 0 1 1315 )); -DATA(insert ( 2766 0 2 2743 )); -DATA(insert ( 2766 0 3 2743 )); -DATA(insert ( 2766 0 4 2744 )); -DATA(insert ( 2767 0 1 836 )); -DATA(insert ( 2767 0 2 2743 )); -DATA(insert ( 2767 0 3 2743 )); -DATA(insert ( 2767 0 4 2744 )); -DATA(insert ( 2768 0 1 359 )); -DATA(insert ( 2768 0 2 2743 )); -DATA(insert ( 2768 0 3 2743 )); -DATA(insert ( 2768 0 4 2744 )); -DATA(insert ( 2769 0 1 1769 )); -DATA(insert ( 2769 0 2 2743 )); -DATA(insert ( 2769 0 3 2743 )); -DATA(insert ( 2769 0 4 2744 )); -DATA(insert ( 2770 0 1 356 )); -DATA(insert ( 2770 0 2 2743 )); -DATA(insert ( 2770 0 3 2743 )); -DATA(insert ( 2770 0 4 2744 )); -DATA(insert ( 2771 0 1 404 )); -DATA(insert ( 2771 0 2 2743 )); -DATA(insert ( 2771 0 3 2743 )); -DATA(insert ( 2771 0 4 2744 )); -DATA(insert ( 2772 0 1 1107 )); -DATA(insert ( 2772 0 2 2743 )); -DATA(insert ( 2772 0 3 2743 )); -DATA(insert ( 2772 0 4 2744 )); -DATA(insert ( 2773 0 1 1314 )); -DATA(insert ( 2773 0 2 2743 )); -DATA(insert ( 2773 0 3 2743 )); -DATA(insert ( 2773 0 4 2744 )); -DATA(insert ( 2774 0 1 1358 )); -DATA(insert ( 2774 0 2 2743 )); -DATA(insert ( 2774 0 3 2743 )); -DATA(insert ( 2774 0 4 2744 )); -DATA(insert ( 2775 0 1 1672 )); -DATA(insert ( 2775 0 2 2743 )); -DATA(insert ( 2775 0 3 2743 )); -DATA(insert ( 2775 0 4 2744 )); -DATA(insert ( 2776 0 1 360 )); -DATA(insert ( 2776 0 2 2743 )); -DATA(insert ( 2776 0 3 2743 )); -DATA(insert ( 2776 0 4 2744 )); -DATA(insert ( 2777 0 1 2045 )); -DATA(insert ( 2777 0 2 2743 )); -DATA(insert ( 2777 0 3 2743 )); -DATA(insert ( 2777 0 4 2744 )); -DATA(insert ( 2778 0 1 377 )); -DATA(insert ( 2778 0 2 2743 )); -DATA(insert ( 2778 0 3 2743 )); -DATA(insert ( 2778 0 4 2744 )); -DATA(insert ( 2779 0 1 380 )); -DATA(insert ( 2779 0 2 2743 )); -DATA(insert ( 2779 0 3 2743 )); -DATA(insert ( 2779 0 4 2744 )); -DATA(insert ( 2780 0 1 381 )); -DATA(insert ( 2780 0 2 2743 )); -DATA(insert ( 2780 0 3 2743 )); -DATA(insert ( 2780 0 4 2744 )); +DATA(insert ( 2745 1007 1007 1 351 )); +DATA(insert ( 2745 1007 1007 2 2743 )); +DATA(insert ( 2745 1007 1007 3 2743 )); +DATA(insert ( 2745 1007 1007 4 2744 )); +DATA(insert ( 2745 1009 1009 1 360 )); +DATA(insert ( 2745 1009 1009 2 2743 )); +DATA(insert ( 2745 1009 1009 3 2743 )); +DATA(insert ( 2745 1009 1009 4 2744 )); +DATA(insert ( 2745 1023 1023 1 357 )); +DATA(insert ( 2745 1023 1023 2 2743 )); +DATA(insert ( 2745 1023 1023 3 2743 )); +DATA(insert ( 2745 1023 1023 4 2744 )); +DATA(insert ( 2745 1561 1561 1 1596 )); +DATA(insert ( 2745 1561 1561 2 2743 )); +DATA(insert ( 2745 1561 1561 3 2743 )); +DATA(insert ( 2745 1561 1561 4 2744 )); +DATA(insert ( 2745 1000 1000 1 1693 )); +DATA(insert ( 2745 1000 1000 2 2743 )); +DATA(insert ( 2745 1000 1000 3 2743 )); +DATA(insert ( 2745 1000 1000 4 2744 )); +DATA(insert ( 2745 1014 1014 1 1078 )); +DATA(insert ( 2745 1014 1014 2 2743 )); +DATA(insert ( 2745 1014 1014 3 2743 )); +DATA(insert ( 2745 1014 1014 4 2744 )); +DATA(insert ( 2745 1001 1001 1 1954 )); +DATA(insert ( 2745 1001 1001 2 2743 )); +DATA(insert ( 2745 1001 1001 3 2743 )); +DATA(insert ( 2745 1001 1001 4 2744 )); +DATA(insert ( 2745 1002 1002 1 358 )); +DATA(insert ( 2745 1002 1002 2 2743 )); +DATA(insert ( 2745 1002 1002 3 2743 )); +DATA(insert ( 2745 1002 1002 4 2744 )); +DATA(insert ( 2745 1182 1182 1 1092 )); +DATA(insert ( 2745 1182 1182 2 2743 )); +DATA(insert ( 2745 1182 1182 3 2743 )); +DATA(insert ( 2745 1182 1182 4 2744 )); +DATA(insert ( 2745 1021 1021 1 354 )); +DATA(insert ( 2745 1021 1021 2 2743 )); +DATA(insert ( 2745 1021 1021 3 2743 )); +DATA(insert ( 2745 1021 1021 4 2744 )); +DATA(insert ( 2745 1022 1022 1 355 )); +DATA(insert ( 2745 1022 1022 2 2743 )); +DATA(insert ( 2745 1022 1022 3 2743 )); +DATA(insert ( 2745 1022 1022 4 2744 )); +DATA(insert ( 2745 1041 1041 1 926 )); +DATA(insert ( 2745 1041 1041 2 2743 )); +DATA(insert ( 2745 1041 1041 3 2743 )); +DATA(insert ( 2745 1041 1041 4 2744 )); +DATA(insert ( 2745 1005 1005 1 350 )); +DATA(insert ( 2745 1005 1005 2 2743 )); +DATA(insert ( 2745 1005 1005 3 2743 )); +DATA(insert ( 2745 1005 1005 4 2744 )); +DATA(insert ( 2745 1016 1016 1 842 )); +DATA(insert ( 2745 1016 1016 2 2743 )); +DATA(insert ( 2745 1016 1016 3 2743 )); +DATA(insert ( 2745 1016 1016 4 2744 )); +DATA(insert ( 2745 1187 1187 1 1315 )); +DATA(insert ( 2745 1187 1187 2 2743 )); +DATA(insert ( 2745 1187 1187 3 2743 )); +DATA(insert ( 2745 1187 1187 4 2744 )); +DATA(insert ( 2745 1040 1040 1 836 )); +DATA(insert ( 2745 1040 1040 2 2743 )); +DATA(insert ( 2745 1040 1040 3 2743 )); +DATA(insert ( 2745 1040 1040 4 2744 )); +DATA(insert ( 2745 1003 1003 1 359 )); +DATA(insert ( 2745 1003 1003 2 2743 )); +DATA(insert ( 2745 1003 1003 3 2743 )); +DATA(insert ( 2745 1003 1003 4 2744 )); +DATA(insert ( 2745 1231 1231 1 1769 )); +DATA(insert ( 2745 1231 1231 2 2743 )); +DATA(insert ( 2745 1231 1231 3 2743 )); +DATA(insert ( 2745 1231 1231 4 2744 )); +DATA(insert ( 2745 1028 1028 1 356 )); +DATA(insert ( 2745 1028 1028 2 2743 )); +DATA(insert ( 2745 1028 1028 3 2743 )); +DATA(insert ( 2745 1028 1028 4 2744 )); +DATA(insert ( 2745 1013 1013 1 404 )); +DATA(insert ( 2745 1013 1013 2 2743 )); +DATA(insert ( 2745 1013 1013 3 2743 )); +DATA(insert ( 2745 1013 1013 4 2744 )); +DATA(insert ( 2745 1183 1183 1 1107 )); +DATA(insert ( 2745 1183 1183 2 2743 )); +DATA(insert ( 2745 1183 1183 3 2743 )); +DATA(insert ( 2745 1183 1183 4 2744 )); +DATA(insert ( 2745 1185 1185 1 1314 )); +DATA(insert ( 2745 1185 1185 2 2743 )); +DATA(insert ( 2745 1185 1185 3 2743 )); +DATA(insert ( 2745 1185 1185 4 2744 )); +DATA(insert ( 2745 1270 1270 1 1358 )); +DATA(insert ( 2745 1270 1270 2 2743 )); +DATA(insert ( 2745 1270 1270 3 2743 )); +DATA(insert ( 2745 1270 1270 4 2744 )); +DATA(insert ( 2745 1563 1563 1 1672 )); +DATA(insert ( 2745 1563 1563 2 2743 )); +DATA(insert ( 2745 1563 1563 3 2743 )); +DATA(insert ( 2745 1563 1563 4 2744 )); +DATA(insert ( 2745 1115 1115 1 2045 )); +DATA(insert ( 2745 1115 1115 2 2743 )); +DATA(insert ( 2745 1115 1115 3 2743 )); +DATA(insert ( 2745 1115 1115 4 2744 )); +DATA(insert ( 2745 791 791 1 377 )); +DATA(insert ( 2745 791 791 2 2743 )); +DATA(insert ( 2745 791 791 3 2743 )); +DATA(insert ( 2745 791 791 4 2744 )); +DATA(insert ( 2745 1024 1024 1 380 )); +DATA(insert ( 2745 1024 1024 2 2743 )); +DATA(insert ( 2745 1024 1024 3 2743 )); +DATA(insert ( 2745 1024 1024 4 2744 )); +DATA(insert ( 2745 1025 1025 1 381 )); +DATA(insert ( 2745 1025 1025 2 2743 )); +DATA(insert ( 2745 1025 1025 3 2743 )); +DATA(insert ( 2745 1025 1025 4 2744 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index cee9f752bf..8aa9ea3d68 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -4,16 +4,17 @@ * definition of the system "opclass" relation (pg_opclass) * along with the relation's initial contents. * - * New definition for Postgres 7.2: the primary key for this table is - * --- that is, there is a row for each valid combination - * of opclass name and index access method type. This row specifies the - * expected input data type for the opclass (the type of the heap column, - * or the expression output type in the case of an index expression). Note - * that types binary-coercible to the specified type will be accepted too. + * The primary key for this table is --- + * that is, there is a row for each valid combination of opclass name and + * index access method type. This row specifies the expected input data type + * for the opclass (the type of the heap column, or the expression output type + * in the case of an index expression). Note that types binary-coercible to + * the specified type will be accepted too. * - * For a given pair, there can be at most one row that + * For a given pair, there can be at most one row that * has opcdefault = true; this row is the default opclass for such data in - * such an index. + * such an index. (This is not currently enforced by an index, because we + * don't support partial indexes on system catalogs.) * * Normally opckeytype = InvalidOid (zero), indicating that the data stored * in the index is the same as the data in the indexed column. If opckeytype @@ -27,7 +28,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.71 2006/07/21 20:51:33 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.72 2006/12/23 00:43:12 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -54,10 +55,11 @@ CATALOG(pg_opclass,2616) { - Oid opcamid; /* index access method opclass is for */ + Oid opcmethod; /* index access method opclass is for */ NameData opcname; /* name of this opclass */ Oid opcnamespace; /* namespace of this opclass */ Oid opcowner; /* opclass owner */ + Oid opcfamily; /* containing operator family */ Oid opcintype; /* type of data indexed by opclass */ bool opcdefault; /* T if opclass is default for opcintype */ Oid opckeytype; /* type of data in index, or InvalidOid */ @@ -74,138 +76,129 @@ typedef FormData_pg_opclass *Form_pg_opclass; * compiler constants for pg_opclass * ---------------- */ -#define Natts_pg_opclass 7 -#define Anum_pg_opclass_opcamid 1 +#define Natts_pg_opclass 8 +#define Anum_pg_opclass_opcmethod 1 #define Anum_pg_opclass_opcname 2 #define Anum_pg_opclass_opcnamespace 3 #define Anum_pg_opclass_opcowner 4 -#define Anum_pg_opclass_opcintype 5 -#define Anum_pg_opclass_opcdefault 6 -#define Anum_pg_opclass_opckeytype 7 +#define Anum_pg_opclass_opcfamily 5 +#define Anum_pg_opclass_opcintype 6 +#define Anum_pg_opclass_opcdefault 7 +#define Anum_pg_opclass_opckeytype 8 /* ---------------- * initial contents of pg_opclass + * + * Note: we hard-wire an OID only for a few entries that have to be explicitly + * referenced in the C code for bootstrapping purposes. The rest get OIDs + * assigned on-the-fly during initdb. * ---------------- */ -DATA(insert OID = 421 ( 403 abstime_ops PGNSP PGUID 702 t 0 )); -DATA(insert OID = 397 ( 403 array_ops PGNSP PGUID 2277 t 0 )); -#define ARRAY_BTREE_OPS_OID 397 -DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 )); -DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 )); -#define BOOL_BTREE_OPS_OID 424 -DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID 1042 t 0 )); -#define BPCHAR_BTREE_OPS_OID 426 -DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID 1042 t 0 )); -DATA(insert OID = 428 ( 403 bytea_ops PGNSP PGUID 17 t 0 )); -#define BYTEA_BTREE_OPS_OID 428 -DATA(insert OID = 429 ( 403 char_ops PGNSP PGUID 18 t 0 )); -DATA(insert OID = 431 ( 405 char_ops PGNSP PGUID 18 t 0 )); -DATA(insert OID = 432 ( 403 cidr_ops PGNSP PGUID 650 t 0 )); -#define CIDR_BTREE_OPS_OID 432 -DATA(insert OID = 433 ( 405 cidr_ops PGNSP PGUID 650 t 0 )); -DATA(insert OID = 434 ( 403 date_ops PGNSP PGUID 1082 t 0 )); -DATA(insert OID = 435 ( 405 date_ops PGNSP PGUID 1082 t 0 )); -DATA(insert OID = 1970 ( 403 float4_ops PGNSP PGUID 700 t 0 )); -DATA(insert OID = 1971 ( 405 float4_ops PGNSP PGUID 700 t 0 )); -DATA(insert OID = 1972 ( 403 float8_ops PGNSP PGUID 701 t 0 )); -DATA(insert OID = 1973 ( 405 float8_ops PGNSP PGUID 701 t 0 )); -DATA(insert OID = 1974 ( 403 inet_ops PGNSP PGUID 869 t 0 )); -#define INET_BTREE_OPS_OID 1974 -DATA(insert OID = 1975 ( 405 inet_ops PGNSP PGUID 869 t 0 )); -DATA(insert OID = 1976 ( 403 int2_ops PGNSP PGUID 21 t 0 )); -#define INT2_BTREE_OPS_OID 1976 -DATA(insert OID = 1977 ( 405 int2_ops PGNSP PGUID 21 t 0 )); -DATA(insert OID = 1978 ( 403 int4_ops PGNSP PGUID 23 t 0 )); +DATA(insert ( 403 abstime_ops PGNSP PGUID 421 702 t 0 )); +DATA(insert ( 403 array_ops PGNSP PGUID 397 2277 t 0 )); +DATA(insert ( 403 bit_ops PGNSP PGUID 423 1560 t 0 )); +DATA(insert ( 403 bool_ops PGNSP PGUID 424 16 t 0 )); +DATA(insert ( 403 bpchar_ops PGNSP PGUID 426 1042 t 0 )); +DATA(insert ( 405 bpchar_ops PGNSP PGUID 427 1042 t 0 )); +DATA(insert ( 403 bytea_ops PGNSP PGUID 428 17 t 0 )); +DATA(insert ( 403 char_ops PGNSP PGUID 429 18 t 0 )); +DATA(insert ( 405 char_ops PGNSP PGUID 431 18 t 0 )); +DATA(insert ( 403 cidr_ops PGNSP PGUID 1974 869 f 0 )); +DATA(insert ( 405 cidr_ops PGNSP PGUID 1975 869 f 0 )); +DATA(insert ( 403 date_ops PGNSP PGUID 434 1082 t 0 )); +DATA(insert ( 405 date_ops PGNSP PGUID 435 1082 t 0 )); +DATA(insert ( 403 float4_ops PGNSP PGUID 1970 700 t 0 )); +DATA(insert ( 405 float4_ops PGNSP PGUID 1971 700 t 0 )); +DATA(insert ( 403 float8_ops PGNSP PGUID 1970 701 t 0 )); +DATA(insert ( 405 float8_ops PGNSP PGUID 1971 701 t 0 )); +DATA(insert ( 403 inet_ops PGNSP PGUID 1974 869 t 0 )); +DATA(insert ( 405 inet_ops PGNSP PGUID 1975 869 t 0 )); +DATA(insert OID = 1979 ( 403 int2_ops PGNSP PGUID 1976 21 t 0 )); +#define INT2_BTREE_OPS_OID 1979 +DATA(insert ( 405 int2_ops PGNSP PGUID 1977 21 t 0 )); +DATA(insert OID = 1978 ( 403 int4_ops PGNSP PGUID 1976 23 t 0 )); #define INT4_BTREE_OPS_OID 1978 -DATA(insert OID = 1979 ( 405 int4_ops PGNSP PGUID 23 t 0 )); -DATA(insert OID = 1980 ( 403 int8_ops PGNSP PGUID 20 t 0 )); -DATA(insert OID = 1981 ( 405 int8_ops PGNSP PGUID 20 t 0 )); -DATA(insert OID = 1982 ( 403 interval_ops PGNSP PGUID 1186 t 0 )); -DATA(insert OID = 1983 ( 405 interval_ops PGNSP PGUID 1186 t 0 )); -DATA(insert OID = 1984 ( 403 macaddr_ops PGNSP PGUID 829 t 0 )); -DATA(insert OID = 1985 ( 405 macaddr_ops PGNSP PGUID 829 t 0 )); -DATA(insert OID = 1986 ( 403 name_ops PGNSP PGUID 19 t 0 )); -#define NAME_BTREE_OPS_OID 1986 -DATA(insert OID = 1987 ( 405 name_ops PGNSP PGUID 19 t 0 )); -DATA(insert OID = 1988 ( 403 numeric_ops PGNSP PGUID 1700 t 0 )); -DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID 26 t 0 )); -#define OID_BTREE_OPS_OID 1989 -DATA(insert OID = 1990 ( 405 oid_ops PGNSP PGUID 26 t 0 )); -DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID 30 t 0 )); -DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID 30 t 0 )); -DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID 25 t 0 )); -#define TEXT_BTREE_OPS_OID 1994 -DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID 25 t 0 )); -DATA(insert OID = 1996 ( 403 time_ops PGNSP PGUID 1083 t 0 )); -DATA(insert OID = 1997 ( 405 time_ops PGNSP PGUID 1083 t 0 )); -DATA(insert OID = 1998 ( 403 timestamptz_ops PGNSP PGUID 1184 t 0 )); -DATA(insert OID = 1999 ( 405 timestamptz_ops PGNSP PGUID 1184 t 0 )); -DATA(insert OID = 2000 ( 403 timetz_ops PGNSP PGUID 1266 t 0 )); -DATA(insert OID = 2001 ( 405 timetz_ops PGNSP PGUID 1266 t 0 )); -DATA(insert OID = 2002 ( 403 varbit_ops PGNSP PGUID 1562 t 0 )); -DATA(insert OID = 2003 ( 403 varchar_ops PGNSP PGUID 1043 t 0 )); -#define VARCHAR_BTREE_OPS_OID 2003 -DATA(insert OID = 2004 ( 405 varchar_ops PGNSP PGUID 1043 t 0 )); -DATA(insert OID = 2039 ( 403 timestamp_ops PGNSP PGUID 1114 t 0 )); -DATA(insert OID = 2040 ( 405 timestamp_ops PGNSP PGUID 1114 t 0 )); -DATA(insert OID = 2095 ( 403 text_pattern_ops PGNSP PGUID 25 f 0 )); -#define TEXT_PATTERN_BTREE_OPS_OID 2095 -DATA(insert OID = 2096 ( 403 varchar_pattern_ops PGNSP PGUID 1043 f 0 )); -#define VARCHAR_PATTERN_BTREE_OPS_OID 2096 -DATA(insert OID = 2097 ( 403 bpchar_pattern_ops PGNSP PGUID 1042 f 0 )); -#define BPCHAR_PATTERN_BTREE_OPS_OID 2097 -DATA(insert OID = 2098 ( 403 name_pattern_ops PGNSP PGUID 19 f 0 )); -#define NAME_PATTERN_BTREE_OPS_OID 2098 -DATA(insert OID = 2099 ( 403 money_ops PGNSP PGUID 790 t 0 )); -DATA(insert OID = 2222 ( 405 bool_ops PGNSP PGUID 16 t 0 )); -#define BOOL_HASH_OPS_OID 2222 -DATA(insert OID = 2223 ( 405 bytea_ops PGNSP PGUID 17 t 0 )); -DATA(insert OID = 2224 ( 405 int2vector_ops PGNSP PGUID 22 t 0 )); -DATA(insert OID = 2789 ( 403 tid_ops PGNSP PGUID 27 t 0 )); -DATA(insert OID = 2225 ( 405 xid_ops PGNSP PGUID 28 t 0 )); -DATA(insert OID = 2226 ( 405 cid_ops PGNSP PGUID 29 t 0 )); -DATA(insert OID = 2227 ( 405 abstime_ops PGNSP PGUID 702 t 0 )); -DATA(insert OID = 2228 ( 405 reltime_ops PGNSP PGUID 703 t 0 )); -DATA(insert OID = 2229 ( 405 text_pattern_ops PGNSP PGUID 25 f 0 )); -DATA(insert OID = 2230 ( 405 varchar_pattern_ops PGNSP PGUID 1043 f 0 )); -DATA(insert OID = 2231 ( 405 bpchar_pattern_ops PGNSP PGUID 1042 f 0 )); -DATA(insert OID = 2232 ( 405 name_pattern_ops PGNSP PGUID 19 f 0 )); -DATA(insert OID = 2233 ( 403 reltime_ops PGNSP PGUID 703 t 0 )); -DATA(insert OID = 2234 ( 403 tinterval_ops PGNSP PGUID 704 t 0 )); -DATA(insert OID = 2235 ( 405 aclitem_ops PGNSP PGUID 1033 t 0 )); -DATA(insert OID = 2593 ( 783 box_ops PGNSP PGUID 603 t 0 )); -DATA(insert OID = 2594 ( 783 poly_ops PGNSP PGUID 604 t 603 )); -DATA(insert OID = 2595 ( 783 circle_ops PGNSP PGUID 718 t 603 )); -DATA(insert OID = 2745 ( 2742 _int4_ops PGNSP PGUID 1007 t 23 )); -DATA(insert OID = 2746 ( 2742 _text_ops PGNSP PGUID 1009 t 25 )); -DATA(insert OID = 2753 ( 2742 _abstime_ops PGNSP PGUID 1023 t 702 )); -DATA(insert OID = 2754 ( 2742 _bit_ops PGNSP PGUID 1561 t 1560 )); -DATA(insert OID = 2755 ( 2742 _bool_ops PGNSP PGUID 1000 t 16 )); -DATA(insert OID = 2756 ( 2742 _bpchar_ops PGNSP PGUID 1014 t 1042 )); -DATA(insert OID = 2757 ( 2742 _bytea_ops PGNSP PGUID 1001 t 17 )); -DATA(insert OID = 2758 ( 2742 _char_ops PGNSP PGUID 1002 t 18 )); -DATA(insert OID = 2759 ( 2742 _cidr_ops PGNSP PGUID 651 t 650 )); -DATA(insert OID = 2760 ( 2742 _date_ops PGNSP PGUID 1182 t 1082 )); -DATA(insert OID = 2761 ( 2742 _float4_ops PGNSP PGUID 1021 t 700 )); -DATA(insert OID = 2762 ( 2742 _float8_ops PGNSP PGUID 1022 t 701 )); -DATA(insert OID = 2763 ( 2742 _inet_ops PGNSP PGUID 1041 t 869 )); -DATA(insert OID = 2764 ( 2742 _int2_ops PGNSP PGUID 1005 t 21 )); -DATA(insert OID = 2765 ( 2742 _int8_ops PGNSP PGUID 1016 t 20 )); -DATA(insert OID = 2766 ( 2742 _interval_ops PGNSP PGUID 1187 t 1186 )); -DATA(insert OID = 2767 ( 2742 _macaddr_ops PGNSP PGUID 1040 t 829 )); -DATA(insert OID = 2768 ( 2742 _name_ops PGNSP PGUID 1003 t 19 )); -DATA(insert OID = 2769 ( 2742 _numeric_ops PGNSP PGUID 1231 t 1700 )); -DATA(insert OID = 2770 ( 2742 _oid_ops PGNSP PGUID 1028 t 26 )); -DATA(insert OID = 2771 ( 2742 _oidvector_ops PGNSP PGUID 1013 t 30 )); -DATA(insert OID = 2772 ( 2742 _time_ops PGNSP PGUID 1183 t 1083 )); -DATA(insert OID = 2773 ( 2742 _timestamptz_ops PGNSP PGUID 1185 t 1184 )); -DATA(insert OID = 2774 ( 2742 _timetz_ops PGNSP PGUID 1270 t 1266 )); -DATA(insert OID = 2775 ( 2742 _varbit_ops PGNSP PGUID 1563 t 1562 )); -DATA(insert OID = 2776 ( 2742 _varchar_ops PGNSP PGUID 1015 t 1043 )); -DATA(insert OID = 2777 ( 2742 _timestamp_ops PGNSP PGUID 1115 t 1114 )); -DATA(insert OID = 2778 ( 2742 _money_ops PGNSP PGUID 791 t 790 )); -DATA(insert OID = 2779 ( 2742 _reltime_ops PGNSP PGUID 1024 t 703 )); -DATA(insert OID = 2780 ( 2742 _tinterval_ops PGNSP PGUID 1025 t 704 )); +DATA(insert ( 405 int4_ops PGNSP PGUID 1977 23 t 0 )); +DATA(insert ( 403 int8_ops PGNSP PGUID 1976 20 t 0 )); +DATA(insert ( 405 int8_ops PGNSP PGUID 1977 20 t 0 )); +DATA(insert ( 403 interval_ops PGNSP PGUID 1982 1186 t 0 )); +DATA(insert ( 405 interval_ops PGNSP PGUID 1983 1186 t 0 )); +DATA(insert ( 403 macaddr_ops PGNSP PGUID 1984 829 t 0 )); +DATA(insert ( 405 macaddr_ops PGNSP PGUID 1985 829 t 0 )); +DATA(insert ( 403 name_ops PGNSP PGUID 1986 19 t 0 )); +DATA(insert ( 405 name_ops PGNSP PGUID 1987 19 t 0 )); +DATA(insert ( 403 numeric_ops PGNSP PGUID 1988 1700 t 0 )); +DATA(insert OID = 1981 ( 403 oid_ops PGNSP PGUID 1989 26 t 0 )); +#define OID_BTREE_OPS_OID 1981 +DATA(insert ( 405 oid_ops PGNSP PGUID 1990 26 t 0 )); +DATA(insert ( 403 oidvector_ops PGNSP PGUID 1991 30 t 0 )); +DATA(insert ( 405 oidvector_ops PGNSP PGUID 1992 30 t 0 )); +DATA(insert ( 403 text_ops PGNSP PGUID 1994 25 t 0 )); +DATA(insert ( 405 text_ops PGNSP PGUID 1995 25 t 0 )); +DATA(insert ( 403 time_ops PGNSP PGUID 1996 1083 t 0 )); +DATA(insert ( 405 time_ops PGNSP PGUID 1997 1083 t 0 )); +DATA(insert ( 403 timestamptz_ops PGNSP PGUID 434 1184 t 0 )); +DATA(insert ( 405 timestamptz_ops PGNSP PGUID 1999 1184 t 0 )); +DATA(insert ( 403 timetz_ops PGNSP PGUID 2000 1266 t 0 )); +DATA(insert ( 405 timetz_ops PGNSP PGUID 2001 1266 t 0 )); +DATA(insert ( 403 varbit_ops PGNSP PGUID 2002 1562 t 0 )); +DATA(insert ( 403 varchar_ops PGNSP PGUID 1994 25 f 0 )); +DATA(insert ( 405 varchar_ops PGNSP PGUID 1995 25 f 0 )); +DATA(insert ( 403 timestamp_ops PGNSP PGUID 434 1114 t 0 )); +DATA(insert ( 405 timestamp_ops PGNSP PGUID 2040 1114 t 0 )); +DATA(insert ( 403 text_pattern_ops PGNSP PGUID 2095 25 f 0 )); +DATA(insert ( 403 varchar_pattern_ops PGNSP PGUID 2095 25 f 0 )); +DATA(insert ( 403 bpchar_pattern_ops PGNSP PGUID 2097 1042 f 0 )); +DATA(insert ( 403 name_pattern_ops PGNSP PGUID 2098 19 f 0 )); +DATA(insert ( 403 money_ops PGNSP PGUID 2099 790 t 0 )); +DATA(insert ( 405 bool_ops PGNSP PGUID 2222 16 t 0 )); +DATA(insert ( 405 bytea_ops PGNSP PGUID 2223 17 t 0 )); +DATA(insert ( 405 int2vector_ops PGNSP PGUID 2224 22 t 0 )); +DATA(insert ( 403 tid_ops PGNSP PGUID 2789 27 t 0 )); +DATA(insert ( 405 xid_ops PGNSP PGUID 2225 28 t 0 )); +DATA(insert ( 405 cid_ops PGNSP PGUID 2226 29 t 0 )); +DATA(insert ( 405 abstime_ops PGNSP PGUID 2227 702 t 0 )); +DATA(insert ( 405 reltime_ops PGNSP PGUID 2228 703 t 0 )); +DATA(insert ( 405 text_pattern_ops PGNSP PGUID 2229 25 f 0 )); +DATA(insert ( 405 varchar_pattern_ops PGNSP PGUID 2229 25 f 0 )); +DATA(insert ( 405 bpchar_pattern_ops PGNSP PGUID 2231 1042 f 0 )); +DATA(insert ( 405 name_pattern_ops PGNSP PGUID 2232 19 f 0 )); +DATA(insert ( 403 reltime_ops PGNSP PGUID 2233 703 t 0 )); +DATA(insert ( 403 tinterval_ops PGNSP PGUID 2234 704 t 0 )); +DATA(insert ( 405 aclitem_ops PGNSP PGUID 2235 1033 t 0 )); +DATA(insert ( 783 box_ops PGNSP PGUID 2593 603 t 0 )); +DATA(insert ( 783 poly_ops PGNSP PGUID 2594 604 t 603 )); +DATA(insert ( 783 circle_ops PGNSP PGUID 2595 718 t 603 )); +DATA(insert ( 2742 _int4_ops PGNSP PGUID 2745 1007 t 23 )); +DATA(insert ( 2742 _text_ops PGNSP PGUID 2745 1009 t 25 )); +DATA(insert ( 2742 _abstime_ops PGNSP PGUID 2745 1023 t 702 )); +DATA(insert ( 2742 _bit_ops PGNSP PGUID 2745 1561 t 1560 )); +DATA(insert ( 2742 _bool_ops PGNSP PGUID 2745 1000 t 16 )); +DATA(insert ( 2742 _bpchar_ops PGNSP PGUID 2745 1014 t 1042 )); +DATA(insert ( 2742 _bytea_ops PGNSP PGUID 2745 1001 t 17 )); +DATA(insert ( 2742 _char_ops PGNSP PGUID 2745 1002 t 18 )); +DATA(insert ( 2742 _cidr_ops PGNSP PGUID 2745 651 t 650 )); +DATA(insert ( 2742 _date_ops PGNSP PGUID 2745 1182 t 1082 )); +DATA(insert ( 2742 _float4_ops PGNSP PGUID 2745 1021 t 700 )); +DATA(insert ( 2742 _float8_ops PGNSP PGUID 2745 1022 t 701 )); +DATA(insert ( 2742 _inet_ops PGNSP PGUID 2745 1041 t 869 )); +DATA(insert ( 2742 _int2_ops PGNSP PGUID 2745 1005 t 21 )); +DATA(insert ( 2742 _int8_ops PGNSP PGUID 2745 1016 t 20 )); +DATA(insert ( 2742 _interval_ops PGNSP PGUID 2745 1187 t 1186 )); +DATA(insert ( 2742 _macaddr_ops PGNSP PGUID 2745 1040 t 829 )); +DATA(insert ( 2742 _name_ops PGNSP PGUID 2745 1003 t 19 )); +DATA(insert ( 2742 _numeric_ops PGNSP PGUID 2745 1231 t 1700 )); +DATA(insert ( 2742 _oid_ops PGNSP PGUID 2745 1028 t 26 )); +DATA(insert ( 2742 _oidvector_ops PGNSP PGUID 2745 1013 t 30 )); +DATA(insert ( 2742 _time_ops PGNSP PGUID 2745 1183 t 1083 )); +DATA(insert ( 2742 _timestamptz_ops PGNSP PGUID 2745 1185 t 1184 )); +DATA(insert ( 2742 _timetz_ops PGNSP PGUID 2745 1270 t 1266 )); +DATA(insert ( 2742 _varbit_ops PGNSP PGUID 2745 1563 t 1562 )); +DATA(insert ( 2742 _varchar_ops PGNSP PGUID 2745 1015 t 1043 )); +DATA(insert ( 2742 _timestamp_ops PGNSP PGUID 2745 1115 t 1114 )); +DATA(insert ( 2742 _money_ops PGNSP PGUID 2745 791 t 790 )); +DATA(insert ( 2742 _reltime_ops PGNSP PGUID 2745 1024 t 703 )); +DATA(insert ( 2742 _tinterval_ops PGNSP PGUID 2745 1025 t 704 )); #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index b64b3c5136..b2acdc425b 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.146 2006/10/04 00:30:07 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.147 2006/12/23 00:43:12 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -44,16 +44,13 @@ CATALOG(pg_operator,2617) Oid oprnamespace; /* OID of namespace containing this oper */ Oid oprowner; /* operator owner */ char oprkind; /* 'l', 'r', or 'b' */ + bool oprcanmerge; /* can be used in merge join? */ bool oprcanhash; /* can be used in hash join? */ Oid oprleft; /* left arg type, or 0 if 'l' oprkind */ Oid oprright; /* right arg type, or 0 if 'r' oprkind */ Oid oprresult; /* result datatype */ Oid oprcom; /* OID of commutator oper, or 0 if none */ Oid oprnegate; /* OID of negator oper, or 0 if none */ - Oid oprlsortop; /* OID of left sortop, if mergejoinable */ - Oid oprrsortop; /* OID of right sortop, if mergejoinable */ - Oid oprltcmpop; /* OID of "lr" oper, if mergejoinable */ regproc oprcode; /* OID of underlying function */ regproc oprrest; /* OID of restriction estimator, or 0 */ regproc oprjoin; /* OID of join estimator, or 0 */ @@ -71,837 +68,832 @@ typedef FormData_pg_operator *Form_pg_operator; * ---------------- */ -#define Natts_pg_operator 17 +#define Natts_pg_operator 14 #define Anum_pg_operator_oprname 1 #define Anum_pg_operator_oprnamespace 2 #define Anum_pg_operator_oprowner 3 #define Anum_pg_operator_oprkind 4 -#define Anum_pg_operator_oprcanhash 5 -#define Anum_pg_operator_oprleft 6 -#define Anum_pg_operator_oprright 7 -#define Anum_pg_operator_oprresult 8 -#define Anum_pg_operator_oprcom 9 -#define Anum_pg_operator_oprnegate 10 -#define Anum_pg_operator_oprlsortop 11 -#define Anum_pg_operator_oprrsortop 12 -#define Anum_pg_operator_oprltcmpop 13 -#define Anum_pg_operator_oprgtcmpop 14 -#define Anum_pg_operator_oprcode 15 -#define Anum_pg_operator_oprrest 16 -#define Anum_pg_operator_oprjoin 17 +#define Anum_pg_operator_oprcanmerge 5 +#define Anum_pg_operator_oprcanhash 6 +#define Anum_pg_operator_oprleft 7 +#define Anum_pg_operator_oprright 8 +#define Anum_pg_operator_oprresult 9 +#define Anum_pg_operator_oprcom 10 +#define Anum_pg_operator_oprnegate 11 +#define Anum_pg_operator_oprcode 12 +#define Anum_pg_operator_oprrest 13 +#define Anum_pg_operator_oprjoin 14 /* ---------------- * initial contents of pg_operator * ---------------- */ -DATA(insert OID = 15 ( "=" PGNSP PGUID b f 23 20 16 416 36 97 412 37 76 int48eq eqsel eqjoinsel )); -DATA(insert OID = 36 ( "<>" PGNSP PGUID b f 23 20 16 417 15 0 0 0 0 int48ne neqsel neqjoinsel )); -DATA(insert OID = 37 ( "<" PGNSP PGUID b f 23 20 16 419 82 0 0 0 0 int48lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 76 ( ">" PGNSP PGUID b f 23 20 16 418 80 0 0 0 0 int48gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 80 ( "<=" PGNSP PGUID b f 23 20 16 430 76 0 0 0 0 int48le scalarltsel scalarltjoinsel )); -DATA(insert OID = 82 ( ">=" PGNSP PGUID b f 23 20 16 420 37 0 0 0 0 int48ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 15 ( "=" PGNSP PGUID b t f 23 20 16 416 36 int48eq eqsel eqjoinsel )); +DATA(insert OID = 36 ( "<>" PGNSP PGUID b f f 23 20 16 417 15 int48ne neqsel neqjoinsel )); +DATA(insert OID = 37 ( "<" PGNSP PGUID b f f 23 20 16 419 82 int48lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 76 ( ">" PGNSP PGUID b f f 23 20 16 418 80 int48gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 80 ( "<=" PGNSP PGUID b f f 23 20 16 430 76 int48le scalarltsel scalarltjoinsel )); +DATA(insert OID = 82 ( ">=" PGNSP PGUID b f f 23 20 16 420 37 int48ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 58 ( "<" PGNSP PGUID b f 16 16 16 59 1695 0 0 0 0 boollt scalarltsel scalarltjoinsel )); -DATA(insert OID = 59 ( ">" PGNSP PGUID b f 16 16 16 58 1694 0 0 0 0 boolgt scalargtsel scalargtjoinsel )); -DATA(insert OID = 85 ( "<>" PGNSP PGUID b f 16 16 16 85 91 0 0 0 0 boolne neqsel neqjoinsel )); -DATA(insert OID = 91 ( "=" PGNSP PGUID b t 16 16 16 91 85 58 58 58 59 booleq eqsel eqjoinsel )); +DATA(insert OID = 58 ( "<" PGNSP PGUID b f f 16 16 16 59 1695 boollt scalarltsel scalarltjoinsel )); +DATA(insert OID = 59 ( ">" PGNSP PGUID b f f 16 16 16 58 1694 boolgt scalargtsel scalargtjoinsel )); +DATA(insert OID = 85 ( "<>" PGNSP PGUID b f f 16 16 16 85 91 boolne neqsel neqjoinsel )); +DATA(insert OID = 91 ( "=" PGNSP PGUID b t t 16 16 16 91 85 booleq eqsel eqjoinsel )); #define BooleanEqualOperator 91 -DATA(insert OID = 1694 ( "<=" PGNSP PGUID b f 16 16 16 1695 59 0 0 0 0 boolle scalarltsel scalarltjoinsel )); -DATA(insert OID = 1695 ( ">=" PGNSP PGUID b f 16 16 16 1694 58 0 0 0 0 boolge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1694 ( "<=" PGNSP PGUID b f f 16 16 16 1695 59 boolle scalarltsel scalarltjoinsel )); +DATA(insert OID = 1695 ( ">=" PGNSP PGUID b f f 16 16 16 1694 58 boolge scalargtsel scalargtjoinsel )); -DATA(insert OID = 92 ( "=" PGNSP PGUID b t 18 18 16 92 630 631 631 631 633 chareq eqsel eqjoinsel )); -DATA(insert OID = 93 ( "=" PGNSP PGUID b t 19 19 16 93 643 660 660 660 662 nameeq eqsel eqjoinsel )); -DATA(insert OID = 94 ( "=" PGNSP PGUID b t 21 21 16 94 519 95 95 95 520 int2eq eqsel eqjoinsel )); -DATA(insert OID = 95 ( "<" PGNSP PGUID b f 21 21 16 520 524 0 0 0 0 int2lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 96 ( "=" PGNSP PGUID b t 23 23 16 96 518 97 97 97 521 int4eq eqsel eqjoinsel )); -DATA(insert OID = 97 ( "<" PGNSP PGUID b f 23 23 16 521 525 0 0 0 0 int4lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 98 ( "=" PGNSP PGUID b t 25 25 16 98 531 664 664 664 666 texteq eqsel eqjoinsel )); +DATA(insert OID = 92 ( "=" PGNSP PGUID b t t 18 18 16 92 630 chareq eqsel eqjoinsel )); +DATA(insert OID = 93 ( "=" PGNSP PGUID b t t 19 19 16 93 643 nameeq eqsel eqjoinsel )); +DATA(insert OID = 94 ( "=" PGNSP PGUID b t t 21 21 16 94 519 int2eq eqsel eqjoinsel )); +DATA(insert OID = 95 ( "<" PGNSP PGUID b f f 21 21 16 520 524 int2lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 96 ( "=" PGNSP PGUID b t t 23 23 16 96 518 int4eq eqsel eqjoinsel )); +DATA(insert OID = 97 ( "<" PGNSP PGUID b f f 23 23 16 521 525 int4lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 98 ( "=" PGNSP PGUID b t t 25 25 16 98 531 texteq eqsel eqjoinsel )); -DATA(insert OID = 349 ( "||" PGNSP PGUID b f 2277 2283 2277 0 0 0 0 0 0 array_append - - )); -DATA(insert OID = 374 ( "||" PGNSP PGUID b f 2283 2277 2277 0 0 0 0 0 0 array_prepend - - )); -DATA(insert OID = 375 ( "||" PGNSP PGUID b f 2277 2277 2277 0 0 0 0 0 0 array_cat - - )); +DATA(insert OID = 349 ( "||" PGNSP PGUID b f f 2277 2283 2277 0 0 array_append - - )); +DATA(insert OID = 374 ( "||" PGNSP PGUID b f f 2283 2277 2277 0 0 array_prepend - - )); +DATA(insert OID = 375 ( "||" PGNSP PGUID b f f 2277 2277 2277 0 0 array_cat - - )); -DATA(insert OID = 352 ( "=" PGNSP PGUID b t 28 28 16 352 0 0 0 0 0 xideq eqsel eqjoinsel )); -DATA(insert OID = 353 ( "=" PGNSP PGUID b f 28 23 16 0 0 0 0 0 0 xideqint4 eqsel eqjoinsel )); -DATA(insert OID = 388 ( "!" PGNSP PGUID r f 20 0 1700 0 0 0 0 0 0 numeric_fac - - )); -DATA(insert OID = 389 ( "!!" PGNSP PGUID l f 0 20 1700 0 0 0 0 0 0 numeric_fac - - )); -DATA(insert OID = 385 ( "=" PGNSP PGUID b t 29 29 16 385 0 0 0 0 0 cideq eqsel eqjoinsel )); -DATA(insert OID = 386 ( "=" PGNSP PGUID b t 22 22 16 386 0 0 0 0 0 int2vectoreq eqsel eqjoinsel )); +DATA(insert OID = 352 ( "=" PGNSP PGUID b f t 28 28 16 352 0 xideq eqsel eqjoinsel )); +DATA(insert OID = 353 ( "=" PGNSP PGUID b f f 28 23 16 0 0 xideqint4 eqsel eqjoinsel )); +DATA(insert OID = 388 ( "!" PGNSP PGUID r f f 20 0 1700 0 0 numeric_fac - - )); +DATA(insert OID = 389 ( "!!" PGNSP PGUID l f f 0 20 1700 0 0 numeric_fac - - )); +DATA(insert OID = 385 ( "=" PGNSP PGUID b f t 29 29 16 385 0 cideq eqsel eqjoinsel )); +DATA(insert OID = 386 ( "=" PGNSP PGUID b f t 22 22 16 386 0 int2vectoreq eqsel eqjoinsel )); -DATA(insert OID = 387 ( "=" PGNSP PGUID b f 27 27 16 387 402 2799 2799 2799 2800 tideq eqsel eqjoinsel )); +DATA(insert OID = 387 ( "=" PGNSP PGUID b t f 27 27 16 387 402 tideq eqsel eqjoinsel )); #define TIDEqualOperator 387 -DATA(insert OID = 402 ( "<>" PGNSP PGUID b f 27 27 16 402 387 0 0 0 0 tidne neqsel neqjoinsel )); -DATA(insert OID = 2799 ( "<" PGNSP PGUID b f 27 27 16 2800 2802 0 0 0 0 tidlt scalarltsel scalarltjoinsel )); +DATA(insert OID = 402 ( "<>" PGNSP PGUID b f f 27 27 16 402 387 tidne neqsel neqjoinsel )); +DATA(insert OID = 2799 ( "<" PGNSP PGUID b f f 27 27 16 2800 2802 tidlt scalarltsel scalarltjoinsel )); #define TIDLessOperator 2799 -DATA(insert OID = 2800 ( ">" PGNSP PGUID b f 27 27 16 2799 2801 0 0 0 0 tidgt scalargtsel scalargtjoinsel )); -DATA(insert OID = 2801 ( "<=" PGNSP PGUID b f 27 27 16 2802 2800 0 0 0 0 tidle scalarltsel scalarltjoinsel )); -DATA(insert OID = 2802 ( ">=" PGNSP PGUID b f 27 27 16 2801 2799 0 0 0 0 tidge scalargtsel scalargtjoinsel )); +DATA(insert OID = 2800 ( ">" PGNSP PGUID b f f 27 27 16 2799 2801 tidgt scalargtsel scalargtjoinsel )); +DATA(insert OID = 2801 ( "<=" PGNSP PGUID b f f 27 27 16 2802 2800 tidle scalarltsel scalarltjoinsel )); +DATA(insert OID = 2802 ( ">=" PGNSP PGUID b f f 27 27 16 2801 2799 tidge scalargtsel scalargtjoinsel )); -DATA(insert OID = 410 ( "=" PGNSP PGUID b t 20 20 16 410 411 412 412 412 413 int8eq eqsel eqjoinsel )); -DATA(insert OID = 411 ( "<>" PGNSP PGUID b f 20 20 16 411 410 0 0 0 0 int8ne neqsel neqjoinsel )); -DATA(insert OID = 412 ( "<" PGNSP PGUID b f 20 20 16 413 415 0 0 0 0 int8lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 413 ( ">" PGNSP PGUID b f 20 20 16 412 414 0 0 0 0 int8gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 414 ( "<=" PGNSP PGUID b f 20 20 16 415 413 0 0 0 0 int8le scalarltsel scalarltjoinsel )); -DATA(insert OID = 415 ( ">=" PGNSP PGUID b f 20 20 16 414 412 0 0 0 0 int8ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 410 ( "=" PGNSP PGUID b t t 20 20 16 410 411 int8eq eqsel eqjoinsel )); +DATA(insert OID = 411 ( "<>" PGNSP PGUID b f f 20 20 16 411 410 int8ne neqsel neqjoinsel )); +DATA(insert OID = 412 ( "<" PGNSP PGUID b f f 20 20 16 413 415 int8lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 413 ( ">" PGNSP PGUID b f f 20 20 16 412 414 int8gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 414 ( "<=" PGNSP PGUID b f f 20 20 16 415 413 int8le scalarltsel scalarltjoinsel )); +DATA(insert OID = 415 ( ">=" PGNSP PGUID b f f 20 20 16 414 412 int8ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 416 ( "=" PGNSP PGUID b f 20 23 16 15 417 412 97 418 419 int84eq eqsel eqjoinsel )); -DATA(insert OID = 417 ( "<>" PGNSP PGUID b f 20 23 16 36 416 0 0 0 0 int84ne neqsel neqjoinsel )); -DATA(insert OID = 418 ( "<" PGNSP PGUID b f 20 23 16 76 430 0 0 0 0 int84lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 419 ( ">" PGNSP PGUID b f 20 23 16 37 420 0 0 0 0 int84gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 420 ( "<=" PGNSP PGUID b f 20 23 16 82 419 0 0 0 0 int84le scalarltsel scalarltjoinsel )); -DATA(insert OID = 430 ( ">=" PGNSP PGUID b f 20 23 16 80 418 0 0 0 0 int84ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 439 ( "%" PGNSP PGUID b f 20 20 20 0 0 0 0 0 0 int8mod - - )); -DATA(insert OID = 473 ( "@" PGNSP PGUID l f 0 20 20 0 0 0 0 0 0 int8abs - - )); +DATA(insert OID = 416 ( "=" PGNSP PGUID b t f 20 23 16 15 417 int84eq eqsel eqjoinsel )); +DATA(insert OID = 417 ( "<>" PGNSP PGUID b f f 20 23 16 36 416 int84ne neqsel neqjoinsel )); +DATA(insert OID = 418 ( "<" PGNSP PGUID b f f 20 23 16 76 430 int84lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 419 ( ">" PGNSP PGUID b f f 20 23 16 37 420 int84gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 420 ( "<=" PGNSP PGUID b f f 20 23 16 82 419 int84le scalarltsel scalarltjoinsel )); +DATA(insert OID = 430 ( ">=" PGNSP PGUID b f f 20 23 16 80 418 int84ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 439 ( "%" PGNSP PGUID b f f 20 20 20 0 0 int8mod - - )); +DATA(insert OID = 473 ( "@" PGNSP PGUID l f f 0 20 20 0 0 int8abs - - )); -DATA(insert OID = 484 ( "-" PGNSP PGUID l f 0 20 20 0 0 0 0 0 0 int8um - - )); -DATA(insert OID = 485 ( "<<" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_left positionsel positionjoinsel )); -DATA(insert OID = 486 ( "&<" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_overleft positionsel positionjoinsel )); -DATA(insert OID = 487 ( "&>" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_overright positionsel positionjoinsel )); -DATA(insert OID = 488 ( ">>" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_right positionsel positionjoinsel )); -DATA(insert OID = 489 ( "<@" PGNSP PGUID b f 604 604 16 490 0 0 0 0 0 poly_contained contsel contjoinsel )); -DATA(insert OID = 490 ( "@>" PGNSP PGUID b f 604 604 16 489 0 0 0 0 0 poly_contain contsel contjoinsel )); -DATA(insert OID = 491 ( "~=" PGNSP PGUID b f 604 604 16 491 0 0 0 0 0 poly_same eqsel eqjoinsel )); -DATA(insert OID = 492 ( "&&" PGNSP PGUID b f 604 604 16 492 0 0 0 0 0 poly_overlap areasel areajoinsel )); -DATA(insert OID = 493 ( "<<" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_left positionsel positionjoinsel )); -DATA(insert OID = 494 ( "&<" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_overleft positionsel positionjoinsel )); -DATA(insert OID = 495 ( "&>" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_overright positionsel positionjoinsel )); -DATA(insert OID = 496 ( ">>" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_right positionsel positionjoinsel )); -DATA(insert OID = 497 ( "<@" PGNSP PGUID b f 603 603 16 498 0 0 0 0 0 box_contained contsel contjoinsel )); -DATA(insert OID = 498 ( "@>" PGNSP PGUID b f 603 603 16 497 0 0 0 0 0 box_contain contsel contjoinsel )); -DATA(insert OID = 499 ( "~=" PGNSP PGUID b f 603 603 16 499 0 0 0 0 0 box_same eqsel eqjoinsel )); -DATA(insert OID = 500 ( "&&" PGNSP PGUID b f 603 603 16 500 0 0 0 0 0 box_overlap areasel areajoinsel )); -DATA(insert OID = 501 ( ">=" PGNSP PGUID b f 603 603 16 505 504 0 0 0 0 box_ge areasel areajoinsel )); -DATA(insert OID = 502 ( ">" PGNSP PGUID b f 603 603 16 504 505 0 0 0 0 box_gt areasel areajoinsel )); -DATA(insert OID = 503 ( "=" PGNSP PGUID b f 603 603 16 503 0 504 504 504 502 box_eq eqsel eqjoinsel )); -DATA(insert OID = 504 ( "<" PGNSP PGUID b f 603 603 16 502 501 0 0 0 0 box_lt areasel areajoinsel )); -DATA(insert OID = 505 ( "<=" PGNSP PGUID b f 603 603 16 501 502 0 0 0 0 box_le areasel areajoinsel )); -DATA(insert OID = 506 ( ">^" PGNSP PGUID b f 600 600 16 0 0 0 0 0 0 point_above positionsel positionjoinsel )); -DATA(insert OID = 507 ( "<<" PGNSP PGUID b f 600 600 16 0 0 0 0 0 0 point_left positionsel positionjoinsel )); -DATA(insert OID = 508 ( ">>" PGNSP PGUID b f 600 600 16 0 0 0 0 0 0 point_right positionsel positionjoinsel )); -DATA(insert OID = 509 ( "<^" PGNSP PGUID b f 600 600 16 0 0 0 0 0 0 point_below positionsel positionjoinsel )); -DATA(insert OID = 510 ( "~=" PGNSP PGUID b f 600 600 16 510 713 0 0 0 0 point_eq eqsel eqjoinsel )); -DATA(insert OID = 511 ( "<@" PGNSP PGUID b f 600 603 16 0 0 0 0 0 0 on_pb - - )); -DATA(insert OID = 512 ( "<@" PGNSP PGUID b f 600 602 16 755 0 0 0 0 0 on_ppath - - )); -DATA(insert OID = 513 ( "@@" PGNSP PGUID l f 0 603 600 0 0 0 0 0 0 box_center - - )); -DATA(insert OID = 514 ( "*" PGNSP PGUID b f 23 23 23 514 0 0 0 0 0 int4mul - - )); -DATA(insert OID = 517 ( "<->" PGNSP PGUID b f 600 600 701 517 0 0 0 0 0 point_distance - - )); -DATA(insert OID = 518 ( "<>" PGNSP PGUID b f 23 23 16 518 96 0 0 0 0 int4ne neqsel neqjoinsel )); -DATA(insert OID = 519 ( "<>" PGNSP PGUID b f 21 21 16 519 94 0 0 0 0 int2ne neqsel neqjoinsel )); -DATA(insert OID = 520 ( ">" PGNSP PGUID b f 21 21 16 95 522 0 0 0 0 int2gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 521 ( ">" PGNSP PGUID b f 23 23 16 97 523 0 0 0 0 int4gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 522 ( "<=" PGNSP PGUID b f 21 21 16 524 520 0 0 0 0 int2le scalarltsel scalarltjoinsel )); -DATA(insert OID = 523 ( "<=" PGNSP PGUID b f 23 23 16 525 521 0 0 0 0 int4le scalarltsel scalarltjoinsel )); -DATA(insert OID = 524 ( ">=" PGNSP PGUID b f 21 21 16 522 95 0 0 0 0 int2ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 525 ( ">=" PGNSP PGUID b f 23 23 16 523 97 0 0 0 0 int4ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 526 ( "*" PGNSP PGUID b f 21 21 21 526 0 0 0 0 0 int2mul - - )); -DATA(insert OID = 527 ( "/" PGNSP PGUID b f 21 21 21 0 0 0 0 0 0 int2div - - )); -DATA(insert OID = 528 ( "/" PGNSP PGUID b f 23 23 23 0 0 0 0 0 0 int4div - - )); -DATA(insert OID = 529 ( "%" PGNSP PGUID b f 21 21 21 0 0 0 0 0 0 int2mod - - )); -DATA(insert OID = 530 ( "%" PGNSP PGUID b f 23 23 23 0 0 0 0 0 0 int4mod - - )); -DATA(insert OID = 531 ( "<>" PGNSP PGUID b f 25 25 16 531 98 0 0 0 0 textne neqsel neqjoinsel )); -DATA(insert OID = 532 ( "=" PGNSP PGUID b f 21 23 16 533 538 95 97 534 536 int24eq eqsel eqjoinsel )); -DATA(insert OID = 533 ( "=" PGNSP PGUID b f 23 21 16 532 539 97 95 535 537 int42eq eqsel eqjoinsel )); -DATA(insert OID = 534 ( "<" PGNSP PGUID b f 21 23 16 537 542 0 0 0 0 int24lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 535 ( "<" PGNSP PGUID b f 23 21 16 536 543 0 0 0 0 int42lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 536 ( ">" PGNSP PGUID b f 21 23 16 535 540 0 0 0 0 int24gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 537 ( ">" PGNSP PGUID b f 23 21 16 534 541 0 0 0 0 int42gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 538 ( "<>" PGNSP PGUID b f 21 23 16 539 532 0 0 0 0 int24ne neqsel neqjoinsel )); -DATA(insert OID = 539 ( "<>" PGNSP PGUID b f 23 21 16 538 533 0 0 0 0 int42ne neqsel neqjoinsel )); -DATA(insert OID = 540 ( "<=" PGNSP PGUID b f 21 23 16 543 536 0 0 0 0 int24le scalarltsel scalarltjoinsel )); -DATA(insert OID = 541 ( "<=" PGNSP PGUID b f 23 21 16 542 537 0 0 0 0 int42le scalarltsel scalarltjoinsel )); -DATA(insert OID = 542 ( ">=" PGNSP PGUID b f 21 23 16 541 534 0 0 0 0 int24ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 543 ( ">=" PGNSP PGUID b f 23 21 16 540 535 0 0 0 0 int42ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 544 ( "*" PGNSP PGUID b f 21 23 23 545 0 0 0 0 0 int24mul - - )); -DATA(insert OID = 545 ( "*" PGNSP PGUID b f 23 21 23 544 0 0 0 0 0 int42mul - - )); -DATA(insert OID = 546 ( "/" PGNSP PGUID b f 21 23 23 0 0 0 0 0 0 int24div - - )); -DATA(insert OID = 547 ( "/" PGNSP PGUID b f 23 21 23 0 0 0 0 0 0 int42div - - )); -DATA(insert OID = 548 ( "%" PGNSP PGUID b f 21 23 23 0 0 0 0 0 0 int24mod - - )); -DATA(insert OID = 549 ( "%" PGNSP PGUID b f 23 21 23 0 0 0 0 0 0 int42mod - - )); -DATA(insert OID = 550 ( "+" PGNSP PGUID b f 21 21 21 550 0 0 0 0 0 int2pl - - )); -DATA(insert OID = 551 ( "+" PGNSP PGUID b f 23 23 23 551 0 0 0 0 0 int4pl - - )); -DATA(insert OID = 552 ( "+" PGNSP PGUID b f 21 23 23 553 0 0 0 0 0 int24pl - - )); -DATA(insert OID = 553 ( "+" PGNSP PGUID b f 23 21 23 552 0 0 0 0 0 int42pl - - )); -DATA(insert OID = 554 ( "-" PGNSP PGUID b f 21 21 21 0 0 0 0 0 0 int2mi - - )); -DATA(insert OID = 555 ( "-" PGNSP PGUID b f 23 23 23 0 0 0 0 0 0 int4mi - - )); -DATA(insert OID = 556 ( "-" PGNSP PGUID b f 21 23 23 0 0 0 0 0 0 int24mi - - )); -DATA(insert OID = 557 ( "-" PGNSP PGUID b f 23 21 23 0 0 0 0 0 0 int42mi - - )); -DATA(insert OID = 558 ( "-" PGNSP PGUID l f 0 23 23 0 0 0 0 0 0 int4um - - )); -DATA(insert OID = 559 ( "-" PGNSP PGUID l f 0 21 21 0 0 0 0 0 0 int2um - - )); -DATA(insert OID = 560 ( "=" PGNSP PGUID b t 702 702 16 560 561 562 562 562 563 abstimeeq eqsel eqjoinsel )); -DATA(insert OID = 561 ( "<>" PGNSP PGUID b f 702 702 16 561 560 0 0 0 0 abstimene neqsel neqjoinsel )); -DATA(insert OID = 562 ( "<" PGNSP PGUID b f 702 702 16 563 565 0 0 0 0 abstimelt scalarltsel scalarltjoinsel )); -DATA(insert OID = 563 ( ">" PGNSP PGUID b f 702 702 16 562 564 0 0 0 0 abstimegt scalargtsel scalargtjoinsel )); -DATA(insert OID = 564 ( "<=" PGNSP PGUID b f 702 702 16 565 563 0 0 0 0 abstimele scalarltsel scalarltjoinsel )); -DATA(insert OID = 565 ( ">=" PGNSP PGUID b f 702 702 16 564 562 0 0 0 0 abstimege scalargtsel scalargtjoinsel )); -DATA(insert OID = 566 ( "=" PGNSP PGUID b t 703 703 16 566 567 568 568 568 569 reltimeeq eqsel eqjoinsel )); -DATA(insert OID = 567 ( "<>" PGNSP PGUID b f 703 703 16 567 566 0 0 0 0 reltimene neqsel neqjoinsel )); -DATA(insert OID = 568 ( "<" PGNSP PGUID b f 703 703 16 569 571 0 0 0 0 reltimelt scalarltsel scalarltjoinsel )); -DATA(insert OID = 569 ( ">" PGNSP PGUID b f 703 703 16 568 570 0 0 0 0 reltimegt scalargtsel scalargtjoinsel )); -DATA(insert OID = 570 ( "<=" PGNSP PGUID b f 703 703 16 571 569 0 0 0 0 reltimele scalarltsel scalarltjoinsel )); -DATA(insert OID = 571 ( ">=" PGNSP PGUID b f 703 703 16 570 568 0 0 0 0 reltimege scalargtsel scalargtjoinsel )); -DATA(insert OID = 572 ( "~=" PGNSP PGUID b f 704 704 16 572 0 0 0 0 0 tintervalsame eqsel eqjoinsel )); -DATA(insert OID = 573 ( "<<" PGNSP PGUID b f 704 704 16 0 0 0 0 0 0 tintervalct - - )); -DATA(insert OID = 574 ( "&&" PGNSP PGUID b f 704 704 16 574 0 0 0 0 0 tintervalov - - )); -DATA(insert OID = 575 ( "#=" PGNSP PGUID b f 704 703 16 0 576 0 0 0 0 tintervalleneq - - )); -DATA(insert OID = 576 ( "#<>" PGNSP PGUID b f 704 703 16 0 575 0 0 0 0 tintervallenne - - )); -DATA(insert OID = 577 ( "#<" PGNSP PGUID b f 704 703 16 0 580 0 0 0 0 tintervallenlt - - )); -DATA(insert OID = 578 ( "#>" PGNSP PGUID b f 704 703 16 0 579 0 0 0 0 tintervallengt - - )); -DATA(insert OID = 579 ( "#<=" PGNSP PGUID b f 704 703 16 0 578 0 0 0 0 tintervallenle - - )); -DATA(insert OID = 580 ( "#>=" PGNSP PGUID b f 704 703 16 0 577 0 0 0 0 tintervallenge - - )); -DATA(insert OID = 581 ( "+" PGNSP PGUID b f 702 703 702 0 0 0 0 0 0 timepl - - )); -DATA(insert OID = 582 ( "-" PGNSP PGUID b f 702 703 702 0 0 0 0 0 0 timemi - - )); -DATA(insert OID = 583 ( "" PGNSP PGUID b f 702 704 16 0 0 0 0 0 0 intinterval - - )); -DATA(insert OID = 584 ( "-" PGNSP PGUID l f 0 700 700 0 0 0 0 0 0 float4um - - )); -DATA(insert OID = 585 ( "-" PGNSP PGUID l f 0 701 701 0 0 0 0 0 0 float8um - - )); -DATA(insert OID = 586 ( "+" PGNSP PGUID b f 700 700 700 586 0 0 0 0 0 float4pl - - )); -DATA(insert OID = 587 ( "-" PGNSP PGUID b f 700 700 700 0 0 0 0 0 0 float4mi - - )); -DATA(insert OID = 588 ( "/" PGNSP PGUID b f 700 700 700 0 0 0 0 0 0 float4div - - )); -DATA(insert OID = 589 ( "*" PGNSP PGUID b f 700 700 700 589 0 0 0 0 0 float4mul - - )); -DATA(insert OID = 590 ( "@" PGNSP PGUID l f 0 700 700 0 0 0 0 0 0 float4abs - - )); -DATA(insert OID = 591 ( "+" PGNSP PGUID b f 701 701 701 591 0 0 0 0 0 float8pl - - )); -DATA(insert OID = 592 ( "-" PGNSP PGUID b f 701 701 701 0 0 0 0 0 0 float8mi - - )); -DATA(insert OID = 593 ( "/" PGNSP PGUID b f 701 701 701 0 0 0 0 0 0 float8div - - )); -DATA(insert OID = 594 ( "*" PGNSP PGUID b f 701 701 701 594 0 0 0 0 0 float8mul - - )); -DATA(insert OID = 595 ( "@" PGNSP PGUID l f 0 701 701 0 0 0 0 0 0 float8abs - - )); -DATA(insert OID = 596 ( "|/" PGNSP PGUID l f 0 701 701 0 0 0 0 0 0 dsqrt - - )); -DATA(insert OID = 597 ( "||/" PGNSP PGUID l f 0 701 701 0 0 0 0 0 0 dcbrt - - )); -DATA(insert OID = 1284 ( "|" PGNSP PGUID l f 0 704 702 0 0 0 0 0 0 tintervalstart - - )); -DATA(insert OID = 606 ( "<#>" PGNSP PGUID b f 702 702 704 0 0 0 0 0 0 mktinterval - - )); +DATA(insert OID = 484 ( "-" PGNSP PGUID l f f 0 20 20 0 0 int8um - - )); +DATA(insert OID = 485 ( "<<" PGNSP PGUID b f f 604 604 16 0 0 poly_left positionsel positionjoinsel )); +DATA(insert OID = 486 ( "&<" PGNSP PGUID b f f 604 604 16 0 0 poly_overleft positionsel positionjoinsel )); +DATA(insert OID = 487 ( "&>" PGNSP PGUID b f f 604 604 16 0 0 poly_overright positionsel positionjoinsel )); +DATA(insert OID = 488 ( ">>" PGNSP PGUID b f f 604 604 16 0 0 poly_right positionsel positionjoinsel )); +DATA(insert OID = 489 ( "<@" PGNSP PGUID b f f 604 604 16 490 0 poly_contained contsel contjoinsel )); +DATA(insert OID = 490 ( "@>" PGNSP PGUID b f f 604 604 16 489 0 poly_contain contsel contjoinsel )); +DATA(insert OID = 491 ( "~=" PGNSP PGUID b f f 604 604 16 491 0 poly_same eqsel eqjoinsel )); +DATA(insert OID = 492 ( "&&" PGNSP PGUID b f f 604 604 16 492 0 poly_overlap areasel areajoinsel )); +DATA(insert OID = 493 ( "<<" PGNSP PGUID b f f 603 603 16 0 0 box_left positionsel positionjoinsel )); +DATA(insert OID = 494 ( "&<" PGNSP PGUID b f f 603 603 16 0 0 box_overleft positionsel positionjoinsel )); +DATA(insert OID = 495 ( "&>" PGNSP PGUID b f f 603 603 16 0 0 box_overright positionsel positionjoinsel )); +DATA(insert OID = 496 ( ">>" PGNSP PGUID b f f 603 603 16 0 0 box_right positionsel positionjoinsel )); +DATA(insert OID = 497 ( "<@" PGNSP PGUID b f f 603 603 16 498 0 box_contained contsel contjoinsel )); +DATA(insert OID = 498 ( "@>" PGNSP PGUID b f f 603 603 16 497 0 box_contain contsel contjoinsel )); +DATA(insert OID = 499 ( "~=" PGNSP PGUID b f f 603 603 16 499 0 box_same eqsel eqjoinsel )); +DATA(insert OID = 500 ( "&&" PGNSP PGUID b f f 603 603 16 500 0 box_overlap areasel areajoinsel )); +DATA(insert OID = 501 ( ">=" PGNSP PGUID b f f 603 603 16 505 504 box_ge areasel areajoinsel )); +DATA(insert OID = 502 ( ">" PGNSP PGUID b f f 603 603 16 504 505 box_gt areasel areajoinsel )); +DATA(insert OID = 503 ( "=" PGNSP PGUID b f f 603 603 16 503 0 box_eq eqsel eqjoinsel )); +DATA(insert OID = 504 ( "<" PGNSP PGUID b f f 603 603 16 502 501 box_lt areasel areajoinsel )); +DATA(insert OID = 505 ( "<=" PGNSP PGUID b f f 603 603 16 501 502 box_le areasel areajoinsel )); +DATA(insert OID = 506 ( ">^" PGNSP PGUID b f f 600 600 16 0 0 point_above positionsel positionjoinsel )); +DATA(insert OID = 507 ( "<<" PGNSP PGUID b f f 600 600 16 0 0 point_left positionsel positionjoinsel )); +DATA(insert OID = 508 ( ">>" PGNSP PGUID b f f 600 600 16 0 0 point_right positionsel positionjoinsel )); +DATA(insert OID = 509 ( "<^" PGNSP PGUID b f f 600 600 16 0 0 point_below positionsel positionjoinsel )); +DATA(insert OID = 510 ( "~=" PGNSP PGUID b f f 600 600 16 510 713 point_eq eqsel eqjoinsel )); +DATA(insert OID = 511 ( "<@" PGNSP PGUID b f f 600 603 16 0 0 on_pb - - )); +DATA(insert OID = 512 ( "<@" PGNSP PGUID b f f 600 602 16 755 0 on_ppath - - )); +DATA(insert OID = 513 ( "@@" PGNSP PGUID l f f 0 603 600 0 0 box_center - - )); +DATA(insert OID = 514 ( "*" PGNSP PGUID b f f 23 23 23 514 0 int4mul - - )); +DATA(insert OID = 517 ( "<->" PGNSP PGUID b f f 600 600 701 517 0 point_distance - - )); +DATA(insert OID = 518 ( "<>" PGNSP PGUID b f f 23 23 16 518 96 int4ne neqsel neqjoinsel )); +DATA(insert OID = 519 ( "<>" PGNSP PGUID b f f 21 21 16 519 94 int2ne neqsel neqjoinsel )); +DATA(insert OID = 520 ( ">" PGNSP PGUID b f f 21 21 16 95 522 int2gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 521 ( ">" PGNSP PGUID b f f 23 23 16 97 523 int4gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 522 ( "<=" PGNSP PGUID b f f 21 21 16 524 520 int2le scalarltsel scalarltjoinsel )); +DATA(insert OID = 523 ( "<=" PGNSP PGUID b f f 23 23 16 525 521 int4le scalarltsel scalarltjoinsel )); +DATA(insert OID = 524 ( ">=" PGNSP PGUID b f f 21 21 16 522 95 int2ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 525 ( ">=" PGNSP PGUID b f f 23 23 16 523 97 int4ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 526 ( "*" PGNSP PGUID b f f 21 21 21 526 0 int2mul - - )); +DATA(insert OID = 527 ( "/" PGNSP PGUID b f f 21 21 21 0 0 int2div - - )); +DATA(insert OID = 528 ( "/" PGNSP PGUID b f f 23 23 23 0 0 int4div - - )); +DATA(insert OID = 529 ( "%" PGNSP PGUID b f f 21 21 21 0 0 int2mod - - )); +DATA(insert OID = 530 ( "%" PGNSP PGUID b f f 23 23 23 0 0 int4mod - - )); +DATA(insert OID = 531 ( "<>" PGNSP PGUID b f f 25 25 16 531 98 textne neqsel neqjoinsel )); +DATA(insert OID = 532 ( "=" PGNSP PGUID b t f 21 23 16 533 538 int24eq eqsel eqjoinsel )); +DATA(insert OID = 533 ( "=" PGNSP PGUID b t f 23 21 16 532 539 int42eq eqsel eqjoinsel )); +DATA(insert OID = 534 ( "<" PGNSP PGUID b f f 21 23 16 537 542 int24lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 535 ( "<" PGNSP PGUID b f f 23 21 16 536 543 int42lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 536 ( ">" PGNSP PGUID b f f 21 23 16 535 540 int24gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 537 ( ">" PGNSP PGUID b f f 23 21 16 534 541 int42gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 538 ( "<>" PGNSP PGUID b f f 21 23 16 539 532 int24ne neqsel neqjoinsel )); +DATA(insert OID = 539 ( "<>" PGNSP PGUID b f f 23 21 16 538 533 int42ne neqsel neqjoinsel )); +DATA(insert OID = 540 ( "<=" PGNSP PGUID b f f 21 23 16 543 536 int24le scalarltsel scalarltjoinsel )); +DATA(insert OID = 541 ( "<=" PGNSP PGUID b f f 23 21 16 542 537 int42le scalarltsel scalarltjoinsel )); +DATA(insert OID = 542 ( ">=" PGNSP PGUID b f f 21 23 16 541 534 int24ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 543 ( ">=" PGNSP PGUID b f f 23 21 16 540 535 int42ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 544 ( "*" PGNSP PGUID b f f 21 23 23 545 0 int24mul - - )); +DATA(insert OID = 545 ( "*" PGNSP PGUID b f f 23 21 23 544 0 int42mul - - )); +DATA(insert OID = 546 ( "/" PGNSP PGUID b f f 21 23 23 0 0 int24div - - )); +DATA(insert OID = 547 ( "/" PGNSP PGUID b f f 23 21 23 0 0 int42div - - )); +DATA(insert OID = 548 ( "%" PGNSP PGUID b f f 21 23 23 0 0 int24mod - - )); +DATA(insert OID = 549 ( "%" PGNSP PGUID b f f 23 21 23 0 0 int42mod - - )); +DATA(insert OID = 550 ( "+" PGNSP PGUID b f f 21 21 21 550 0 int2pl - - )); +DATA(insert OID = 551 ( "+" PGNSP PGUID b f f 23 23 23 551 0 int4pl - - )); +DATA(insert OID = 552 ( "+" PGNSP PGUID b f f 21 23 23 553 0 int24pl - - )); +DATA(insert OID = 553 ( "+" PGNSP PGUID b f f 23 21 23 552 0 int42pl - - )); +DATA(insert OID = 554 ( "-" PGNSP PGUID b f f 21 21 21 0 0 int2mi - - )); +DATA(insert OID = 555 ( "-" PGNSP PGUID b f f 23 23 23 0 0 int4mi - - )); +DATA(insert OID = 556 ( "-" PGNSP PGUID b f f 21 23 23 0 0 int24mi - - )); +DATA(insert OID = 557 ( "-" PGNSP PGUID b f f 23 21 23 0 0 int42mi - - )); +DATA(insert OID = 558 ( "-" PGNSP PGUID l f f 0 23 23 0 0 int4um - - )); +DATA(insert OID = 559 ( "-" PGNSP PGUID l f f 0 21 21 0 0 int2um - - )); +DATA(insert OID = 560 ( "=" PGNSP PGUID b t t 702 702 16 560 561 abstimeeq eqsel eqjoinsel )); +DATA(insert OID = 561 ( "<>" PGNSP PGUID b f f 702 702 16 561 560 abstimene neqsel neqjoinsel )); +DATA(insert OID = 562 ( "<" PGNSP PGUID b f f 702 702 16 563 565 abstimelt scalarltsel scalarltjoinsel )); +DATA(insert OID = 563 ( ">" PGNSP PGUID b f f 702 702 16 562 564 abstimegt scalargtsel scalargtjoinsel )); +DATA(insert OID = 564 ( "<=" PGNSP PGUID b f f 702 702 16 565 563 abstimele scalarltsel scalarltjoinsel )); +DATA(insert OID = 565 ( ">=" PGNSP PGUID b f f 702 702 16 564 562 abstimege scalargtsel scalargtjoinsel )); +DATA(insert OID = 566 ( "=" PGNSP PGUID b t t 703 703 16 566 567 reltimeeq eqsel eqjoinsel )); +DATA(insert OID = 567 ( "<>" PGNSP PGUID b f f 703 703 16 567 566 reltimene neqsel neqjoinsel )); +DATA(insert OID = 568 ( "<" PGNSP PGUID b f f 703 703 16 569 571 reltimelt scalarltsel scalarltjoinsel )); +DATA(insert OID = 569 ( ">" PGNSP PGUID b f f 703 703 16 568 570 reltimegt scalargtsel scalargtjoinsel )); +DATA(insert OID = 570 ( "<=" PGNSP PGUID b f f 703 703 16 571 569 reltimele scalarltsel scalarltjoinsel )); +DATA(insert OID = 571 ( ">=" PGNSP PGUID b f f 703 703 16 570 568 reltimege scalargtsel scalargtjoinsel )); +DATA(insert OID = 572 ( "~=" PGNSP PGUID b f f 704 704 16 572 0 tintervalsame eqsel eqjoinsel )); +DATA(insert OID = 573 ( "<<" PGNSP PGUID b f f 704 704 16 0 0 tintervalct - - )); +DATA(insert OID = 574 ( "&&" PGNSP PGUID b f f 704 704 16 574 0 tintervalov - - )); +DATA(insert OID = 575 ( "#=" PGNSP PGUID b f f 704 703 16 0 576 tintervalleneq - - )); +DATA(insert OID = 576 ( "#<>" PGNSP PGUID b f f 704 703 16 0 575 tintervallenne - - )); +DATA(insert OID = 577 ( "#<" PGNSP PGUID b f f 704 703 16 0 580 tintervallenlt - - )); +DATA(insert OID = 578 ( "#>" PGNSP PGUID b f f 704 703 16 0 579 tintervallengt - - )); +DATA(insert OID = 579 ( "#<=" PGNSP PGUID b f f 704 703 16 0 578 tintervallenle - - )); +DATA(insert OID = 580 ( "#>=" PGNSP PGUID b f f 704 703 16 0 577 tintervallenge - - )); +DATA(insert OID = 581 ( "+" PGNSP PGUID b f f 702 703 702 0 0 timepl - - )); +DATA(insert OID = 582 ( "-" PGNSP PGUID b f f 702 703 702 0 0 timemi - - )); +DATA(insert OID = 583 ( "" PGNSP PGUID b f f 702 704 16 0 0 intinterval - - )); +DATA(insert OID = 584 ( "-" PGNSP PGUID l f f 0 700 700 0 0 float4um - - )); +DATA(insert OID = 585 ( "-" PGNSP PGUID l f f 0 701 701 0 0 float8um - - )); +DATA(insert OID = 586 ( "+" PGNSP PGUID b f f 700 700 700 586 0 float4pl - - )); +DATA(insert OID = 587 ( "-" PGNSP PGUID b f f 700 700 700 0 0 float4mi - - )); +DATA(insert OID = 588 ( "/" PGNSP PGUID b f f 700 700 700 0 0 float4div - - )); +DATA(insert OID = 589 ( "*" PGNSP PGUID b f f 700 700 700 589 0 float4mul - - )); +DATA(insert OID = 590 ( "@" PGNSP PGUID l f f 0 700 700 0 0 float4abs - - )); +DATA(insert OID = 591 ( "+" PGNSP PGUID b f f 701 701 701 591 0 float8pl - - )); +DATA(insert OID = 592 ( "-" PGNSP PGUID b f f 701 701 701 0 0 float8mi - - )); +DATA(insert OID = 593 ( "/" PGNSP PGUID b f f 701 701 701 0 0 float8div - - )); +DATA(insert OID = 594 ( "*" PGNSP PGUID b f f 701 701 701 594 0 float8mul - - )); +DATA(insert OID = 595 ( "@" PGNSP PGUID l f f 0 701 701 0 0 float8abs - - )); +DATA(insert OID = 596 ( "|/" PGNSP PGUID l f f 0 701 701 0 0 dsqrt - - )); +DATA(insert OID = 597 ( "||/" PGNSP PGUID l f f 0 701 701 0 0 dcbrt - - )); +DATA(insert OID = 1284 ( "|" PGNSP PGUID l f f 0 704 702 0 0 tintervalstart - - )); +DATA(insert OID = 606 ( "<#>" PGNSP PGUID b f f 702 702 704 0 0 mktinterval - - )); -DATA(insert OID = 607 ( "=" PGNSP PGUID b t 26 26 16 607 608 609 609 609 610 oideq eqsel eqjoinsel )); -#define MIN_OIDCMP 607 /* used by cache code */ -DATA(insert OID = 608 ( "<>" PGNSP PGUID b f 26 26 16 608 607 0 0 0 0 oidne neqsel neqjoinsel )); -DATA(insert OID = 609 ( "<" PGNSP PGUID b f 26 26 16 610 612 0 0 0 0 oidlt scalarltsel scalarltjoinsel )); -DATA(insert OID = 610 ( ">" PGNSP PGUID b f 26 26 16 609 611 0 0 0 0 oidgt scalargtsel scalargtjoinsel )); -DATA(insert OID = 611 ( "<=" PGNSP PGUID b f 26 26 16 612 610 0 0 0 0 oidle scalarltsel scalarltjoinsel )); -DATA(insert OID = 612 ( ">=" PGNSP PGUID b f 26 26 16 611 609 0 0 0 0 oidge scalargtsel scalargtjoinsel )); -#define MAX_OIDCMP 612 /* used by cache code */ +DATA(insert OID = 607 ( "=" PGNSP PGUID b t t 26 26 16 607 608 oideq eqsel eqjoinsel )); +DATA(insert OID = 608 ( "<>" PGNSP PGUID b f f 26 26 16 608 607 oidne neqsel neqjoinsel )); +DATA(insert OID = 609 ( "<" PGNSP PGUID b f f 26 26 16 610 612 oidlt scalarltsel scalarltjoinsel )); +DATA(insert OID = 610 ( ">" PGNSP PGUID b f f 26 26 16 609 611 oidgt scalargtsel scalargtjoinsel )); +DATA(insert OID = 611 ( "<=" PGNSP PGUID b f f 26 26 16 612 610 oidle scalarltsel scalarltjoinsel )); +DATA(insert OID = 612 ( ">=" PGNSP PGUID b f f 26 26 16 611 609 oidge scalargtsel scalargtjoinsel )); -DATA(insert OID = 644 ( "<>" PGNSP PGUID b f 30 30 16 644 649 0 0 0 0 oidvectorne neqsel neqjoinsel )); -DATA(insert OID = 645 ( "<" PGNSP PGUID b f 30 30 16 646 648 0 0 0 0 oidvectorlt scalarltsel scalarltjoinsel )); -DATA(insert OID = 646 ( ">" PGNSP PGUID b f 30 30 16 645 647 0 0 0 0 oidvectorgt scalargtsel scalargtjoinsel )); -DATA(insert OID = 647 ( "<=" PGNSP PGUID b f 30 30 16 648 646 0 0 0 0 oidvectorle scalarltsel scalarltjoinsel )); -DATA(insert OID = 648 ( ">=" PGNSP PGUID b f 30 30 16 647 645 0 0 0 0 oidvectorge scalargtsel scalargtjoinsel )); -DATA(insert OID = 649 ( "=" PGNSP PGUID b t 30 30 16 649 644 645 645 645 646 oidvectoreq eqsel eqjoinsel )); +DATA(insert OID = 644 ( "<>" PGNSP PGUID b f f 30 30 16 644 649 oidvectorne neqsel neqjoinsel )); +DATA(insert OID = 645 ( "<" PGNSP PGUID b f f 30 30 16 646 648 oidvectorlt scalarltsel scalarltjoinsel )); +DATA(insert OID = 646 ( ">" PGNSP PGUID b f f 30 30 16 645 647 oidvectorgt scalargtsel scalargtjoinsel )); +DATA(insert OID = 647 ( "<=" PGNSP PGUID b f f 30 30 16 648 646 oidvectorle scalarltsel scalarltjoinsel )); +DATA(insert OID = 648 ( ">=" PGNSP PGUID b f f 30 30 16 647 645 oidvectorge scalargtsel scalargtjoinsel )); +DATA(insert OID = 649 ( "=" PGNSP PGUID b t t 30 30 16 649 644 oidvectoreq eqsel eqjoinsel )); -DATA(insert OID = 613 ( "<->" PGNSP PGUID b f 600 628 701 0 0 0 0 0 0 dist_pl - - )); -DATA(insert OID = 614 ( "<->" PGNSP PGUID b f 600 601 701 0 0 0 0 0 0 dist_ps - - )); -DATA(insert OID = 615 ( "<->" PGNSP PGUID b f 600 603 701 0 0 0 0 0 0 dist_pb - - )); -DATA(insert OID = 616 ( "<->" PGNSP PGUID b f 601 628 701 0 0 0 0 0 0 dist_sl - - )); -DATA(insert OID = 617 ( "<->" PGNSP PGUID b f 601 603 701 0 0 0 0 0 0 dist_sb - - )); -DATA(insert OID = 618 ( "<->" PGNSP PGUID b f 600 602 701 0 0 0 0 0 0 dist_ppath - - )); +DATA(insert OID = 613 ( "<->" PGNSP PGUID b f f 600 628 701 0 0 dist_pl - - )); +DATA(insert OID = 614 ( "<->" PGNSP PGUID b f f 600 601 701 0 0 dist_ps - - )); +DATA(insert OID = 615 ( "<->" PGNSP PGUID b f f 600 603 701 0 0 dist_pb - - )); +DATA(insert OID = 616 ( "<->" PGNSP PGUID b f f 601 628 701 0 0 dist_sl - - )); +DATA(insert OID = 617 ( "<->" PGNSP PGUID b f f 601 603 701 0 0 dist_sb - - )); +DATA(insert OID = 618 ( "<->" PGNSP PGUID b f f 600 602 701 0 0 dist_ppath - - )); -DATA(insert OID = 620 ( "=" PGNSP PGUID b t 700 700 16 620 621 622 622 622 623 float4eq eqsel eqjoinsel )); -DATA(insert OID = 621 ( "<>" PGNSP PGUID b f 700 700 16 621 620 0 0 0 0 float4ne neqsel neqjoinsel )); -DATA(insert OID = 622 ( "<" PGNSP PGUID b f 700 700 16 623 625 0 0 0 0 float4lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 623 ( ">" PGNSP PGUID b f 700 700 16 622 624 0 0 0 0 float4gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 624 ( "<=" PGNSP PGUID b f 700 700 16 625 623 0 0 0 0 float4le scalarltsel scalarltjoinsel )); -DATA(insert OID = 625 ( ">=" PGNSP PGUID b f 700 700 16 624 622 0 0 0 0 float4ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 626 ( "!!=" PGNSP PGUID b f 23 25 16 0 0 0 0 0 0 int4notin - - )); -DATA(insert OID = 627 ( "!!=" PGNSP PGUID b f 26 25 16 0 0 0 0 0 0 oidnotin - - )); -DATA(insert OID = 630 ( "<>" PGNSP PGUID b f 18 18 16 630 92 0 0 0 0 charne neqsel neqjoinsel )); +DATA(insert OID = 620 ( "=" PGNSP PGUID b t t 700 700 16 620 621 float4eq eqsel eqjoinsel )); +DATA(insert OID = 621 ( "<>" PGNSP PGUID b f f 700 700 16 621 620 float4ne neqsel neqjoinsel )); +DATA(insert OID = 622 ( "<" PGNSP PGUID b f f 700 700 16 623 625 float4lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 623 ( ">" PGNSP PGUID b f f 700 700 16 622 624 float4gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 624 ( "<=" PGNSP PGUID b f f 700 700 16 625 623 float4le scalarltsel scalarltjoinsel )); +DATA(insert OID = 625 ( ">=" PGNSP PGUID b f f 700 700 16 624 622 float4ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 626 ( "!!=" PGNSP PGUID b f f 23 25 16 0 0 int4notin - - )); +DATA(insert OID = 627 ( "!!=" PGNSP PGUID b f f 26 25 16 0 0 oidnotin - - )); +DATA(insert OID = 630 ( "<>" PGNSP PGUID b f f 18 18 16 630 92 charne neqsel neqjoinsel )); -DATA(insert OID = 631 ( "<" PGNSP PGUID b f 18 18 16 633 634 0 0 0 0 charlt scalarltsel scalarltjoinsel )); -DATA(insert OID = 632 ( "<=" PGNSP PGUID b f 18 18 16 634 633 0 0 0 0 charle scalarltsel scalarltjoinsel )); -DATA(insert OID = 633 ( ">" PGNSP PGUID b f 18 18 16 631 632 0 0 0 0 chargt scalargtsel scalargtjoinsel )); -DATA(insert OID = 634 ( ">=" PGNSP PGUID b f 18 18 16 632 631 0 0 0 0 charge scalargtsel scalargtjoinsel )); +DATA(insert OID = 631 ( "<" PGNSP PGUID b f f 18 18 16 633 634 charlt scalarltsel scalarltjoinsel )); +DATA(insert OID = 632 ( "<=" PGNSP PGUID b f f 18 18 16 634 633 charle scalarltsel scalarltjoinsel )); +DATA(insert OID = 633 ( ">" PGNSP PGUID b f f 18 18 16 631 632 chargt scalargtsel scalargtjoinsel )); +DATA(insert OID = 634 ( ">=" PGNSP PGUID b f f 18 18 16 632 631 charge scalargtsel scalargtjoinsel )); -DATA(insert OID = 639 ( "~" PGNSP PGUID b f 19 25 16 0 640 0 0 0 0 nameregexeq regexeqsel regexeqjoinsel )); +DATA(insert OID = 639 ( "~" PGNSP PGUID b f f 19 25 16 0 640 nameregexeq regexeqsel regexeqjoinsel )); #define OID_NAME_REGEXEQ_OP 639 -DATA(insert OID = 640 ( "!~" PGNSP PGUID b f 19 25 16 0 639 0 0 0 0 nameregexne regexnesel regexnejoinsel )); -DATA(insert OID = 641 ( "~" PGNSP PGUID b f 25 25 16 0 642 0 0 0 0 textregexeq regexeqsel regexeqjoinsel )); +DATA(insert OID = 640 ( "!~" PGNSP PGUID b f f 19 25 16 0 639 nameregexne regexnesel regexnejoinsel )); +DATA(insert OID = 641 ( "~" PGNSP PGUID b f f 25 25 16 0 642 textregexeq regexeqsel regexeqjoinsel )); #define OID_TEXT_REGEXEQ_OP 641 -DATA(insert OID = 642 ( "!~" PGNSP PGUID b f 25 25 16 0 641 0 0 0 0 textregexne regexnesel regexnejoinsel )); -DATA(insert OID = 643 ( "<>" PGNSP PGUID b f 19 19 16 643 93 0 0 0 0 namene neqsel neqjoinsel )); -DATA(insert OID = 654 ( "||" PGNSP PGUID b f 25 25 25 0 0 0 0 0 0 textcat - - )); +DATA(insert OID = 642 ( "!~" PGNSP PGUID b f f 25 25 16 0 641 textregexne regexnesel regexnejoinsel )); +DATA(insert OID = 643 ( "<>" PGNSP PGUID b f f 19 19 16 643 93 namene neqsel neqjoinsel )); +DATA(insert OID = 654 ( "||" PGNSP PGUID b f f 25 25 25 0 0 textcat - - )); -DATA(insert OID = 660 ( "<" PGNSP PGUID b f 19 19 16 662 663 0 0 0 0 namelt scalarltsel scalarltjoinsel )); -DATA(insert OID = 661 ( "<=" PGNSP PGUID b f 19 19 16 663 662 0 0 0 0 namele scalarltsel scalarltjoinsel )); -DATA(insert OID = 662 ( ">" PGNSP PGUID b f 19 19 16 660 661 0 0 0 0 namegt scalargtsel scalargtjoinsel )); -DATA(insert OID = 663 ( ">=" PGNSP PGUID b f 19 19 16 661 660 0 0 0 0 namege scalargtsel scalargtjoinsel )); -DATA(insert OID = 664 ( "<" PGNSP PGUID b f 25 25 16 666 667 0 0 0 0 text_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 665 ( "<=" PGNSP PGUID b f 25 25 16 667 666 0 0 0 0 text_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 666 ( ">" PGNSP PGUID b f 25 25 16 664 665 0 0 0 0 text_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 667 ( ">=" PGNSP PGUID b f 25 25 16 665 664 0 0 0 0 text_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 660 ( "<" PGNSP PGUID b f f 19 19 16 662 663 namelt scalarltsel scalarltjoinsel )); +DATA(insert OID = 661 ( "<=" PGNSP PGUID b f f 19 19 16 663 662 namele scalarltsel scalarltjoinsel )); +DATA(insert OID = 662 ( ">" PGNSP PGUID b f f 19 19 16 660 661 namegt scalargtsel scalargtjoinsel )); +DATA(insert OID = 663 ( ">=" PGNSP PGUID b f f 19 19 16 661 660 namege scalargtsel scalargtjoinsel )); +DATA(insert OID = 664 ( "<" PGNSP PGUID b f f 25 25 16 666 667 text_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 665 ( "<=" PGNSP PGUID b f f 25 25 16 667 666 text_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 666 ( ">" PGNSP PGUID b f f 25 25 16 664 665 text_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 667 ( ">=" PGNSP PGUID b f f 25 25 16 665 664 text_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 670 ( "=" PGNSP PGUID b t 701 701 16 670 671 672 672 672 674 float8eq eqsel eqjoinsel )); -DATA(insert OID = 671 ( "<>" PGNSP PGUID b f 701 701 16 671 670 0 0 0 0 float8ne neqsel neqjoinsel )); -DATA(insert OID = 672 ( "<" PGNSP PGUID b f 701 701 16 674 675 0 0 0 0 float8lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 673 ( "<=" PGNSP PGUID b f 701 701 16 675 674 0 0 0 0 float8le scalarltsel scalarltjoinsel )); -DATA(insert OID = 674 ( ">" PGNSP PGUID b f 701 701 16 672 673 0 0 0 0 float8gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 675 ( ">=" PGNSP PGUID b f 701 701 16 673 672 0 0 0 0 float8ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 670 ( "=" PGNSP PGUID b t t 701 701 16 670 671 float8eq eqsel eqjoinsel )); +DATA(insert OID = 671 ( "<>" PGNSP PGUID b f f 701 701 16 671 670 float8ne neqsel neqjoinsel )); +DATA(insert OID = 672 ( "<" PGNSP PGUID b f f 701 701 16 674 675 float8lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 673 ( "<=" PGNSP PGUID b f f 701 701 16 675 674 float8le scalarltsel scalarltjoinsel )); +DATA(insert OID = 674 ( ">" PGNSP PGUID b f f 701 701 16 672 673 float8gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 675 ( ">=" PGNSP PGUID b f f 701 701 16 673 672 float8ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 682 ( "@" PGNSP PGUID l f 0 21 21 0 0 0 0 0 0 int2abs - - )); -DATA(insert OID = 684 ( "+" PGNSP PGUID b f 20 20 20 684 0 0 0 0 0 int8pl - - )); -DATA(insert OID = 685 ( "-" PGNSP PGUID b f 20 20 20 0 0 0 0 0 0 int8mi - - )); -DATA(insert OID = 686 ( "*" PGNSP PGUID b f 20 20 20 686 0 0 0 0 0 int8mul - - )); -DATA(insert OID = 687 ( "/" PGNSP PGUID b f 20 20 20 0 0 0 0 0 0 int8div - - )); -DATA(insert OID = 688 ( "+" PGNSP PGUID b f 20 23 20 692 0 0 0 0 0 int84pl - - )); -DATA(insert OID = 689 ( "-" PGNSP PGUID b f 20 23 20 0 0 0 0 0 0 int84mi - - )); -DATA(insert OID = 690 ( "*" PGNSP PGUID b f 20 23 20 694 0 0 0 0 0 int84mul - - )); -DATA(insert OID = 691 ( "/" PGNSP PGUID b f 20 23 20 0 0 0 0 0 0 int84div - - )); -DATA(insert OID = 692 ( "+" PGNSP PGUID b f 23 20 20 688 0 0 0 0 0 int48pl - - )); -DATA(insert OID = 693 ( "-" PGNSP PGUID b f 23 20 20 0 0 0 0 0 0 int48mi - - )); -DATA(insert OID = 694 ( "*" PGNSP PGUID b f 23 20 20 690 0 0 0 0 0 int48mul - - )); -DATA(insert OID = 695 ( "/" PGNSP PGUID b f 23 20 20 0 0 0 0 0 0 int48div - - )); +DATA(insert OID = 682 ( "@" PGNSP PGUID l f f 0 21 21 0 0 int2abs - - )); +DATA(insert OID = 684 ( "+" PGNSP PGUID b f f 20 20 20 684 0 int8pl - - )); +DATA(insert OID = 685 ( "-" PGNSP PGUID b f f 20 20 20 0 0 int8mi - - )); +DATA(insert OID = 686 ( "*" PGNSP PGUID b f f 20 20 20 686 0 int8mul - - )); +DATA(insert OID = 687 ( "/" PGNSP PGUID b f f 20 20 20 0 0 int8div - - )); +DATA(insert OID = 688 ( "+" PGNSP PGUID b f f 20 23 20 692 0 int84pl - - )); +DATA(insert OID = 689 ( "-" PGNSP PGUID b f f 20 23 20 0 0 int84mi - - )); +DATA(insert OID = 690 ( "*" PGNSP PGUID b f f 20 23 20 694 0 int84mul - - )); +DATA(insert OID = 691 ( "/" PGNSP PGUID b f f 20 23 20 0 0 int84div - - )); +DATA(insert OID = 692 ( "+" PGNSP PGUID b f f 23 20 20 688 0 int48pl - - )); +DATA(insert OID = 693 ( "-" PGNSP PGUID b f f 23 20 20 0 0 int48mi - - )); +DATA(insert OID = 694 ( "*" PGNSP PGUID b f f 23 20 20 690 0 int48mul - - )); +DATA(insert OID = 695 ( "/" PGNSP PGUID b f f 23 20 20 0 0 int48div - - )); -DATA(insert OID = 706 ( "<->" PGNSP PGUID b f 603 603 701 706 0 0 0 0 0 box_distance - - )); -DATA(insert OID = 707 ( "<->" PGNSP PGUID b f 602 602 701 707 0 0 0 0 0 path_distance - - )); -DATA(insert OID = 708 ( "<->" PGNSP PGUID b f 628 628 701 708 0 0 0 0 0 line_distance - - )); -DATA(insert OID = 709 ( "<->" PGNSP PGUID b f 601 601 701 709 0 0 0 0 0 lseg_distance - - )); -DATA(insert OID = 712 ( "<->" PGNSP PGUID b f 604 604 701 712 0 0 0 0 0 poly_distance - - )); +DATA(insert OID = 706 ( "<->" PGNSP PGUID b f f 603 603 701 706 0 box_distance - - )); +DATA(insert OID = 707 ( "<->" PGNSP PGUID b f f 602 602 701 707 0 path_distance - - )); +DATA(insert OID = 708 ( "<->" PGNSP PGUID b f f 628 628 701 708 0 line_distance - - )); +DATA(insert OID = 709 ( "<->" PGNSP PGUID b f f 601 601 701 709 0 lseg_distance - - )); +DATA(insert OID = 712 ( "<->" PGNSP PGUID b f f 604 604 701 712 0 poly_distance - - )); -DATA(insert OID = 713 ( "<>" PGNSP PGUID b f 600 600 16 713 510 0 0 0 0 point_ne neqsel neqjoinsel )); +DATA(insert OID = 713 ( "<>" PGNSP PGUID b f f 600 600 16 713 510 point_ne neqsel neqjoinsel )); /* add translation/rotation/scaling operators for geometric types. - thomas 97/05/10 */ -DATA(insert OID = 731 ( "+" PGNSP PGUID b f 600 600 600 731 0 0 0 0 0 point_add - - )); -DATA(insert OID = 732 ( "-" PGNSP PGUID b f 600 600 600 0 0 0 0 0 0 point_sub - - )); -DATA(insert OID = 733 ( "*" PGNSP PGUID b f 600 600 600 733 0 0 0 0 0 point_mul - - )); -DATA(insert OID = 734 ( "/" PGNSP PGUID b f 600 600 600 0 0 0 0 0 0 point_div - - )); -DATA(insert OID = 735 ( "+" PGNSP PGUID b f 602 602 602 735 0 0 0 0 0 path_add - - )); -DATA(insert OID = 736 ( "+" PGNSP PGUID b f 602 600 602 0 0 0 0 0 0 path_add_pt - - )); -DATA(insert OID = 737 ( "-" PGNSP PGUID b f 602 600 602 0 0 0 0 0 0 path_sub_pt - - )); -DATA(insert OID = 738 ( "*" PGNSP PGUID b f 602 600 602 0 0 0 0 0 0 path_mul_pt - - )); -DATA(insert OID = 739 ( "/" PGNSP PGUID b f 602 600 602 0 0 0 0 0 0 path_div_pt - - )); -DATA(insert OID = 755 ( "@>" PGNSP PGUID b f 602 600 16 512 0 0 0 0 0 path_contain_pt - - )); -DATA(insert OID = 756 ( "<@" PGNSP PGUID b f 600 604 16 757 0 0 0 0 0 pt_contained_poly - - )); -DATA(insert OID = 757 ( "@>" PGNSP PGUID b f 604 600 16 756 0 0 0 0 0 poly_contain_pt - - )); -DATA(insert OID = 758 ( "<@" PGNSP PGUID b f 600 718 16 759 0 0 0 0 0 pt_contained_circle - - )); -DATA(insert OID = 759 ( "@>" PGNSP PGUID b f 718 600 16 758 0 0 0 0 0 circle_contain_pt - - )); +DATA(insert OID = 731 ( "+" PGNSP PGUID b f f 600 600 600 731 0 point_add - - )); +DATA(insert OID = 732 ( "-" PGNSP PGUID b f f 600 600 600 0 0 point_sub - - )); +DATA(insert OID = 733 ( "*" PGNSP PGUID b f f 600 600 600 733 0 point_mul - - )); +DATA(insert OID = 734 ( "/" PGNSP PGUID b f f 600 600 600 0 0 point_div - - )); +DATA(insert OID = 735 ( "+" PGNSP PGUID b f f 602 602 602 735 0 path_add - - )); +DATA(insert OID = 736 ( "+" PGNSP PGUID b f f 602 600 602 0 0 path_add_pt - - )); +DATA(insert OID = 737 ( "-" PGNSP PGUID b f f 602 600 602 0 0 path_sub_pt - - )); +DATA(insert OID = 738 ( "*" PGNSP PGUID b f f 602 600 602 0 0 path_mul_pt - - )); +DATA(insert OID = 739 ( "/" PGNSP PGUID b f f 602 600 602 0 0 path_div_pt - - )); +DATA(insert OID = 755 ( "@>" PGNSP PGUID b f f 602 600 16 512 0 path_contain_pt - - )); +DATA(insert OID = 756 ( "<@" PGNSP PGUID b f f 600 604 16 757 0 pt_contained_poly - - )); +DATA(insert OID = 757 ( "@>" PGNSP PGUID b f f 604 600 16 756 0 poly_contain_pt - - )); +DATA(insert OID = 758 ( "<@" PGNSP PGUID b f f 600 718 16 759 0 pt_contained_circle - - )); +DATA(insert OID = 759 ( "@>" PGNSP PGUID b f f 718 600 16 758 0 circle_contain_pt - - )); -DATA(insert OID = 773 ( "@" PGNSP PGUID l f 0 23 23 0 0 0 0 0 0 int4abs - - )); +DATA(insert OID = 773 ( "@" PGNSP PGUID l f f 0 23 23 0 0 int4abs - - )); /* additional operators for geometric types - thomas 1997-07-09 */ -DATA(insert OID = 792 ( "=" PGNSP PGUID b f 602 602 16 792 0 0 0 0 0 path_n_eq eqsel eqjoinsel )); -DATA(insert OID = 793 ( "<" PGNSP PGUID b f 602 602 16 794 0 0 0 0 0 path_n_lt - - )); -DATA(insert OID = 794 ( ">" PGNSP PGUID b f 602 602 16 793 0 0 0 0 0 path_n_gt - - )); -DATA(insert OID = 795 ( "<=" PGNSP PGUID b f 602 602 16 796 0 0 0 0 0 path_n_le - - )); -DATA(insert OID = 796 ( ">=" PGNSP PGUID b f 602 602 16 795 0 0 0 0 0 path_n_ge - - )); -DATA(insert OID = 797 ( "#" PGNSP PGUID l f 0 602 23 0 0 0 0 0 0 path_npoints - - )); -DATA(insert OID = 798 ( "?#" PGNSP PGUID b f 602 602 16 0 0 0 0 0 0 path_inter - - )); -DATA(insert OID = 799 ( "@-@" PGNSP PGUID l f 0 602 701 0 0 0 0 0 0 path_length - - )); -DATA(insert OID = 800 ( ">^" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_above_eq positionsel positionjoinsel )); -DATA(insert OID = 801 ( "<^" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_below_eq positionsel positionjoinsel )); -DATA(insert OID = 802 ( "?#" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_overlap areasel areajoinsel )); -DATA(insert OID = 803 ( "#" PGNSP PGUID b f 603 603 603 0 0 0 0 0 0 box_intersect - - )); -DATA(insert OID = 804 ( "+" PGNSP PGUID b f 603 600 603 0 0 0 0 0 0 box_add - - )); -DATA(insert OID = 805 ( "-" PGNSP PGUID b f 603 600 603 0 0 0 0 0 0 box_sub - - )); -DATA(insert OID = 806 ( "*" PGNSP PGUID b f 603 600 603 0 0 0 0 0 0 box_mul - - )); -DATA(insert OID = 807 ( "/" PGNSP PGUID b f 603 600 603 0 0 0 0 0 0 box_div - - )); -DATA(insert OID = 808 ( "?-" PGNSP PGUID b f 600 600 16 808 0 0 0 0 0 point_horiz - - )); -DATA(insert OID = 809 ( "?|" PGNSP PGUID b f 600 600 16 809 0 0 0 0 0 point_vert - - )); +DATA(insert OID = 792 ( "=" PGNSP PGUID b f f 602 602 16 792 0 path_n_eq eqsel eqjoinsel )); +DATA(insert OID = 793 ( "<" PGNSP PGUID b f f 602 602 16 794 0 path_n_lt - - )); +DATA(insert OID = 794 ( ">" PGNSP PGUID b f f 602 602 16 793 0 path_n_gt - - )); +DATA(insert OID = 795 ( "<=" PGNSP PGUID b f f 602 602 16 796 0 path_n_le - - )); +DATA(insert OID = 796 ( ">=" PGNSP PGUID b f f 602 602 16 795 0 path_n_ge - - )); +DATA(insert OID = 797 ( "#" PGNSP PGUID l f f 0 602 23 0 0 path_npoints - - )); +DATA(insert OID = 798 ( "?#" PGNSP PGUID b f f 602 602 16 0 0 path_inter - - )); +DATA(insert OID = 799 ( "@-@" PGNSP PGUID l f f 0 602 701 0 0 path_length - - )); +DATA(insert OID = 800 ( ">^" PGNSP PGUID b f f 603 603 16 0 0 box_above_eq positionsel positionjoinsel )); +DATA(insert OID = 801 ( "<^" PGNSP PGUID b f f 603 603 16 0 0 box_below_eq positionsel positionjoinsel )); +DATA(insert OID = 802 ( "?#" PGNSP PGUID b f f 603 603 16 0 0 box_overlap areasel areajoinsel )); +DATA(insert OID = 803 ( "#" PGNSP PGUID b f f 603 603 603 0 0 box_intersect - - )); +DATA(insert OID = 804 ( "+" PGNSP PGUID b f f 603 600 603 0 0 box_add - - )); +DATA(insert OID = 805 ( "-" PGNSP PGUID b f f 603 600 603 0 0 box_sub - - )); +DATA(insert OID = 806 ( "*" PGNSP PGUID b f f 603 600 603 0 0 box_mul - - )); +DATA(insert OID = 807 ( "/" PGNSP PGUID b f f 603 600 603 0 0 box_div - - )); +DATA(insert OID = 808 ( "?-" PGNSP PGUID b f f 600 600 16 808 0 point_horiz - - )); +DATA(insert OID = 809 ( "?|" PGNSP PGUID b f f 600 600 16 809 0 point_vert - - )); -DATA(insert OID = 811 ( "=" PGNSP PGUID b f 704 704 16 811 812 0 0 0 0 tintervaleq eqsel eqjoinsel )); -DATA(insert OID = 812 ( "<>" PGNSP PGUID b f 704 704 16 812 811 0 0 0 0 tintervalne neqsel neqjoinsel )); -DATA(insert OID = 813 ( "<" PGNSP PGUID b f 704 704 16 814 816 0 0 0 0 tintervallt scalarltsel scalarltjoinsel )); -DATA(insert OID = 814 ( ">" PGNSP PGUID b f 704 704 16 813 815 0 0 0 0 tintervalgt scalargtsel scalargtjoinsel )); -DATA(insert OID = 815 ( "<=" PGNSP PGUID b f 704 704 16 816 814 0 0 0 0 tintervalle scalarltsel scalarltjoinsel )); -DATA(insert OID = 816 ( ">=" PGNSP PGUID b f 704 704 16 815 813 0 0 0 0 tintervalge scalargtsel scalargtjoinsel )); +DATA(insert OID = 811 ( "=" PGNSP PGUID b t f 704 704 16 811 812 tintervaleq eqsel eqjoinsel )); +DATA(insert OID = 812 ( "<>" PGNSP PGUID b f f 704 704 16 812 811 tintervalne neqsel neqjoinsel )); +DATA(insert OID = 813 ( "<" PGNSP PGUID b f f 704 704 16 814 816 tintervallt scalarltsel scalarltjoinsel )); +DATA(insert OID = 814 ( ">" PGNSP PGUID b f f 704 704 16 813 815 tintervalgt scalargtsel scalargtjoinsel )); +DATA(insert OID = 815 ( "<=" PGNSP PGUID b f f 704 704 16 816 814 tintervalle scalarltsel scalarltjoinsel )); +DATA(insert OID = 816 ( ">=" PGNSP PGUID b f f 704 704 16 815 813 tintervalge scalargtsel scalargtjoinsel )); -DATA(insert OID = 843 ( "*" PGNSP PGUID b f 790 700 790 845 0 0 0 0 0 cash_mul_flt4 - - )); -DATA(insert OID = 844 ( "/" PGNSP PGUID b f 790 700 790 0 0 0 0 0 0 cash_div_flt4 - - )); -DATA(insert OID = 845 ( "*" PGNSP PGUID b f 700 790 790 843 0 0 0 0 0 flt4_mul_cash - - )); +DATA(insert OID = 843 ( "*" PGNSP PGUID b f f 790 700 790 845 0 cash_mul_flt4 - - )); +DATA(insert OID = 844 ( "/" PGNSP PGUID b f f 790 700 790 0 0 cash_div_flt4 - - )); +DATA(insert OID = 845 ( "*" PGNSP PGUID b f f 700 790 790 843 0 flt4_mul_cash - - )); -DATA(insert OID = 900 ( "=" PGNSP PGUID b f 790 790 16 900 901 902 902 902 903 cash_eq eqsel eqjoinsel )); -DATA(insert OID = 901 ( "<>" PGNSP PGUID b f 790 790 16 901 900 0 0 0 0 cash_ne neqsel neqjoinsel )); -DATA(insert OID = 902 ( "<" PGNSP PGUID b f 790 790 16 903 905 0 0 0 0 cash_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 903 ( ">" PGNSP PGUID b f 790 790 16 902 904 0 0 0 0 cash_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 904 ( "<=" PGNSP PGUID b f 790 790 16 905 903 0 0 0 0 cash_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 905 ( ">=" PGNSP PGUID b f 790 790 16 904 902 0 0 0 0 cash_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 906 ( "+" PGNSP PGUID b f 790 790 790 906 0 0 0 0 0 cash_pl - - )); -DATA(insert OID = 907 ( "-" PGNSP PGUID b f 790 790 790 0 0 0 0 0 0 cash_mi - - )); -DATA(insert OID = 908 ( "*" PGNSP PGUID b f 790 701 790 916 0 0 0 0 0 cash_mul_flt8 - - )); -DATA(insert OID = 909 ( "/" PGNSP PGUID b f 790 701 790 0 0 0 0 0 0 cash_div_flt8 - - )); -DATA(insert OID = 912 ( "*" PGNSP PGUID b f 790 23 790 917 0 0 0 0 0 cash_mul_int4 - - )); -DATA(insert OID = 913 ( "/" PGNSP PGUID b f 790 23 790 0 0 0 0 0 0 cash_div_int4 - - )); -DATA(insert OID = 914 ( "*" PGNSP PGUID b f 790 21 790 918 0 0 0 0 0 cash_mul_int2 - - )); -DATA(insert OID = 915 ( "/" PGNSP PGUID b f 790 21 790 0 0 0 0 0 0 cash_div_int2 - - )); -DATA(insert OID = 916 ( "*" PGNSP PGUID b f 701 790 790 908 0 0 0 0 0 flt8_mul_cash - - )); -DATA(insert OID = 917 ( "*" PGNSP PGUID b f 23 790 790 912 0 0 0 0 0 int4_mul_cash - - )); -DATA(insert OID = 918 ( "*" PGNSP PGUID b f 21 790 790 914 0 0 0 0 0 int2_mul_cash - - )); +DATA(insert OID = 900 ( "=" PGNSP PGUID b t f 790 790 16 900 901 cash_eq eqsel eqjoinsel )); +DATA(insert OID = 901 ( "<>" PGNSP PGUID b f f 790 790 16 901 900 cash_ne neqsel neqjoinsel )); +DATA(insert OID = 902 ( "<" PGNSP PGUID b f f 790 790 16 903 905 cash_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 903 ( ">" PGNSP PGUID b f f 790 790 16 902 904 cash_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 904 ( "<=" PGNSP PGUID b f f 790 790 16 905 903 cash_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 905 ( ">=" PGNSP PGUID b f f 790 790 16 904 902 cash_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 906 ( "+" PGNSP PGUID b f f 790 790 790 906 0 cash_pl - - )); +DATA(insert OID = 907 ( "-" PGNSP PGUID b f f 790 790 790 0 0 cash_mi - - )); +DATA(insert OID = 908 ( "*" PGNSP PGUID b f f 790 701 790 916 0 cash_mul_flt8 - - )); +DATA(insert OID = 909 ( "/" PGNSP PGUID b f f 790 701 790 0 0 cash_div_flt8 - - )); +DATA(insert OID = 912 ( "*" PGNSP PGUID b f f 790 23 790 917 0 cash_mul_int4 - - )); +DATA(insert OID = 913 ( "/" PGNSP PGUID b f f 790 23 790 0 0 cash_div_int4 - - )); +DATA(insert OID = 914 ( "*" PGNSP PGUID b f f 790 21 790 918 0 cash_mul_int2 - - )); +DATA(insert OID = 915 ( "/" PGNSP PGUID b f f 790 21 790 0 0 cash_div_int2 - - )); +DATA(insert OID = 916 ( "*" PGNSP PGUID b f f 701 790 790 908 0 flt8_mul_cash - - )); +DATA(insert OID = 917 ( "*" PGNSP PGUID b f f 23 790 790 912 0 int4_mul_cash - - )); +DATA(insert OID = 918 ( "*" PGNSP PGUID b f f 21 790 790 914 0 int2_mul_cash - - )); -DATA(insert OID = 965 ( "^" PGNSP PGUID b f 701 701 701 0 0 0 0 0 0 dpow - - )); -DATA(insert OID = 966 ( "+" PGNSP PGUID b f 1034 1033 1034 0 0 0 0 0 0 aclinsert - - )); -DATA(insert OID = 967 ( "-" PGNSP PGUID b f 1034 1033 1034 0 0 0 0 0 0 aclremove - - )); -DATA(insert OID = 968 ( "@>" PGNSP PGUID b f 1034 1033 16 0 0 0 0 0 0 aclcontains - - )); -DATA(insert OID = 974 ( "=" PGNSP PGUID b t 1033 1033 16 974 0 0 0 0 0 aclitemeq eqsel eqjoinsel )); +DATA(insert OID = 965 ( "^" PGNSP PGUID b f f 701 701 701 0 0 dpow - - )); +DATA(insert OID = 966 ( "+" PGNSP PGUID b f f 1034 1033 1034 0 0 aclinsert - - )); +DATA(insert OID = 967 ( "-" PGNSP PGUID b f f 1034 1033 1034 0 0 aclremove - - )); +DATA(insert OID = 968 ( "@>" PGNSP PGUID b f f 1034 1033 16 0 0 aclcontains - - )); +DATA(insert OID = 974 ( "=" PGNSP PGUID b f t 1033 1033 16 974 0 aclitemeq eqsel eqjoinsel )); /* additional geometric operators - thomas 1997-07-09 */ -DATA(insert OID = 969 ( "@@" PGNSP PGUID l f 0 601 600 0 0 0 0 0 0 lseg_center - - )); -DATA(insert OID = 970 ( "@@" PGNSP PGUID l f 0 602 600 0 0 0 0 0 0 path_center - - )); -DATA(insert OID = 971 ( "@@" PGNSP PGUID l f 0 604 600 0 0 0 0 0 0 poly_center - - )); +DATA(insert OID = 969 ( "@@" PGNSP PGUID l f f 0 601 600 0 0 lseg_center - - )); +DATA(insert OID = 970 ( "@@" PGNSP PGUID l f f 0 602 600 0 0 path_center - - )); +DATA(insert OID = 971 ( "@@" PGNSP PGUID l f f 0 604 600 0 0 poly_center - - )); -DATA(insert OID = 1054 ( "=" PGNSP PGUID b t 1042 1042 16 1054 1057 1058 1058 1058 1060 bpchareq eqsel eqjoinsel )); -DATA(insert OID = 1055 ( "~" PGNSP PGUID b f 1042 25 16 0 1056 0 0 0 0 bpcharregexeq regexeqsel regexeqjoinsel )); +DATA(insert OID = 1054 ( "=" PGNSP PGUID b t t 1042 1042 16 1054 1057 bpchareq eqsel eqjoinsel )); +DATA(insert OID = 1055 ( "~" PGNSP PGUID b f f 1042 25 16 0 1056 bpcharregexeq regexeqsel regexeqjoinsel )); #define OID_BPCHAR_REGEXEQ_OP 1055 -DATA(insert OID = 1056 ( "!~" PGNSP PGUID b f 1042 25 16 0 1055 0 0 0 0 bpcharregexne regexnesel regexnejoinsel )); -DATA(insert OID = 1057 ( "<>" PGNSP PGUID b f 1042 1042 16 1057 1054 0 0 0 0 bpcharne neqsel neqjoinsel )); -DATA(insert OID = 1058 ( "<" PGNSP PGUID b f 1042 1042 16 1060 1061 0 0 0 0 bpcharlt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1059 ( "<=" PGNSP PGUID b f 1042 1042 16 1061 1060 0 0 0 0 bpcharle scalarltsel scalarltjoinsel )); -DATA(insert OID = 1060 ( ">" PGNSP PGUID b f 1042 1042 16 1058 1059 0 0 0 0 bpchargt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1061 ( ">=" PGNSP PGUID b f 1042 1042 16 1059 1058 0 0 0 0 bpcharge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1056 ( "!~" PGNSP PGUID b f f 1042 25 16 0 1055 bpcharregexne regexnesel regexnejoinsel )); +DATA(insert OID = 1057 ( "<>" PGNSP PGUID b f f 1042 1042 16 1057 1054 bpcharne neqsel neqjoinsel )); +DATA(insert OID = 1058 ( "<" PGNSP PGUID b f f 1042 1042 16 1060 1061 bpcharlt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1059 ( "<=" PGNSP PGUID b f f 1042 1042 16 1061 1060 bpcharle scalarltsel scalarltjoinsel )); +DATA(insert OID = 1060 ( ">" PGNSP PGUID b f f 1042 1042 16 1058 1059 bpchargt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1061 ( ">=" PGNSP PGUID b f f 1042 1042 16 1059 1058 bpcharge scalargtsel scalargtjoinsel )); /* generic array comparison operators */ -DATA(insert OID = 1070 ( "=" PGNSP PGUID b f 2277 2277 16 1070 1071 1072 1072 1072 1073 array_eq eqsel eqjoinsel )); +DATA(insert OID = 1070 ( "=" PGNSP PGUID b t f 2277 2277 16 1070 1071 array_eq eqsel eqjoinsel )); #define ARRAY_EQ_OP 1070 -DATA(insert OID = 1071 ( "<>" PGNSP PGUID b f 2277 2277 16 1071 1070 0 0 0 0 array_ne neqsel neqjoinsel )); -DATA(insert OID = 1072 ( "<" PGNSP PGUID b f 2277 2277 16 1073 1075 0 0 0 0 array_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1071 ( "<>" PGNSP PGUID b f f 2277 2277 16 1071 1070 array_ne neqsel neqjoinsel )); +DATA(insert OID = 1072 ( "<" PGNSP PGUID b f f 2277 2277 16 1073 1075 array_lt scalarltsel scalarltjoinsel )); #define ARRAY_LT_OP 1072 -DATA(insert OID = 1073 ( ">" PGNSP PGUID b f 2277 2277 16 1072 1074 0 0 0 0 array_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1073 ( ">" PGNSP PGUID b f f 2277 2277 16 1072 1074 array_gt scalargtsel scalargtjoinsel )); #define ARRAY_GT_OP 1073 -DATA(insert OID = 1074 ( "<=" PGNSP PGUID b f 2277 2277 16 1075 1073 0 0 0 0 array_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1075 ( ">=" PGNSP PGUID b f 2277 2277 16 1074 1072 0 0 0 0 array_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1074 ( "<=" PGNSP PGUID b f f 2277 2277 16 1075 1073 array_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1075 ( ">=" PGNSP PGUID b f f 2277 2277 16 1074 1072 array_ge scalargtsel scalargtjoinsel )); /* date operators */ -DATA(insert OID = 1076 ( "+" PGNSP PGUID b f 1082 1186 1114 2551 0 0 0 0 0 date_pl_interval - - )); -DATA(insert OID = 1077 ( "-" PGNSP PGUID b f 1082 1186 1114 0 0 0 0 0 0 date_mi_interval - - )); -DATA(insert OID = 1093 ( "=" PGNSP PGUID b t 1082 1082 16 1093 1094 1095 1095 1095 1097 date_eq eqsel eqjoinsel )); -DATA(insert OID = 1094 ( "<>" PGNSP PGUID b f 1082 1082 16 1094 1093 0 0 0 0 date_ne neqsel neqjoinsel )); -DATA(insert OID = 1095 ( "<" PGNSP PGUID b f 1082 1082 16 1097 1098 0 0 0 0 date_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1096 ( "<=" PGNSP PGUID b f 1082 1082 16 1098 1097 0 0 0 0 date_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1097 ( ">" PGNSP PGUID b f 1082 1082 16 1095 1096 0 0 0 0 date_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1098 ( ">=" PGNSP PGUID b f 1082 1082 16 1096 1095 0 0 0 0 date_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1099 ( "-" PGNSP PGUID b f 1082 1082 23 0 0 0 0 0 0 date_mi - - )); -DATA(insert OID = 1100 ( "+" PGNSP PGUID b f 1082 23 1082 2555 0 0 0 0 0 date_pli - - )); -DATA(insert OID = 1101 ( "-" PGNSP PGUID b f 1082 23 1082 0 0 0 0 0 0 date_mii - - )); +DATA(insert OID = 1076 ( "+" PGNSP PGUID b f f 1082 1186 1114 2551 0 date_pl_interval - - )); +DATA(insert OID = 1077 ( "-" PGNSP PGUID b f f 1082 1186 1114 0 0 date_mi_interval - - )); +DATA(insert OID = 1093 ( "=" PGNSP PGUID b t t 1082 1082 16 1093 1094 date_eq eqsel eqjoinsel )); +DATA(insert OID = 1094 ( "<>" PGNSP PGUID b f f 1082 1082 16 1094 1093 date_ne neqsel neqjoinsel )); +DATA(insert OID = 1095 ( "<" PGNSP PGUID b f f 1082 1082 16 1097 1098 date_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1096 ( "<=" PGNSP PGUID b f f 1082 1082 16 1098 1097 date_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1097 ( ">" PGNSP PGUID b f f 1082 1082 16 1095 1096 date_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1098 ( ">=" PGNSP PGUID b f f 1082 1082 16 1096 1095 date_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1099 ( "-" PGNSP PGUID b f f 1082 1082 23 0 0 date_mi - - )); +DATA(insert OID = 1100 ( "+" PGNSP PGUID b f f 1082 23 1082 2555 0 date_pli - - )); +DATA(insert OID = 1101 ( "-" PGNSP PGUID b f f 1082 23 1082 0 0 date_mii - - )); /* time operators */ -DATA(insert OID = 1108 ( "=" PGNSP PGUID b t 1083 1083 16 1108 1109 1110 1110 1110 1112 time_eq eqsel eqjoinsel )); -DATA(insert OID = 1109 ( "<>" PGNSP PGUID b f 1083 1083 16 1109 1108 0 0 0 0 time_ne neqsel neqjoinsel )); -DATA(insert OID = 1110 ( "<" PGNSP PGUID b f 1083 1083 16 1112 1113 0 0 0 0 time_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1111 ( "<=" PGNSP PGUID b f 1083 1083 16 1113 1112 0 0 0 0 time_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1112 ( ">" PGNSP PGUID b f 1083 1083 16 1110 1111 0 0 0 0 time_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1113 ( ">=" PGNSP PGUID b f 1083 1083 16 1111 1110 0 0 0 0 time_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1108 ( "=" PGNSP PGUID b t t 1083 1083 16 1108 1109 time_eq eqsel eqjoinsel )); +DATA(insert OID = 1109 ( "<>" PGNSP PGUID b f f 1083 1083 16 1109 1108 time_ne neqsel neqjoinsel )); +DATA(insert OID = 1110 ( "<" PGNSP PGUID b f f 1083 1083 16 1112 1113 time_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1111 ( "<=" PGNSP PGUID b f f 1083 1083 16 1113 1112 time_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1112 ( ">" PGNSP PGUID b f f 1083 1083 16 1110 1111 time_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1113 ( ">=" PGNSP PGUID b f f 1083 1083 16 1111 1110 time_ge scalargtsel scalargtjoinsel )); /* timetz operators */ -DATA(insert OID = 1550 ( "=" PGNSP PGUID b t 1266 1266 16 1550 1551 1552 1552 1552 1554 timetz_eq eqsel eqjoinsel )); -DATA(insert OID = 1551 ( "<>" PGNSP PGUID b f 1266 1266 16 1551 1550 0 0 0 0 timetz_ne neqsel neqjoinsel )); -DATA(insert OID = 1552 ( "<" PGNSP PGUID b f 1266 1266 16 1554 1555 0 0 0 0 timetz_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1553 ( "<=" PGNSP PGUID b f 1266 1266 16 1555 1554 0 0 0 0 timetz_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1554 ( ">" PGNSP PGUID b f 1266 1266 16 1552 1553 0 0 0 0 timetz_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1555 ( ">=" PGNSP PGUID b f 1266 1266 16 1553 1552 0 0 0 0 timetz_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1550 ( "=" PGNSP PGUID b t t 1266 1266 16 1550 1551 timetz_eq eqsel eqjoinsel )); +DATA(insert OID = 1551 ( "<>" PGNSP PGUID b f f 1266 1266 16 1551 1550 timetz_ne neqsel neqjoinsel )); +DATA(insert OID = 1552 ( "<" PGNSP PGUID b f f 1266 1266 16 1554 1555 timetz_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1553 ( "<=" PGNSP PGUID b f f 1266 1266 16 1555 1554 timetz_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1554 ( ">" PGNSP PGUID b f f 1266 1266 16 1552 1553 timetz_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1555 ( ">=" PGNSP PGUID b f f 1266 1266 16 1553 1552 timetz_ge scalargtsel scalargtjoinsel )); /* float48 operators */ -DATA(insert OID = 1116 ( "+" PGNSP PGUID b f 700 701 701 1126 0 0 0 0 0 float48pl - - )); -DATA(insert OID = 1117 ( "-" PGNSP PGUID b f 700 701 701 0 0 0 0 0 0 float48mi - - )); -DATA(insert OID = 1118 ( "/" PGNSP PGUID b f 700 701 701 0 0 0 0 0 0 float48div - - )); -DATA(insert OID = 1119 ( "*" PGNSP PGUID b f 700 701 701 1129 0 0 0 0 0 float48mul - - )); -DATA(insert OID = 1120 ( "=" PGNSP PGUID b f 700 701 16 1130 1121 622 672 1122 1123 float48eq eqsel eqjoinsel )); -DATA(insert OID = 1121 ( "<>" PGNSP PGUID b f 700 701 16 1131 1120 0 0 0 0 float48ne neqsel neqjoinsel )); -DATA(insert OID = 1122 ( "<" PGNSP PGUID b f 700 701 16 1133 1125 0 0 0 0 float48lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1123 ( ">" PGNSP PGUID b f 700 701 16 1132 1124 0 0 0 0 float48gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1124 ( "<=" PGNSP PGUID b f 700 701 16 1135 1123 0 0 0 0 float48le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1125 ( ">=" PGNSP PGUID b f 700 701 16 1134 1122 0 0 0 0 float48ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1116 ( "+" PGNSP PGUID b f f 700 701 701 1126 0 float48pl - - )); +DATA(insert OID = 1117 ( "-" PGNSP PGUID b f f 700 701 701 0 0 float48mi - - )); +DATA(insert OID = 1118 ( "/" PGNSP PGUID b f f 700 701 701 0 0 float48div - - )); +DATA(insert OID = 1119 ( "*" PGNSP PGUID b f f 700 701 701 1129 0 float48mul - - )); +DATA(insert OID = 1120 ( "=" PGNSP PGUID b t f 700 701 16 1130 1121 float48eq eqsel eqjoinsel )); +DATA(insert OID = 1121 ( "<>" PGNSP PGUID b f f 700 701 16 1131 1120 float48ne neqsel neqjoinsel )); +DATA(insert OID = 1122 ( "<" PGNSP PGUID b f f 700 701 16 1133 1125 float48lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1123 ( ">" PGNSP PGUID b f f 700 701 16 1132 1124 float48gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1124 ( "<=" PGNSP PGUID b f f 700 701 16 1135 1123 float48le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1125 ( ">=" PGNSP PGUID b f f 700 701 16 1134 1122 float48ge scalargtsel scalargtjoinsel )); /* float84 operators */ -DATA(insert OID = 1126 ( "+" PGNSP PGUID b f 701 700 701 1116 0 0 0 0 0 float84pl - - )); -DATA(insert OID = 1127 ( "-" PGNSP PGUID b f 701 700 701 0 0 0 0 0 0 float84mi - - )); -DATA(insert OID = 1128 ( "/" PGNSP PGUID b f 701 700 701 0 0 0 0 0 0 float84div - - )); -DATA(insert OID = 1129 ( "*" PGNSP PGUID b f 701 700 701 1119 0 0 0 0 0 float84mul - - )); -DATA(insert OID = 1130 ( "=" PGNSP PGUID b f 701 700 16 1120 1131 672 622 1132 1133 float84eq eqsel eqjoinsel )); -DATA(insert OID = 1131 ( "<>" PGNSP PGUID b f 701 700 16 1121 1130 0 0 0 0 float84ne neqsel neqjoinsel )); -DATA(insert OID = 1132 ( "<" PGNSP PGUID b f 701 700 16 1123 1135 0 0 0 0 float84lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1133 ( ">" PGNSP PGUID b f 701 700 16 1122 1134 0 0 0 0 float84gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1134 ( "<=" PGNSP PGUID b f 701 700 16 1125 1133 0 0 0 0 float84le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1135 ( ">=" PGNSP PGUID b f 701 700 16 1124 1132 0 0 0 0 float84ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1126 ( "+" PGNSP PGUID b f f 701 700 701 1116 0 float84pl - - )); +DATA(insert OID = 1127 ( "-" PGNSP PGUID b f f 701 700 701 0 0 float84mi - - )); +DATA(insert OID = 1128 ( "/" PGNSP PGUID b f f 701 700 701 0 0 float84div - - )); +DATA(insert OID = 1129 ( "*" PGNSP PGUID b f f 701 700 701 1119 0 float84mul - - )); +DATA(insert OID = 1130 ( "=" PGNSP PGUID b t f 701 700 16 1120 1131 float84eq eqsel eqjoinsel )); +DATA(insert OID = 1131 ( "<>" PGNSP PGUID b f f 701 700 16 1121 1130 float84ne neqsel neqjoinsel )); +DATA(insert OID = 1132 ( "<" PGNSP PGUID b f f 701 700 16 1123 1135 float84lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1133 ( ">" PGNSP PGUID b f f 701 700 16 1122 1134 float84gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1134 ( "<=" PGNSP PGUID b f f 701 700 16 1125 1133 float84le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1135 ( ">=" PGNSP PGUID b f f 701 700 16 1124 1132 float84ge scalargtsel scalargtjoinsel )); /* LIKE hacks by Keith Parks. */ -DATA(insert OID = 1207 ( "~~" PGNSP PGUID b f 19 25 16 0 1208 0 0 0 0 namelike likesel likejoinsel )); +DATA(insert OID = 1207 ( "~~" PGNSP PGUID b f f 19 25 16 0 1208 namelike likesel likejoinsel )); #define OID_NAME_LIKE_OP 1207 -DATA(insert OID = 1208 ( "!~~" PGNSP PGUID b f 19 25 16 0 1207 0 0 0 0 namenlike nlikesel nlikejoinsel )); -DATA(insert OID = 1209 ( "~~" PGNSP PGUID b f 25 25 16 0 1210 0 0 0 0 textlike likesel likejoinsel )); +DATA(insert OID = 1208 ( "!~~" PGNSP PGUID b f f 19 25 16 0 1207 namenlike nlikesel nlikejoinsel )); +DATA(insert OID = 1209 ( "~~" PGNSP PGUID b f f 25 25 16 0 1210 textlike likesel likejoinsel )); #define OID_TEXT_LIKE_OP 1209 -DATA(insert OID = 1210 ( "!~~" PGNSP PGUID b f 25 25 16 0 1209 0 0 0 0 textnlike nlikesel nlikejoinsel )); -DATA(insert OID = 1211 ( "~~" PGNSP PGUID b f 1042 25 16 0 1212 0 0 0 0 bpcharlike likesel likejoinsel )); +DATA(insert OID = 1210 ( "!~~" PGNSP PGUID b f f 25 25 16 0 1209 textnlike nlikesel nlikejoinsel )); +DATA(insert OID = 1211 ( "~~" PGNSP PGUID b f f 1042 25 16 0 1212 bpcharlike likesel likejoinsel )); #define OID_BPCHAR_LIKE_OP 1211 -DATA(insert OID = 1212 ( "!~~" PGNSP PGUID b f 1042 25 16 0 1211 0 0 0 0 bpcharnlike nlikesel nlikejoinsel )); +DATA(insert OID = 1212 ( "!~~" PGNSP PGUID b f f 1042 25 16 0 1211 bpcharnlike nlikesel nlikejoinsel )); /* case-insensitive regex hacks */ -DATA(insert OID = 1226 ( "~*" PGNSP PGUID b f 19 25 16 0 1227 0 0 0 0 nameicregexeq icregexeqsel icregexeqjoinsel )); +DATA(insert OID = 1226 ( "~*" PGNSP PGUID b f f 19 25 16 0 1227 nameicregexeq icregexeqsel icregexeqjoinsel )); #define OID_NAME_ICREGEXEQ_OP 1226 -DATA(insert OID = 1227 ( "!~*" PGNSP PGUID b f 19 25 16 0 1226 0 0 0 0 nameicregexne icregexnesel icregexnejoinsel )); -DATA(insert OID = 1228 ( "~*" PGNSP PGUID b f 25 25 16 0 1229 0 0 0 0 texticregexeq icregexeqsel icregexeqjoinsel )); +DATA(insert OID = 1227 ( "!~*" PGNSP PGUID b f f 19 25 16 0 1226 nameicregexne icregexnesel icregexnejoinsel )); +DATA(insert OID = 1228 ( "~*" PGNSP PGUID b f f 25 25 16 0 1229 texticregexeq icregexeqsel icregexeqjoinsel )); #define OID_TEXT_ICREGEXEQ_OP 1228 -DATA(insert OID = 1229 ( "!~*" PGNSP PGUID b f 25 25 16 0 1228 0 0 0 0 texticregexne icregexnesel icregexnejoinsel )); -DATA(insert OID = 1234 ( "~*" PGNSP PGUID b f 1042 25 16 0 1235 0 0 0 0 bpcharicregexeq icregexeqsel icregexeqjoinsel )); +DATA(insert OID = 1229 ( "!~*" PGNSP PGUID b f f 25 25 16 0 1228 texticregexne icregexnesel icregexnejoinsel )); +DATA(insert OID = 1234 ( "~*" PGNSP PGUID b f f 1042 25 16 0 1235 bpcharicregexeq icregexeqsel icregexeqjoinsel )); #define OID_BPCHAR_ICREGEXEQ_OP 1234 -DATA(insert OID = 1235 ( "!~*" PGNSP PGUID b f 1042 25 16 0 1234 0 0 0 0 bpcharicregexne icregexnesel icregexnejoinsel )); +DATA(insert OID = 1235 ( "!~*" PGNSP PGUID b f f 1042 25 16 0 1234 bpcharicregexne icregexnesel icregexnejoinsel )); /* timestamptz operators */ -DATA(insert OID = 1320 ( "=" PGNSP PGUID b t 1184 1184 16 1320 1321 1322 1322 1322 1324 timestamptz_eq eqsel eqjoinsel )); -DATA(insert OID = 1321 ( "<>" PGNSP PGUID b f 1184 1184 16 1321 1320 0 0 0 0 timestamptz_ne neqsel neqjoinsel )); -DATA(insert OID = 1322 ( "<" PGNSP PGUID b f 1184 1184 16 1324 1325 0 0 0 0 timestamptz_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1323 ( "<=" PGNSP PGUID b f 1184 1184 16 1325 1324 0 0 0 0 timestamptz_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1324 ( ">" PGNSP PGUID b f 1184 1184 16 1322 1323 0 0 0 0 timestamptz_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1325 ( ">=" PGNSP PGUID b f 1184 1184 16 1323 1322 0 0 0 0 timestamptz_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1327 ( "+" PGNSP PGUID b f 1184 1186 1184 2554 0 0 0 0 0 timestamptz_pl_interval - - )); -DATA(insert OID = 1328 ( "-" PGNSP PGUID b f 1184 1184 1186 0 0 0 0 0 0 timestamptz_mi - - )); -DATA(insert OID = 1329 ( "-" PGNSP PGUID b f 1184 1186 1184 0 0 0 0 0 0 timestamptz_mi_interval - - )); +DATA(insert OID = 1320 ( "=" PGNSP PGUID b t t 1184 1184 16 1320 1321 timestamptz_eq eqsel eqjoinsel )); +DATA(insert OID = 1321 ( "<>" PGNSP PGUID b f f 1184 1184 16 1321 1320 timestamptz_ne neqsel neqjoinsel )); +DATA(insert OID = 1322 ( "<" PGNSP PGUID b f f 1184 1184 16 1324 1325 timestamptz_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1323 ( "<=" PGNSP PGUID b f f 1184 1184 16 1325 1324 timestamptz_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1324 ( ">" PGNSP PGUID b f f 1184 1184 16 1322 1323 timestamptz_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1325 ( ">=" PGNSP PGUID b f f 1184 1184 16 1323 1322 timestamptz_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1327 ( "+" PGNSP PGUID b f f 1184 1186 1184 2554 0 timestamptz_pl_interval - - )); +DATA(insert OID = 1328 ( "-" PGNSP PGUID b f f 1184 1184 1186 0 0 timestamptz_mi - - )); +DATA(insert OID = 1329 ( "-" PGNSP PGUID b f f 1184 1186 1184 0 0 timestamptz_mi_interval - - )); /* interval operators */ -DATA(insert OID = 1330 ( "=" PGNSP PGUID b t 1186 1186 16 1330 1331 1332 1332 1332 1334 interval_eq eqsel eqjoinsel )); -DATA(insert OID = 1331 ( "<>" PGNSP PGUID b f 1186 1186 16 1331 1330 0 0 0 0 interval_ne neqsel neqjoinsel )); -DATA(insert OID = 1332 ( "<" PGNSP PGUID b f 1186 1186 16 1334 1335 0 0 0 0 interval_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1333 ( "<=" PGNSP PGUID b f 1186 1186 16 1335 1334 0 0 0 0 interval_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1334 ( ">" PGNSP PGUID b f 1186 1186 16 1332 1333 0 0 0 0 interval_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1335 ( ">=" PGNSP PGUID b f 1186 1186 16 1333 1332 0 0 0 0 interval_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1330 ( "=" PGNSP PGUID b t t 1186 1186 16 1330 1331 interval_eq eqsel eqjoinsel )); +DATA(insert OID = 1331 ( "<>" PGNSP PGUID b f f 1186 1186 16 1331 1330 interval_ne neqsel neqjoinsel )); +DATA(insert OID = 1332 ( "<" PGNSP PGUID b f f 1186 1186 16 1334 1335 interval_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1333 ( "<=" PGNSP PGUID b f f 1186 1186 16 1335 1334 interval_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1334 ( ">" PGNSP PGUID b f f 1186 1186 16 1332 1333 interval_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1335 ( ">=" PGNSP PGUID b f f 1186 1186 16 1333 1332 interval_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1336 ( "-" PGNSP PGUID l f 0 1186 1186 0 0 0 0 0 0 interval_um - - )); -DATA(insert OID = 1337 ( "+" PGNSP PGUID b f 1186 1186 1186 1337 0 0 0 0 0 interval_pl - - )); -DATA(insert OID = 1338 ( "-" PGNSP PGUID b f 1186 1186 1186 0 0 0 0 0 0 interval_mi - - )); +DATA(insert OID = 1336 ( "-" PGNSP PGUID l f f 0 1186 1186 0 0 interval_um - - )); +DATA(insert OID = 1337 ( "+" PGNSP PGUID b f f 1186 1186 1186 1337 0 interval_pl - - )); +DATA(insert OID = 1338 ( "-" PGNSP PGUID b f f 1186 1186 1186 0 0 interval_mi - - )); -DATA(insert OID = 1360 ( "+" PGNSP PGUID b f 1082 1083 1114 1363 0 0 0 0 0 datetime_pl - - )); -DATA(insert OID = 1361 ( "+" PGNSP PGUID b f 1082 1266 1184 1366 0 0 0 0 0 datetimetz_pl - - )); -DATA(insert OID = 1363 ( "+" PGNSP PGUID b f 1083 1082 1114 1360 0 0 0 0 0 timedate_pl - - )); -DATA(insert OID = 1366 ( "+" PGNSP PGUID b f 1266 1082 1184 1361 0 0 0 0 0 timetzdate_pl - - )); +DATA(insert OID = 1360 ( "+" PGNSP PGUID b f f 1082 1083 1114 1363 0 datetime_pl - - )); +DATA(insert OID = 1361 ( "+" PGNSP PGUID b f f 1082 1266 1184 1366 0 datetimetz_pl - - )); +DATA(insert OID = 1363 ( "+" PGNSP PGUID b f f 1083 1082 1114 1360 0 timedate_pl - - )); +DATA(insert OID = 1366 ( "+" PGNSP PGUID b f f 1266 1082 1184 1361 0 timetzdate_pl - - )); -DATA(insert OID = 1399 ( "-" PGNSP PGUID b f 1083 1083 1186 0 0 0 0 0 0 time_mi_time - - )); +DATA(insert OID = 1399 ( "-" PGNSP PGUID b f f 1083 1083 1186 0 0 time_mi_time - - )); /* additional geometric operators - thomas 97/04/18 */ -DATA(insert OID = 1420 ( "@@" PGNSP PGUID l f 0 718 600 0 0 0 0 0 0 circle_center - - )); -DATA(insert OID = 1500 ( "=" PGNSP PGUID b f 718 718 16 1500 1501 1502 1502 1502 1503 circle_eq eqsel eqjoinsel )); -DATA(insert OID = 1501 ( "<>" PGNSP PGUID b f 718 718 16 1501 1500 0 0 0 0 circle_ne neqsel neqjoinsel )); -DATA(insert OID = 1502 ( "<" PGNSP PGUID b f 718 718 16 1503 1505 0 0 0 0 circle_lt areasel areajoinsel )); -DATA(insert OID = 1503 ( ">" PGNSP PGUID b f 718 718 16 1502 1504 0 0 0 0 circle_gt areasel areajoinsel )); -DATA(insert OID = 1504 ( "<=" PGNSP PGUID b f 718 718 16 1505 1503 0 0 0 0 circle_le areasel areajoinsel )); -DATA(insert OID = 1505 ( ">=" PGNSP PGUID b f 718 718 16 1504 1502 0 0 0 0 circle_ge areasel areajoinsel )); +DATA(insert OID = 1420 ( "@@" PGNSP PGUID l f f 0 718 600 0 0 circle_center - - )); +DATA(insert OID = 1500 ( "=" PGNSP PGUID b f f 718 718 16 1500 1501 circle_eq eqsel eqjoinsel )); +DATA(insert OID = 1501 ( "<>" PGNSP PGUID b f f 718 718 16 1501 1500 circle_ne neqsel neqjoinsel )); +DATA(insert OID = 1502 ( "<" PGNSP PGUID b f f 718 718 16 1503 1505 circle_lt areasel areajoinsel )); +DATA(insert OID = 1503 ( ">" PGNSP PGUID b f f 718 718 16 1502 1504 circle_gt areasel areajoinsel )); +DATA(insert OID = 1504 ( "<=" PGNSP PGUID b f f 718 718 16 1505 1503 circle_le areasel areajoinsel )); +DATA(insert OID = 1505 ( ">=" PGNSP PGUID b f f 718 718 16 1504 1502 circle_ge areasel areajoinsel )); -DATA(insert OID = 1506 ( "<<" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_left positionsel positionjoinsel )); -DATA(insert OID = 1507 ( "&<" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_overleft positionsel positionjoinsel )); -DATA(insert OID = 1508 ( "&>" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_overright positionsel positionjoinsel )); -DATA(insert OID = 1509 ( ">>" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_right positionsel positionjoinsel )); -DATA(insert OID = 1510 ( "<@" PGNSP PGUID b f 718 718 16 1511 0 0 0 0 0 circle_contained contsel contjoinsel )); -DATA(insert OID = 1511 ( "@>" PGNSP PGUID b f 718 718 16 1510 0 0 0 0 0 circle_contain contsel contjoinsel )); -DATA(insert OID = 1512 ( "~=" PGNSP PGUID b f 718 718 16 1512 0 0 0 0 0 circle_same eqsel eqjoinsel )); -DATA(insert OID = 1513 ( "&&" PGNSP PGUID b f 718 718 16 1513 0 0 0 0 0 circle_overlap areasel areajoinsel )); -DATA(insert OID = 1514 ( "|>>" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_above positionsel positionjoinsel )); -DATA(insert OID = 1515 ( "<<|" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_below positionsel positionjoinsel )); +DATA(insert OID = 1506 ( "<<" PGNSP PGUID b f f 718 718 16 0 0 circle_left positionsel positionjoinsel )); +DATA(insert OID = 1507 ( "&<" PGNSP PGUID b f f 718 718 16 0 0 circle_overleft positionsel positionjoinsel )); +DATA(insert OID = 1508 ( "&>" PGNSP PGUID b f f 718 718 16 0 0 circle_overright positionsel positionjoinsel )); +DATA(insert OID = 1509 ( ">>" PGNSP PGUID b f f 718 718 16 0 0 circle_right positionsel positionjoinsel )); +DATA(insert OID = 1510 ( "<@" PGNSP PGUID b f f 718 718 16 1511 0 circle_contained contsel contjoinsel )); +DATA(insert OID = 1511 ( "@>" PGNSP PGUID b f f 718 718 16 1510 0 circle_contain contsel contjoinsel )); +DATA(insert OID = 1512 ( "~=" PGNSP PGUID b f f 718 718 16 1512 0 circle_same eqsel eqjoinsel )); +DATA(insert OID = 1513 ( "&&" PGNSP PGUID b f f 718 718 16 1513 0 circle_overlap areasel areajoinsel )); +DATA(insert OID = 1514 ( "|>>" PGNSP PGUID b f f 718 718 16 0 0 circle_above positionsel positionjoinsel )); +DATA(insert OID = 1515 ( "<<|" PGNSP PGUID b f f 718 718 16 0 0 circle_below positionsel positionjoinsel )); -DATA(insert OID = 1516 ( "+" PGNSP PGUID b f 718 600 718 0 0 0 0 0 0 circle_add_pt - - )); -DATA(insert OID = 1517 ( "-" PGNSP PGUID b f 718 600 718 0 0 0 0 0 0 circle_sub_pt - - )); -DATA(insert OID = 1518 ( "*" PGNSP PGUID b f 718 600 718 0 0 0 0 0 0 circle_mul_pt - - )); -DATA(insert OID = 1519 ( "/" PGNSP PGUID b f 718 600 718 0 0 0 0 0 0 circle_div_pt - - )); +DATA(insert OID = 1516 ( "+" PGNSP PGUID b f f 718 600 718 0 0 circle_add_pt - - )); +DATA(insert OID = 1517 ( "-" PGNSP PGUID b f f 718 600 718 0 0 circle_sub_pt - - )); +DATA(insert OID = 1518 ( "*" PGNSP PGUID b f f 718 600 718 0 0 circle_mul_pt - - )); +DATA(insert OID = 1519 ( "/" PGNSP PGUID b f f 718 600 718 0 0 circle_div_pt - - )); -DATA(insert OID = 1520 ( "<->" PGNSP PGUID b f 718 718 701 1520 0 0 0 0 0 circle_distance - - )); -DATA(insert OID = 1521 ( "#" PGNSP PGUID l f 0 604 23 0 0 0 0 0 0 poly_npoints - - )); -DATA(insert OID = 1522 ( "<->" PGNSP PGUID b f 600 718 701 0 0 0 0 0 0 dist_pc - - )); -DATA(insert OID = 1523 ( "<->" PGNSP PGUID b f 718 604 701 0 0 0 0 0 0 dist_cpoly - - )); +DATA(insert OID = 1520 ( "<->" PGNSP PGUID b f f 718 718 701 1520 0 circle_distance - - )); +DATA(insert OID = 1521 ( "#" PGNSP PGUID l f f 0 604 23 0 0 poly_npoints - - )); +DATA(insert OID = 1522 ( "<->" PGNSP PGUID b f f 600 718 701 0 0 dist_pc - - )); +DATA(insert OID = 1523 ( "<->" PGNSP PGUID b f f 718 604 701 0 0 dist_cpoly - - )); /* additional geometric operators - thomas 1997-07-09 */ -DATA(insert OID = 1524 ( "<->" PGNSP PGUID b f 628 603 701 0 0 0 0 0 0 dist_lb - - )); +DATA(insert OID = 1524 ( "<->" PGNSP PGUID b f f 628 603 701 0 0 dist_lb - - )); -DATA(insert OID = 1525 ( "?#" PGNSP PGUID b f 601 601 16 1525 0 0 0 0 0 lseg_intersect - - )); -DATA(insert OID = 1526 ( "?||" PGNSP PGUID b f 601 601 16 1526 0 0 0 0 0 lseg_parallel - - )); -DATA(insert OID = 1527 ( "?-|" PGNSP PGUID b f 601 601 16 1527 0 0 0 0 0 lseg_perp - - )); -DATA(insert OID = 1528 ( "?-" PGNSP PGUID l f 0 601 16 0 0 0 0 0 0 lseg_horizontal - - )); -DATA(insert OID = 1529 ( "?|" PGNSP PGUID l f 0 601 16 0 0 0 0 0 0 lseg_vertical - - )); -DATA(insert OID = 1535 ( "=" PGNSP PGUID b f 601 601 16 1535 1586 0 0 0 0 lseg_eq eqsel eqjoinsel )); -DATA(insert OID = 1536 ( "#" PGNSP PGUID b f 601 601 600 1536 0 0 0 0 0 lseg_interpt - - )); -DATA(insert OID = 1537 ( "?#" PGNSP PGUID b f 601 628 16 0 0 0 0 0 0 inter_sl - - )); -DATA(insert OID = 1538 ( "?#" PGNSP PGUID b f 601 603 16 0 0 0 0 0 0 inter_sb - - )); -DATA(insert OID = 1539 ( "?#" PGNSP PGUID b f 628 603 16 0 0 0 0 0 0 inter_lb - - )); +DATA(insert OID = 1525 ( "?#" PGNSP PGUID b f f 601 601 16 1525 0 lseg_intersect - - )); +DATA(insert OID = 1526 ( "?||" PGNSP PGUID b f f 601 601 16 1526 0 lseg_parallel - - )); +DATA(insert OID = 1527 ( "?-|" PGNSP PGUID b f f 601 601 16 1527 0 lseg_perp - - )); +DATA(insert OID = 1528 ( "?-" PGNSP PGUID l f f 0 601 16 0 0 lseg_horizontal - - )); +DATA(insert OID = 1529 ( "?|" PGNSP PGUID l f f 0 601 16 0 0 lseg_vertical - - )); +DATA(insert OID = 1535 ( "=" PGNSP PGUID b f f 601 601 16 1535 1586 lseg_eq eqsel eqjoinsel )); +DATA(insert OID = 1536 ( "#" PGNSP PGUID b f f 601 601 600 1536 0 lseg_interpt - - )); +DATA(insert OID = 1537 ( "?#" PGNSP PGUID b f f 601 628 16 0 0 inter_sl - - )); +DATA(insert OID = 1538 ( "?#" PGNSP PGUID b f f 601 603 16 0 0 inter_sb - - )); +DATA(insert OID = 1539 ( "?#" PGNSP PGUID b f f 628 603 16 0 0 inter_lb - - )); -DATA(insert OID = 1546 ( "<@" PGNSP PGUID b f 600 628 16 0 0 0 0 0 0 on_pl - - )); -DATA(insert OID = 1547 ( "<@" PGNSP PGUID b f 600 601 16 0 0 0 0 0 0 on_ps - - )); -DATA(insert OID = 1548 ( "<@" PGNSP PGUID b f 601 628 16 0 0 0 0 0 0 on_sl - - )); -DATA(insert OID = 1549 ( "<@" PGNSP PGUID b f 601 603 16 0 0 0 0 0 0 on_sb - - )); +DATA(insert OID = 1546 ( "<@" PGNSP PGUID b f f 600 628 16 0 0 on_pl - - )); +DATA(insert OID = 1547 ( "<@" PGNSP PGUID b f f 600 601 16 0 0 on_ps - - )); +DATA(insert OID = 1548 ( "<@" PGNSP PGUID b f f 601 628 16 0 0 on_sl - - )); +DATA(insert OID = 1549 ( "<@" PGNSP PGUID b f f 601 603 16 0 0 on_sb - - )); -DATA(insert OID = 1557 ( "##" PGNSP PGUID b f 600 628 600 0 0 0 0 0 0 close_pl - - )); -DATA(insert OID = 1558 ( "##" PGNSP PGUID b f 600 601 600 0 0 0 0 0 0 close_ps - - )); -DATA(insert OID = 1559 ( "##" PGNSP PGUID b f 600 603 600 0 0 0 0 0 0 close_pb - - )); +DATA(insert OID = 1557 ( "##" PGNSP PGUID b f f 600 628 600 0 0 close_pl - - )); +DATA(insert OID = 1558 ( "##" PGNSP PGUID b f f 600 601 600 0 0 close_ps - - )); +DATA(insert OID = 1559 ( "##" PGNSP PGUID b f f 600 603 600 0 0 close_pb - - )); -DATA(insert OID = 1566 ( "##" PGNSP PGUID b f 601 628 600 0 0 0 0 0 0 close_sl - - )); -DATA(insert OID = 1567 ( "##" PGNSP PGUID b f 601 603 600 0 0 0 0 0 0 close_sb - - )); -DATA(insert OID = 1568 ( "##" PGNSP PGUID b f 628 603 600 0 0 0 0 0 0 close_lb - - )); -DATA(insert OID = 1577 ( "##" PGNSP PGUID b f 628 601 600 0 0 0 0 0 0 close_ls - - )); -DATA(insert OID = 1578 ( "##" PGNSP PGUID b f 601 601 600 0 0 0 0 0 0 close_lseg - - )); -DATA(insert OID = 1583 ( "*" PGNSP PGUID b f 1186 701 1186 1584 0 0 0 0 0 interval_mul - - )); -DATA(insert OID = 1584 ( "*" PGNSP PGUID b f 701 1186 1186 1583 0 0 0 0 0 mul_d_interval - - )); -DATA(insert OID = 1585 ( "/" PGNSP PGUID b f 1186 701 1186 0 0 0 0 0 0 interval_div - - )); +DATA(insert OID = 1566 ( "##" PGNSP PGUID b f f 601 628 600 0 0 close_sl - - )); +DATA(insert OID = 1567 ( "##" PGNSP PGUID b f f 601 603 600 0 0 close_sb - - )); +DATA(insert OID = 1568 ( "##" PGNSP PGUID b f f 628 603 600 0 0 close_lb - - )); +DATA(insert OID = 1577 ( "##" PGNSP PGUID b f f 628 601 600 0 0 close_ls - - )); +DATA(insert OID = 1578 ( "##" PGNSP PGUID b f f 601 601 600 0 0 close_lseg - - )); +DATA(insert OID = 1583 ( "*" PGNSP PGUID b f f 1186 701 1186 1584 0 interval_mul - - )); +DATA(insert OID = 1584 ( "*" PGNSP PGUID b f f 701 1186 1186 1583 0 mul_d_interval - - )); +DATA(insert OID = 1585 ( "/" PGNSP PGUID b f f 1186 701 1186 0 0 interval_div - - )); -DATA(insert OID = 1586 ( "<>" PGNSP PGUID b f 601 601 16 1586 1535 0 0 0 0 lseg_ne neqsel neqjoinsel )); -DATA(insert OID = 1587 ( "<" PGNSP PGUID b f 601 601 16 1589 1590 0 0 0 0 lseg_lt - - )); -DATA(insert OID = 1588 ( "<=" PGNSP PGUID b f 601 601 16 1590 1589 0 0 0 0 lseg_le - - )); -DATA(insert OID = 1589 ( ">" PGNSP PGUID b f 601 601 16 1587 1588 0 0 0 0 lseg_gt - - )); -DATA(insert OID = 1590 ( ">=" PGNSP PGUID b f 601 601 16 1588 1587 0 0 0 0 lseg_ge - - )); +DATA(insert OID = 1586 ( "<>" PGNSP PGUID b f f 601 601 16 1586 1535 lseg_ne neqsel neqjoinsel )); +DATA(insert OID = 1587 ( "<" PGNSP PGUID b f f 601 601 16 1589 1590 lseg_lt - - )); +DATA(insert OID = 1588 ( "<=" PGNSP PGUID b f f 601 601 16 1590 1589 lseg_le - - )); +DATA(insert OID = 1589 ( ">" PGNSP PGUID b f f 601 601 16 1587 1588 lseg_gt - - )); +DATA(insert OID = 1590 ( ">=" PGNSP PGUID b f f 601 601 16 1588 1587 lseg_ge - - )); -DATA(insert OID = 1591 ( "@-@" PGNSP PGUID l f 0 601 701 0 0 0 0 0 0 lseg_length - - )); +DATA(insert OID = 1591 ( "@-@" PGNSP PGUID l f f 0 601 701 0 0 lseg_length - - )); -DATA(insert OID = 1611 ( "?#" PGNSP PGUID b f 628 628 16 1611 0 0 0 0 0 line_intersect - - )); -DATA(insert OID = 1612 ( "?||" PGNSP PGUID b f 628 628 16 1612 0 0 0 0 0 line_parallel - - )); -DATA(insert OID = 1613 ( "?-|" PGNSP PGUID b f 628 628 16 1613 0 0 0 0 0 line_perp - - )); -DATA(insert OID = 1614 ( "?-" PGNSP PGUID l f 0 628 16 0 0 0 0 0 0 line_horizontal - - )); -DATA(insert OID = 1615 ( "?|" PGNSP PGUID l f 0 628 16 0 0 0 0 0 0 line_vertical - - )); -DATA(insert OID = 1616 ( "=" PGNSP PGUID b f 628 628 16 1616 0 0 0 0 0 line_eq eqsel eqjoinsel )); -DATA(insert OID = 1617 ( "#" PGNSP PGUID b f 628 628 600 1617 0 0 0 0 0 line_interpt - - )); +DATA(insert OID = 1611 ( "?#" PGNSP PGUID b f f 628 628 16 1611 0 line_intersect - - )); +DATA(insert OID = 1612 ( "?||" PGNSP PGUID b f f 628 628 16 1612 0 line_parallel - - )); +DATA(insert OID = 1613 ( "?-|" PGNSP PGUID b f f 628 628 16 1613 0 line_perp - - )); +DATA(insert OID = 1614 ( "?-" PGNSP PGUID l f f 0 628 16 0 0 line_horizontal - - )); +DATA(insert OID = 1615 ( "?|" PGNSP PGUID l f f 0 628 16 0 0 line_vertical - - )); +DATA(insert OID = 1616 ( "=" PGNSP PGUID b f f 628 628 16 1616 0 line_eq eqsel eqjoinsel )); +DATA(insert OID = 1617 ( "#" PGNSP PGUID b f f 628 628 600 1617 0 line_interpt - - )); /* MAC type */ -DATA(insert OID = 1220 ( "=" PGNSP PGUID b t 829 829 16 1220 1221 1222 1222 1222 1224 macaddr_eq eqsel eqjoinsel )); -DATA(insert OID = 1221 ( "<>" PGNSP PGUID b f 829 829 16 1221 1220 0 0 0 0 macaddr_ne neqsel neqjoinsel )); -DATA(insert OID = 1222 ( "<" PGNSP PGUID b f 829 829 16 1224 1225 0 0 0 0 macaddr_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1223 ( "<=" PGNSP PGUID b f 829 829 16 1225 1224 0 0 0 0 macaddr_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1224 ( ">" PGNSP PGUID b f 829 829 16 1222 1223 0 0 0 0 macaddr_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1225 ( ">=" PGNSP PGUID b f 829 829 16 1223 1222 0 0 0 0 macaddr_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1220 ( "=" PGNSP PGUID b t t 829 829 16 1220 1221 macaddr_eq eqsel eqjoinsel )); +DATA(insert OID = 1221 ( "<>" PGNSP PGUID b f f 829 829 16 1221 1220 macaddr_ne neqsel neqjoinsel )); +DATA(insert OID = 1222 ( "<" PGNSP PGUID b f f 829 829 16 1224 1225 macaddr_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1223 ( "<=" PGNSP PGUID b f f 829 829 16 1225 1224 macaddr_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1224 ( ">" PGNSP PGUID b f f 829 829 16 1222 1223 macaddr_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1225 ( ">=" PGNSP PGUID b f f 829 829 16 1223 1222 macaddr_ge scalargtsel scalargtjoinsel )); /* INET type (these also support CIDR via implicit cast) */ -DATA(insert OID = 1201 ( "=" PGNSP PGUID b t 869 869 16 1201 1202 1203 1203 1203 1205 network_eq eqsel eqjoinsel )); -DATA(insert OID = 1202 ( "<>" PGNSP PGUID b f 869 869 16 1202 1201 0 0 0 0 network_ne neqsel neqjoinsel )); -DATA(insert OID = 1203 ( "<" PGNSP PGUID b f 869 869 16 1205 1206 0 0 0 0 network_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1204 ( "<=" PGNSP PGUID b f 869 869 16 1206 1205 0 0 0 0 network_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1205 ( ">" PGNSP PGUID b f 869 869 16 1203 1204 0 0 0 0 network_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1206 ( ">=" PGNSP PGUID b f 869 869 16 1204 1203 0 0 0 0 network_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 931 ( "<<" PGNSP PGUID b f 869 869 16 933 0 0 0 0 0 network_sub - - )); +DATA(insert OID = 1201 ( "=" PGNSP PGUID b t t 869 869 16 1201 1202 network_eq eqsel eqjoinsel )); +DATA(insert OID = 1202 ( "<>" PGNSP PGUID b f f 869 869 16 1202 1201 network_ne neqsel neqjoinsel )); +DATA(insert OID = 1203 ( "<" PGNSP PGUID b f f 869 869 16 1205 1206 network_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1204 ( "<=" PGNSP PGUID b f f 869 869 16 1206 1205 network_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1205 ( ">" PGNSP PGUID b f f 869 869 16 1203 1204 network_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1206 ( ">=" PGNSP PGUID b f f 869 869 16 1204 1203 network_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 931 ( "<<" PGNSP PGUID b f f 869 869 16 933 0 network_sub - - )); #define OID_INET_SUB_OP 931 -DATA(insert OID = 932 ( "<<=" PGNSP PGUID b f 869 869 16 934 0 0 0 0 0 network_subeq - - )); +DATA(insert OID = 932 ( "<<=" PGNSP PGUID b f f 869 869 16 934 0 network_subeq - - )); #define OID_INET_SUBEQ_OP 932 -DATA(insert OID = 933 ( ">>" PGNSP PGUID b f 869 869 16 931 0 0 0 0 0 network_sup - - )); +DATA(insert OID = 933 ( ">>" PGNSP PGUID b f f 869 869 16 931 0 network_sup - - )); #define OID_INET_SUP_OP 933 -DATA(insert OID = 934 ( ">>=" PGNSP PGUID b f 869 869 16 932 0 0 0 0 0 network_supeq - - )); +DATA(insert OID = 934 ( ">>=" PGNSP PGUID b f f 869 869 16 932 0 network_supeq - - )); #define OID_INET_SUPEQ_OP 934 -DATA(insert OID = 2634 ( "~" PGNSP PGUID l f 0 869 869 0 0 0 0 0 0 inetnot - - )); -DATA(insert OID = 2635 ( "&" PGNSP PGUID b f 869 869 869 0 0 0 0 0 0 inetand - - )); -DATA(insert OID = 2636 ( "|" PGNSP PGUID b f 869 869 869 0 0 0 0 0 0 inetor - - )); -DATA(insert OID = 2637 ( "+" PGNSP PGUID b f 869 20 869 2638 0 0 0 0 0 inetpl - - )); -DATA(insert OID = 2638 ( "+" PGNSP PGUID b f 20 869 869 2637 0 0 0 0 0 int8pl_inet - - )); -DATA(insert OID = 2639 ( "-" PGNSP PGUID b f 869 20 869 0 0 0 0 0 0 inetmi_int8 - - )); -DATA(insert OID = 2640 ( "-" PGNSP PGUID b f 869 869 20 0 0 0 0 0 0 inetmi - - )); +DATA(insert OID = 2634 ( "~" PGNSP PGUID l f f 0 869 869 0 0 inetnot - - )); +DATA(insert OID = 2635 ( "&" PGNSP PGUID b f f 869 869 869 0 0 inetand - - )); +DATA(insert OID = 2636 ( "|" PGNSP PGUID b f f 869 869 869 0 0 inetor - - )); +DATA(insert OID = 2637 ( "+" PGNSP PGUID b f f 869 20 869 2638 0 inetpl - - )); +DATA(insert OID = 2638 ( "+" PGNSP PGUID b f f 20 869 869 2637 0 int8pl_inet - - )); +DATA(insert OID = 2639 ( "-" PGNSP PGUID b f f 869 20 869 0 0 inetmi_int8 - - )); +DATA(insert OID = 2640 ( "-" PGNSP PGUID b f f 869 869 20 0 0 inetmi - - )); /* case-insensitive LIKE hacks */ -DATA(insert OID = 1625 ( "~~*" PGNSP PGUID b f 19 25 16 0 1626 0 0 0 0 nameiclike iclikesel iclikejoinsel )); +DATA(insert OID = 1625 ( "~~*" PGNSP PGUID b f f 19 25 16 0 1626 nameiclike iclikesel iclikejoinsel )); #define OID_NAME_ICLIKE_OP 1625 -DATA(insert OID = 1626 ( "!~~*" PGNSP PGUID b f 19 25 16 0 1625 0 0 0 0 nameicnlike icnlikesel icnlikejoinsel )); -DATA(insert OID = 1627 ( "~~*" PGNSP PGUID b f 25 25 16 0 1628 0 0 0 0 texticlike iclikesel iclikejoinsel )); +DATA(insert OID = 1626 ( "!~~*" PGNSP PGUID b f f 19 25 16 0 1625 nameicnlike icnlikesel icnlikejoinsel )); +DATA(insert OID = 1627 ( "~~*" PGNSP PGUID b f f 25 25 16 0 1628 texticlike iclikesel iclikejoinsel )); #define OID_TEXT_ICLIKE_OP 1627 -DATA(insert OID = 1628 ( "!~~*" PGNSP PGUID b f 25 25 16 0 1627 0 0 0 0 texticnlike icnlikesel icnlikejoinsel )); -DATA(insert OID = 1629 ( "~~*" PGNSP PGUID b f 1042 25 16 0 1630 0 0 0 0 bpchariclike iclikesel iclikejoinsel )); +DATA(insert OID = 1628 ( "!~~*" PGNSP PGUID b f f 25 25 16 0 1627 texticnlike icnlikesel icnlikejoinsel )); +DATA(insert OID = 1629 ( "~~*" PGNSP PGUID b f f 1042 25 16 0 1630 bpchariclike iclikesel iclikejoinsel )); #define OID_BPCHAR_ICLIKE_OP 1629 -DATA(insert OID = 1630 ( "!~~*" PGNSP PGUID b f 1042 25 16 0 1629 0 0 0 0 bpcharicnlike icnlikesel icnlikejoinsel )); +DATA(insert OID = 1630 ( "!~~*" PGNSP PGUID b f f 1042 25 16 0 1629 bpcharicnlike icnlikesel icnlikejoinsel )); /* NUMERIC type - OID's 1700-1799 */ -DATA(insert OID = 1751 ( "-" PGNSP PGUID l f 0 1700 1700 0 0 0 0 0 0 numeric_uminus - - )); -DATA(insert OID = 1752 ( "=" PGNSP PGUID b f 1700 1700 16 1752 1753 1754 1754 1754 1756 numeric_eq eqsel eqjoinsel )); -DATA(insert OID = 1753 ( "<>" PGNSP PGUID b f 1700 1700 16 1753 1752 0 0 0 0 numeric_ne neqsel neqjoinsel )); -DATA(insert OID = 1754 ( "<" PGNSP PGUID b f 1700 1700 16 1756 1757 0 0 0 0 numeric_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1755 ( "<=" PGNSP PGUID b f 1700 1700 16 1757 1756 0 0 0 0 numeric_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1756 ( ">" PGNSP PGUID b f 1700 1700 16 1754 1755 0 0 0 0 numeric_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1757 ( ">=" PGNSP PGUID b f 1700 1700 16 1755 1754 0 0 0 0 numeric_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1758 ( "+" PGNSP PGUID b f 1700 1700 1700 1758 0 0 0 0 0 numeric_add - - )); -DATA(insert OID = 1759 ( "-" PGNSP PGUID b f 1700 1700 1700 0 0 0 0 0 0 numeric_sub - - )); -DATA(insert OID = 1760 ( "*" PGNSP PGUID b f 1700 1700 1700 1760 0 0 0 0 0 numeric_mul - - )); -DATA(insert OID = 1761 ( "/" PGNSP PGUID b f 1700 1700 1700 0 0 0 0 0 0 numeric_div - - )); -DATA(insert OID = 1762 ( "%" PGNSP PGUID b f 1700 1700 1700 0 0 0 0 0 0 numeric_mod - - )); -DATA(insert OID = 1038 ( "^" PGNSP PGUID b f 1700 1700 1700 0 0 0 0 0 0 numeric_power - - )); -DATA(insert OID = 1763 ( "@" PGNSP PGUID l f 0 1700 1700 0 0 0 0 0 0 numeric_abs - - )); +DATA(insert OID = 1751 ( "-" PGNSP PGUID l f f 0 1700 1700 0 0 numeric_uminus - - )); +DATA(insert OID = 1752 ( "=" PGNSP PGUID b t f 1700 1700 16 1752 1753 numeric_eq eqsel eqjoinsel )); +DATA(insert OID = 1753 ( "<>" PGNSP PGUID b f f 1700 1700 16 1753 1752 numeric_ne neqsel neqjoinsel )); +DATA(insert OID = 1754 ( "<" PGNSP PGUID b f f 1700 1700 16 1756 1757 numeric_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1755 ( "<=" PGNSP PGUID b f f 1700 1700 16 1757 1756 numeric_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1756 ( ">" PGNSP PGUID b f f 1700 1700 16 1754 1755 numeric_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1757 ( ">=" PGNSP PGUID b f f 1700 1700 16 1755 1754 numeric_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1758 ( "+" PGNSP PGUID b f f 1700 1700 1700 1758 0 numeric_add - - )); +DATA(insert OID = 1759 ( "-" PGNSP PGUID b f f 1700 1700 1700 0 0 numeric_sub - - )); +DATA(insert OID = 1760 ( "*" PGNSP PGUID b f f 1700 1700 1700 1760 0 numeric_mul - - )); +DATA(insert OID = 1761 ( "/" PGNSP PGUID b f f 1700 1700 1700 0 0 numeric_div - - )); +DATA(insert OID = 1762 ( "%" PGNSP PGUID b f f 1700 1700 1700 0 0 numeric_mod - - )); +DATA(insert OID = 1038 ( "^" PGNSP PGUID b f f 1700 1700 1700 0 0 numeric_power - - )); +DATA(insert OID = 1763 ( "@" PGNSP PGUID l f f 0 1700 1700 0 0 numeric_abs - - )); -DATA(insert OID = 1784 ( "=" PGNSP PGUID b f 1560 1560 16 1784 1785 1786 1786 1786 1787 biteq eqsel eqjoinsel )); -DATA(insert OID = 1785 ( "<>" PGNSP PGUID b f 1560 1560 16 1785 1784 0 0 0 0 bitne neqsel neqjoinsel )); -DATA(insert OID = 1786 ( "<" PGNSP PGUID b f 1560 1560 16 1787 1789 0 0 0 0 bitlt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1787 ( ">" PGNSP PGUID b f 1560 1560 16 1786 1788 0 0 0 0 bitgt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1788 ( "<=" PGNSP PGUID b f 1560 1560 16 1789 1787 0 0 0 0 bitle scalarltsel scalarltjoinsel )); -DATA(insert OID = 1789 ( ">=" PGNSP PGUID b f 1560 1560 16 1788 1786 0 0 0 0 bitge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1791 ( "&" PGNSP PGUID b f 1560 1560 1560 1791 0 0 0 0 0 bitand - - )); -DATA(insert OID = 1792 ( "|" PGNSP PGUID b f 1560 1560 1560 1792 0 0 0 0 0 bitor - - )); -DATA(insert OID = 1793 ( "#" PGNSP PGUID b f 1560 1560 1560 1793 0 0 0 0 0 bitxor - - )); -DATA(insert OID = 1794 ( "~" PGNSP PGUID l f 0 1560 1560 0 0 0 0 0 0 bitnot - - )); -DATA(insert OID = 1795 ( "<<" PGNSP PGUID b f 1560 23 1560 0 0 0 0 0 0 bitshiftleft - - )); -DATA(insert OID = 1796 ( ">>" PGNSP PGUID b f 1560 23 1560 0 0 0 0 0 0 bitshiftright - - )); -DATA(insert OID = 1797 ( "||" PGNSP PGUID b f 1560 1560 1560 0 0 0 0 0 0 bitcat - - )); +DATA(insert OID = 1784 ( "=" PGNSP PGUID b t f 1560 1560 16 1784 1785 biteq eqsel eqjoinsel )); +DATA(insert OID = 1785 ( "<>" PGNSP PGUID b f f 1560 1560 16 1785 1784 bitne neqsel neqjoinsel )); +DATA(insert OID = 1786 ( "<" PGNSP PGUID b f f 1560 1560 16 1787 1789 bitlt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1787 ( ">" PGNSP PGUID b f f 1560 1560 16 1786 1788 bitgt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1788 ( "<=" PGNSP PGUID b f f 1560 1560 16 1789 1787 bitle scalarltsel scalarltjoinsel )); +DATA(insert OID = 1789 ( ">=" PGNSP PGUID b f f 1560 1560 16 1788 1786 bitge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1791 ( "&" PGNSP PGUID b f f 1560 1560 1560 1791 0 bitand - - )); +DATA(insert OID = 1792 ( "|" PGNSP PGUID b f f 1560 1560 1560 1792 0 bitor - - )); +DATA(insert OID = 1793 ( "#" PGNSP PGUID b f f 1560 1560 1560 1793 0 bitxor - - )); +DATA(insert OID = 1794 ( "~" PGNSP PGUID l f f 0 1560 1560 0 0 bitnot - - )); +DATA(insert OID = 1795 ( "<<" PGNSP PGUID b f f 1560 23 1560 0 0 bitshiftleft - - )); +DATA(insert OID = 1796 ( ">>" PGNSP PGUID b f f 1560 23 1560 0 0 bitshiftright - - )); +DATA(insert OID = 1797 ( "||" PGNSP PGUID b f f 1560 1560 1560 0 0 bitcat - - )); -DATA(insert OID = 1800 ( "+" PGNSP PGUID b f 1083 1186 1083 1849 0 0 0 0 0 time_pl_interval - - )); -DATA(insert OID = 1801 ( "-" PGNSP PGUID b f 1083 1186 1083 0 0 0 0 0 0 time_mi_interval - - )); -DATA(insert OID = 1802 ( "+" PGNSP PGUID b f 1266 1186 1266 2552 0 0 0 0 0 timetz_pl_interval - - )); -DATA(insert OID = 1803 ( "-" PGNSP PGUID b f 1266 1186 1266 0 0 0 0 0 0 timetz_mi_interval - - )); +DATA(insert OID = 1800 ( "+" PGNSP PGUID b f f 1083 1186 1083 1849 0 time_pl_interval - - )); +DATA(insert OID = 1801 ( "-" PGNSP PGUID b f f 1083 1186 1083 0 0 time_mi_interval - - )); +DATA(insert OID = 1802 ( "+" PGNSP PGUID b f f 1266 1186 1266 2552 0 timetz_pl_interval - - )); +DATA(insert OID = 1803 ( "-" PGNSP PGUID b f f 1266 1186 1266 0 0 timetz_mi_interval - - )); -DATA(insert OID = 1804 ( "=" PGNSP PGUID b f 1562 1562 16 1804 1805 1806 1806 1806 1807 varbiteq eqsel eqjoinsel )); -DATA(insert OID = 1805 ( "<>" PGNSP PGUID b f 1562 1562 16 1805 1804 0 0 0 0 varbitne neqsel neqjoinsel )); -DATA(insert OID = 1806 ( "<" PGNSP PGUID b f 1562 1562 16 1807 1809 0 0 0 0 varbitlt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1807 ( ">" PGNSP PGUID b f 1562 1562 16 1806 1808 0 0 0 0 varbitgt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1808 ( "<=" PGNSP PGUID b f 1562 1562 16 1809 1807 0 0 0 0 varbitle scalarltsel scalarltjoinsel )); -DATA(insert OID = 1809 ( ">=" PGNSP PGUID b f 1562 1562 16 1808 1806 0 0 0 0 varbitge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1804 ( "=" PGNSP PGUID b t f 1562 1562 16 1804 1805 varbiteq eqsel eqjoinsel )); +DATA(insert OID = 1805 ( "<>" PGNSP PGUID b f f 1562 1562 16 1805 1804 varbitne neqsel neqjoinsel )); +DATA(insert OID = 1806 ( "<" PGNSP PGUID b f f 1562 1562 16 1807 1809 varbitlt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1807 ( ">" PGNSP PGUID b f f 1562 1562 16 1806 1808 varbitgt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1808 ( "<=" PGNSP PGUID b f f 1562 1562 16 1809 1807 varbitle scalarltsel scalarltjoinsel )); +DATA(insert OID = 1809 ( ">=" PGNSP PGUID b f f 1562 1562 16 1808 1806 varbitge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1849 ( "+" PGNSP PGUID b f 1186 1083 1083 1800 0 0 0 0 0 interval_pl_time - - )); +DATA(insert OID = 1849 ( "+" PGNSP PGUID b f f 1186 1083 1083 1800 0 interval_pl_time - - )); -DATA(insert OID = 1862 ( "=" PGNSP PGUID b f 21 20 16 1868 1863 95 412 1864 1865 int28eq eqsel eqjoinsel )); -DATA(insert OID = 1863 ( "<>" PGNSP PGUID b f 21 20 16 1869 1862 0 0 0 0 int28ne neqsel neqjoinsel )); -DATA(insert OID = 1864 ( "<" PGNSP PGUID b f 21 20 16 1871 1867 0 0 0 0 int28lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1865 ( ">" PGNSP PGUID b f 21 20 16 1870 1866 0 0 0 0 int28gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1866 ( "<=" PGNSP PGUID b f 21 20 16 1873 1865 0 0 0 0 int28le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1867 ( ">=" PGNSP PGUID b f 21 20 16 1872 1864 0 0 0 0 int28ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1862 ( "=" PGNSP PGUID b t f 21 20 16 1868 1863 int28eq eqsel eqjoinsel )); +DATA(insert OID = 1863 ( "<>" PGNSP PGUID b f f 21 20 16 1869 1862 int28ne neqsel neqjoinsel )); +DATA(insert OID = 1864 ( "<" PGNSP PGUID b f f 21 20 16 1871 1867 int28lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1865 ( ">" PGNSP PGUID b f f 21 20 16 1870 1866 int28gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1866 ( "<=" PGNSP PGUID b f f 21 20 16 1873 1865 int28le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1867 ( ">=" PGNSP PGUID b f f 21 20 16 1872 1864 int28ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1868 ( "=" PGNSP PGUID b f 20 21 16 1862 1869 412 95 1870 1871 int82eq eqsel eqjoinsel )); -DATA(insert OID = 1869 ( "<>" PGNSP PGUID b f 20 21 16 1863 1868 0 0 0 0 int82ne neqsel neqjoinsel )); -DATA(insert OID = 1870 ( "<" PGNSP PGUID b f 20 21 16 1865 1873 0 0 0 0 int82lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1871 ( ">" PGNSP PGUID b f 20 21 16 1864 1872 0 0 0 0 int82gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1872 ( "<=" PGNSP PGUID b f 20 21 16 1867 1871 0 0 0 0 int82le scalarltsel scalarltjoinsel )); -DATA(insert OID = 1873 ( ">=" PGNSP PGUID b f 20 21 16 1866 1870 0 0 0 0 int82ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 1868 ( "=" PGNSP PGUID b t f 20 21 16 1862 1869 int82eq eqsel eqjoinsel )); +DATA(insert OID = 1869 ( "<>" PGNSP PGUID b f f 20 21 16 1863 1868 int82ne neqsel neqjoinsel )); +DATA(insert OID = 1870 ( "<" PGNSP PGUID b f f 20 21 16 1865 1873 int82lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1871 ( ">" PGNSP PGUID b f f 20 21 16 1864 1872 int82gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1872 ( "<=" PGNSP PGUID b f f 20 21 16 1867 1871 int82le scalarltsel scalarltjoinsel )); +DATA(insert OID = 1873 ( ">=" PGNSP PGUID b f f 20 21 16 1866 1870 int82ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 1874 ( "&" PGNSP PGUID b f 21 21 21 1874 0 0 0 0 0 int2and - - )); -DATA(insert OID = 1875 ( "|" PGNSP PGUID b f 21 21 21 1875 0 0 0 0 0 int2or - - )); -DATA(insert OID = 1876 ( "#" PGNSP PGUID b f 21 21 21 1876 0 0 0 0 0 int2xor - - )); -DATA(insert OID = 1877 ( "~" PGNSP PGUID l f 0 21 21 0 0 0 0 0 0 int2not - - )); -DATA(insert OID = 1878 ( "<<" PGNSP PGUID b f 21 23 21 0 0 0 0 0 0 int2shl - - )); -DATA(insert OID = 1879 ( ">>" PGNSP PGUID b f 21 23 21 0 0 0 0 0 0 int2shr - - )); +DATA(insert OID = 1874 ( "&" PGNSP PGUID b f f 21 21 21 1874 0 int2and - - )); +DATA(insert OID = 1875 ( "|" PGNSP PGUID b f f 21 21 21 1875 0 int2or - - )); +DATA(insert OID = 1876 ( "#" PGNSP PGUID b f f 21 21 21 1876 0 int2xor - - )); +DATA(insert OID = 1877 ( "~" PGNSP PGUID l f f 0 21 21 0 0 int2not - - )); +DATA(insert OID = 1878 ( "<<" PGNSP PGUID b f f 21 23 21 0 0 int2shl - - )); +DATA(insert OID = 1879 ( ">>" PGNSP PGUID b f f 21 23 21 0 0 int2shr - - )); -DATA(insert OID = 1880 ( "&" PGNSP PGUID b f 23 23 23 1880 0 0 0 0 0 int4and - - )); -DATA(insert OID = 1881 ( "|" PGNSP PGUID b f 23 23 23 1881 0 0 0 0 0 int4or - - )); -DATA(insert OID = 1882 ( "#" PGNSP PGUID b f 23 23 23 1882 0 0 0 0 0 int4xor - - )); -DATA(insert OID = 1883 ( "~" PGNSP PGUID l f 0 23 23 0 0 0 0 0 0 int4not - - )); -DATA(insert OID = 1884 ( "<<" PGNSP PGUID b f 23 23 23 0 0 0 0 0 0 int4shl - - )); -DATA(insert OID = 1885 ( ">>" PGNSP PGUID b f 23 23 23 0 0 0 0 0 0 int4shr - - )); +DATA(insert OID = 1880 ( "&" PGNSP PGUID b f f 23 23 23 1880 0 int4and - - )); +DATA(insert OID = 1881 ( "|" PGNSP PGUID b f f 23 23 23 1881 0 int4or - - )); +DATA(insert OID = 1882 ( "#" PGNSP PGUID b f f 23 23 23 1882 0 int4xor - - )); +DATA(insert OID = 1883 ( "~" PGNSP PGUID l f f 0 23 23 0 0 int4not - - )); +DATA(insert OID = 1884 ( "<<" PGNSP PGUID b f f 23 23 23 0 0 int4shl - - )); +DATA(insert OID = 1885 ( ">>" PGNSP PGUID b f f 23 23 23 0 0 int4shr - - )); -DATA(insert OID = 1886 ( "&" PGNSP PGUID b f 20 20 20 1886 0 0 0 0 0 int8and - - )); -DATA(insert OID = 1887 ( "|" PGNSP PGUID b f 20 20 20 1887 0 0 0 0 0 int8or - - )); -DATA(insert OID = 1888 ( "#" PGNSP PGUID b f 20 20 20 1888 0 0 0 0 0 int8xor - - )); -DATA(insert OID = 1889 ( "~" PGNSP PGUID l f 0 20 20 0 0 0 0 0 0 int8not - - )); -DATA(insert OID = 1890 ( "<<" PGNSP PGUID b f 20 23 20 0 0 0 0 0 0 int8shl - - )); -DATA(insert OID = 1891 ( ">>" PGNSP PGUID b f 20 23 20 0 0 0 0 0 0 int8shr - - )); +DATA(insert OID = 1886 ( "&" PGNSP PGUID b f f 20 20 20 1886 0 int8and - - )); +DATA(insert OID = 1887 ( "|" PGNSP PGUID b f f 20 20 20 1887 0 int8or - - )); +DATA(insert OID = 1888 ( "#" PGNSP PGUID b f f 20 20 20 1888 0 int8xor - - )); +DATA(insert OID = 1889 ( "~" PGNSP PGUID l f f 0 20 20 0 0 int8not - - )); +DATA(insert OID = 1890 ( "<<" PGNSP PGUID b f f 20 23 20 0 0 int8shl - - )); +DATA(insert OID = 1891 ( ">>" PGNSP PGUID b f f 20 23 20 0 0 int8shr - - )); -DATA(insert OID = 1916 ( "+" PGNSP PGUID l f 0 20 20 0 0 0 0 0 0 int8up - - )); -DATA(insert OID = 1917 ( "+" PGNSP PGUID l f 0 21 21 0 0 0 0 0 0 int2up - - )); -DATA(insert OID = 1918 ( "+" PGNSP PGUID l f 0 23 23 0 0 0 0 0 0 int4up - - )); -DATA(insert OID = 1919 ( "+" PGNSP PGUID l f 0 700 700 0 0 0 0 0 0 float4up - - )); -DATA(insert OID = 1920 ( "+" PGNSP PGUID l f 0 701 701 0 0 0 0 0 0 float8up - - )); -DATA(insert OID = 1921 ( "+" PGNSP PGUID l f 0 1700 1700 0 0 0 0 0 0 numeric_uplus - - )); +DATA(insert OID = 1916 ( "+" PGNSP PGUID l f f 0 20 20 0 0 int8up - - )); +DATA(insert OID = 1917 ( "+" PGNSP PGUID l f f 0 21 21 0 0 int2up - - )); +DATA(insert OID = 1918 ( "+" PGNSP PGUID l f f 0 23 23 0 0 int4up - - )); +DATA(insert OID = 1919 ( "+" PGNSP PGUID l f f 0 700 700 0 0 float4up - - )); +DATA(insert OID = 1920 ( "+" PGNSP PGUID l f f 0 701 701 0 0 float8up - - )); +DATA(insert OID = 1921 ( "+" PGNSP PGUID l f f 0 1700 1700 0 0 numeric_uplus - - )); /* bytea operators */ -DATA(insert OID = 1955 ( "=" PGNSP PGUID b t 17 17 16 1955 1956 1957 1957 1957 1959 byteaeq eqsel eqjoinsel )); -DATA(insert OID = 1956 ( "<>" PGNSP PGUID b f 17 17 16 1956 1955 0 0 0 0 byteane neqsel neqjoinsel )); -DATA(insert OID = 1957 ( "<" PGNSP PGUID b f 17 17 16 1959 1960 0 0 0 0 bytealt scalarltsel scalarltjoinsel )); -DATA(insert OID = 1958 ( "<=" PGNSP PGUID b f 17 17 16 1960 1959 0 0 0 0 byteale scalarltsel scalarltjoinsel )); -DATA(insert OID = 1959 ( ">" PGNSP PGUID b f 17 17 16 1957 1958 0 0 0 0 byteagt scalargtsel scalargtjoinsel )); -DATA(insert OID = 1960 ( ">=" PGNSP PGUID b f 17 17 16 1958 1957 0 0 0 0 byteage scalargtsel scalargtjoinsel )); -DATA(insert OID = 2016 ( "~~" PGNSP PGUID b f 17 17 16 0 2017 0 0 0 0 bytealike likesel likejoinsel )); +DATA(insert OID = 1955 ( "=" PGNSP PGUID b t t 17 17 16 1955 1956 byteaeq eqsel eqjoinsel )); +DATA(insert OID = 1956 ( "<>" PGNSP PGUID b f f 17 17 16 1956 1955 byteane neqsel neqjoinsel )); +DATA(insert OID = 1957 ( "<" PGNSP PGUID b f f 17 17 16 1959 1960 bytealt scalarltsel scalarltjoinsel )); +DATA(insert OID = 1958 ( "<=" PGNSP PGUID b f f 17 17 16 1960 1959 byteale scalarltsel scalarltjoinsel )); +DATA(insert OID = 1959 ( ">" PGNSP PGUID b f f 17 17 16 1957 1958 byteagt scalargtsel scalargtjoinsel )); +DATA(insert OID = 1960 ( ">=" PGNSP PGUID b f f 17 17 16 1958 1957 byteage scalargtsel scalargtjoinsel )); +DATA(insert OID = 2016 ( "~~" PGNSP PGUID b f f 17 17 16 0 2017 bytealike likesel likejoinsel )); #define OID_BYTEA_LIKE_OP 2016 -DATA(insert OID = 2017 ( "!~~" PGNSP PGUID b f 17 17 16 0 2016 0 0 0 0 byteanlike nlikesel nlikejoinsel )); -DATA(insert OID = 2018 ( "||" PGNSP PGUID b f 17 17 17 0 0 0 0 0 0 byteacat - - )); +DATA(insert OID = 2017 ( "!~~" PGNSP PGUID b f f 17 17 16 0 2016 byteanlike nlikesel nlikejoinsel )); +DATA(insert OID = 2018 ( "||" PGNSP PGUID b f f 17 17 17 0 0 byteacat - - )); /* timestamp operators */ -DATA(insert OID = 2060 ( "=" PGNSP PGUID b t 1114 1114 16 2060 2061 2062 2062 2062 2064 timestamp_eq eqsel eqjoinsel )); -DATA(insert OID = 2061 ( "<>" PGNSP PGUID b f 1114 1114 16 2061 2060 0 0 0 0 timestamp_ne neqsel neqjoinsel )); -DATA(insert OID = 2062 ( "<" PGNSP PGUID b f 1114 1114 16 2064 2065 0 0 0 0 timestamp_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 2063 ( "<=" PGNSP PGUID b f 1114 1114 16 2065 2064 0 0 0 0 timestamp_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 2064 ( ">" PGNSP PGUID b f 1114 1114 16 2062 2063 0 0 0 0 timestamp_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 2065 ( ">=" PGNSP PGUID b f 1114 1114 16 2063 2062 0 0 0 0 timestamp_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 2066 ( "+" PGNSP PGUID b f 1114 1186 1114 2553 0 0 0 0 0 timestamp_pl_interval - - )); -DATA(insert OID = 2067 ( "-" PGNSP PGUID b f 1114 1114 1186 0 0 0 0 0 0 timestamp_mi - - )); -DATA(insert OID = 2068 ( "-" PGNSP PGUID b f 1114 1186 1114 0 0 0 0 0 0 timestamp_mi_interval - - )); +DATA(insert OID = 2060 ( "=" PGNSP PGUID b t t 1114 1114 16 2060 2061 timestamp_eq eqsel eqjoinsel )); +DATA(insert OID = 2061 ( "<>" PGNSP PGUID b f f 1114 1114 16 2061 2060 timestamp_ne neqsel neqjoinsel )); +DATA(insert OID = 2062 ( "<" PGNSP PGUID b f f 1114 1114 16 2064 2065 timestamp_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 2063 ( "<=" PGNSP PGUID b f f 1114 1114 16 2065 2064 timestamp_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 2064 ( ">" PGNSP PGUID b f f 1114 1114 16 2062 2063 timestamp_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 2065 ( ">=" PGNSP PGUID b f f 1114 1114 16 2063 2062 timestamp_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 2066 ( "+" PGNSP PGUID b f f 1114 1186 1114 2553 0 timestamp_pl_interval - - )); +DATA(insert OID = 2067 ( "-" PGNSP PGUID b f f 1114 1114 1186 0 0 timestamp_mi - - )); +DATA(insert OID = 2068 ( "-" PGNSP PGUID b f f 1114 1186 1114 0 0 timestamp_mi_interval - - )); /* character-by-character (not collation order) comparison operators for character types */ -DATA(insert OID = 2314 ( "~<~" PGNSP PGUID b f 25 25 16 2318 2317 0 0 0 0 text_pattern_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 2315 ( "~<=~" PGNSP PGUID b f 25 25 16 2317 2318 0 0 0 0 text_pattern_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 2316 ( "~=~" PGNSP PGUID b t 25 25 16 2316 2319 2314 2314 2314 2318 text_pattern_eq eqsel eqjoinsel )); -DATA(insert OID = 2317 ( "~>=~" PGNSP PGUID b f 25 25 16 2315 2314 0 0 0 0 text_pattern_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 2318 ( "~>~" PGNSP PGUID b f 25 25 16 2314 2315 0 0 0 0 text_pattern_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 2319 ( "~<>~" PGNSP PGUID b f 25 25 16 2319 2316 0 0 0 0 text_pattern_ne neqsel neqjoinsel )); +DATA(insert OID = 2314 ( "~<~" PGNSP PGUID b f f 25 25 16 2318 2317 text_pattern_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 2315 ( "~<=~" PGNSP PGUID b f f 25 25 16 2317 2318 text_pattern_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 2316 ( "~=~" PGNSP PGUID b t t 25 25 16 2316 2319 text_pattern_eq eqsel eqjoinsel )); +DATA(insert OID = 2317 ( "~>=~" PGNSP PGUID b f f 25 25 16 2315 2314 text_pattern_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 2318 ( "~>~" PGNSP PGUID b f f 25 25 16 2314 2315 text_pattern_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 2319 ( "~<>~" PGNSP PGUID b f f 25 25 16 2319 2316 text_pattern_ne neqsel neqjoinsel )); -DATA(insert OID = 2326 ( "~<~" PGNSP PGUID b f 1042 1042 16 2330 2329 0 0 0 0 bpchar_pattern_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 2327 ( "~<=~" PGNSP PGUID b f 1042 1042 16 2329 2330 0 0 0 0 bpchar_pattern_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 2328 ( "~=~" PGNSP PGUID b t 1042 1042 16 2328 2331 2326 2326 2326 2330 bpchar_pattern_eq eqsel eqjoinsel )); -DATA(insert OID = 2329 ( "~>=~" PGNSP PGUID b f 1042 1042 16 2327 2326 0 0 0 0 bpchar_pattern_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 2330 ( "~>~" PGNSP PGUID b f 1042 1042 16 2326 2327 0 0 0 0 bpchar_pattern_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 2331 ( "~<>~" PGNSP PGUID b f 1042 1042 16 2331 2328 0 0 0 0 bpchar_pattern_ne neqsel neqjoinsel )); +DATA(insert OID = 2326 ( "~<~" PGNSP PGUID b f f 1042 1042 16 2330 2329 bpchar_pattern_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 2327 ( "~<=~" PGNSP PGUID b f f 1042 1042 16 2329 2330 bpchar_pattern_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 2328 ( "~=~" PGNSP PGUID b t t 1042 1042 16 2328 2331 bpchar_pattern_eq eqsel eqjoinsel )); +DATA(insert OID = 2329 ( "~>=~" PGNSP PGUID b f f 1042 1042 16 2327 2326 bpchar_pattern_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 2330 ( "~>~" PGNSP PGUID b f f 1042 1042 16 2326 2327 bpchar_pattern_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 2331 ( "~<>~" PGNSP PGUID b f f 1042 1042 16 2331 2328 bpchar_pattern_ne neqsel neqjoinsel )); -DATA(insert OID = 2332 ( "~<~" PGNSP PGUID b f 19 19 16 2336 2335 0 0 0 0 name_pattern_lt scalarltsel scalarltjoinsel )); -DATA(insert OID = 2333 ( "~<=~" PGNSP PGUID b f 19 19 16 2335 2336 0 0 0 0 name_pattern_le scalarltsel scalarltjoinsel )); -DATA(insert OID = 2334 ( "~=~" PGNSP PGUID b t 19 19 16 2334 2337 2332 2332 2332 2336 name_pattern_eq eqsel eqjoinsel )); -DATA(insert OID = 2335 ( "~>=~" PGNSP PGUID b f 19 19 16 2333 2332 0 0 0 0 name_pattern_ge scalargtsel scalargtjoinsel )); -DATA(insert OID = 2336 ( "~>~" PGNSP PGUID b f 19 19 16 2332 2333 0 0 0 0 name_pattern_gt scalargtsel scalargtjoinsel )); -DATA(insert OID = 2337 ( "~<>~" PGNSP PGUID b f 19 19 16 2337 2334 0 0 0 0 name_pattern_ne neqsel neqjoinsel )); +DATA(insert OID = 2332 ( "~<~" PGNSP PGUID b f f 19 19 16 2336 2335 name_pattern_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 2333 ( "~<=~" PGNSP PGUID b f f 19 19 16 2335 2336 name_pattern_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 2334 ( "~=~" PGNSP PGUID b t t 19 19 16 2334 2337 name_pattern_eq eqsel eqjoinsel )); +DATA(insert OID = 2335 ( "~>=~" PGNSP PGUID b f f 19 19 16 2333 2332 name_pattern_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 2336 ( "~>~" PGNSP PGUID b f f 19 19 16 2332 2333 name_pattern_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 2337 ( "~<>~" PGNSP PGUID b f f 19 19 16 2337 2334 name_pattern_ne neqsel neqjoinsel )); /* crosstype operations for date vs. timestamp and timestamptz */ -DATA(insert OID = 2345 ( "<" PGNSP PGUID b f 1082 1114 16 2375 2348 0 0 0 0 date_lt_timestamp scalarltsel scalarltjoinsel )); -DATA(insert OID = 2346 ( "<=" PGNSP PGUID b f 1082 1114 16 2374 2349 0 0 0 0 date_le_timestamp scalarltsel scalarltjoinsel )); -DATA(insert OID = 2347 ( "=" PGNSP PGUID b f 1082 1114 16 2373 2350 1095 2062 2345 2349 date_eq_timestamp eqsel eqjoinsel )); -DATA(insert OID = 2348 ( ">=" PGNSP PGUID b f 1082 1114 16 2372 2345 0 0 0 0 date_ge_timestamp scalargtsel scalargtjoinsel )); -DATA(insert OID = 2349 ( ">" PGNSP PGUID b f 1082 1114 16 2371 2346 0 0 0 0 date_gt_timestamp scalargtsel scalargtjoinsel )); -DATA(insert OID = 2350 ( "<>" PGNSP PGUID b f 1082 1114 16 2376 2347 0 0 0 0 date_ne_timestamp neqsel neqjoinsel )); +DATA(insert OID = 2345 ( "<" PGNSP PGUID b f f 1082 1114 16 2375 2348 date_lt_timestamp scalarltsel scalarltjoinsel )); +DATA(insert OID = 2346 ( "<=" PGNSP PGUID b f f 1082 1114 16 2374 2349 date_le_timestamp scalarltsel scalarltjoinsel )); +DATA(insert OID = 2347 ( "=" PGNSP PGUID b t f 1082 1114 16 2373 2350 date_eq_timestamp eqsel eqjoinsel )); +DATA(insert OID = 2348 ( ">=" PGNSP PGUID b f f 1082 1114 16 2372 2345 date_ge_timestamp scalargtsel scalargtjoinsel )); +DATA(insert OID = 2349 ( ">" PGNSP PGUID b f f 1082 1114 16 2371 2346 date_gt_timestamp scalargtsel scalargtjoinsel )); +DATA(insert OID = 2350 ( "<>" PGNSP PGUID b f f 1082 1114 16 2376 2347 date_ne_timestamp neqsel neqjoinsel )); -DATA(insert OID = 2358 ( "<" PGNSP PGUID b f 1082 1184 16 2388 2361 0 0 0 0 date_lt_timestamptz scalarltsel scalarltjoinsel )); -DATA(insert OID = 2359 ( "<=" PGNSP PGUID b f 1082 1184 16 2387 2362 0 0 0 0 date_le_timestamptz scalarltsel scalarltjoinsel )); -DATA(insert OID = 2360 ( "=" PGNSP PGUID b f 1082 1184 16 2386 2363 1095 1322 2358 2362 date_eq_timestamptz eqsel eqjoinsel )); -DATA(insert OID = 2361 ( ">=" PGNSP PGUID b f 1082 1184 16 2385 2358 0 0 0 0 date_ge_timestamptz scalargtsel scalargtjoinsel )); -DATA(insert OID = 2362 ( ">" PGNSP PGUID b f 1082 1184 16 2384 2359 0 0 0 0 date_gt_timestamptz scalargtsel scalargtjoinsel )); -DATA(insert OID = 2363 ( "<>" PGNSP PGUID b f 1082 1184 16 2389 2360 0 0 0 0 date_ne_timestamptz neqsel neqjoinsel )); +DATA(insert OID = 2358 ( "<" PGNSP PGUID b f f 1082 1184 16 2388 2361 date_lt_timestamptz scalarltsel scalarltjoinsel )); +DATA(insert OID = 2359 ( "<=" PGNSP PGUID b f f 1082 1184 16 2387 2362 date_le_timestamptz scalarltsel scalarltjoinsel )); +DATA(insert OID = 2360 ( "=" PGNSP PGUID b t f 1082 1184 16 2386 2363 date_eq_timestamptz eqsel eqjoinsel )); +DATA(insert OID = 2361 ( ">=" PGNSP PGUID b f f 1082 1184 16 2385 2358 date_ge_timestamptz scalargtsel scalargtjoinsel )); +DATA(insert OID = 2362 ( ">" PGNSP PGUID b f f 1082 1184 16 2384 2359 date_gt_timestamptz scalargtsel scalargtjoinsel )); +DATA(insert OID = 2363 ( "<>" PGNSP PGUID b f f 1082 1184 16 2389 2360 date_ne_timestamptz neqsel neqjoinsel )); -DATA(insert OID = 2371 ( "<" PGNSP PGUID b f 1114 1082 16 2349 2374 0 0 0 0 timestamp_lt_date scalarltsel scalarltjoinsel )); -DATA(insert OID = 2372 ( "<=" PGNSP PGUID b f 1114 1082 16 2348 2375 0 0 0 0 timestamp_le_date scalarltsel scalarltjoinsel )); -DATA(insert OID = 2373 ( "=" PGNSP PGUID b f 1114 1082 16 2347 2376 2062 1095 2371 2375 timestamp_eq_date eqsel eqjoinsel )); -DATA(insert OID = 2374 ( ">=" PGNSP PGUID b f 1114 1082 16 2346 2371 0 0 0 0 timestamp_ge_date scalargtsel scalargtjoinsel )); -DATA(insert OID = 2375 ( ">" PGNSP PGUID b f 1114 1082 16 2345 2372 0 0 0 0 timestamp_gt_date scalargtsel scalargtjoinsel )); -DATA(insert OID = 2376 ( "<>" PGNSP PGUID b f 1114 1082 16 2350 2373 0 0 0 0 timestamp_ne_date neqsel neqjoinsel )); +DATA(insert OID = 2371 ( "<" PGNSP PGUID b f f 1114 1082 16 2349 2374 timestamp_lt_date scalarltsel scalarltjoinsel )); +DATA(insert OID = 2372 ( "<=" PGNSP PGUID b f f 1114 1082 16 2348 2375 timestamp_le_date scalarltsel scalarltjoinsel )); +DATA(insert OID = 2373 ( "=" PGNSP PGUID b t f 1114 1082 16 2347 2376 timestamp_eq_date eqsel eqjoinsel )); +DATA(insert OID = 2374 ( ">=" PGNSP PGUID b f f 1114 1082 16 2346 2371 timestamp_ge_date scalargtsel scalargtjoinsel )); +DATA(insert OID = 2375 ( ">" PGNSP PGUID b f f 1114 1082 16 2345 2372 timestamp_gt_date scalargtsel scalargtjoinsel )); +DATA(insert OID = 2376 ( "<>" PGNSP PGUID b f f 1114 1082 16 2350 2373 timestamp_ne_date neqsel neqjoinsel )); -DATA(insert OID = 2384 ( "<" PGNSP PGUID b f 1184 1082 16 2362 2387 0 0 0 0 timestamptz_lt_date scalarltsel scalarltjoinsel )); -DATA(insert OID = 2385 ( "<=" PGNSP PGUID b f 1184 1082 16 2361 2388 0 0 0 0 timestamptz_le_date scalarltsel scalarltjoinsel )); -DATA(insert OID = 2386 ( "=" PGNSP PGUID b f 1184 1082 16 2360 2389 1322 1095 2384 2388 timestamptz_eq_date eqsel eqjoinsel )); -DATA(insert OID = 2387 ( ">=" PGNSP PGUID b f 1184 1082 16 2359 2384 0 0 0 0 timestamptz_ge_date scalargtsel scalargtjoinsel )); -DATA(insert OID = 2388 ( ">" PGNSP PGUID b f 1184 1082 16 2358 2385 0 0 0 0 timestamptz_gt_date scalargtsel scalargtjoinsel )); -DATA(insert OID = 2389 ( "<>" PGNSP PGUID b f 1184 1082 16 2363 2386 0 0 0 0 timestamptz_ne_date neqsel neqjoinsel )); +DATA(insert OID = 2384 ( "<" PGNSP PGUID b f f 1184 1082 16 2362 2387 timestamptz_lt_date scalarltsel scalarltjoinsel )); +DATA(insert OID = 2385 ( "<=" PGNSP PGUID b f f 1184 1082 16 2361 2388 timestamptz_le_date scalarltsel scalarltjoinsel )); +DATA(insert OID = 2386 ( "=" PGNSP PGUID b t f 1184 1082 16 2360 2389 timestamptz_eq_date eqsel eqjoinsel )); +DATA(insert OID = 2387 ( ">=" PGNSP PGUID b f f 1184 1082 16 2359 2384 timestamptz_ge_date scalargtsel scalargtjoinsel )); +DATA(insert OID = 2388 ( ">" PGNSP PGUID b f f 1184 1082 16 2358 2385 timestamptz_gt_date scalargtsel scalargtjoinsel )); +DATA(insert OID = 2389 ( "<>" PGNSP PGUID b f f 1184 1082 16 2363 2386 timestamptz_ne_date neqsel neqjoinsel )); /* crosstype operations for timestamp vs. timestamptz */ -DATA(insert OID = 2534 ( "<" PGNSP PGUID b f 1114 1184 16 2544 2537 0 0 0 0 timestamp_lt_timestamptz scalarltsel scalarltjoinsel )); -DATA(insert OID = 2535 ( "<=" PGNSP PGUID b f 1114 1184 16 2543 2538 0 0 0 0 timestamp_le_timestamptz scalarltsel scalarltjoinsel )); -DATA(insert OID = 2536 ( "=" PGNSP PGUID b f 1114 1184 16 2542 2539 2062 1322 2534 2538 timestamp_eq_timestamptz eqsel eqjoinsel )); -DATA(insert OID = 2537 ( ">=" PGNSP PGUID b f 1114 1184 16 2541 2534 0 0 0 0 timestamp_ge_timestamptz scalargtsel scalargtjoinsel )); -DATA(insert OID = 2538 ( ">" PGNSP PGUID b f 1114 1184 16 2540 2535 0 0 0 0 timestamp_gt_timestamptz scalargtsel scalargtjoinsel )); -DATA(insert OID = 2539 ( "<>" PGNSP PGUID b f 1114 1184 16 2545 2536 0 0 0 0 timestamp_ne_timestamptz neqsel neqjoinsel )); +DATA(insert OID = 2534 ( "<" PGNSP PGUID b f f 1114 1184 16 2544 2537 timestamp_lt_timestamptz scalarltsel scalarltjoinsel )); +DATA(insert OID = 2535 ( "<=" PGNSP PGUID b f f 1114 1184 16 2543 2538 timestamp_le_timestamptz scalarltsel scalarltjoinsel )); +DATA(insert OID = 2536 ( "=" PGNSP PGUID b t f 1114 1184 16 2542 2539 timestamp_eq_timestamptz eqsel eqjoinsel )); +DATA(insert OID = 2537 ( ">=" PGNSP PGUID b f f 1114 1184 16 2541 2534 timestamp_ge_timestamptz scalargtsel scalargtjoinsel )); +DATA(insert OID = 2538 ( ">" PGNSP PGUID b f f 1114 1184 16 2540 2535 timestamp_gt_timestamptz scalargtsel scalargtjoinsel )); +DATA(insert OID = 2539 ( "<>" PGNSP PGUID b f f 1114 1184 16 2545 2536 timestamp_ne_timestamptz neqsel neqjoinsel )); -DATA(insert OID = 2540 ( "<" PGNSP PGUID b f 1184 1114 16 2538 2543 0 0 0 0 timestamptz_lt_timestamp scalarltsel scalarltjoinsel )); -DATA(insert OID = 2541 ( "<=" PGNSP PGUID b f 1184 1114 16 2537 2544 0 0 0 0 timestamptz_le_timestamp scalarltsel scalarltjoinsel )); -DATA(insert OID = 2542 ( "=" PGNSP PGUID b f 1184 1114 16 2536 2545 1322 2062 2540 2544 timestamptz_eq_timestamp eqsel eqjoinsel )); -DATA(insert OID = 2543 ( ">=" PGNSP PGUID b f 1184 1114 16 2535 2540 0 0 0 0 timestamptz_ge_timestamp scalargtsel scalargtjoinsel )); -DATA(insert OID = 2544 ( ">" PGNSP PGUID b f 1184 1114 16 2534 2541 0 0 0 0 timestamptz_gt_timestamp scalargtsel scalargtjoinsel )); -DATA(insert OID = 2545 ( "<>" PGNSP PGUID b f 1184 1114 16 2539 2542 0 0 0 0 timestamptz_ne_timestamp neqsel neqjoinsel )); +DATA(insert OID = 2540 ( "<" PGNSP PGUID b f f 1184 1114 16 2538 2543 timestamptz_lt_timestamp scalarltsel scalarltjoinsel )); +DATA(insert OID = 2541 ( "<=" PGNSP PGUID b f f 1184 1114 16 2537 2544 timestamptz_le_timestamp scalarltsel scalarltjoinsel )); +DATA(insert OID = 2542 ( "=" PGNSP PGUID b t f 1184 1114 16 2536 2545 timestamptz_eq_timestamp eqsel eqjoinsel )); +DATA(insert OID = 2543 ( ">=" PGNSP PGUID b f f 1184 1114 16 2535 2540 timestamptz_ge_timestamp scalargtsel scalargtjoinsel )); +DATA(insert OID = 2544 ( ">" PGNSP PGUID b f f 1184 1114 16 2534 2541 timestamptz_gt_timestamp scalargtsel scalargtjoinsel )); +DATA(insert OID = 2545 ( "<>" PGNSP PGUID b f f 1184 1114 16 2539 2542 timestamptz_ne_timestamp neqsel neqjoinsel )); /* formerly-missing interval + datetime operators */ -DATA(insert OID = 2551 ( "+" PGNSP PGUID b f 1186 1082 1114 1076 0 0 0 0 0 interval_pl_date - - )); -DATA(insert OID = 2552 ( "+" PGNSP PGUID b f 1186 1266 1266 1802 0 0 0 0 0 interval_pl_timetz - - )); -DATA(insert OID = 2553 ( "+" PGNSP PGUID b f 1186 1114 1114 2066 0 0 0 0 0 interval_pl_timestamp - - )); -DATA(insert OID = 2554 ( "+" PGNSP PGUID b f 1186 1184 1184 1327 0 0 0 0 0 interval_pl_timestamptz - - )); -DATA(insert OID = 2555 ( "+" PGNSP PGUID b f 23 1082 1082 1100 0 0 0 0 0 integer_pl_date - - )); +DATA(insert OID = 2551 ( "+" PGNSP PGUID b f f 1186 1082 1114 1076 0 interval_pl_date - - )); +DATA(insert OID = 2552 ( "+" PGNSP PGUID b f f 1186 1266 1266 1802 0 interval_pl_timetz - - )); +DATA(insert OID = 2553 ( "+" PGNSP PGUID b f f 1186 1114 1114 2066 0 interval_pl_timestamp - - )); +DATA(insert OID = 2554 ( "+" PGNSP PGUID b f f 1186 1184 1184 1327 0 interval_pl_timestamptz - - )); +DATA(insert OID = 2555 ( "+" PGNSP PGUID b f f 23 1082 1082 1100 0 integer_pl_date - - )); /* new operators for Y-direction rtree opclasses */ -DATA(insert OID = 2570 ( "<<|" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_below positionsel positionjoinsel )); -DATA(insert OID = 2571 ( "&<|" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_overbelow positionsel positionjoinsel )); -DATA(insert OID = 2572 ( "|&>" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_overabove positionsel positionjoinsel )); -DATA(insert OID = 2573 ( "|>>" PGNSP PGUID b f 603 603 16 0 0 0 0 0 0 box_above positionsel positionjoinsel )); -DATA(insert OID = 2574 ( "<<|" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_below positionsel positionjoinsel )); -DATA(insert OID = 2575 ( "&<|" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_overbelow positionsel positionjoinsel )); -DATA(insert OID = 2576 ( "|&>" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_overabove positionsel positionjoinsel )); -DATA(insert OID = 2577 ( "|>>" PGNSP PGUID b f 604 604 16 0 0 0 0 0 0 poly_above positionsel positionjoinsel )); -DATA(insert OID = 2589 ( "&<|" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_overbelow positionsel positionjoinsel )); -DATA(insert OID = 2590 ( "|&>" PGNSP PGUID b f 718 718 16 0 0 0 0 0 0 circle_overabove positionsel positionjoinsel )); +DATA(insert OID = 2570 ( "<<|" PGNSP PGUID b f f 603 603 16 0 0 box_below positionsel positionjoinsel )); +DATA(insert OID = 2571 ( "&<|" PGNSP PGUID b f f 603 603 16 0 0 box_overbelow positionsel positionjoinsel )); +DATA(insert OID = 2572 ( "|&>" PGNSP PGUID b f f 603 603 16 0 0 box_overabove positionsel positionjoinsel )); +DATA(insert OID = 2573 ( "|>>" PGNSP PGUID b f f 603 603 16 0 0 box_above positionsel positionjoinsel )); +DATA(insert OID = 2574 ( "<<|" PGNSP PGUID b f f 604 604 16 0 0 poly_below positionsel positionjoinsel )); +DATA(insert OID = 2575 ( "&<|" PGNSP PGUID b f f 604 604 16 0 0 poly_overbelow positionsel positionjoinsel )); +DATA(insert OID = 2576 ( "|&>" PGNSP PGUID b f f 604 604 16 0 0 poly_overabove positionsel positionjoinsel )); +DATA(insert OID = 2577 ( "|>>" PGNSP PGUID b f f 604 604 16 0 0 poly_above positionsel positionjoinsel )); +DATA(insert OID = 2589 ( "&<|" PGNSP PGUID b f f 718 718 16 0 0 circle_overbelow positionsel positionjoinsel )); +DATA(insert OID = 2590 ( "|&>" PGNSP PGUID b f f 718 718 16 0 0 circle_overabove positionsel positionjoinsel )); /* overlap/contains/contained for arrays */ -DATA(insert OID = 2750 ( "&&" PGNSP PGUID b f 2277 2277 16 2750 0 0 0 0 0 arrayoverlap areasel areajoinsel )); -DATA(insert OID = 2751 ( "@>" PGNSP PGUID b f 2277 2277 16 2752 0 0 0 0 0 arraycontains contsel contjoinsel )); -DATA(insert OID = 2752 ( "<@" PGNSP PGUID b f 2277 2277 16 2751 0 0 0 0 0 arraycontained contsel contjoinsel )); +DATA(insert OID = 2750 ( "&&" PGNSP PGUID b f f 2277 2277 16 2750 0 arrayoverlap areasel areajoinsel )); +DATA(insert OID = 2751 ( "@>" PGNSP PGUID b f f 2277 2277 16 2752 0 arraycontains contsel contjoinsel )); +DATA(insert OID = 2752 ( "<@" PGNSP PGUID b f f 2277 2277 16 2751 0 arraycontained contsel contjoinsel )); /* obsolete names for contains/contained-by operators; remove these someday */ -DATA(insert OID = 2860 ( "@" PGNSP PGUID b f 604 604 16 2861 0 0 0 0 0 poly_contained contsel contjoinsel )); -DATA(insert OID = 2861 ( "~" PGNSP PGUID b f 604 604 16 2860 0 0 0 0 0 poly_contain contsel contjoinsel )); -DATA(insert OID = 2862 ( "@" PGNSP PGUID b f 603 603 16 2863 0 0 0 0 0 box_contained contsel contjoinsel )); -DATA(insert OID = 2863 ( "~" PGNSP PGUID b f 603 603 16 2862 0 0 0 0 0 box_contain contsel contjoinsel )); -DATA(insert OID = 2864 ( "@" PGNSP PGUID b f 718 718 16 2865 0 0 0 0 0 circle_contained contsel contjoinsel )); -DATA(insert OID = 2865 ( "~" PGNSP PGUID b f 718 718 16 2864 0 0 0 0 0 circle_contain contsel contjoinsel )); -DATA(insert OID = 2866 ( "@" PGNSP PGUID b f 600 603 16 0 0 0 0 0 0 on_pb - - )); -DATA(insert OID = 2867 ( "@" PGNSP PGUID b f 600 602 16 2868 0 0 0 0 0 on_ppath - - )); -DATA(insert OID = 2868 ( "~" PGNSP PGUID b f 602 600 16 2867 0 0 0 0 0 path_contain_pt - - )); -DATA(insert OID = 2869 ( "@" PGNSP PGUID b f 600 604 16 2870 0 0 0 0 0 pt_contained_poly - - )); -DATA(insert OID = 2870 ( "~" PGNSP PGUID b f 604 600 16 2869 0 0 0 0 0 poly_contain_pt - - )); -DATA(insert OID = 2871 ( "@" PGNSP PGUID b f 600 718 16 2872 0 0 0 0 0 pt_contained_circle - - )); -DATA(insert OID = 2872 ( "~" PGNSP PGUID b f 718 600 16 2871 0 0 0 0 0 circle_contain_pt - - )); -DATA(insert OID = 2873 ( "@" PGNSP PGUID b f 600 628 16 0 0 0 0 0 0 on_pl - - )); -DATA(insert OID = 2874 ( "@" PGNSP PGUID b f 600 601 16 0 0 0 0 0 0 on_ps - - )); -DATA(insert OID = 2875 ( "@" PGNSP PGUID b f 601 628 16 0 0 0 0 0 0 on_sl - - )); -DATA(insert OID = 2876 ( "@" PGNSP PGUID b f 601 603 16 0 0 0 0 0 0 on_sb - - )); -DATA(insert OID = 2877 ( "~" PGNSP PGUID b f 1034 1033 16 0 0 0 0 0 0 aclcontains - - )); +DATA(insert OID = 2860 ( "@" PGNSP PGUID b f f 604 604 16 2861 0 poly_contained contsel contjoinsel )); +DATA(insert OID = 2861 ( "~" PGNSP PGUID b f f 604 604 16 2860 0 poly_contain contsel contjoinsel )); +DATA(insert OID = 2862 ( "@" PGNSP PGUID b f f 603 603 16 2863 0 box_contained contsel contjoinsel )); +DATA(insert OID = 2863 ( "~" PGNSP PGUID b f f 603 603 16 2862 0 box_contain contsel contjoinsel )); +DATA(insert OID = 2864 ( "@" PGNSP PGUID b f f 718 718 16 2865 0 circle_contained contsel contjoinsel )); +DATA(insert OID = 2865 ( "~" PGNSP PGUID b f f 718 718 16 2864 0 circle_contain contsel contjoinsel )); +DATA(insert OID = 2866 ( "@" PGNSP PGUID b f f 600 603 16 0 0 on_pb - - )); +DATA(insert OID = 2867 ( "@" PGNSP PGUID b f f 600 602 16 2868 0 on_ppath - - )); +DATA(insert OID = 2868 ( "~" PGNSP PGUID b f f 602 600 16 2867 0 path_contain_pt - - )); +DATA(insert OID = 2869 ( "@" PGNSP PGUID b f f 600 604 16 2870 0 pt_contained_poly - - )); +DATA(insert OID = 2870 ( "~" PGNSP PGUID b f f 604 600 16 2869 0 poly_contain_pt - - )); +DATA(insert OID = 2871 ( "@" PGNSP PGUID b f f 600 718 16 2872 0 pt_contained_circle - - )); +DATA(insert OID = 2872 ( "~" PGNSP PGUID b f f 718 600 16 2871 0 circle_contain_pt - - )); +DATA(insert OID = 2873 ( "@" PGNSP PGUID b f f 600 628 16 0 0 on_pl - - )); +DATA(insert OID = 2874 ( "@" PGNSP PGUID b f f 600 601 16 0 0 on_ps - - )); +DATA(insert OID = 2875 ( "@" PGNSP PGUID b f f 601 628 16 0 0 on_sl - - )); +DATA(insert OID = 2876 ( "@" PGNSP PGUID b f f 601 603 16 0 0 on_sb - - )); +DATA(insert OID = 2877 ( "~" PGNSP PGUID b f f 1034 1033 16 0 0 aclcontains - - )); /* @@ -916,10 +908,7 @@ extern void OperatorCreate(const char *operatorName, List *negatorName, List *restrictionName, List *joinName, - bool canHash, - List *leftSortName, - List *rightSortName, - List *ltCompareName, - List *gtCompareName); + bool canMerge, + bool canHash); #endif /* PG_OPERATOR_H */ diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h new file mode 100644 index 0000000000..8e51fb7419 --- /dev/null +++ b/src/include/catalog/pg_opfamily.h @@ -0,0 +1,138 @@ +/*------------------------------------------------------------------------- + * + * pg_opfamily.h + * definition of the system "opfamily" relation (pg_opfamily) + * along with the relation's initial contents. + * + * + * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/include/catalog/pg_opfamily.h,v 1.1 2006/12/23 00:43:12 tgl Exp $ + * + * NOTES + * the genbki.sh script reads this file and generates .bki + * information from the DATA() statements. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_OPFAMILY_H +#define PG_OPFAMILY_H + +/* ---------------- + * postgres.h contains the system type definitions and the + * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file + * can be read by both genbki.sh and the C compiler. + * ---------------- + */ + +/* ---------------- + * pg_opfamily definition. cpp turns this into + * typedef struct FormData_pg_opfamily + * ---------------- + */ +#define OperatorFamilyRelationId 2753 + +CATALOG(pg_opfamily,2753) +{ + Oid opfmethod; /* index access method opfamily is for */ + NameData opfname; /* name of this opfamily */ + Oid opfnamespace; /* namespace of this opfamily */ + Oid opfowner; /* opfamily owner */ +} FormData_pg_opfamily; + +/* ---------------- + * Form_pg_opfamily corresponds to a pointer to a tuple with + * the format of pg_opfamily relation. + * ---------------- + */ +typedef FormData_pg_opfamily *Form_pg_opfamily; + +/* ---------------- + * compiler constants for pg_opfamily + * ---------------- + */ +#define Natts_pg_opfamily 4 +#define Anum_pg_opfamily_opfmethod 1 +#define Anum_pg_opfamily_opfname 2 +#define Anum_pg_opfamily_opfnamespace 3 +#define Anum_pg_opfamily_opfowner 4 + +/* ---------------- + * initial contents of pg_opfamily + * ---------------- + */ + +DATA(insert OID = 421 ( 403 abstime_ops PGNSP PGUID )); +DATA(insert OID = 397 ( 403 array_ops PGNSP PGUID )); +DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID )); +DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID )); +#define BOOL_BTREE_FAM_OID 424 +DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID )); +#define BPCHAR_BTREE_FAM_OID 426 +DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID )); +DATA(insert OID = 428 ( 403 bytea_ops PGNSP PGUID )); +#define BYTEA_BTREE_FAM_OID 428 +DATA(insert OID = 429 ( 403 char_ops PGNSP PGUID )); +DATA(insert OID = 431 ( 405 char_ops PGNSP PGUID )); +DATA(insert OID = 434 ( 403 datetime_ops PGNSP PGUID )); +DATA(insert OID = 435 ( 405 date_ops PGNSP PGUID )); +DATA(insert OID = 1970 ( 403 float_ops PGNSP PGUID )); +DATA(insert OID = 1971 ( 405 float_ops PGNSP PGUID )); +DATA(insert OID = 1974 ( 403 network_ops PGNSP PGUID )); +#define NETWORK_BTREE_FAM_OID 1974 +DATA(insert OID = 1975 ( 405 network_ops PGNSP PGUID )); +DATA(insert OID = 1976 ( 403 integer_ops PGNSP PGUID )); +#define INTEGER_BTREE_FAM_OID 1976 +DATA(insert OID = 1977 ( 405 integer_ops PGNSP PGUID )); +DATA(insert OID = 1982 ( 403 interval_ops PGNSP PGUID )); +DATA(insert OID = 1983 ( 405 interval_ops PGNSP PGUID )); +DATA(insert OID = 1984 ( 403 macaddr_ops PGNSP PGUID )); +DATA(insert OID = 1985 ( 405 macaddr_ops PGNSP PGUID )); +DATA(insert OID = 1986 ( 403 name_ops PGNSP PGUID )); +#define NAME_BTREE_FAM_OID 1986 +DATA(insert OID = 1987 ( 405 name_ops PGNSP PGUID )); +DATA(insert OID = 1988 ( 403 numeric_ops PGNSP PGUID )); +DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID )); +#define OID_BTREE_FAM_OID 1989 +DATA(insert OID = 1990 ( 405 oid_ops PGNSP PGUID )); +DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID )); +DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID )); +DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID )); +#define TEXT_BTREE_FAM_OID 1994 +DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID )); +DATA(insert OID = 1996 ( 403 time_ops PGNSP PGUID )); +DATA(insert OID = 1997 ( 405 time_ops PGNSP PGUID )); +DATA(insert OID = 1999 ( 405 timestamptz_ops PGNSP PGUID )); +DATA(insert OID = 2000 ( 403 timetz_ops PGNSP PGUID )); +DATA(insert OID = 2001 ( 405 timetz_ops PGNSP PGUID )); +DATA(insert OID = 2002 ( 403 varbit_ops PGNSP PGUID )); +DATA(insert OID = 2040 ( 405 timestamp_ops PGNSP PGUID )); +DATA(insert OID = 2095 ( 403 text_pattern_ops PGNSP PGUID )); +#define TEXT_PATTERN_BTREE_FAM_OID 2095 +DATA(insert OID = 2097 ( 403 bpchar_pattern_ops PGNSP PGUID )); +#define BPCHAR_PATTERN_BTREE_FAM_OID 2097 +DATA(insert OID = 2098 ( 403 name_pattern_ops PGNSP PGUID )); +#define NAME_PATTERN_BTREE_FAM_OID 2098 +DATA(insert OID = 2099 ( 403 money_ops PGNSP PGUID )); +DATA(insert OID = 2222 ( 405 bool_ops PGNSP PGUID )); +#define BOOL_HASH_FAM_OID 2222 +DATA(insert OID = 2223 ( 405 bytea_ops PGNSP PGUID )); +DATA(insert OID = 2224 ( 405 int2vector_ops PGNSP PGUID )); +DATA(insert OID = 2789 ( 403 tid_ops PGNSP PGUID )); +DATA(insert OID = 2225 ( 405 xid_ops PGNSP PGUID )); +DATA(insert OID = 2226 ( 405 cid_ops PGNSP PGUID )); +DATA(insert OID = 2227 ( 405 abstime_ops PGNSP PGUID )); +DATA(insert OID = 2228 ( 405 reltime_ops PGNSP PGUID )); +DATA(insert OID = 2229 ( 405 text_pattern_ops PGNSP PGUID )); +DATA(insert OID = 2231 ( 405 bpchar_pattern_ops PGNSP PGUID )); +DATA(insert OID = 2232 ( 405 name_pattern_ops PGNSP PGUID )); +DATA(insert OID = 2233 ( 403 reltime_ops PGNSP PGUID )); +DATA(insert OID = 2234 ( 403 tinterval_ops PGNSP PGUID )); +DATA(insert OID = 2235 ( 405 aclitem_ops PGNSP PGUID )); +DATA(insert OID = 2593 ( 783 box_ops PGNSP PGUID )); +DATA(insert OID = 2594 ( 783 poly_ops PGNSP PGUID )); +DATA(insert OID = 2595 ( 783 circle_ops PGNSP PGUID )); +DATA(insert OID = 2745 ( 2742 array_ops PGNSP PGUID )); + +#endif /* PG_OPFAMILY_H */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 7b45ea5735..4c8ac8c876 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.77 2006/10/04 00:30:08 momjian Exp $ + * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.78 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -81,6 +81,9 @@ extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId); extern void DefineOpClass(CreateOpClassStmt *stmt); extern void RemoveOpClass(RemoveOpClassStmt *stmt); extern void RemoveOpClassById(Oid opclassOid); +extern void RemoveOpFamilyById(Oid opfamilyOid); +extern void RemoveAmOpEntryById(Oid entryOid); +extern void RemoveAmProcEntryById(Oid entryOid); extern void RenameOpClass(List *name, const char *access_method, const char *newname); extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index f79bf2907c..bc62c90f4d 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.334 2006/11/05 22:42:10 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.335 2006/12/23 00:43:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1318,6 +1318,7 @@ typedef struct CreateOpClassStmt { NodeTag type; List *opclassname; /* qualified name (list of Value strings) */ + List *opfamilyname; /* qualified name (ditto); NIL if omitted */ char *amname; /* name of index AM opclass is for */ TypeName *datatype; /* datatype of indexed column */ List *items; /* List of CreateOpClassItem nodes */ diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 5c2de28a41..e8250504eb 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.85 2006/08/02 01:59:47 joe Exp $ + * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.86 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -351,7 +351,9 @@ typedef struct NestLoop typedef struct MergeJoin { Join join; - List *mergeclauses; + List *mergeclauses; /* mergeclauses as expression trees */ + List *mergefamilies; /* OID list of btree opfamilies */ + List *mergestrategies; /* integer list of btree strategies */ } MergeJoin; /* ---------------- diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 9654181bc3..5946300c97 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -10,7 +10,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.119 2006/12/21 16:05:16 petere Exp $ + * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.120 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -654,7 +654,7 @@ typedef struct RowExpr * * We support row comparison for any operator that can be determined to * act like =, <>, <, <=, >, or >= (we determine this by looking for the - * operator in btree opclasses). Note that the same operator name might + * operator in btree opfamilies). Note that the same operator name might * map to a different operator for each pair of row elements, since the * element datatypes can vary. * @@ -679,7 +679,7 @@ typedef struct RowCompareExpr Expr xpr; RowCompareType rctype; /* LT LE GE or GT, never EQ or NE */ List *opnos; /* OID list of pairwise comparison ops */ - List *opclasses; /* OID list of containing operator classes */ + List *opfamilies; /* OID list of containing operator families */ List *largs; /* the left-hand input arguments */ List *rargs; /* the right-hand input arguments */ } RowCompareExpr; diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index d39e924227..955773d147 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.128 2006/10/04 00:30:09 momjian Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.129 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -300,11 +300,11 @@ typedef struct RelOptInfo * and indexes, but that created confusion without actually doing anything * useful. So now we have a separate IndexOptInfo struct for indexes. * - * classlist[], indexkeys[], and ordering[] have ncolumns entries. + * opfamily[], indexkeys[], and ordering[] have ncolumns entries. * Zeroes in the indexkeys[] array indicate index columns that are * expressions; there is one element in indexprs for each such column. * - * Note: for historical reasons, the classlist and ordering arrays have + * Note: for historical reasons, the opfamily and ordering arrays have * an extra entry that is always zero. Some code scans until it sees a * zero entry, rather than looking at ncolumns. * @@ -326,7 +326,7 @@ typedef struct IndexOptInfo /* index descriptor information */ int ncolumns; /* number of columns in index */ - Oid *classlist; /* OIDs of operator classes for columns */ + Oid *opfamily; /* OIDs of operator families for columns */ int *indexkeys; /* column numbers of index's keys, or 0 */ Oid *ordering; /* OIDs of sort operators for each column */ Oid relam; /* OID of the access method (in pg_am) */ @@ -611,7 +611,9 @@ typedef JoinPath NestPath; * A mergejoin path has these fields. * * path_mergeclauses lists the clauses (in the form of RestrictInfos) - * that will be used in the merge. + * that will be used in the merge. The parallel lists path_mergefamilies + * and path_mergestrategies specify the merge semantics for each clause + * (in effect, defining the relevant sort ordering for each clause). * * Note that the mergeclauses are a subset of the parent relation's * restriction-clause list. Any join clauses that are not mergejoinable @@ -628,6 +630,8 @@ typedef struct MergePath { JoinPath jpath; List *path_mergeclauses; /* join clauses to be used for merge */ + List *path_mergefamilies; /* OID list of btree opfamilies */ + List *path_mergestrategies; /* integer list of btree strategies */ List *outersortkeys; /* keys for explicit sort, if any */ List *innersortkeys; /* keys for explicit sort, if any */ } MergePath; @@ -780,6 +784,7 @@ typedef struct RestrictInfo Oid mergejoinoperator; /* copy of clause operator */ Oid left_sortop; /* leftside sortop needed for mergejoin */ Oid right_sortop; /* rightside sortop needed for mergejoin */ + Oid mergeopfamily; /* btree opfamily relating these ops */ /* cache space for mergeclause processing; NIL if not yet set */ List *left_pathkey; /* canonical pathkey for left side */ diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index f8aebd6a53..59c2a62a0a 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.72 2006/10/04 00:30:09 momjian Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.73 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -71,6 +71,8 @@ extern MergePath *create_mergejoin_path(PlannerInfo *root, List *restrict_clauses, List *pathkeys, List *mergeclauses, + List *mergefamilies, + List *mergestrategies, List *outersortkeys, List *innersortkeys); diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 69eb31bcc5..272b321e64 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.107 2006/10/04 00:30:10 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.108 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,16 +26,22 @@ typedef enum IOFuncSelector IOFunc_send } IOFuncSelector; -extern bool op_in_opclass(Oid opno, Oid opclass); -extern int get_op_opclass_strategy(Oid opno, Oid opclass); -extern void get_op_opclass_properties(Oid opno, Oid opclass, - int *strategy, Oid *subtype, +extern bool op_in_opfamily(Oid opno, Oid opfamily); +extern int get_op_opfamily_strategy(Oid opno, Oid opfamily); +extern void get_op_opfamily_properties(Oid opno, Oid opfamily, + int *strategy, + Oid *lefttype, + Oid *righttype, bool *recheck); -extern Oid get_opclass_member(Oid opclass, Oid subtype, int16 strategy); +extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, + int16 strategy); +extern bool get_op_mergejoin_info(Oid eq_op, Oid *left_sortop, + Oid *right_sortop, Oid *opfamily); extern Oid get_op_hash_function(Oid opno); extern void get_op_btree_interpretation(Oid opno, - List **opclasses, List **opstrats); -extern Oid get_opclass_proc(Oid opclass, Oid subtype, int16 procnum); + List **opfamilies, List **opstrats); +extern Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, + int16 procnum); extern char *get_attname(Oid relid, AttrNumber attnum); extern char *get_relid_attribute_name(Oid relid, AttrNumber attnum); extern AttrNumber get_attnum(Oid relid, const char *attname); @@ -43,16 +49,12 @@ extern Oid get_atttype(Oid relid, AttrNumber attnum); extern int32 get_atttypmod(Oid relid, AttrNumber attnum); extern void get_atttypetypmod(Oid relid, AttrNumber attnum, Oid *typid, int32 *typmod); -extern bool opclass_is_btree(Oid opclass); -extern bool opclass_is_hash(Oid opclass); -extern bool opclass_is_default(Oid opclass); +extern Oid get_opclass_family(Oid opclass); extern Oid get_opclass_input_type(Oid opclass); extern RegProcedure get_opcode(Oid opno); extern char *get_opname(Oid opno); extern void op_input_types(Oid opno, Oid *lefttype, Oid *righttype); -extern bool op_mergejoinable(Oid opno, Oid *leftOp, Oid *rightOp); -extern void op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop, - RegProcedure *ltproc, RegProcedure *gtproc); +extern bool op_mergejoinable(Oid opno); extern bool op_hashjoinable(Oid opno); extern bool op_strict(Oid opno); extern char op_volatile(Oid opno); diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 1f7347c9cd..283c04ae99 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.92 2006/10/04 00:30:10 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.93 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -165,16 +165,15 @@ typedef struct RelationData Form_pg_index rd_index; /* pg_index tuple describing this index */ struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */ /* "struct HeapTupleData *" avoids need to include htup.h here */ - oidvector *rd_indclass; /* extracted pointer to rd_index field */ Form_pg_am rd_am; /* pg_am tuple for index's AM */ /* * index access support info (used only for an index relation) * * Note: only default operators and support procs for each opclass are - * cached, namely those with subtype zero. The arrays are indexed by - * strategy or support number, which is a sufficient identifier given that - * restriction. + * cached, namely those with lefttype and righttype equal to the opclass's + * opcintype. The arrays are indexed by strategy or support number, + * which is a sufficient identifier given that restriction. * * Note: rd_amcache is available for index AMs to cache private data about * an index. This must be just a cache since it may get reset at any time @@ -185,6 +184,8 @@ typedef struct RelationData */ MemoryContext rd_indexcxt; /* private memory cxt for this stuff */ RelationAmInfo *rd_aminfo; /* lookup info for funcs found in pg_am */ + Oid *rd_opfamily; /* OIDs of op families for each index col */ + Oid *rd_opcintype; /* OIDs of opclass declared input data types */ Oid *rd_operator; /* OIDs of index operators */ RegProcedure *rd_support; /* OIDs of support procedures */ FmgrInfo *rd_supportinfo; /* lookup info for support procedures */ diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h index 69a22b37b5..bb6e35bfdc 100644 --- a/src/include/utils/selfuncs.h +++ b/src/include/utils/selfuncs.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.36 2006/10/04 00:30:11 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.37 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -160,6 +160,7 @@ extern Selectivity rowcomparesel(PlannerInfo *root, int varRelid, JoinType jointype); extern void mergejoinscansel(PlannerInfo *root, Node *clause, + Oid opfamily, int strategy, Selectivity *leftscan, Selectivity *rightscan); diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 5c84c7e17c..2305ccd1d0 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.65 2006/07/13 18:01:02 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.66 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -48,21 +48,22 @@ #define CONOID 17 #define DATABASEOID 18 #define INDEXRELID 19 -#define INHRELID 20 -#define LANGNAME 21 -#define LANGOID 22 -#define NAMESPACENAME 23 -#define NAMESPACEOID 24 -#define OPERNAMENSP 25 -#define OPEROID 26 -#define PROCNAMEARGSNSP 27 -#define PROCOID 28 -#define RELNAMENSP 29 -#define RELOID 30 -#define RULERELNAME 31 -#define STATRELATT 32 -#define TYPENAMENSP 33 -#define TYPEOID 34 +#define LANGNAME 20 +#define LANGOID 21 +#define NAMESPACENAME 22 +#define NAMESPACEOID 23 +#define OPERNAMENSP 24 +#define OPEROID 25 +#define OPFAMILYAMNAMENSP 26 +#define OPFAMILYOID 27 +#define PROCNAMEARGSNSP 28 +#define PROCOID 29 +#define RELNAMENSP 30 +#define RELOID 31 +#define RULERELNAME 32 +#define STATRELATT 33 +#define TYPENAMENSP 34 +#define TYPEOID 35 extern void InitCatalogCache(void); extern void InitCatalogCachePhase2(void); diff --git a/src/include/utils/typcache.h b/src/include/utils/typcache.h index 673bf176ad..5c8b0e850a 100644 --- a/src/include/utils/typcache.h +++ b/src/include/utils/typcache.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/typcache.h,v 1.12 2006/10/04 00:30:11 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/typcache.h,v 1.13 2006/12/23 00:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,17 +33,19 @@ typedef struct TypeCacheEntry Oid typrelid; /* - * Information obtained from opclass entries + * Information obtained from opfamily entries * * These will be InvalidOid if no match could be found, or if the * information hasn't yet been requested. */ - Oid btree_opc; /* OID of the default btree opclass */ - Oid hash_opc; /* OID of the default hash opclass */ - Oid eq_opr; /* OID of the equality operator */ - Oid lt_opr; /* OID of the less-than operator */ - Oid gt_opr; /* OID of the greater-than operator */ - Oid cmp_proc; /* OID of the btree comparison function */ + Oid btree_opf; /* the default btree opclass' family */ + Oid btree_opintype; /* the default btree opclass' opcintype */ + Oid hash_opf; /* the default hash opclass' family */ + Oid hash_opintype; /* the default hash opclass' opcintype */ + Oid eq_opr; /* the equality operator */ + Oid lt_opr; /* the less-than operator */ + Oid gt_opr; /* the greater-than operator */ + Oid cmp_proc; /* the btree comparison function */ /* * Pre-set-up fmgr call info for the equality operator and the btree @@ -71,6 +73,7 @@ typedef struct TypeCacheEntry #define TYPECACHE_EQ_OPR_FINFO 0x0010 #define TYPECACHE_CMP_PROC_FINFO 0x0020 #define TYPECACHE_TUPDESC 0x0040 +#define TYPECACHE_BTREE_OPFAMILY 0x0080 extern TypeCacheEntry *lookup_type_cache(Oid type_id, int flags); diff --git a/src/test/regress/expected/oidjoins.out b/src/test/regress/expected/oidjoins.out index 445f41ffb9..cc82b12e02 100644 --- a/src/test/regress/expected/oidjoins.out +++ b/src/test/regress/expected/oidjoins.out @@ -137,20 +137,36 @@ WHERE amcostestimate != 0 AND ------+---------------- (0 rows) -SELECT ctid, amopclaid -FROM pg_catalog.pg_amop fk -WHERE amopclaid != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid); - ctid | amopclaid +SELECT ctid, amoptions +FROM pg_catalog.pg_am fk +WHERE amoptions != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.amoptions); + ctid | amoptions ------+----------- (0 rows) -SELECT ctid, amopsubtype +SELECT ctid, amopfamily FROM pg_catalog.pg_amop fk -WHERE amopsubtype != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype); - ctid | amopsubtype -------+------------- +WHERE amopfamily != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amopfamily); + ctid | amopfamily +------+------------ +(0 rows) + +SELECT ctid, amoplefttype +FROM pg_catalog.pg_amop fk +WHERE amoplefttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoplefttype); + ctid | amoplefttype +------+-------------- +(0 rows) + +SELECT ctid, amoprighttype +FROM pg_catalog.pg_amop fk +WHERE amoprighttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoprighttype); + ctid | amoprighttype +------+--------------- (0 rows) SELECT ctid, amopopr @@ -161,20 +177,36 @@ WHERE amopopr != 0 AND ------+--------- (0 rows) -SELECT ctid, amopclaid -FROM pg_catalog.pg_amproc fk -WHERE amopclaid != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid); - ctid | amopclaid -------+----------- +SELECT ctid, amopmethod +FROM pg_catalog.pg_amop fk +WHERE amopmethod != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.amopmethod); + ctid | amopmethod +------+------------ (0 rows) -SELECT ctid, amprocsubtype +SELECT ctid, amprocfamily FROM pg_catalog.pg_amproc fk -WHERE amprocsubtype != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype); - ctid | amprocsubtype -------+--------------- +WHERE amprocfamily != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amprocfamily); + ctid | amprocfamily +------+-------------- +(0 rows) + +SELECT ctid, amproclefttype +FROM pg_catalog.pg_amproc fk +WHERE amproclefttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amproclefttype); + ctid | amproclefttype +------+---------------- +(0 rows) + +SELECT ctid, amprocrighttype +FROM pg_catalog.pg_amproc fk +WHERE amprocrighttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocrighttype); + ctid | amprocrighttype +------+----------------- (0 rows) SELECT ctid, amproc @@ -241,6 +273,14 @@ WHERE reltype != 0 AND ------+--------- (0 rows) +SELECT ctid, relowner +FROM pg_catalog.pg_class fk +WHERE relowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.relowner); + ctid | relowner +------+---------- +(0 rows) + SELECT ctid, relam FROM pg_catalog.pg_class fk WHERE relam != 0 AND @@ -297,6 +337,14 @@ WHERE connamespace != 0 AND ------+-------------- (0 rows) +SELECT ctid, conowner +FROM pg_catalog.pg_conversion fk +WHERE conowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.conowner); + ctid | conowner +------+---------- +(0 rows) + SELECT ctid, conproc FROM pg_catalog.pg_conversion fk WHERE conproc != 0 AND @@ -305,6 +353,14 @@ WHERE conproc != 0 AND ------+--------- (0 rows) +SELECT ctid, datdba +FROM pg_catalog.pg_database fk +WHERE datdba != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.datdba); + ctid | datdba +------+-------- +(0 rows) + SELECT ctid, dattablespace FROM pg_catalog.pg_database fk WHERE dattablespace != 0 AND @@ -361,12 +417,20 @@ WHERE lanvalidator != 0 AND ------+-------------- (0 rows) -SELECT ctid, opcamid +SELECT ctid, nspowner +FROM pg_catalog.pg_namespace fk +WHERE nspowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.nspowner); + ctid | nspowner +------+---------- +(0 rows) + +SELECT ctid, opcmethod FROM pg_catalog.pg_opclass fk -WHERE opcamid != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opcamid); - ctid | opcamid -------+--------- +WHERE opcmethod != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opcmethod); + ctid | opcmethod +------+----------- (0 rows) SELECT ctid, opcnamespace @@ -377,6 +441,22 @@ WHERE opcnamespace != 0 AND ------+-------------- (0 rows) +SELECT ctid, opcowner +FROM pg_catalog.pg_opclass fk +WHERE opcowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opcowner); + ctid | opcowner +------+---------- +(0 rows) + +SELECT ctid, opcfamily +FROM pg_catalog.pg_opclass fk +WHERE opcfamily != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.opcfamily); + ctid | opcfamily +------+----------- +(0 rows) + SELECT ctid, opcintype FROM pg_catalog.pg_opclass fk WHERE opcintype != 0 AND @@ -385,6 +465,14 @@ WHERE opcintype != 0 AND ------+----------- (0 rows) +SELECT ctid, opckeytype +FROM pg_catalog.pg_opclass fk +WHERE opckeytype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.opckeytype); + ctid | opckeytype +------+------------ +(0 rows) + SELECT ctid, oprnamespace FROM pg_catalog.pg_operator fk WHERE oprnamespace != 0 AND @@ -393,6 +481,14 @@ WHERE oprnamespace != 0 AND ------+-------------- (0 rows) +SELECT ctid, oprowner +FROM pg_catalog.pg_operator fk +WHERE oprowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.oprowner); + ctid | oprowner +------+---------- +(0 rows) + SELECT ctid, oprleft FROM pg_catalog.pg_operator fk WHERE oprleft != 0 AND @@ -433,38 +529,6 @@ WHERE oprnegate != 0 AND ------+----------- (0 rows) -SELECT ctid, oprlsortop -FROM pg_catalog.pg_operator fk -WHERE oprlsortop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprlsortop); - ctid | oprlsortop -------+------------ -(0 rows) - -SELECT ctid, oprrsortop -FROM pg_catalog.pg_operator fk -WHERE oprrsortop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprrsortop); - ctid | oprrsortop -------+------------ -(0 rows) - -SELECT ctid, oprltcmpop -FROM pg_catalog.pg_operator fk -WHERE oprltcmpop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprltcmpop); - ctid | oprltcmpop -------+------------ -(0 rows) - -SELECT ctid, oprgtcmpop -FROM pg_catalog.pg_operator fk -WHERE oprgtcmpop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprgtcmpop); - ctid | oprgtcmpop -------+------------ -(0 rows) - SELECT ctid, oprcode FROM pg_catalog.pg_operator fk WHERE oprcode != 0 AND @@ -489,6 +553,30 @@ WHERE oprjoin != 0 AND ------+--------- (0 rows) +SELECT ctid, opfmethod +FROM pg_catalog.pg_opfamily fk +WHERE opfmethod != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opfmethod); + ctid | opfmethod +------+----------- +(0 rows) + +SELECT ctid, opfnamespace +FROM pg_catalog.pg_opfamily fk +WHERE opfnamespace != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.opfnamespace); + ctid | opfnamespace +------+-------------- +(0 rows) + +SELECT ctid, opfowner +FROM pg_catalog.pg_opfamily fk +WHERE opfowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opfowner); + ctid | opfowner +------+---------- +(0 rows) + SELECT ctid, pronamespace FROM pg_catalog.pg_proc fk WHERE pronamespace != 0 AND @@ -497,6 +585,14 @@ WHERE pronamespace != 0 AND ------+-------------- (0 rows) +SELECT ctid, proowner +FROM pg_catalog.pg_proc fk +WHERE proowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.proowner); + ctid | proowner +------+---------- +(0 rows) + SELECT ctid, prolang FROM pg_catalog.pg_proc fk WHERE prolang != 0 AND @@ -521,6 +617,22 @@ WHERE ev_class != 0 AND ------+---------- (0 rows) +SELECT ctid, refclassid +FROM pg_catalog.pg_shdepend fk +WHERE refclassid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.refclassid); + ctid | refclassid +------+------------ +(0 rows) + +SELECT ctid, classoid +FROM pg_catalog.pg_shdescription fk +WHERE classoid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid); + ctid | classoid +------+---------- +(0 rows) + SELECT ctid, starelid FROM pg_catalog.pg_statistic fk WHERE starelid != 0 AND @@ -553,6 +665,14 @@ WHERE staop3 != 0 AND ------+-------- (0 rows) +SELECT ctid, spcowner +FROM pg_catalog.pg_tablespace fk +WHERE spcowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.spcowner); + ctid | spcowner +------+---------- +(0 rows) + SELECT ctid, tgrelid FROM pg_catalog.pg_trigger fk WHERE tgrelid != 0 AND @@ -577,6 +697,14 @@ WHERE typnamespace != 0 AND ------+-------------- (0 rows) +SELECT ctid, typowner +FROM pg_catalog.pg_type fk +WHERE typowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.typowner); + ctid | typowner +------+---------- +(0 rows) + SELECT ctid, typrelid FROM pg_catalog.pg_type fk WHERE typrelid != 0 AND diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index e455538d69..a0e9483ebd 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -1,7 +1,8 @@ -- -- OPR_SANITY -- Sanity checks for common errors in making operator/procedure system tables: --- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am, pg_amop, pg_amproc, pg_opclass. +-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am, +-- pg_amop, pg_amproc, pg_opclass, pg_opfamily. -- -- None of the SELECTs here should ever find any matching entries, -- so the expected output is easy to maintain ;-). @@ -374,158 +375,58 @@ WHERE p1.oprnegate = p2.oid AND -----+---------+-----+--------- (0 rows) --- Look for mergejoin operators that don't match their links. --- An lsortop/rsortop link leads from an '=' operator to the --- sort operator ('<' operator) that's appropriate for --- its left-side or right-side data type. --- An ltcmpop/gtcmpop link leads from an '=' operator to the --- '<' or '>' operator of the same input datatypes. --- (If the '=' operator has identical L and R input datatypes, --- then lsortop, rsortop, and ltcmpop are all the same operator.) -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprlsortop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprleft != p2.oprleft OR - p1.oprleft != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - oid | oprcode | oid | oprcode ------+---------+-----+--------- -(0 rows) - -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprrsortop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprright != p2.oprleft OR - p1.oprright != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - oid | oprcode | oid | oprcode ------+---------+-----+--------- -(0 rows) - -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprltcmpop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprleft != p2.oprleft OR - p1.oprright != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - oid | oprcode | oid | oprcode ------+---------+-----+--------- -(0 rows) - -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprgtcmpop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('>', '~>~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprleft != p2.oprleft OR - p1.oprright != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - oid | oprcode | oid | oprcode ------+---------+-----+--------- -(0 rows) - --- Make sure all four links are specified if any are. -SELECT p1.oid, p1.oprcode -FROM pg_operator AS p1 -WHERE NOT ((oprlsortop = 0 AND oprrsortop = 0 AND - oprltcmpop = 0 AND oprgtcmpop = 0) OR - (oprlsortop != 0 AND oprrsortop != 0 AND - oprltcmpop != 0 AND oprgtcmpop != 0)); - oid | oprcode ------+--------- -(0 rows) - --- A mergejoinable = operator must have a commutator (usually itself). +-- A mergejoinable or hashjoinable operator must be binary, must return +-- boolean, and must have a commutator (itself, unless it's a cross-type +-- operator). SELECT p1.oid, p1.oprname FROM pg_operator AS p1 -WHERE p1.oprlsortop != 0 AND - p1.oprcom = 0; +WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT + (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0); oid | oprname -----+--------- (0 rows) --- Mergejoinable operators across datatypes must come in closed sets, that --- is if you provide int2 = int4 and int4 = int8 then you must also provide --- int2 = int8 (and commutators of all these). This is necessary because --- the planner tries to deduce additional qual clauses from transitivity --- of mergejoinable operators. If there are clauses int2var = int4var and --- int4var = int8var, the planner will deduce int2var = int8var ... and it --- had better have a way to represent it. -SELECT p1.oid, p2.oid FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprlsortop != p1.oprrsortop AND - p1.oprrsortop = p2.oprlsortop AND - p2.oprlsortop != p2.oprrsortop AND - NOT EXISTS (SELECT 1 FROM pg_operator p3 WHERE - p3.oprlsortop = p1.oprlsortop AND p3.oprrsortop = p2.oprrsortop); - oid | oid ------+----- -(0 rows) - --- Hashing only works on simple equality operators "type = sametype", --- since the hash itself depends on the bitwise representation of the type. --- Check that allegedly hashable operators look like they might be "=". +-- Mergejoinable operators should appear as equality members of btree index +-- opfamilies. SELECT p1.oid, p1.oprname FROM pg_operator AS p1 -WHERE p1.oprcanhash AND NOT - (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND - p1.oprleft = p1.oprright AND p1.oprname IN ('=', '~=~') AND - p1.oprcom = p1.oid); - oid | oprname ------+--------- -(0 rows) - --- In 6.5 we accepted hashable array equality operators when the array element --- type is hashable. However, what we actually need to make hashjoin work on --- an array is a hashable element type *and* no padding between elements in --- the array storage (or, perhaps, guaranteed-zero padding). Currently, --- since the padding code in arrayfuncs.c is pretty bogus, it seems safest --- to just forbid hashjoin on array equality ops. --- This should be reconsidered someday. --- -- Look for array equality operators that are hashable when the underlying --- -- type is not, or vice versa. This is presumably bogus. --- --- SELECT p1.oid, p1.oprcanhash, p2.oid, p2.oprcanhash, t1.typname, t2.typname --- FROM pg_operator AS p1, pg_operator AS p2, pg_type AS t1, pg_type AS t2 --- WHERE p1.oprname = '=' AND p1.oprleft = p1.oprright AND --- p2.oprname = '=' AND p2.oprleft = p2.oprright AND --- p1.oprleft = t1.oid AND p2.oprleft = t2.oid AND t1.typelem = t2.oid AND --- p1.oprcanhash != p2.oprcanhash; --- Substitute check: forbid hashable array ops, period. -SELECT p1.oid, p1.oprname -FROM pg_operator AS p1, pg_proc AS p2 -WHERE p1.oprcanhash AND p1.oprcode = p2.oid AND p2.proname = 'array_eq'; - oid | oprname ------+--------- -(0 rows) - --- Hashable operators should appear as members of hash index opclasses. -SELECT p1.oid, p1.oprname -FROM pg_operator AS p1 -WHERE p1.oprcanhash AND NOT EXISTS - (SELECT 1 FROM pg_opclass op JOIN pg_amop p ON op.oid = amopclaid - WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') AND - amopopr = p1.oid); +WHERE p1.oprcanmerge AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + amopopr = p1.oid AND amopstrategy = 3); oid | oprname -----+--------- (0 rows) -- And the converse. -SELECT p1.oid, p1.oprname, op.opcname -FROM pg_operator AS p1, pg_opclass op, pg_amop p -WHERE amopopr = p1.oid AND amopclaid = op.oid - AND opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') +SELECT p1.oid, p1.oprname, p.amopfamily +FROM pg_operator AS p1, pg_amop p +WHERE amopopr = p1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopstrategy = 3 + AND NOT p1.oprcanmerge; + oid | oprname | amopfamily +-----+---------+------------ +(0 rows) + +-- Hashable operators should appear as members of hash index opfamilies. +SELECT p1.oid, p1.oprname +FROM pg_operator AS p1 +WHERE p1.oprcanhash AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND + amopopr = p1.oid AND amopstrategy = 1); + oid | oprname +-----+--------- +(0 rows) + +-- And the converse. +SELECT p1.oid, p1.oprname, p.amopfamily +FROM pg_operator AS p1, pg_amop p +WHERE amopopr = p1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND NOT p1.oprcanhash; - oid | oprname | opcname ------+---------+--------- + oid | oprname | amopfamily +-----+---------+------------ (0 rows) -- Check that each operator defined in pg_operator matches its oprcode entry @@ -571,7 +472,7 @@ WHERE p1.oprcode = p2.oid AND SELECT p1.oid, p1.oprname, p2.oid, p2.proname FROM pg_operator AS p1, pg_proc AS p2 WHERE p1.oprcode = p2.oid AND - (p1.oprlsortop != 0 OR p1.oprcanhash) AND + (p1.oprcanmerge OR p1.oprcanhash) AND p2.provolatile = 'v'; oid | oprname | oid | proname -----+---------+-----+--------- @@ -720,14 +621,15 @@ WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND ----------+----- (0 rows) --- Check operator is a suitable btree opclass member +-- Check operator is a suitable btree opfamily member SELECT a.aggfnoid::oid, o.oid FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND - NOT EXISTS(SELECT 1 FROM pg_amop ao, pg_opclass oc - WHERE amopclaid = oc.oid AND amopsubtype = 0 - AND amopopr = o.oid AND opcamid = 403 - AND opcintype = o.oprleft AND opcdefault); + NOT EXISTS(SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopopr = o.oid + AND amoplefttype = o.oprleft + AND amoprighttype = o.oprright); aggfnoid | oid ----------+----- (0 rows) @@ -735,31 +637,50 @@ WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND -- Check correspondence of btree strategies and names SELECT DISTINCT proname, oprname, amopstrategy FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p, - pg_amop as ao, pg_opclass oc + pg_amop as ao WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND - amopclaid = oc.oid AND amopopr = o.oid AND opcamid = 403 -ORDER BY 1; + amopopr = o.oid AND + amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') +ORDER BY 1, 2; proname | oprname | amopstrategy ---------+---------+-------------- max | > | 5 min | < | 1 (2 rows) --- **************** pg_opclass **************** --- Look for illegal values in pg_opclass fields +-- **************** pg_opfamily **************** +-- Look for illegal values in pg_opfamily fields SELECT p1.oid -FROM pg_opclass as p1 -WHERE p1.opcamid = 0 OR p1.opcintype = 0; +FROM pg_opfamily as p1 +WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0; oid ----- (0 rows) +-- **************** pg_opclass **************** +-- Look for illegal values in pg_opclass fields +SELECT p1.oid +FROM pg_opclass AS p1 +WHERE p1.opcmethod = 0 OR p1.opcnamespace = 0 OR p1.opcfamily = 0 + OR p1.opcintype = 0; + oid +----- +(0 rows) + +-- opcmethod must match owning opfamily's opfmethod +SELECT p1.oid, p2.oid +FROM pg_opclass AS p1, pg_opfamily AS p2 +WHERE p1.opcfamily = p2.oid AND p1.opcmethod != p2.opfmethod; + oid | oid +-----+----- +(0 rows) + -- There should not be multiple entries in pg_opclass with opcdefault true --- and the same opcamid/opcintype combination. +-- and the same opcmethod/opcintype combination. SELECT p1.oid, p2.oid FROM pg_opclass AS p1, pg_opclass AS p2 WHERE p1.oid != p2.oid AND - p1.opcamid = p2.opcamid AND p1.opcintype = p2.opcintype AND + p1.opcmethod = p2.opcmethod AND p1.opcintype = p2.opcintype AND p1.opcdefault AND p2.opcdefault; oid | oid -----+----- @@ -767,181 +688,221 @@ WHERE p1.oid != p2.oid AND -- **************** pg_amop **************** -- Look for illegal values in pg_amop fields -SELECT p1.amopclaid, p1.amopstrategy +SELECT p1.amopfamily, p1.amopstrategy FROM pg_amop as p1 -WHERE p1.amopclaid = 0 OR p1.amopstrategy <= 0 OR p1.amopopr = 0; - amopclaid | amopstrategy ------------+-------------- +WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0 + OR p1.amopopr = 0 OR p1.amopmethod = 0 OR p1.amopstrategy < 1; + amopfamily | amopstrategy +------------+-------------- +(0 rows) + +-- amoplefttype/amoprighttype must match the operator +SELECT p1.oid, p2.oid +FROM pg_amop AS p1, pg_operator AS p2 +WHERE p1.amopopr = p2.oid AND NOT + (p1.amoplefttype = p2.oprleft AND p1.amoprighttype = p2.oprright); + oid | oid +-----+----- +(0 rows) + +-- amopmethod must match owning opfamily's opfmethod +SELECT p1.oid, p2.oid +FROM pg_amop AS p1, pg_opfamily AS p2 +WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod; + oid | oid +-----+----- (0 rows) -- Cross-check amopstrategy index against parent AM -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.amname -FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3 -WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname +FROM pg_amop AS p1, pg_am AS p2 +WHERE p1.amopmethod = p2.oid AND p1.amopstrategy > p2.amstrategies AND p2.amstrategies <> 0; - amopclaid | amopopr | oid | amname ------------+---------+-----+-------- + amopfamily | amopopr | oid | amname +------------+---------+-----+-------- (0 rows) -- Detect missing pg_amop entries: should have as many strategy operators --- as AM expects for each opclass for the AM. When nondefault subtypes are --- present, enforce condition separately for each subtype. +-- as AM expects for each datatype combination supported by the opfamily. -- We can't check this for AMs with variable strategy sets. -SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype -FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3 -WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND +SELECT p1.amname, p2.amoplefttype, p2.amoprighttype +FROM pg_am AS p1, pg_amop AS p2 +WHERE p2.amopmethod = p1.oid AND p1.amstrategies <> 0 AND - p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4 - WHERE p4.amopclaid = p2.oid AND - p4.amopsubtype = p3.amopsubtype); - oid | amname | oid | opcname | amopsubtype ------+--------+-----+---------+------------- + p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3 + WHERE p3.amopfamily = p2.amopfamily AND + p3.amoplefttype = p2.amoplefttype AND + p3.amoprighttype = p2.amoprighttype); + amname | amoplefttype | amoprighttype +--------+--------------+--------------- (0 rows) -- Check that amopopr points at a reasonable-looking operator, ie a binary -- operator yielding boolean. -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 WHERE p1.amopopr = p2.oid AND (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype); - amopclaid | amopopr | oid | oprname ------------+---------+-----+--------- + amopfamily | amopopr | oid | oprname +------------+---------+-----+--------- (0 rows) -- Make a list of all the distinct operator names being used in particular -- strategy slots. This is a bit hokey, since the list might need to change -- in future releases, but it's an effective way of spotting mistakes such as --- swapping two operators within a class. -SELECT DISTINCT opcamid, amopstrategy, oprname -FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid - LEFT JOIN pg_operator p3 ON amopopr = p3.oid +-- swapping two operators within a family. +SELECT DISTINCT amopmethod, amopstrategy, oprname +FROM pg_amop p1 LEFT JOIN pg_operator p2 ON amopopr = p2.oid ORDER BY 1, 2, 3; - opcamid | amopstrategy | oprname ----------+--------------+--------- - 403 | 1 | < - 403 | 1 | ~<~ - 403 | 2 | <= - 403 | 2 | ~<=~ - 403 | 3 | = - 403 | 3 | ~=~ - 403 | 4 | >= - 403 | 4 | ~>=~ - 403 | 5 | > - 403 | 5 | ~>~ - 405 | 1 | = - 405 | 1 | ~=~ - 783 | 1 | << - 783 | 2 | &< - 783 | 3 | && - 783 | 4 | &> - 783 | 5 | >> - 783 | 6 | ~= - 783 | 7 | @> - 783 | 8 | <@ - 783 | 9 | &<| - 783 | 10 | <<| - 783 | 11 | |>> - 783 | 12 | |&> - 783 | 13 | ~ - 783 | 14 | @ - 2742 | 1 | && - 2742 | 2 | @> - 2742 | 3 | <@ - 2742 | 4 | = + amopmethod | amopstrategy | oprname +------------+--------------+--------- + 403 | 1 | < + 403 | 1 | ~<~ + 403 | 2 | <= + 403 | 2 | ~<=~ + 403 | 3 | = + 403 | 3 | ~=~ + 403 | 4 | >= + 403 | 4 | ~>=~ + 403 | 5 | > + 403 | 5 | ~>~ + 405 | 1 | = + 405 | 1 | ~=~ + 783 | 1 | << + 783 | 2 | &< + 783 | 3 | && + 783 | 4 | &> + 783 | 5 | >> + 783 | 6 | ~= + 783 | 7 | @> + 783 | 8 | <@ + 783 | 9 | &<| + 783 | 10 | <<| + 783 | 11 | |>> + 783 | 12 | |&> + 783 | 13 | ~ + 783 | 14 | @ + 2742 | 1 | && + 2742 | 2 | @> + 2742 | 3 | <@ + 2742 | 4 | = (30 rows) -- Check that all operators linked to by opclass entries have selectivity -- estimators. This is not absolutely required, but it seems a reasonable -- thing to insist on for all standard datatypes. -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 WHERE p1.amopopr = p2.oid AND (p2.oprrest = 0 OR p2.oprjoin = 0); - amopclaid | amopopr | oid | oprname ------------+---------+-----+--------- + amopfamily | amopopr | oid | oprname +------------+---------+-----+--------- (0 rows) --- Check that operator input types match the opclass --- For 8.0, we require that oprleft match opcintype (possibly by coercion). --- When amopsubtype is zero (default), oprright must equal oprleft; --- when amopsubtype is not zero, oprright must equal amopsubtype. -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname -FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3 -WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND - NOT binary_coercible(p3.opcintype, p2.oprleft); - amopclaid | amopopr | oid | oprname | opcname ------------+---------+-----+---------+--------- -(0 rows) - -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname -FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3 -WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND - p1.amopsubtype = 0 AND - p2.oprleft != p2.oprright; - amopclaid | amopopr | oid | oprname | opcname ------------+---------+-----+---------+--------- -(0 rows) - -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname -FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3 -WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND - p1.amopsubtype != 0 AND - p1.amopsubtype != p2.oprright; - amopclaid | amopopr | oid | oprname | opcname ------------+---------+-----+---------+--------- +-- Check that each opclass in an opfamily has associated operators, that is +-- ones whose oprleft matches opcintype (possibly by coercion). +SELECT p1.opcname, p1.opcfamily +FROM pg_opclass AS p1 +WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2 + WHERE p2.amopfamily = p1.opcfamily + AND binary_coercible(p1.opcintype, p2.amoplefttype)); + opcname | opcfamily +---------+----------- (0 rows) -- Operators that are primary members of opclasses must be immutable (else -- it suggests that the index ordering isn't fixed). Operators that are -- cross-type members need only be stable, since they are just shorthands -- for index probe queries. -SELECT p1.amopclaid, p1.amopopr, p2.oprname, p3.prosrc +SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND - p1.amopsubtype = 0 AND + p1.amoplefttype = p1.amoprighttype AND p3.provolatile != 'i'; - amopclaid | amopopr | oprname | prosrc ------------+---------+---------+-------- + amopfamily | amopopr | oprname | prosrc +------------+---------+---------+-------- (0 rows) -SELECT p1.amopclaid, p1.amopopr, p2.oprname, p3.prosrc +SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND - p1.amopsubtype != 0 AND + p1.amoplefttype != p1.amoprighttype AND p3.provolatile = 'v'; - amopclaid | amopopr | oprname | prosrc ------------+---------+---------+-------- + amopfamily | amopopr | oprname | prosrc +------------+---------+---------+-------- +(0 rows) + +-- Multiple-datatype btree opclasses should provide closed sets of equality +-- operators; that is if you provide int2 = int4 and int4 = int8 then you +-- must also provide int2 = int8 (and commutators of all these). This is +-- necessary because the planner tries to deduce additional qual clauses from +-- transitivity of mergejoinable operators. If there are clauses +-- int2var = int4var and int4var = int8var, the planner will deduce +-- int2var = int8var ... and it had better have a way to represent it. +-- check commutative closure +SELECT p1.amoplefttype, p1.amoprighttype +FROM pg_amop AS p1 +WHERE p1.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + p1.amopstrategy = 3 AND + p1.amoplefttype != p1.amoprighttype AND + NOT EXISTS(SELECT 1 FROM pg_amop p2 WHERE + p2.amopfamily = p1.amopfamily AND + p2.amoplefttype = p1.amoprighttype AND + p2.amoprighttype = p1.amoplefttype AND + p2.amopstrategy = 3); + amoplefttype | amoprighttype +--------------+--------------- +(0 rows) + +-- check transitive closure +SELECT p1.amoplefttype, p1.amoprighttype, p2.amoprighttype +FROM pg_amop AS p1, pg_amop AS p2 +WHERE p1.amopfamily = p2.amopfamily AND + p1.amoprighttype = p2.amoplefttype AND + p1.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + p2.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + p1.amopstrategy = 3 AND p2.amopstrategy = 3 AND + p1.amoplefttype != p1.amoprighttype AND + p2.amoplefttype != p2.amoprighttype AND + NOT EXISTS(SELECT 1 FROM pg_amop p3 WHERE + p3.amopfamily = p1.amopfamily AND + p3.amoplefttype = p1.amoplefttype AND + p3.amoprighttype = p2.amoprighttype AND + p3.amopstrategy = 3); + amoplefttype | amoprighttype | amoprighttype +--------------+---------------+--------------- (0 rows) -- **************** pg_amproc **************** -- Look for illegal values in pg_amproc fields -SELECT p1.amopclaid, p1.amprocnum +SELECT p1.amprocfamily, p1.amprocnum FROM pg_amproc as p1 -WHERE p1.amopclaid = 0 OR p1.amprocnum <= 0 OR p1.amproc = 0; - amopclaid | amprocnum ------------+----------- +WHERE p1.amprocfamily = 0 OR p1.amproclefttype = 0 OR p1.amprocrighttype = 0 + OR p1.amprocnum < 1 OR p1.amproc = 0; + amprocfamily | amprocnum +--------------+----------- (0 rows) -- Cross-check amprocnum index against parent AM -SELECT p1.amopclaid, p1.amprocnum, p2.oid, p2.amname -FROM pg_amproc AS p1, pg_am AS p2, pg_opclass AS p3 -WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.amname +FROM pg_amproc AS p1, pg_am AS p2, pg_opfamily AS p3 +WHERE p1.amprocfamily = p3.oid AND p3.opfmethod = p2.oid AND p1.amprocnum > p2.amsupport; - amopclaid | amprocnum | oid | amname ------------+-----------+-----+-------- + amprocfamily | amprocnum | oid | amname +--------------+-----------+-----+-------- (0 rows) -- Detect missing pg_amproc entries: should have as many support functions --- as AM expects for each opclass for the AM. When nondefault subtypes are --- present, enforce condition separately for each subtype. -SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype -FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3 -WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND +-- as AM expects for each datatype combination supported by the opfamily. +SELECT p1.amname, p2.opfname, p3.amproclefttype, p3.amprocrighttype +FROM pg_am AS p1, pg_opfamily AS p2, pg_amproc AS p3 +WHERE p2.opfmethod = p1.oid AND p3.amprocfamily = p2.oid AND p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4 - WHERE p4.amopclaid = p2.oid AND - p4.amprocsubtype = p3.amprocsubtype); - oid | amname | oid | opcname | amprocsubtype ------+--------+-----+---------+--------------- + WHERE p4.amprocfamily = p2.oid AND + p4.amproclefttype = p3.amproclefttype AND + p4.amprocrighttype = p3.amprocrighttype); + amname | opfname | amproclefttype | amprocrighttype +--------+---------+----------------+----------------- (0 rows) -- Unfortunately, we can't check the amproc link very well because the @@ -950,101 +911,79 @@ WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND -- We can check that all the referenced instances of the same support -- routine number take the same number of parameters, but that's about it -- for a general check... -SELECT p1.amopclaid, p1.amprocnum, +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.proname, - p3.opcname, - p4.amopclaid, p4.amprocnum, + p3.opfname, + p4.amprocfamily, p4.amprocnum, p5.oid, p5.proname, - p6.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3, - pg_amproc AS p4, pg_proc AS p5, pg_opclass AS p6 -WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND - p3.opcamid = p6.opcamid AND p1.amprocnum = p4.amprocnum AND + p6.opfname +FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3, + pg_amproc AS p4, pg_proc AS p5, pg_opfamily AS p6 +WHERE p1.amprocfamily = p3.oid AND p4.amprocfamily = p6.oid AND + p3.opfmethod = p6.opfmethod AND p1.amprocnum = p4.amprocnum AND p1.amproc = p2.oid AND p4.amproc = p5.oid AND (p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs); - amopclaid | amprocnum | oid | proname | opcname | amopclaid | amprocnum | oid | proname | opcname ------------+-----------+-----+---------+---------+-----------+-----------+-----+---------+--------- + amprocfamily | amprocnum | oid | proname | opfname | amprocfamily | amprocnum | oid | proname | opfname +--------------+-----------+-----+---------+---------+--------------+-----------+-----+---------+--------- (0 rows) -- For btree, though, we can do better since we know the support routines --- must be of the form cmp(input, input) returns int4 in the default case --- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0. -SELECT p1.amopclaid, p1.amprocnum, +-- must be of the form cmp(lefttype, righttype) returns int4. +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.proname, - p3.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3 -WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') - AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND - amprocsubtype = 0 AND - (opckeytype != 0 - OR amprocnum != 1 + p3.opfname +FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3 +WHERE p3.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND p1.amprocfamily = p3.oid AND p1.amproc = p2.oid AND + (amprocnum != 1 OR proretset - OR prorettype != 23 + OR prorettype != 'int4'::regtype OR pronargs != 2 - OR NOT binary_coercible(opcintype, proargtypes[0]) - OR proargtypes[0] != proargtypes[1]); - amopclaid | amprocnum | oid | proname | opcname ------------+-----------+-----+---------+--------- -(0 rows) - -SELECT p1.amopclaid, p1.amprocnum, - p2.oid, p2.proname, - p3.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3 -WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') - AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND - amprocsubtype != 0 AND - (opckeytype != 0 - OR amprocnum != 1 - OR proretset - OR prorettype != 23 - OR pronargs != 2 - OR NOT binary_coercible(opcintype, proargtypes[0]) - OR proargtypes[1] != amprocsubtype); - amopclaid | amprocnum | oid | proname | opcname ------------+-----------+-----+---------+--------- + OR proargtypes[0] != amproclefttype + OR proargtypes[1] != amprocrighttype); + amprocfamily | amprocnum | oid | proname | opfname +--------------+-----------+-----+---------+--------- (0 rows) -- For hash we can also do a little better: the support routines must be --- of the form hash(something) returns int4. Ideally we'd check that the --- opcintype is binary-coercible to the function's input, but there are --- enough cases where that fails that I'll just leave out the check for now. -SELECT p1.amopclaid, p1.amprocnum, +-- of the form hash(lefttype) returns int4. There are several cases where +-- we cheat and use a hash function that is physically compatible with the +-- datatype even though there's no cast, so for now we can't check that. +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.proname, - p3.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3 -WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') - AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND - (opckeytype != 0 - OR amprocnum != 1 + p3.opfname +FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3 +WHERE p3.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') + AND p1.amprocfamily = p3.oid AND p1.amproc = p2.oid AND + (amprocnum != 1 OR proretset - OR prorettype != 23 + OR prorettype != 'int4'::regtype OR pronargs != 1 --- OR NOT physically_coercible(opcintype, proargtypes[0]) -); - amopclaid | amprocnum | oid | proname | opcname ------------+-----------+-----+---------+--------- +-- OR NOT physically_coercible(amproclefttype, proargtypes[0]) + OR amproclefttype != amprocrighttype); + amprocfamily | amprocnum | oid | proname | opfname +--------------+-----------+-----+---------+--------- (0 rows) --- Support routines that are primary members of opclasses must be immutable +-- Support routines that are primary members of opfamilies must be immutable -- (else it suggests that the index ordering isn't fixed). But cross-type -- members need only be stable, since they are just shorthands -- for index probe queries. -SELECT p1.amopclaid, p1.amproc, p2.prosrc +SELECT p1.amprocfamily, p1.amproc, p2.prosrc FROM pg_amproc AS p1, pg_proc AS p2 WHERE p1.amproc = p2.oid AND - p1.amprocsubtype = 0 AND + p1.amproclefttype = p1.amprocrighttype AND p2.provolatile != 'i'; - amopclaid | amproc | prosrc ------------+--------+-------- + amprocfamily | amproc | prosrc +--------------+--------+-------- (0 rows) -SELECT p1.amopclaid, p1.amproc, p2.prosrc +SELECT p1.amprocfamily, p1.amproc, p2.prosrc FROM pg_amproc AS p1, pg_proc AS p2 WHERE p1.amproc = p2.oid AND - p1.amprocsubtype != 0 AND + p1.amproclefttype != p1.amprocrighttype AND p2.provolatile = 'v'; - amopclaid | amproc | prosrc ------------+--------+-------- + amprocfamily | amproc | prosrc +--------------+--------+-------- (0 rows) diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out index 5b4d9555ae..10687f5669 100644 --- a/src/test/regress/expected/rowtypes.out +++ b/src/test/regress/expected/rowtypes.out @@ -203,7 +203,7 @@ select ROW('ABC','DEF') ~~ ROW('DEF','ABC') as fail; ERROR: could not determine interpretation of row comparison operator ~~ LINE 1: select ROW('ABC','DEF') ~~ ROW('DEF','ABC') as fail; ^ -HINT: Row comparison operators must be associated with btree operator classes. +HINT: Row comparison operators must be associated with btree operator families. -- Check row comparison with a subselect select unique1, unique2 from tenk1 where (unique1, unique2) < any (select ten, ten from tenk1 where hundred < 3); diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index d2c68e8791..5e6a570e24 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -105,6 +105,7 @@ SELECT relname, relhasindex pg_namespace | t pg_opclass | t pg_operator | t + pg_opfamily | t pg_pltemplate | t pg_proc | t pg_rewrite | t @@ -140,7 +141,7 @@ SELECT relname, relhasindex timetz_tbl | f tinterval_tbl | f varchar_tbl | f -(129 rows) +(130 rows) -- -- another sanity check: every system catalog that has OIDs should have diff --git a/src/test/regress/sql/oidjoins.sql b/src/test/regress/sql/oidjoins.sql index 910d55f9f9..bf713e9fa7 100644 --- a/src/test/regress/sql/oidjoins.sql +++ b/src/test/regress/sql/oidjoins.sql @@ -69,26 +69,42 @@ SELECT ctid, amcostestimate FROM pg_catalog.pg_am fk WHERE amcostestimate != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.amcostestimate); -SELECT ctid, amopclaid +SELECT ctid, amoptions +FROM pg_catalog.pg_am fk +WHERE amoptions != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.amoptions); +SELECT ctid, amopfamily FROM pg_catalog.pg_amop fk -WHERE amopclaid != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid); -SELECT ctid, amopsubtype +WHERE amopfamily != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amopfamily); +SELECT ctid, amoplefttype FROM pg_catalog.pg_amop fk -WHERE amopsubtype != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype); +WHERE amoplefttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoplefttype); +SELECT ctid, amoprighttype +FROM pg_catalog.pg_amop fk +WHERE amoprighttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amoprighttype); SELECT ctid, amopopr FROM pg_catalog.pg_amop fk WHERE amopopr != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.amopopr); -SELECT ctid, amopclaid +SELECT ctid, amopmethod +FROM pg_catalog.pg_amop fk +WHERE amopmethod != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.amopmethod); +SELECT ctid, amprocfamily FROM pg_catalog.pg_amproc fk -WHERE amopclaid != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid); -SELECT ctid, amprocsubtype +WHERE amprocfamily != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.amprocfamily); +SELECT ctid, amproclefttype FROM pg_catalog.pg_amproc fk -WHERE amprocsubtype != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype); +WHERE amproclefttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amproclefttype); +SELECT ctid, amprocrighttype +FROM pg_catalog.pg_amproc fk +WHERE amprocrighttype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocrighttype); SELECT ctid, amproc FROM pg_catalog.pg_amproc fk WHERE amproc != 0 AND @@ -121,6 +137,10 @@ SELECT ctid, reltype FROM pg_catalog.pg_class fk WHERE reltype != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.reltype); +SELECT ctid, relowner +FROM pg_catalog.pg_class fk +WHERE relowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.relowner); SELECT ctid, relam FROM pg_catalog.pg_class fk WHERE relam != 0 AND @@ -149,10 +169,18 @@ SELECT ctid, connamespace FROM pg_catalog.pg_conversion fk WHERE connamespace != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.connamespace); +SELECT ctid, conowner +FROM pg_catalog.pg_conversion fk +WHERE conowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.conowner); SELECT ctid, conproc FROM pg_catalog.pg_conversion fk WHERE conproc != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.conproc); +SELECT ctid, datdba +FROM pg_catalog.pg_database fk +WHERE datdba != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.datdba); SELECT ctid, dattablespace FROM pg_catalog.pg_database fk WHERE dattablespace != 0 AND @@ -181,22 +209,42 @@ SELECT ctid, lanvalidator FROM pg_catalog.pg_language fk WHERE lanvalidator != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.lanvalidator); -SELECT ctid, opcamid +SELECT ctid, nspowner +FROM pg_catalog.pg_namespace fk +WHERE nspowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.nspowner); +SELECT ctid, opcmethod FROM pg_catalog.pg_opclass fk -WHERE opcamid != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opcamid); +WHERE opcmethod != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opcmethod); SELECT ctid, opcnamespace FROM pg_catalog.pg_opclass fk WHERE opcnamespace != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.opcnamespace); +SELECT ctid, opcowner +FROM pg_catalog.pg_opclass fk +WHERE opcowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opcowner); +SELECT ctid, opcfamily +FROM pg_catalog.pg_opclass fk +WHERE opcfamily != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opfamily pk WHERE pk.oid = fk.opcfamily); SELECT ctid, opcintype FROM pg_catalog.pg_opclass fk WHERE opcintype != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.opcintype); +SELECT ctid, opckeytype +FROM pg_catalog.pg_opclass fk +WHERE opckeytype != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.opckeytype); SELECT ctid, oprnamespace FROM pg_catalog.pg_operator fk WHERE oprnamespace != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.oprnamespace); +SELECT ctid, oprowner +FROM pg_catalog.pg_operator fk +WHERE oprowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.oprowner); SELECT ctid, oprleft FROM pg_catalog.pg_operator fk WHERE oprleft != 0 AND @@ -217,22 +265,6 @@ SELECT ctid, oprnegate FROM pg_catalog.pg_operator fk WHERE oprnegate != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate); -SELECT ctid, oprlsortop -FROM pg_catalog.pg_operator fk -WHERE oprlsortop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprlsortop); -SELECT ctid, oprrsortop -FROM pg_catalog.pg_operator fk -WHERE oprrsortop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprrsortop); -SELECT ctid, oprltcmpop -FROM pg_catalog.pg_operator fk -WHERE oprltcmpop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprltcmpop); -SELECT ctid, oprgtcmpop -FROM pg_catalog.pg_operator fk -WHERE oprgtcmpop != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprgtcmpop); SELECT ctid, oprcode FROM pg_catalog.pg_operator fk WHERE oprcode != 0 AND @@ -245,10 +277,26 @@ SELECT ctid, oprjoin FROM pg_catalog.pg_operator fk WHERE oprjoin != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.oprjoin); +SELECT ctid, opfmethod +FROM pg_catalog.pg_opfamily fk +WHERE opfmethod != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_am pk WHERE pk.oid = fk.opfmethod); +SELECT ctid, opfnamespace +FROM pg_catalog.pg_opfamily fk +WHERE opfnamespace != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.opfnamespace); +SELECT ctid, opfowner +FROM pg_catalog.pg_opfamily fk +WHERE opfowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.opfowner); SELECT ctid, pronamespace FROM pg_catalog.pg_proc fk WHERE pronamespace != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.pronamespace); +SELECT ctid, proowner +FROM pg_catalog.pg_proc fk +WHERE proowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.proowner); SELECT ctid, prolang FROM pg_catalog.pg_proc fk WHERE prolang != 0 AND @@ -261,6 +309,14 @@ SELECT ctid, ev_class FROM pg_catalog.pg_rewrite fk WHERE ev_class != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.ev_class); +SELECT ctid, refclassid +FROM pg_catalog.pg_shdepend fk +WHERE refclassid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.refclassid); +SELECT ctid, classoid +FROM pg_catalog.pg_shdescription fk +WHERE classoid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.classoid); SELECT ctid, starelid FROM pg_catalog.pg_statistic fk WHERE starelid != 0 AND @@ -277,6 +333,10 @@ SELECT ctid, staop3 FROM pg_catalog.pg_statistic fk WHERE staop3 != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.staop3); +SELECT ctid, spcowner +FROM pg_catalog.pg_tablespace fk +WHERE spcowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.spcowner); SELECT ctid, tgrelid FROM pg_catalog.pg_trigger fk WHERE tgrelid != 0 AND @@ -289,6 +349,10 @@ SELECT ctid, typnamespace FROM pg_catalog.pg_type fk WHERE typnamespace != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.typnamespace); +SELECT ctid, typowner +FROM pg_catalog.pg_type fk +WHERE typowner != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.typowner); SELECT ctid, typrelid FROM pg_catalog.pg_type fk WHERE typrelid != 0 AND diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql index 5195a290ab..4dd39eb164 100644 --- a/src/test/regress/sql/opr_sanity.sql +++ b/src/test/regress/sql/opr_sanity.sql @@ -1,7 +1,8 @@ -- -- OPR_SANITY -- Sanity checks for common errors in making operator/procedure system tables: --- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am, pg_amop, pg_amproc, pg_opclass. +-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am, +-- pg_amop, pg_amproc, pg_opclass, pg_opfamily. -- -- None of the SELECTs here should ever find any matching entries, -- so the expected output is easy to maintain ;-). @@ -307,135 +308,48 @@ WHERE p1.oprnegate = p2.oid AND p1.oid != p2.oprnegate OR p1.oid = p2.oid); --- Look for mergejoin operators that don't match their links. --- An lsortop/rsortop link leads from an '=' operator to the --- sort operator ('<' operator) that's appropriate for --- its left-side or right-side data type. --- An ltcmpop/gtcmpop link leads from an '=' operator to the --- '<' or '>' operator of the same input datatypes. --- (If the '=' operator has identical L and R input datatypes, --- then lsortop, rsortop, and ltcmpop are all the same operator.) - -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprlsortop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprleft != p2.oprleft OR - p1.oprleft != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprrsortop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprright != p2.oprleft OR - p1.oprright != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprltcmpop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprleft != p2.oprleft OR - p1.oprright != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - -SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode -FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprgtcmpop = p2.oid AND - (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('>', '~>~') OR - p1.oprkind != 'b' OR p2.oprkind != 'b' OR - p1.oprleft != p2.oprleft OR - p1.oprright != p2.oprright OR - p1.oprresult != 'bool'::regtype OR - p2.oprresult != 'bool'::regtype); - --- Make sure all four links are specified if any are. - -SELECT p1.oid, p1.oprcode -FROM pg_operator AS p1 -WHERE NOT ((oprlsortop = 0 AND oprrsortop = 0 AND - oprltcmpop = 0 AND oprgtcmpop = 0) OR - (oprlsortop != 0 AND oprrsortop != 0 AND - oprltcmpop != 0 AND oprgtcmpop != 0)); - --- A mergejoinable = operator must have a commutator (usually itself). +-- A mergejoinable or hashjoinable operator must be binary, must return +-- boolean, and must have a commutator (itself, unless it's a cross-type +-- operator). SELECT p1.oid, p1.oprname FROM pg_operator AS p1 -WHERE p1.oprlsortop != 0 AND - p1.oprcom = 0; +WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT + (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0); --- Mergejoinable operators across datatypes must come in closed sets, that --- is if you provide int2 = int4 and int4 = int8 then you must also provide --- int2 = int8 (and commutators of all these). This is necessary because --- the planner tries to deduce additional qual clauses from transitivity --- of mergejoinable operators. If there are clauses int2var = int4var and --- int4var = int8var, the planner will deduce int2var = int8var ... and it --- had better have a way to represent it. - -SELECT p1.oid, p2.oid FROM pg_operator AS p1, pg_operator AS p2 -WHERE p1.oprlsortop != p1.oprrsortop AND - p1.oprrsortop = p2.oprlsortop AND - p2.oprlsortop != p2.oprrsortop AND - NOT EXISTS (SELECT 1 FROM pg_operator p3 WHERE - p3.oprlsortop = p1.oprlsortop AND p3.oprrsortop = p2.oprrsortop); - - --- Hashing only works on simple equality operators "type = sametype", --- since the hash itself depends on the bitwise representation of the type. --- Check that allegedly hashable operators look like they might be "=". +-- Mergejoinable operators should appear as equality members of btree index +-- opfamilies. SELECT p1.oid, p1.oprname FROM pg_operator AS p1 -WHERE p1.oprcanhash AND NOT - (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND - p1.oprleft = p1.oprright AND p1.oprname IN ('=', '~=~') AND - p1.oprcom = p1.oid); +WHERE p1.oprcanmerge AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + amopopr = p1.oid AND amopstrategy = 3); --- In 6.5 we accepted hashable array equality operators when the array element --- type is hashable. However, what we actually need to make hashjoin work on --- an array is a hashable element type *and* no padding between elements in --- the array storage (or, perhaps, guaranteed-zero padding). Currently, --- since the padding code in arrayfuncs.c is pretty bogus, it seems safest --- to just forbid hashjoin on array equality ops. --- This should be reconsidered someday. +-- And the converse. --- -- Look for array equality operators that are hashable when the underlying --- -- type is not, or vice versa. This is presumably bogus. --- --- SELECT p1.oid, p1.oprcanhash, p2.oid, p2.oprcanhash, t1.typname, t2.typname --- FROM pg_operator AS p1, pg_operator AS p2, pg_type AS t1, pg_type AS t2 --- WHERE p1.oprname = '=' AND p1.oprleft = p1.oprright AND --- p2.oprname = '=' AND p2.oprleft = p2.oprright AND --- p1.oprleft = t1.oid AND p2.oprleft = t2.oid AND t1.typelem = t2.oid AND --- p1.oprcanhash != p2.oprcanhash; +SELECT p1.oid, p1.oprname, p.amopfamily +FROM pg_operator AS p1, pg_amop p +WHERE amopopr = p1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopstrategy = 3 + AND NOT p1.oprcanmerge; --- Substitute check: forbid hashable array ops, period. -SELECT p1.oid, p1.oprname -FROM pg_operator AS p1, pg_proc AS p2 -WHERE p1.oprcanhash AND p1.oprcode = p2.oid AND p2.proname = 'array_eq'; - --- Hashable operators should appear as members of hash index opclasses. +-- Hashable operators should appear as members of hash index opfamilies. SELECT p1.oid, p1.oprname FROM pg_operator AS p1 WHERE p1.oprcanhash AND NOT EXISTS - (SELECT 1 FROM pg_opclass op JOIN pg_amop p ON op.oid = amopclaid - WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') AND - amopopr = p1.oid); + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND + amopopr = p1.oid AND amopstrategy = 1); -- And the converse. -SELECT p1.oid, p1.oprname, op.opcname -FROM pg_operator AS p1, pg_opclass op, pg_amop p -WHERE amopopr = p1.oid AND amopclaid = op.oid - AND opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') +SELECT p1.oid, p1.oprname, p.amopfamily +FROM pg_operator AS p1, pg_amop p +WHERE amopopr = p1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND NOT p1.oprcanhash; -- Check that each operator defined in pg_operator matches its oprcode entry @@ -474,7 +388,7 @@ WHERE p1.oprcode = p2.oid AND SELECT p1.oid, p1.oprname, p2.oid, p2.proname FROM pg_operator AS p1, pg_proc AS p2 WHERE p1.oprcode = p2.oid AND - (p1.oprlsortop != 0 OR p1.oprcanhash) AND + (p1.oprcanmerge OR p1.oprcanhash) AND p2.provolatile = 'v'; -- If oprrest is set, the operator must return boolean, @@ -596,74 +510,105 @@ WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND (oprkind != 'b' OR oprresult != 'boolean'::regtype OR oprleft != p.proargtypes[0] OR oprright != p.proargtypes[0]); --- Check operator is a suitable btree opclass member +-- Check operator is a suitable btree opfamily member SELECT a.aggfnoid::oid, o.oid FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND - NOT EXISTS(SELECT 1 FROM pg_amop ao, pg_opclass oc - WHERE amopclaid = oc.oid AND amopsubtype = 0 - AND amopopr = o.oid AND opcamid = 403 - AND opcintype = o.oprleft AND opcdefault); + NOT EXISTS(SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopopr = o.oid + AND amoplefttype = o.oprleft + AND amoprighttype = o.oprright); -- Check correspondence of btree strategies and names SELECT DISTINCT proname, oprname, amopstrategy FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p, - pg_amop as ao, pg_opclass oc + pg_amop as ao WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND - amopclaid = oc.oid AND amopopr = o.oid AND opcamid = 403 -ORDER BY 1; + amopopr = o.oid AND + amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') +ORDER BY 1, 2; + +-- **************** pg_opfamily **************** + +-- Look for illegal values in pg_opfamily fields + +SELECT p1.oid +FROM pg_opfamily as p1 +WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0; -- **************** pg_opclass **************** -- Look for illegal values in pg_opclass fields SELECT p1.oid -FROM pg_opclass as p1 -WHERE p1.opcamid = 0 OR p1.opcintype = 0; +FROM pg_opclass AS p1 +WHERE p1.opcmethod = 0 OR p1.opcnamespace = 0 OR p1.opcfamily = 0 + OR p1.opcintype = 0; + +-- opcmethod must match owning opfamily's opfmethod + +SELECT p1.oid, p2.oid +FROM pg_opclass AS p1, pg_opfamily AS p2 +WHERE p1.opcfamily = p2.oid AND p1.opcmethod != p2.opfmethod; -- There should not be multiple entries in pg_opclass with opcdefault true --- and the same opcamid/opcintype combination. +-- and the same opcmethod/opcintype combination. SELECT p1.oid, p2.oid FROM pg_opclass AS p1, pg_opclass AS p2 WHERE p1.oid != p2.oid AND - p1.opcamid = p2.opcamid AND p1.opcintype = p2.opcintype AND + p1.opcmethod = p2.opcmethod AND p1.opcintype = p2.opcintype AND p1.opcdefault AND p2.opcdefault; -- **************** pg_amop **************** -- Look for illegal values in pg_amop fields -SELECT p1.amopclaid, p1.amopstrategy +SELECT p1.amopfamily, p1.amopstrategy FROM pg_amop as p1 -WHERE p1.amopclaid = 0 OR p1.amopstrategy <= 0 OR p1.amopopr = 0; +WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0 + OR p1.amopopr = 0 OR p1.amopmethod = 0 OR p1.amopstrategy < 1; + +-- amoplefttype/amoprighttype must match the operator + +SELECT p1.oid, p2.oid +FROM pg_amop AS p1, pg_operator AS p2 +WHERE p1.amopopr = p2.oid AND NOT + (p1.amoplefttype = p2.oprleft AND p1.amoprighttype = p2.oprright); + +-- amopmethod must match owning opfamily's opfmethod + +SELECT p1.oid, p2.oid +FROM pg_amop AS p1, pg_opfamily AS p2 +WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod; -- Cross-check amopstrategy index against parent AM -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.amname -FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3 -WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname +FROM pg_amop AS p1, pg_am AS p2 +WHERE p1.amopmethod = p2.oid AND p1.amopstrategy > p2.amstrategies AND p2.amstrategies <> 0; -- Detect missing pg_amop entries: should have as many strategy operators --- as AM expects for each opclass for the AM. When nondefault subtypes are --- present, enforce condition separately for each subtype. +-- as AM expects for each datatype combination supported by the opfamily. -- We can't check this for AMs with variable strategy sets. -SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype -FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3 -WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND +SELECT p1.amname, p2.amoplefttype, p2.amoprighttype +FROM pg_am AS p1, pg_amop AS p2 +WHERE p2.amopmethod = p1.oid AND p1.amstrategies <> 0 AND - p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4 - WHERE p4.amopclaid = p2.oid AND - p4.amopsubtype = p3.amopsubtype); + p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3 + WHERE p3.amopfamily = p2.amopfamily AND + p3.amoplefttype = p2.amoplefttype AND + p3.amoprighttype = p2.amoprighttype); -- Check that amopopr points at a reasonable-looking operator, ie a binary -- operator yielding boolean. -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 WHERE p1.amopopr = p2.oid AND (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype); @@ -671,86 +616,109 @@ WHERE p1.amopopr = p2.oid AND -- Make a list of all the distinct operator names being used in particular -- strategy slots. This is a bit hokey, since the list might need to change -- in future releases, but it's an effective way of spotting mistakes such as --- swapping two operators within a class. +-- swapping two operators within a family. -SELECT DISTINCT opcamid, amopstrategy, oprname -FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid - LEFT JOIN pg_operator p3 ON amopopr = p3.oid +SELECT DISTINCT amopmethod, amopstrategy, oprname +FROM pg_amop p1 LEFT JOIN pg_operator p2 ON amopopr = p2.oid ORDER BY 1, 2, 3; -- Check that all operators linked to by opclass entries have selectivity -- estimators. This is not absolutely required, but it seems a reasonable -- thing to insist on for all standard datatypes. -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 WHERE p1.amopopr = p2.oid AND (p2.oprrest = 0 OR p2.oprjoin = 0); --- Check that operator input types match the opclass --- For 8.0, we require that oprleft match opcintype (possibly by coercion). --- When amopsubtype is zero (default), oprright must equal oprleft; --- when amopsubtype is not zero, oprright must equal amopsubtype. +-- Check that each opclass in an opfamily has associated operators, that is +-- ones whose oprleft matches opcintype (possibly by coercion). -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname -FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3 -WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND - NOT binary_coercible(p3.opcintype, p2.oprleft); - -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname -FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3 -WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND - p1.amopsubtype = 0 AND - p2.oprleft != p2.oprright; - -SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname -FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3 -WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND - p1.amopsubtype != 0 AND - p1.amopsubtype != p2.oprright; +SELECT p1.opcname, p1.opcfamily +FROM pg_opclass AS p1 +WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2 + WHERE p2.amopfamily = p1.opcfamily + AND binary_coercible(p1.opcintype, p2.amoplefttype)); -- Operators that are primary members of opclasses must be immutable (else -- it suggests that the index ordering isn't fixed). Operators that are -- cross-type members need only be stable, since they are just shorthands -- for index probe queries. -SELECT p1.amopclaid, p1.amopopr, p2.oprname, p3.prosrc +SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND - p1.amopsubtype = 0 AND + p1.amoplefttype = p1.amoprighttype AND p3.provolatile != 'i'; -SELECT p1.amopclaid, p1.amopopr, p2.oprname, p3.prosrc +SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND - p1.amopsubtype != 0 AND + p1.amoplefttype != p1.amoprighttype AND p3.provolatile = 'v'; +-- Multiple-datatype btree opclasses should provide closed sets of equality +-- operators; that is if you provide int2 = int4 and int4 = int8 then you +-- must also provide int2 = int8 (and commutators of all these). This is +-- necessary because the planner tries to deduce additional qual clauses from +-- transitivity of mergejoinable operators. If there are clauses +-- int2var = int4var and int4var = int8var, the planner will deduce +-- int2var = int8var ... and it had better have a way to represent it. + +-- check commutative closure +SELECT p1.amoplefttype, p1.amoprighttype +FROM pg_amop AS p1 +WHERE p1.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + p1.amopstrategy = 3 AND + p1.amoplefttype != p1.amoprighttype AND + NOT EXISTS(SELECT 1 FROM pg_amop p2 WHERE + p2.amopfamily = p1.amopfamily AND + p2.amoplefttype = p1.amoprighttype AND + p2.amoprighttype = p1.amoplefttype AND + p2.amopstrategy = 3); + +-- check transitive closure +SELECT p1.amoplefttype, p1.amoprighttype, p2.amoprighttype +FROM pg_amop AS p1, pg_amop AS p2 +WHERE p1.amopfamily = p2.amopfamily AND + p1.amoprighttype = p2.amoplefttype AND + p1.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + p2.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + p1.amopstrategy = 3 AND p2.amopstrategy = 3 AND + p1.amoplefttype != p1.amoprighttype AND + p2.amoplefttype != p2.amoprighttype AND + NOT EXISTS(SELECT 1 FROM pg_amop p3 WHERE + p3.amopfamily = p1.amopfamily AND + p3.amoplefttype = p1.amoplefttype AND + p3.amoprighttype = p2.amoprighttype AND + p3.amopstrategy = 3); + -- **************** pg_amproc **************** -- Look for illegal values in pg_amproc fields -SELECT p1.amopclaid, p1.amprocnum +SELECT p1.amprocfamily, p1.amprocnum FROM pg_amproc as p1 -WHERE p1.amopclaid = 0 OR p1.amprocnum <= 0 OR p1.amproc = 0; +WHERE p1.amprocfamily = 0 OR p1.amproclefttype = 0 OR p1.amprocrighttype = 0 + OR p1.amprocnum < 1 OR p1.amproc = 0; -- Cross-check amprocnum index against parent AM -SELECT p1.amopclaid, p1.amprocnum, p2.oid, p2.amname -FROM pg_amproc AS p1, pg_am AS p2, pg_opclass AS p3 -WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.amname +FROM pg_amproc AS p1, pg_am AS p2, pg_opfamily AS p3 +WHERE p1.amprocfamily = p3.oid AND p3.opfmethod = p2.oid AND p1.amprocnum > p2.amsupport; -- Detect missing pg_amproc entries: should have as many support functions --- as AM expects for each opclass for the AM. When nondefault subtypes are --- present, enforce condition separately for each subtype. +-- as AM expects for each datatype combination supported by the opfamily. -SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype -FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3 -WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND +SELECT p1.amname, p2.opfname, p3.amproclefttype, p3.amprocrighttype +FROM pg_am AS p1, pg_opfamily AS p2, pg_amproc AS p3 +WHERE p2.opfmethod = p1.oid AND p3.amprocfamily = p2.oid AND p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4 - WHERE p4.amopclaid = p2.oid AND - p4.amprocsubtype = p3.amprocsubtype); + WHERE p4.amprocfamily = p2.oid AND + p4.amproclefttype = p3.amproclefttype AND + p4.amprocrighttype = p3.amprocrighttype); -- Unfortunately, we can't check the amproc link very well because the -- signature of the function may be different for different support routines @@ -759,85 +727,66 @@ WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND -- routine number take the same number of parameters, but that's about it -- for a general check... -SELECT p1.amopclaid, p1.amprocnum, +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.proname, - p3.opcname, - p4.amopclaid, p4.amprocnum, + p3.opfname, + p4.amprocfamily, p4.amprocnum, p5.oid, p5.proname, - p6.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3, - pg_amproc AS p4, pg_proc AS p5, pg_opclass AS p6 -WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND - p3.opcamid = p6.opcamid AND p1.amprocnum = p4.amprocnum AND + p6.opfname +FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3, + pg_amproc AS p4, pg_proc AS p5, pg_opfamily AS p6 +WHERE p1.amprocfamily = p3.oid AND p4.amprocfamily = p6.oid AND + p3.opfmethod = p6.opfmethod AND p1.amprocnum = p4.amprocnum AND p1.amproc = p2.oid AND p4.amproc = p5.oid AND (p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs); -- For btree, though, we can do better since we know the support routines --- must be of the form cmp(input, input) returns int4 in the default case --- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0. +-- must be of the form cmp(lefttype, righttype) returns int4. -SELECT p1.amopclaid, p1.amprocnum, +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.proname, - p3.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3 -WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') - AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND - amprocsubtype = 0 AND - (opckeytype != 0 - OR amprocnum != 1 + p3.opfname +FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3 +WHERE p3.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND p1.amprocfamily = p3.oid AND p1.amproc = p2.oid AND + (amprocnum != 1 OR proretset - OR prorettype != 23 + OR prorettype != 'int4'::regtype OR pronargs != 2 - OR NOT binary_coercible(opcintype, proargtypes[0]) - OR proargtypes[0] != proargtypes[1]); - -SELECT p1.amopclaid, p1.amprocnum, - p2.oid, p2.proname, - p3.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3 -WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') - AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND - amprocsubtype != 0 AND - (opckeytype != 0 - OR amprocnum != 1 - OR proretset - OR prorettype != 23 - OR pronargs != 2 - OR NOT binary_coercible(opcintype, proargtypes[0]) - OR proargtypes[1] != amprocsubtype); + OR proargtypes[0] != amproclefttype + OR proargtypes[1] != amprocrighttype); -- For hash we can also do a little better: the support routines must be --- of the form hash(something) returns int4. Ideally we'd check that the --- opcintype is binary-coercible to the function's input, but there are --- enough cases where that fails that I'll just leave out the check for now. +-- of the form hash(lefttype) returns int4. There are several cases where +-- we cheat and use a hash function that is physically compatible with the +-- datatype even though there's no cast, so for now we can't check that. -SELECT p1.amopclaid, p1.amprocnum, +SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.proname, - p3.opcname -FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3 -WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') - AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND - (opckeytype != 0 - OR amprocnum != 1 + p3.opfname +FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3 +WHERE p3.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') + AND p1.amprocfamily = p3.oid AND p1.amproc = p2.oid AND + (amprocnum != 1 OR proretset - OR prorettype != 23 + OR prorettype != 'int4'::regtype OR pronargs != 1 --- OR NOT physically_coercible(opcintype, proargtypes[0]) -); +-- OR NOT physically_coercible(amproclefttype, proargtypes[0]) + OR amproclefttype != amprocrighttype); --- Support routines that are primary members of opclasses must be immutable +-- Support routines that are primary members of opfamilies must be immutable -- (else it suggests that the index ordering isn't fixed). But cross-type -- members need only be stable, since they are just shorthands -- for index probe queries. -SELECT p1.amopclaid, p1.amproc, p2.prosrc +SELECT p1.amprocfamily, p1.amproc, p2.prosrc FROM pg_amproc AS p1, pg_proc AS p2 WHERE p1.amproc = p2.oid AND - p1.amprocsubtype = 0 AND + p1.amproclefttype = p1.amprocrighttype AND p2.provolatile != 'i'; -SELECT p1.amopclaid, p1.amproc, p2.prosrc +SELECT p1.amprocfamily, p1.amproc, p2.prosrc FROM pg_amproc AS p1, pg_proc AS p2 WHERE p1.amproc = p2.oid AND - p1.amprocsubtype != 0 AND + p1.amproclefttype != p1.amprocrighttype AND p2.provolatile = 'v'; diff --git a/src/tools/findoidjoins/README b/src/tools/findoidjoins/README index ce31b19472..aec8f1bd8d 100644 --- a/src/tools/findoidjoins/README +++ b/src/tools/findoidjoins/README @@ -7,13 +7,16 @@ anything but an empty database, such as template1; else it's likely to be very slow. Run on an empty database, it returns the system join relationships (shown -below for 8.1). Note that unexpected matches may indicate bogus entries +below for 8.3). Note that unexpected matches may indicate bogus entries in system tables --- don't accept a peculiar match without question. In particular, a field shown as joining to more than one target table is -probably messed up. In 8.1, the *only* fields that should join to more -than one target are pg_description.objoid, pg_depend.objid, and -pg_depend.refobjid. (Running make_oidjoins_check is an easy way to spot -fields joining to more than one table, BTW.) +probably messed up. In 8.3, the *only* fields that should join to more +than one target are pg_description.objoid, pg_depend.objid, +pg_depend.refobjid, pg_shdescription.objoid, pg_shdepend.objid, and +pg_shdepend.refobjid. (Running make_oidjoins_check is an easy way to spot +fields joining to more than one table, BTW.) NOTE: in an empty database, +findoidjoins may not report joins for pg_shdescription and pg_shdepend for +lack of any entries there. The shell script make_oidjoins_check converts findoidjoins' output into an SQL script that checks for dangling links (entries in an @@ -26,7 +29,7 @@ revision in the patterns of cross-links between system tables. (Ideally we'd just regenerate the script as part of the regression tests themselves, but that seems too slow...) -NOTE: in 8.1, make_oidjoins_check produces two bogus join checks: +NOTE: in 8.3, make_oidjoins_check produces two bogus join checks: Join pg_catalog.pg_class.relfilenode => pg_catalog.pg_class.oid Join pg_catalog.pg_database.datlastsysoid => pg_catalog.pg_database.oid These are artifacts and should not be added to the oidjoins regress test. @@ -50,11 +53,15 @@ Join pg_catalog.pg_am.ambuild => pg_catalog.pg_proc.oid Join pg_catalog.pg_am.ambulkdelete => pg_catalog.pg_proc.oid Join pg_catalog.pg_am.amvacuumcleanup => pg_catalog.pg_proc.oid Join pg_catalog.pg_am.amcostestimate => pg_catalog.pg_proc.oid -Join pg_catalog.pg_amop.amopclaid => pg_catalog.pg_opclass.oid -Join pg_catalog.pg_amop.amopsubtype => pg_catalog.pg_type.oid +Join pg_catalog.pg_am.amoptions => pg_catalog.pg_proc.oid +Join pg_catalog.pg_amop.amopfamily => pg_catalog.pg_opfamily.oid +Join pg_catalog.pg_amop.amoplefttype => pg_catalog.pg_type.oid +Join pg_catalog.pg_amop.amoprighttype => pg_catalog.pg_type.oid Join pg_catalog.pg_amop.amopopr => pg_catalog.pg_operator.oid -Join pg_catalog.pg_amproc.amopclaid => pg_catalog.pg_opclass.oid -Join pg_catalog.pg_amproc.amprocsubtype => pg_catalog.pg_type.oid +Join pg_catalog.pg_amop.amopmethod => pg_catalog.pg_am.oid +Join pg_catalog.pg_amproc.amprocfamily => pg_catalog.pg_opfamily.oid +Join pg_catalog.pg_amproc.amproclefttype => pg_catalog.pg_type.oid +Join pg_catalog.pg_amproc.amprocrighttype => pg_catalog.pg_type.oid Join pg_catalog.pg_amproc.amproc => pg_catalog.pg_proc.oid Join pg_catalog.pg_attribute.attrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_attribute.atttypid => pg_catalog.pg_type.oid @@ -63,6 +70,7 @@ Join pg_catalog.pg_cast.casttarget => pg_catalog.pg_type.oid Join pg_catalog.pg_cast.castfunc => pg_catalog.pg_proc.oid Join pg_catalog.pg_class.relnamespace => pg_catalog.pg_namespace.oid Join pg_catalog.pg_class.reltype => pg_catalog.pg_type.oid +Join pg_catalog.pg_class.relowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_class.relam => pg_catalog.pg_am.oid Join pg_catalog.pg_class.reltablespace => pg_catalog.pg_tablespace.oid Join pg_catalog.pg_class.reltoastrelid => pg_catalog.pg_class.oid @@ -70,7 +78,9 @@ Join pg_catalog.pg_class.reltoastidxid => pg_catalog.pg_class.oid Join pg_catalog.pg_constraint.connamespace => pg_catalog.pg_namespace.oid Join pg_catalog.pg_constraint.contypid => pg_catalog.pg_type.oid Join pg_catalog.pg_conversion.connamespace => pg_catalog.pg_namespace.oid +Join pg_catalog.pg_conversion.conowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_conversion.conproc => pg_catalog.pg_proc.oid +Join pg_catalog.pg_database.datdba => pg_catalog.pg_authid.oid Join pg_catalog.pg_database.dattablespace => pg_catalog.pg_tablespace.oid Join pg_catalog.pg_depend.classid => pg_catalog.pg_class.oid Join pg_catalog.pg_depend.refclassid => pg_catalog.pg_class.oid @@ -78,33 +88,42 @@ Join pg_catalog.pg_description.classoid => pg_catalog.pg_class.oid Join pg_catalog.pg_index.indexrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_index.indrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_language.lanvalidator => pg_catalog.pg_proc.oid -Join pg_catalog.pg_opclass.opcamid => pg_catalog.pg_am.oid +Join pg_catalog.pg_namespace.nspowner => pg_catalog.pg_authid.oid +Join pg_catalog.pg_opclass.opcmethod => pg_catalog.pg_am.oid Join pg_catalog.pg_opclass.opcnamespace => pg_catalog.pg_namespace.oid +Join pg_catalog.pg_opclass.opcowner => pg_catalog.pg_authid.oid +Join pg_catalog.pg_opclass.opcfamily => pg_catalog.pg_opfamily.oid Join pg_catalog.pg_opclass.opcintype => pg_catalog.pg_type.oid +Join pg_catalog.pg_opclass.opckeytype => pg_catalog.pg_type.oid Join pg_catalog.pg_operator.oprnamespace => pg_catalog.pg_namespace.oid +Join pg_catalog.pg_operator.oprowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_operator.oprleft => pg_catalog.pg_type.oid Join pg_catalog.pg_operator.oprright => pg_catalog.pg_type.oid Join pg_catalog.pg_operator.oprresult => pg_catalog.pg_type.oid Join pg_catalog.pg_operator.oprcom => pg_catalog.pg_operator.oid Join pg_catalog.pg_operator.oprnegate => pg_catalog.pg_operator.oid -Join pg_catalog.pg_operator.oprlsortop => pg_catalog.pg_operator.oid -Join pg_catalog.pg_operator.oprrsortop => pg_catalog.pg_operator.oid -Join pg_catalog.pg_operator.oprltcmpop => pg_catalog.pg_operator.oid -Join pg_catalog.pg_operator.oprgtcmpop => pg_catalog.pg_operator.oid Join pg_catalog.pg_operator.oprcode => pg_catalog.pg_proc.oid Join pg_catalog.pg_operator.oprrest => pg_catalog.pg_proc.oid Join pg_catalog.pg_operator.oprjoin => pg_catalog.pg_proc.oid +Join pg_catalog.pg_opfamily.opfmethod => pg_catalog.pg_am.oid +Join pg_catalog.pg_opfamily.opfnamespace => pg_catalog.pg_namespace.oid +Join pg_catalog.pg_opfamily.opfowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_proc.pronamespace => pg_catalog.pg_namespace.oid +Join pg_catalog.pg_proc.proowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_proc.prolang => pg_catalog.pg_language.oid Join pg_catalog.pg_proc.prorettype => pg_catalog.pg_type.oid Join pg_catalog.pg_rewrite.ev_class => pg_catalog.pg_class.oid +Join pg_catalog.pg_shdepend.refclassid => pg_catalog.pg_class.oid +Join pg_catalog.pg_shdescription.classoid => pg_catalog.pg_class.oid Join pg_catalog.pg_statistic.starelid => pg_catalog.pg_class.oid Join pg_catalog.pg_statistic.staop1 => pg_catalog.pg_operator.oid Join pg_catalog.pg_statistic.staop2 => pg_catalog.pg_operator.oid Join pg_catalog.pg_statistic.staop3 => pg_catalog.pg_operator.oid +Join pg_catalog.pg_tablespace.spcowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_trigger.tgrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_trigger.tgfoid => pg_catalog.pg_proc.oid Join pg_catalog.pg_type.typnamespace => pg_catalog.pg_namespace.oid +Join pg_catalog.pg_type.typowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_type.typrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_type.typelem => pg_catalog.pg_type.oid Join pg_catalog.pg_type.typinput => pg_catalog.pg_proc.oid diff --git a/src/tutorial/syscat.source b/src/tutorial/syscat.source index 50bd2e31a6..f6460d3fc0 100644 --- a/src/tutorial/syscat.source +++ b/src/tutorial/syscat.source @@ -7,7 +7,7 @@ -- Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group -- Portions Copyright (c) 1994, Regents of the University of California -- --- $PostgreSQL: pgsql/src/tutorial/syscat.source,v 1.16 2006/03/05 15:59:11 momjian Exp $ +-- $PostgreSQL: pgsql/src/tutorial/syscat.source,v 1.17 2006/12/23 00:43:13 tgl Exp $ -- --------------------------------------------------------------------------- @@ -165,18 +165,18 @@ SELECT n.nspname, p.proname, format_type(t.oid, null) as typname -- --- lists all the operator classes that can be used with each access method --- as well as the operators that cn be used with the respective operator --- classes +-- lists all the operator families that can be used with each access method +-- as well as the operators that can be used with the respective operator +-- families -- -SELECT n.nspname, am.amname, opc.opcname, opr.oprname - FROM pg_namespace n, pg_am am, pg_opclass opc, +SELECT am.amname, n.nspname, opf.opfname, opr.oprname + FROM pg_namespace n, pg_am am, pg_opfamily opf, pg_amop amop, pg_operator opr - WHERE opc.opcnamespace = n.oid - and opc.opcamid = am.oid - and amop.amopclaid = opc.oid + WHERE opf.opfnamespace = n.oid + and opf.opfmethod = am.oid + and amop.amopfamily = opf.oid and amop.amopopr = opr.oid - ORDER BY nspname, amname, opcname, oprname; + ORDER BY nspname, amname, opfname, oprname; -- -- Reset the search path