aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/hash/hashfunc.c28
-rw-r--r--src/backend/access/index/indexam.c33
-rw-r--r--src/backend/access/nbtree/nbtsearch.c26
-rw-r--r--src/backend/catalog/Makefile6
-rw-r--r--src/backend/catalog/dependency.c194
-rw-r--r--src/backend/catalog/namespace.c88
-rw-r--r--src/backend/catalog/pg_operator.c98
-rw-r--r--src/backend/commands/indexcmds.c53
-rw-r--r--src/backend/commands/opclasscmds.c733
-rw-r--r--src/backend/commands/operatorcmds.c44
-rw-r--r--src/backend/commands/tablecmds.c4
-rw-r--r--src/backend/executor/execQual.c23
-rw-r--r--src/backend/executor/nodeIndexscan.c23
-rw-r--r--src/backend/executor/nodeMergejoin.c255
-rw-r--r--src/backend/nodes/copyfuncs.c8
-rw-r--r--src/backend/nodes/equalfuncs.c5
-rw-r--r--src/backend/nodes/outfuncs.c9
-rw-r--r--src/backend/nodes/readfuncs.c4
-rw-r--r--src/backend/optimizer/path/costsize.c9
-rw-r--r--src/backend/optimizer/path/indxpath.c324
-rw-r--r--src/backend/optimizer/path/joinpath.c67
-rw-r--r--src/backend/optimizer/plan/createplan.c60
-rw-r--r--src/backend/optimizer/plan/initsplan.c24
-rw-r--r--src/backend/optimizer/plan/planagg.c18
-rw-r--r--src/backend/optimizer/plan/subselect.c6
-rw-r--r--src/backend/optimizer/util/clauses.c10
-rw-r--r--src/backend/optimizer/util/pathnode.c10
-rw-r--r--src/backend/optimizer/util/plancat.c8
-rw-r--r--src/backend/optimizer/util/predtest.c83
-rw-r--r--src/backend/optimizer/util/restrictinfo.c3
-rw-r--r--src/backend/parser/parse_expr.c119
-rw-r--r--src/backend/utils/adt/ruleutils.c27
-rw-r--r--src/backend/utils/adt/selfuncs.c148
-rw-r--r--src/backend/utils/cache/catcache.c20
-rw-r--r--src/backend/utils/cache/lsyscache.c413
-rw-r--r--src/backend/utils/cache/relcache.c181
-rw-r--r--src/backend/utils/cache/syscache.c64
-rw-r--r--src/backend/utils/cache/typcache.c76
-rw-r--r--src/backend/utils/sort/tuplesort.c37
-rw-r--r--src/bin/initdb/initdb.c11
-rw-r--r--src/bin/pg_dump/pg_dump.c162
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/dependency.h5
-rw-r--r--src/include/catalog/indexing.h19
-rw-r--r--src/include/catalog/namespace.h5
-rw-r--r--src/include/catalog/pg_amop.h1011
-rw-r--r--src/include/catalog/pg_amproc.h477
-rw-r--r--src/include/catalog/pg_opclass.h259
-rw-r--r--src/include/catalog/pg_operator.h1471
-rw-r--r--src/include/catalog/pg_opfamily.h138
-rw-r--r--src/include/commands/defrem.h5
-rw-r--r--src/include/nodes/parsenodes.h3
-rw-r--r--src/include/nodes/plannodes.h6
-rw-r--r--src/include/nodes/primnodes.h6
-rw-r--r--src/include/nodes/relation.h15
-rw-r--r--src/include/optimizer/pathnode.h4
-rw-r--r--src/include/utils/lsyscache.h30
-rw-r--r--src/include/utils/rel.h11
-rw-r--r--src/include/utils/selfuncs.h3
-rw-r--r--src/include/utils/syscache.h33
-rw-r--r--src/include/utils/typcache.h19
-rw-r--r--src/test/regress/expected/oidjoins.out242
-rw-r--r--src/test/regress/expected/opr_sanity.out591
-rw-r--r--src/test/regress/expected/rowtypes.out2
-rw-r--r--src/test/regress/expected/sanity_check.out3
-rw-r--r--src/test/regress/sql/oidjoins.sql126
-rw-r--r--src/test/regress/sql/opr_sanity.sql425
-rw-r--r--src/tools/findoidjoins/README49
-rw-r--r--src/tutorial/syscat.source20
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,
- &ltop,
- &gtop,
- &ltproc,
- &gtproc);
-
- 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, &ltop, &gtop, 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