diff options
Diffstat (limited to 'src')
69 files changed, 4554 insertions, 3942 deletions
diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index 1e2d779a14c..f6b39bada2a 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 493e9f0ad00..6d60f461784 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 6d9be1b0176..284b92e0d28 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 2e2d885f894..110619425b1 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 cab4f1006bc..770b189606e 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 1d6162ca12e..5c661a098bb 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); @@ -1071,6 +1072,89 @@ OpclassIsVisible(Oid opcid) } /* + * 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. * Returns OID if conversion found in search path, else InvalidOid. diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 13efb7227ad..65ecb65b926 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 L<R compare operator (for merge join) - * gtCompareName X L>R 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 (canHash) + if (canMerge) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only binary operators can hash"))); - if (leftSortName || rightSortName || ltCompareName || gtCompareName) + errmsg("only binary operators can merge join"))); + if (canHash) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only binary operators can merge join"))); + errmsg("only binary operators can hash"))); } 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 5f54f66f591..a5cc047c69b 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 d4dec746501..8b1b27ef3e7 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,27 +43,187 @@ /* * 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 76884e8cd82..a84feee2a71 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), @@ -157,26 +154,6 @@ DefineOperator(List *names, List *parameters) 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.. */ OperatorCreate(oprName, /* operator name */ @@ -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 ea80c4e8286..2a1116f7580 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 10b02b4a3ec..1e9865c3007 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 9773f2341ec..4371fc1a280 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 8a9f6fe2300..97824920d63 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 */ @@ -133,19 +133,10 @@ typedef struct MergeJoinClauseData 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); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_PROC, - get_func_name(qual->opfuncid)); - - /* 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); + /* 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(ltproc)); + get_func_name(cmpproc)); /* 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 3bb95b658d1..ca841cb181a 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 ef21e67fafb..a7c4ef4e2a8 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 5ddf60dbbb1..b18b6988cfa 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 689cef3edf2..37b39439eb0 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 71685643efa..fbcf7d2b5f5 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 b15affa54d5..af081b82c8e 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 6882439ca3a..06022b373b5 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 <math.h> +#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 14f1f1a10f4..f924994480b 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 da321a637b2..229b779af03 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 e64340ed21c..fcc8d510786 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 7793d071cda..f42a28cddd5 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 73ad926418f..0f720c40e93 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 01f3151bee8..5042a3ff563 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 70a77bd3bd8..5b80991aefe 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 4a2609a4ab6..5f81cae4e85 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 9176ae1680c..adfd9e47858 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 234a15b6afb..2a48741b3a2 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 a99942010b6..b2ff95f457b 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 230ce549f3b..73e82cd5e01 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 <ctype.h> #include <math.h> -#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); + + /* + * 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 */ + } - /* Verify mergejoinability and get left and right "<" operators */ - if (!op_mergejoinable(opno, - &lsortop, - &rsortop)) - goto fail; /* shouldn't happen */ + 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 55b9d5baf07..1a1d19f399a 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 fdc31e0d977..824ef4a1efe 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); @@ -133,10 +138,160 @@ get_opclass_member(Oid opclass, Oid subtype, int16 strategy) } /* + * 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,58 +317,44 @@ 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. */ catlist = SearchSysCacheList(AMOPOPID, 1, @@ -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,67 +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) -{ - 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 == 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) +Oid +get_opclass_family(Oid opclass) { HeapTuple tp; Form_pg_opclass cla_tup; - bool result; + Oid result; tp = SearchSysCache(CLAOID, ObjectIdGetDatum(opclass), @@ -546,7 +631,7 @@ opclass_is_default(Oid opclass) 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 65cd1e72907..be5fb60dc8e 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; @@ -948,18 +951,6 @@ RelationInitIndexAccessInfo(Relation relation) 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 */ tuple = SearchSysCache(AMOID, @@ -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; @@ -1177,22 +1187,54 @@ LookupOpclassInfo(Oid operatorClassOid, 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(opcentry->opcintype)); + ScanKeyInit(&skey[2], + Anum_pg_amop_amoprighttype, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(InvalidOid)); + 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 e19fba05840..f2fb0796cbb 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 c5a0272414d..192675c95ee 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); + Oid opclass; + + opclass = GetDefaultOpClass(type_id, BTREE_AM_OID); + if (OidIsValid(opclass)) + { + 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_opc == InvalidOid) + if (typentry->btree_opf == InvalidOid) { - if (typentry->hash_opc == InvalidOid) - typentry->hash_opc = GetDefaultOpClass(type_id, - HASH_AM_OID); + 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 652f9a2ff44..dceaf5a6556 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 ce5439a1dd1..cd31e135dee 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 c4df03083e1..ae8d54936f1 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 945c9a1b229..f0a840a3dde 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 da7d7ac8e4e..b3ec0ccf2c6 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 6587b34db72..215119afd04 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 ab354f53ac6..e1d9b190f2b 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 1203434727f..6907547eef5 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 <amopclaid, amopsubtype, amopstrategy>. - * 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 <amopfamily, amoplefttype, amoprighttype, + * amopstrategy>. 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 <amopclaid, amopopr>, 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 <amopfamily, amopopr>, 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 )); - -/* - * gin _int4_ops - */ -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 ( 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 array_ops (these anyarray operators are used with all the opclasses + * of the family) + */ +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 291931b707b..1f81ff78309 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 <amopclaid, amprocsubtype, amprocnum>. - * 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 <amprocfamily, amproclefttype, + * amprocrighttype, amprocnum>. 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 cee9f752bf0..8aa9ea3d68a 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 - * <opcamid, opcname> --- 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 <opcmethod, opcname, opcnamespace> --- + * 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 <opcamid, opcintype> pair, there can be at most one row that + * For a given <opcmethod, opcintype> 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 b64b3c5136f..b2acdc425b1 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 "l<r" oper, if mergejoinable */ - Oid oprgtcmpop; /* OID of "l>r" 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 = 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 = 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 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 = 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 = 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 = 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 = 387 ( "=" PGNSP PGUID b f 27 27 16 387 402 2799 2799 2799 2800 tideq eqsel eqjoinsel )); +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 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 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 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 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 639 ( "~" PGNSP PGUID b f 19 25 16 0 640 0 0 0 0 nameregexeq regexeqsel regexeqjoinsel )); +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 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 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 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 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 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 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 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 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 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 = 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 = 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 = 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 = 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 = 713 ( "<>" PGNSP PGUID b f 600 600 16 713 510 0 0 0 0 point_ne neqsel neqjoinsel )); +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 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 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 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 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 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 = 773 ( "@" PGNSP PGUID l f 0 23 23 0 0 0 0 0 0 int4abs - - )); +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 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 = 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 = 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 = 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 = 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 = 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 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 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 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 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 = 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 = 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 = 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 = 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 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 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 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 = 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 = 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 = 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 = 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 = 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 = 1591 ( "@-@" PGNSP PGUID l f 0 601 701 0 0 0 0 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 = 1524 ( "<->" PGNSP PGUID b f f 628 603 701 0 0 dist_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 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 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 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 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 f 0 601 701 0 0 lseg_length - - )); + +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 = 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 = 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 = 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 = 1849 ( "+" PGNSP PGUID b f 1186 1083 1083 1800 0 0 0 0 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 = 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 = 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 = 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 = 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 = 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 = 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 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 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 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 f 1186 1083 1083 1800 0 interval_pl_time - - )); + +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 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 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 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 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 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 = 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 = 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 = 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 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 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 = 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 = 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 = 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 = 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 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 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 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 00000000000..8e51fb74191 --- /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 7b45ea57358..4c8ac8c876a 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 f79bf2907ce..bc62c90f4dc 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 5c2de28a417..e8250504eb4 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 9654181bc3d..5946300c975 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 d39e924227f..955773d147c 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 f8aebd6a53a..59c2a62a0ac 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 69eb31bcc55..272b321e642 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 1f7347c9cdc..283c04ae991 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 69a22b37b56..bb6e35bfdcf 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 5c84c7e17ca..2305ccd1d03 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 673bf176ade..5c8b0e850a9 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 445f41ffb94..cc82b12e027 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 +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, 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); - ctid | amopclaid -------+----------- +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, amprocsubtype +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); - ctid | amprocsubtype -------+--------------- +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 e455538d69f..a0e9483ebd0 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); +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) --- 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 ------+--------- +-- 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 = 'btree') + AND amopstrategy = 3 + AND NOT p1.oprcanmerge; + oid | oprname | amopfamily +-----+---------+------------ (0 rows) --- 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); 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 = '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_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; + oid +----- +(0 rows) + -- **************** 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; 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 ------------+---------+-----+--------- -(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 ------------+---------+-----+---------+--------- + amopfamily | amopopr | oid | oprname +------------+---------+-----+--------- (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, - 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[0] != proargtypes[1]); - amopclaid | amprocnum | oid | proname | opcname ------------+-----------+-----+---------+--------- -(0 rows) - -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[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 5b4d9555aed..10687f5669e 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 d2c68e8791e..5e6a570e244 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 910d55f9f94..bf713e9fa7c 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 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 amopclaid != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid); -SELECT ctid, 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 amopsubtype != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype); +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 5195a290abb..4dd39eb164e 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; - --- 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. +WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT + (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0); -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); - --- 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'; +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); --- Hashable operators should appear as members of hash index opclasses. +-- 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 = 'btree') + AND amopstrategy = 3 + AND NOT p1.oprcanmerge; + +-- 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. - -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[0] != proargtypes[1]); +-- 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[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 ce31b194728..aec8f1bd8de 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 50bd2e31a66..f6460d3fc07 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 |