diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 9a8729b..9bd3169 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -646,6 +646,13 @@
+ amoppurpose
+ int2
+
+ Bit field indicating valid purposes of operator within operator family (1 = search, 2 = ordering)
+
+
+
amopopr
oid
pg_operator.oid
diff --git a/doc/src/sgml/ref/alter_opfamily.sgml b/doc/src/sgml/ref/alter_opfamily.sgml
index ed4877d..aa1655b 100644
--- a/doc/src/sgml/ref/alter_opfamily.sgml
+++ b/doc/src/sgml/ref/alter_opfamily.sgml
@@ -22,7 +22,7 @@ PostgreSQL documentation
ALTER OPERATOR FAMILY name USING index_method ADD
- { OPERATOR strategy_number operator_name ( op_type, op_type )
+ { OPERATOR strategy_number operator_name ( op_type, op_type ) [ FOR ( op_purpose [, ...] ) ]
| FUNCTION support_number [ ( op_type [ , op_type ] ) ] function_name ( argument_type [, ...] )
} [, ... ]
ALTER OPERATOR FAMILY name USING index_method DROP
@@ -155,6 +155,24 @@ ALTER OPERATOR FAMILY name USING op_purpose
+
+
+ The purpose of the operator within the operator class. An operator
+ may serve more than one purpose. SEARCH indicates
+ that the operator class supports index searches based on this operator,
+ while ORDER indicates that the operator class can
+ be used to retrieve results in order in a query containing a clause
+ of the form ORDER BY column
+ operator_name
+ value. More than one purpose
+ may be specified. If the clause is omitted, the default is
+ SEARCH.
+
+
+
+
+
support_number
diff --git a/doc/src/sgml/ref/create_opclass.sgml b/doc/src/sgml/ref/create_opclass.sgml
index d7372aa..d3cfca6 100644
--- a/doc/src/sgml/ref/create_opclass.sgml
+++ b/doc/src/sgml/ref/create_opclass.sgml
@@ -23,7 +23,7 @@ PostgreSQL documentation
CREATE OPERATOR CLASS name [ DEFAULT ] FOR TYPE data_type
USING index_method [ FAMILY family_name ] AS
- { OPERATOR strategy_number operator_name [ ( op_type, op_type ) ]
+ { OPERATOR strategy_number operator_name [ ( op_type, op_type ) ] [ FOR ( op_purpose [, ...] ) ]
| FUNCTION support_number [ ( op_type [ , op_type ] ) ] function_name ( argument_type [, ...] )
| STORAGE storage_type
} [, ... ]
@@ -181,6 +181,24 @@ CREATE OPERATOR CLASS name [ DEFAUL
+ op_purpose
+
+
+ The purpose of the operator within the operator class. An operator
+ may serve more than one purpose. SEARCH indicates
+ that the operator class supports index searches based on this operator,
+ while ORDER indicates that the operator class can
+ be used to retrieve results in order in a query containing a clause
+ of the form ORDER BY column
+ operator_name
+ value. More than one purpose
+ may be specified. If the clause is omitted, the default is
+ SEARCH.
+
+
+
+
+
support_number
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 8f0f226..238e9dc 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -21,6 +21,7 @@
#include "access/nbtree.h"
#include "access/reloptions.h"
#include "access/relscan.h"
+#include "catalog/pg_amop.h"
#include "executor/execdebug.h"
#include "miscadmin.h"
#include "storage/bufmgr.h"
@@ -622,7 +623,8 @@ _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op,
cmp_op = get_opfamily_member(rel->rd_opfamily[leftarg->sk_attno - 1],
lefttype,
righttype,
- strat);
+ strat,
+ AMOP_SEARCH);
if (OidIsValid(cmp_op))
{
RegProcedure cmp_proc = get_opcode(cmp_op);
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 9407d0f..c512792 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -24,6 +24,7 @@
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_tablespace.h"
@@ -988,10 +989,11 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
errdetail("Only commutative operators can be used in exclusion constraints.")));
/*
- * Operator must be a member of the right opfamily, too
+ * Operator must be a member of the right opfamily, too.
+ * And should be useful for search.
*/
opfamily = get_opclass_family(classOidP[attn]);
- strat = get_op_opfamily_strategy(opid, opfamily);
+ strat = get_op_opfamily_strategy(opid, opfamily, AMOP_SEARCH);
if (strat == 0)
{
HeapTuple opftuple;
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index ea66e95..a0f375b 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -54,6 +54,7 @@ typedef struct
int number; /* strategy or support proc number */
Oid lefttype; /* lefttype */
Oid righttype; /* righttype */
+ int purpose; /* purpose */
} OpFamilyMember;
@@ -502,6 +503,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
member->object = operOid;
member->number = item->number;
+ member->purpose = item->purpose;
assignOperTypes(member, amoid, typeoid);
addFamilyMember(&operators, member, false);
break;
@@ -870,6 +872,7 @@ AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid,
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
member->object = operOid;
member->number = item->number;
+ member->purpose = item->purpose;
assignOperTypes(member, amoid, InvalidOid);
addFamilyMember(&operators, member, false);
break;
@@ -1029,6 +1032,9 @@ processTypesSpec(List *args, Oid *lefttype, Oid *righttype)
/*
* Determine the lefttype/righttype to assign to an operator,
* and do any validity checking we can manage.
+ *
+ * member->object and member->purpose should already be initialized
+ * when this function is called.
*/
static void
assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
@@ -1049,10 +1055,10 @@ assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("index operators must be binary")));
- if (opform->oprresult != BOOLOID)
+ if (opform->oprresult != BOOLOID && (member->purpose & AMOP_SEARCH) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("index operators must return boolean")));
+ errmsg("index search operators must return boolean")));
/*
* If lefttype/righttype isn't specified, use the operator's input types
@@ -1235,6 +1241,7 @@ storeOperators(List *opfamilyname, Oid amoid,
values[Anum_pg_amop_amopstrategy - 1] = Int16GetDatum(op->number);
values[Anum_pg_amop_amopopr - 1] = ObjectIdGetDatum(op->object);
values[Anum_pg_amop_amopmethod - 1] = ObjectIdGetDatum(amoid);
+ values[Anum_pg_amop_amoppurpose - 1] = Int32GetDatum(op->purpose);
tup = heap_form_tuple(rel->rd_att, values, nulls);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c009711..4afba2f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -26,6 +26,7 @@
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_inherits.h"
@@ -5184,7 +5185,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
* We'll use it for PK = PK comparisons.
*/
ppeqop = get_opfamily_member(opfamily, opcintype, opcintype,
- eqstrategy);
+ eqstrategy, AMOP_SEARCH);
if (!OidIsValid(ppeqop))
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
@@ -5197,10 +5198,10 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
fktyped = getBaseType(fktype);
pfeqop = get_opfamily_member(opfamily, opcintype, fktyped,
- eqstrategy);
+ eqstrategy, AMOP_SEARCH);
if (OidIsValid(pfeqop))
ffeqop = get_opfamily_member(opfamily, fktyped, fktyped,
- eqstrategy);
+ eqstrategy, AMOP_SEARCH);
else
ffeqop = InvalidOid; /* keep compiler quiet */
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 7d7c1a1..a72fc9f 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -38,6 +38,7 @@
#include "access/nbtree.h"
#include "access/tupconvert.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_type.h"
#include "commands/typecmds.h"
#include "executor/execdebug.h"
@@ -4712,7 +4713,7 @@ ExecInitExpr(Expr *node, PlanState *parent)
Oid righttype;
Oid proc;
- get_op_opfamily_properties(opno, opfamily,
+ get_op_opfamily_properties(opno, opfamily, AMOP_SEARCH,
&strategy,
&lefttype,
&righttype);
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index ee5fc72..9ccd5ec 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -27,6 +27,7 @@
#include "access/genam.h"
#include "access/nbtree.h"
#include "access/relscan.h"
+#include "catalog/pg_amop.h"
#include "executor/execdebug.h"
#include "executor/nodeIndexscan.h"
#include "optimizer/clauses.h"
@@ -742,7 +743,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid,
*/
opfamily = index->rd_opfamily[varattno - 1];
- get_op_opfamily_properties(opno, opfamily,
+ get_op_opfamily_properties(opno, opfamily, AMOP_SEARCH,
&op_strategy,
&op_lefttype,
&op_righttype);
@@ -832,7 +833,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid,
elog(ERROR, "bogus RowCompare index qualification");
opfamily = index->rd_opfamily[varattno - 1];
- get_op_opfamily_properties(opno, opfamily,
+ get_op_opfamily_properties(opno, opfamily, AMOP_SEARCH,
&op_strategy,
&op_lefttype,
&op_righttype);
@@ -935,7 +936,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid,
*/
opfamily = index->rd_opfamily[varattno - 1];
- get_op_opfamily_properties(opno, opfamily,
+ get_op_opfamily_properties(opno, opfamily, AMOP_SEARCH,
&op_strategy,
&op_lefttype,
&op_righttype);
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index e8ce5bc..d0836c4 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -201,7 +201,7 @@ MJExamineQuals(List *mergeclauses,
clause->rexpr = ExecInitExpr((Expr *) lsecond(qual->args), parent);
/* Extract the operator's declared left/right datatypes */
- get_op_opfamily_properties(qual->opno, opfamily,
+ get_op_opfamily_properties(qual->opno, opfamily, AMOP_SEARCH,
&op_strategy,
&op_lefttype,
&op_righttype);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 5346c72..801e018 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2974,6 +2974,7 @@ _copyCreateOpClassItem(CreateOpClassItem *from)
COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(number);
COPY_NODE_FIELD(class_args);
+ COPY_NODE_FIELD(purpose);
COPY_NODE_FIELD(storedtype);
return newnode;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 7cb2192..58c81ba 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1453,6 +1453,7 @@ _equalCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b)
COMPARE_NODE_FIELD(args);
COMPARE_SCALAR_FIELD(number);
COMPARE_NODE_FIELD(class_args);
+ COMPARE_NODE_FIELD(purpose);
COMPARE_NODE_FIELD(storedtype);
return true;
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index e44e960..704fdb7 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -17,6 +17,7 @@
#include "postgres.h"
#include "access/skey.h"
+#include "catalog/pg_amop.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
@@ -1023,7 +1024,7 @@ select_equality_operator(EquivalenceClass *ec, Oid lefttype, Oid righttype)
Oid opno;
opno = get_opfamily_member(opfamily, lefttype, righttype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber, AMOP_SEARCH);
if (OidIsValid(opno))
return opno;
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 38b0930..0101abc 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -19,6 +19,7 @@
#include "access/skey.h"
#include "catalog/pg_am.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_type.h"
@@ -87,7 +88,7 @@ static bool match_clause_to_indexcol(IndexOptInfo *index,
RestrictInfo *rinfo,
Relids outer_relids,
SaOpControl saop_control);
-static bool is_indexable_operator(Oid expr_op, Oid opfamily,
+static bool is_indexable_operator(Oid expr_op, Oid opfamily, int purpose,
bool indexkey_on_left);
static bool match_rowcompare_to_indexcol(IndexOptInfo *index,
int indexcol,
@@ -1272,7 +1273,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
bms_is_subset(right_relids, outer_relids) &&
!contain_volatile_functions(rightop))
{
- if (is_indexable_operator(expr_op, opfamily, true))
+ if (is_indexable_operator(expr_op, opfamily, AMOP_SEARCH, true))
return true;
/*
@@ -1290,7 +1291,7 @@ match_clause_to_indexcol(IndexOptInfo *index,
bms_is_subset(left_relids, outer_relids) &&
!contain_volatile_functions(leftop))
{
- if (is_indexable_operator(expr_op, opfamily, false))
+ if (is_indexable_operator(expr_op, opfamily, AMOP_SEARCH, false))
return true;
/*
@@ -1314,7 +1315,8 @@ match_clause_to_indexcol(IndexOptInfo *index,
* the opfamily.
*/
static bool
-is_indexable_operator(Oid expr_op, Oid opfamily, bool indexkey_on_left)
+is_indexable_operator(Oid expr_op, Oid opfamily, int purpose,
+ bool indexkey_on_left)
{
/* Get the commuted operator if necessary */
if (!indexkey_on_left)
@@ -1325,7 +1327,7 @@ is_indexable_operator(Oid expr_op, Oid opfamily, bool indexkey_on_left)
}
/* OK if the (commuted) operator is a member of the index's opfamily */
- return op_in_opfamily(expr_op, opfamily);
+ return op_in_opfamily(expr_op, opfamily, purpose);
}
/*
@@ -1384,7 +1386,7 @@ match_rowcompare_to_indexcol(IndexOptInfo *index,
return false;
/* We're good if the operator is the right type of opfamily member */
- switch (get_op_opfamily_strategy(expr_op, opfamily))
+ switch (get_op_opfamily_strategy(expr_op, opfamily, AMOP_SEARCH))
{
case BTLessStrategyNumber:
case BTLessEqualStrategyNumber:
@@ -2552,7 +2554,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
case OID_BPCHAR_LIKE_OP:
case OID_NAME_LIKE_OP:
case OID_BYTEA_LIKE_OP:
- if (!op_in_opfamily(expr_op, opfamily))
+ if (!op_in_opfamily(expr_op, opfamily, AMOP_SEARCH))
{
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like,
&prefix, &rest);
@@ -2563,7 +2565,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
case OID_TEXT_ICLIKE_OP:
case OID_BPCHAR_ICLIKE_OP:
case OID_NAME_ICLIKE_OP:
- if (!op_in_opfamily(expr_op, opfamily))
+ if (!op_in_opfamily(expr_op, opfamily, AMOP_SEARCH))
{
/* the right-hand const is type text for all of these */
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like_IC,
@@ -2575,7 +2577,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
case OID_TEXT_REGEXEQ_OP:
case OID_BPCHAR_REGEXEQ_OP:
case OID_NAME_REGEXEQ_OP:
- if (!op_in_opfamily(expr_op, opfamily))
+ if (!op_in_opfamily(expr_op, opfamily, AMOP_SEARCH))
{
/* the right-hand const is type text for all of these */
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex,
@@ -2587,7 +2589,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
case OID_TEXT_ICREGEXEQ_OP:
case OID_BPCHAR_ICREGEXEQ_OP:
case OID_NAME_ICREGEXEQ_OP:
- if (!op_in_opfamily(expr_op, opfamily))
+ if (!op_in_opfamily(expr_op, opfamily, AMOP_SEARCH))
{
/* the right-hand const is type text for all of these */
pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC,
@@ -2598,7 +2600,7 @@ expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily)
case OID_INET_SUB_OP:
case OID_INET_SUBEQ_OP:
- if (!op_in_opfamily(expr_op, opfamily))
+ if (!op_in_opfamily(expr_op, opfamily, AMOP_SEARCH))
{
return network_prefix_quals(leftop, expr_op, opfamily,
patt->constvalue);
@@ -2656,7 +2658,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
expr_op = linitial_oid(clause->opnos);
if (!var_on_left)
expr_op = get_commutator(expr_op);
- get_op_opfamily_properties(expr_op, index->opfamily[indexcol],
+ get_op_opfamily_properties(expr_op, index->opfamily[indexcol], AMOP_SEARCH,
&op_strategy,
&op_lefttype,
&op_righttype);
@@ -2719,12 +2721,12 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
break; /* no match found */
/* Now, do we have the right operator for this column? */
- if (get_op_opfamily_strategy(expr_op, index->opfamily[i])
+ if (get_op_opfamily_strategy(expr_op, index->opfamily[i], AMOP_SEARCH)
!= op_strategy)
break;
/* Add opfamily and datatypes to lists */
- get_op_opfamily_properties(expr_op, index->opfamily[i],
+ get_op_opfamily_properties(expr_op, index->opfamily[i], AMOP_SEARCH,
&op_strategy,
&op_lefttype,
&op_righttype);
@@ -2776,7 +2778,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
Oid righttype = lfirst_oid(righttypes_cell);
expr_op = get_opfamily_member(opfam, lefttype, righttype,
- op_strategy);
+ op_strategy, AMOP_SEARCH);
if (!OidIsValid(expr_op)) /* should not happen */
elog(ERROR, "could not find member %d(%u,%u) of opfamily %u",
op_strategy, lefttype, righttype, opfam);
@@ -2900,7 +2902,7 @@ prefix_quals(Node *leftop, Oid opfamily,
if (pstatus == Pattern_Prefix_Exact)
{
oproid = get_opfamily_member(opfamily, datatype, datatype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber, AMOP_SEARCH);
if (oproid == InvalidOid)
elog(ERROR, "no = operator for opfamily %u", opfamily);
expr = make_opclause(oproid, BOOLOID, false,
@@ -2915,7 +2917,7 @@ prefix_quals(Node *leftop, Oid opfamily,
* We can always say "x >= prefix".
*/
oproid = get_opfamily_member(opfamily, datatype, datatype,
- BTGreaterEqualStrategyNumber);
+ BTGreaterEqualStrategyNumber, AMOP_SEARCH);
if (oproid == InvalidOid)
elog(ERROR, "no >= operator for opfamily %u", opfamily);
expr = make_opclause(oproid, BOOLOID, false,
@@ -2928,7 +2930,7 @@ prefix_quals(Node *leftop, Oid opfamily,
*-------
*/
oproid = get_opfamily_member(opfamily, datatype, datatype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber, AMOP_SEARCH);
if (oproid == InvalidOid)
elog(ERROR, "no < operator for opfamily %u", opfamily);
fmgr_info(get_opcode(oproid), <proc);
@@ -2982,14 +2984,16 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop)
if (is_eq)
{
opr1oid = get_opfamily_member(opfamily, datatype, datatype,
- BTGreaterEqualStrategyNumber);
+ BTGreaterEqualStrategyNumber,
+ AMOP_SEARCH);
if (opr1oid == InvalidOid)
elog(ERROR, "no >= operator for opfamily %u", opfamily);
}
else
{
opr1oid = get_opfamily_member(opfamily, datatype, datatype,
- BTGreaterStrategyNumber);
+ BTGreaterStrategyNumber,
+ AMOP_SEARCH);
if (opr1oid == InvalidOid)
elog(ERROR, "no > operator for opfamily %u", opfamily);
}
@@ -3005,7 +3009,7 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop)
/* create clause "key <= network_scan_last( rightop )" */
opr2oid = get_opfamily_member(opfamily, datatype, datatype,
- BTLessEqualStrategyNumber);
+ BTLessEqualStrategyNumber, AMOP_SEARCH);
if (opr2oid == InvalidOid)
elog(ERROR, "no <= operator for opfamily %u", opfamily);
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 643d57a..753ee8b 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -18,6 +18,7 @@
#include "postgres.h"
#include "access/skey.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
@@ -266,7 +267,8 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
equality_op = get_opfamily_member(opfamily,
opcintype,
opcintype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber,
+ AMOP_SEARCH);
if (!OidIsValid(equality_op)) /* shouldn't happen */
elog(ERROR, "could not find equality operator for ordering operator %u",
ordering_op);
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 52dd27b..fe2c650 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -20,6 +20,7 @@
#include
#include "access/skey.h"
+#include "catalog/pg_amop.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
@@ -3403,7 +3404,8 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
sortop = get_opfamily_member(pathkey->pk_opfamily,
pk_datatype,
pk_datatype,
- pathkey->pk_strategy);
+ pathkey->pk_strategy,
+ AMOP_SEARCH);
if (!OidIsValid(sortop)) /* should not happen */
elog(ERROR, "could not find member %d(%u,%u) of opfamily %u",
pathkey->pk_strategy, pk_datatype, pk_datatype,
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index e590ee0..7b605de 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -16,6 +16,7 @@
#include "catalog/pg_aggregate.h"
#include "catalog/pg_am.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
@@ -390,7 +391,8 @@ build_minmax_path(PlannerInfo *root, RelOptInfo *rel, MinMaxAggInfo *info)
continue;
strategy =
get_op_opfamily_strategy(((OpExpr *) rinfo->clause)->opno,
- index->opfamily[prevcol]);
+ index->opfamily[prevcol],
+ AMOP_SEARCH);
if (strategy == BTEqualStrategyNumber)
break;
}
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 5ab4a31..bb013af 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -1640,8 +1640,9 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
Form_pg_amop pred_form = (Form_pg_amop) GETSTRUCT(pred_tuple);
HeapTuple clause_tuple;
- /* Must be btree */
- if (pred_form->amopmethod != BTREE_AM_OID)
+ /* Must be btree operator, usable for searching */
+ if (pred_form->amopmethod != BTREE_AM_OID
+ || (pred_form->amoppurpose & AMOP_SEARCH) == 0)
continue;
/* Get the predicate operator's btree strategy number */
@@ -1664,7 +1665,7 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
clause_tuple = SearchSysCache2(AMOPOPID,
ObjectIdGetDatum(clause_op),
ObjectIdGetDatum(opfamily_id));
- if (HeapTupleIsValid(clause_tuple))
+ if (HeapTupleIsValid(clause_tuple)) /* ZZZ */
{
Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple);
@@ -1725,7 +1726,8 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
test_op = get_opfamily_member(opfamily_id,
pred_form->amoprighttype,
clause_righttype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber,
+ AMOP_SEARCH);
if (OidIsValid(test_op))
test_op = get_negator(test_op);
}
@@ -1734,7 +1736,8 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
test_op = get_opfamily_member(opfamily_id,
pred_form->amoprighttype,
clause_righttype,
- test_strategy);
+ test_strategy,
+ AMOP_SEARCH);
}
if (OidIsValid(test_op))
{
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 1394b21..f4c434d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -51,6 +51,7 @@
#include
#include
+#include "catalog/pg_amop.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_trigger.h"
@@ -341,6 +342,7 @@ static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_
offset_clause select_offset_value
select_offset_value2 opt_select_fetch_first_value
%type row_or_rows first_or_next
+%type opclass_purpose opclass_purpose_list opclass_purpose_elt
%type OptSeqOptList SeqOptList
%type SeqOptElem
@@ -3933,22 +3935,25 @@ opclass_item_list:
;
opclass_item:
- OPERATOR Iconst any_operator opt_recheck
+ OPERATOR Iconst any_operator opt_recheck opclass_purpose
{
CreateOpClassItem *n = makeNode(CreateOpClassItem);
n->itemtype = OPCLASS_ITEM_OPERATOR;
n->name = $3;
n->args = NIL;
n->number = $2;
+ n->purpose = $5;
$$ = (Node *) n;
}
| OPERATOR Iconst any_operator oper_argtypes opt_recheck
+ opclass_purpose
{
CreateOpClassItem *n = makeNode(CreateOpClassItem);
n->itemtype = OPCLASS_ITEM_OPERATOR;
n->name = $3;
n->args = $4;
n->number = $2;
+ n->purpose = $6;
$$ = (Node *) n;
}
| FUNCTION Iconst func_name func_args
@@ -4004,6 +4009,25 @@ opt_recheck: RECHECK
| /*EMPTY*/ { $$ = FALSE; }
;
+opclass_purpose:
+ FOR '(' opclass_purpose_list ')'
+ { $$ = $3; }
+ | /*EMPTY*/ { $$ = AMOP_SEARCH; }
+ ;
+
+opclass_purpose_list:
+ opclass_purpose_elt { $$ = $1; }
+ | opclass_purpose_elt ',' opclass_purpose_list { $$ = $1 | $3; }
+ ;
+
+/*
+ * This could accept a ColId if we so wished; there's no need for these to
+ * be keywords. This way is simpler for now, though...
+ */
+opclass_purpose_elt:
+ SEARCH { $$ = AMOP_SEARCH; }
+ | ORDER { $$ = AMOP_ORDER; }
+ ;
CreateOpFamilyStmt:
CREATE OPERATOR FAMILY any_name USING access_method
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index c744221..8a2d702 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -94,6 +94,7 @@
#include "access/gin.h"
#include "access/sysattr.h"
#include "catalog/index.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
@@ -1215,7 +1216,8 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
* Pattern specifies an exact match, so pretend operator is '='
*/
Oid eqopr = get_opfamily_member(opfamily, vartype, vartype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber,
+ AMOP_SEARCH);
if (eqopr == InvalidOid)
elog(ERROR, "no = operator for opfamily %u", opfamily);
@@ -2631,7 +2633,7 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
examine_variable(root, right, 0, &rightvar);
/* Extract the operator's declared left/right datatypes */
- get_op_opfamily_properties(opno, opfamily,
+ get_op_opfamily_properties(opno, opfamily, AMOP_SEARCH,
&op_strategy,
&op_lefttype,
&op_righttype);
@@ -2653,10 +2655,12 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
/* easy case */
ltop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
leop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTLessEqualStrategyNumber);
+ BTLessEqualStrategyNumber,
+ AMOP_SEARCH);
lsortop = ltop;
rsortop = ltop;
lstatop = lsortop;
@@ -2668,24 +2672,30 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
{
ltop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
leop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTLessEqualStrategyNumber);
+ BTLessEqualStrategyNumber,
+ AMOP_SEARCH);
lsortop = get_opfamily_member(opfamily,
op_lefttype, op_lefttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
rsortop = get_opfamily_member(opfamily,
op_righttype, op_righttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
lstatop = lsortop;
rstatop = rsortop;
revltop = get_opfamily_member(opfamily,
op_righttype, op_lefttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
revleop = get_opfamily_member(opfamily,
op_righttype, op_lefttype,
- BTLessEqualStrategyNumber);
+ BTLessEqualStrategyNumber,
+ AMOP_SEARCH);
}
break;
case BTGreaterStrategyNumber:
@@ -2696,15 +2706,18 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
/* easy case */
ltop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTGreaterStrategyNumber);
+ BTGreaterStrategyNumber,
+ AMOP_SEARCH);
leop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTGreaterEqualStrategyNumber);
+ BTGreaterEqualStrategyNumber,
+ AMOP_SEARCH);
lsortop = ltop;
rsortop = ltop;
lstatop = get_opfamily_member(opfamily,
op_lefttype, op_lefttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
rstatop = lstatop;
revltop = ltop;
revleop = leop;
@@ -2713,28 +2726,36 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
{
ltop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTGreaterStrategyNumber);
+ BTGreaterStrategyNumber,
+ AMOP_SEARCH);
leop = get_opfamily_member(opfamily,
op_lefttype, op_righttype,
- BTGreaterEqualStrategyNumber);
+ BTGreaterEqualStrategyNumber,
+ AMOP_SEARCH);
lsortop = get_opfamily_member(opfamily,
op_lefttype, op_lefttype,
- BTGreaterStrategyNumber);
+ BTGreaterStrategyNumber,
+ AMOP_SEARCH);
rsortop = get_opfamily_member(opfamily,
op_righttype, op_righttype,
- BTGreaterStrategyNumber);
+ BTGreaterStrategyNumber,
+ AMOP_SEARCH);
lstatop = get_opfamily_member(opfamily,
op_lefttype, op_lefttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
rstatop = get_opfamily_member(opfamily,
op_righttype, op_righttype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
revltop = get_opfamily_member(opfamily,
op_righttype, op_lefttype,
- BTGreaterStrategyNumber);
+ BTGreaterStrategyNumber,
+ AMOP_SEARCH);
revleop = get_opfamily_member(opfamily,
op_righttype, op_lefttype,
- BTGreaterEqualStrategyNumber);
+ BTGreaterEqualStrategyNumber,
+ AMOP_SEARCH);
}
break;
default:
@@ -5086,7 +5107,7 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
Selectivity eq_sel;
cmpopr = get_opfamily_member(opfamily, vartype, vartype,
- BTGreaterEqualStrategyNumber);
+ BTGreaterEqualStrategyNumber, AMOP_SEARCH);
if (cmpopr == InvalidOid)
elog(ERROR, "no >= operator for opfamily %u", opfamily);
fmgr_info(get_opcode(cmpopr), &opproc);
@@ -5107,7 +5128,7 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
*-------
*/
cmpopr = get_opfamily_member(opfamily, vartype, vartype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber, AMOP_SEARCH);
if (cmpopr == InvalidOid)
elog(ERROR, "no < operator for opfamily %u", opfamily);
fmgr_info(get_opcode(cmpopr), &opproc);
@@ -5147,7 +5168,7 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
* small estimate from the >= condition; so we still need to clamp.
*/
cmpopr = get_opfamily_member(opfamily, vartype, vartype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber, AMOP_SEARCH);
if (cmpopr == InvalidOid)
elog(ERROR, "no = operator for opfamily %u", opfamily);
eq_sel = var_eq_const(vardata, cmpopr, prefixcon->constvalue,
@@ -6018,7 +6039,8 @@ btcostestimate(PG_FUNCTION_ARGS)
if (OidIsValid(clause_op))
{
op_strategy = get_op_opfamily_strategy(clause_op,
- index->opfamily[indexcol]);
+ index->opfamily[indexcol],
+ AMOP_SEARCH);
Assert(op_strategy != 0); /* not a member of opfamily?? */
if (op_strategy == BTEqualStrategyNumber)
eqQualHere = true;
@@ -6431,6 +6453,7 @@ gincostestimate(PG_FUNCTION_ARGS)
* within the index opfamily.
*/
get_op_opfamily_properties(clause_op, index->opfamily[indexcol],
+ AMOP_SEARCH,
&strategy_op, &lefttype, &righttype);
/*
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 740e8c4..a95a030 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -44,24 +44,36 @@ get_attavgwidth_hook_type get_attavgwidth_hook = NULL;
/*
* op_in_opfamily
*
- * Return t iff operator 'opno' is in operator family 'opfamily'.
+ * Return t iff operator 'opno' is in operator family 'opfamily'
+ * with purpose 'purpose'.
*/
bool
-op_in_opfamily(Oid opno, Oid opfamily)
+op_in_opfamily(Oid opno, Oid opfamily, int purpose)
{
- return SearchSysCacheExists2(AMOPOPID,
- ObjectIdGetDatum(opno),
- ObjectIdGetDatum(opfamily));
+ HeapTuple tp;
+ Form_pg_amop amop_tup;
+ int amop_purpose;
+
+ tp = SearchSysCache2(AMOPOPID,
+ ObjectIdGetDatum(opno),
+ ObjectIdGetDatum(opfamily));
+ if (!HeapTupleIsValid(tp))
+ return 0;
+ amop_tup = (Form_pg_amop) GETSTRUCT(tp);
+ amop_purpose = amop_tup->amoppurpose;
+ ReleaseSysCache(tp);
+ return (amop_purpose & purpose) != 0;
}
/*
* get_op_opfamily_strategy
*
* Get the operator's strategy number within the specified opfamily,
- * or 0 if it's not a member of the opfamily.
+ * or 0 if it's not a member of the opfamily or not useful for the
+ * specified purpose.
*/
int
-get_op_opfamily_strategy(Oid opno, Oid opfamily)
+get_op_opfamily_strategy(Oid opno, Oid opfamily, int purpose)
{
HeapTuple tp;
Form_pg_amop amop_tup;
@@ -73,7 +85,10 @@ get_op_opfamily_strategy(Oid opno, Oid opfamily)
if (!HeapTupleIsValid(tp))
return 0;
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
- result = amop_tup->amopstrategy;
+ if ((amop_tup->amoppurpose & purpose) != 0)
+ result = amop_tup->amopstrategy;
+ else
+ result = 0;
ReleaseSysCache(tp);
return result;
}
@@ -88,7 +103,7 @@ get_op_opfamily_strategy(Oid opno, Oid opfamily)
* therefore we raise an error if the tuple is not found.
*/
void
-get_op_opfamily_properties(Oid opno, Oid opfamily,
+get_op_opfamily_properties(Oid opno, Oid opfamily, int purpose,
int *strategy,
Oid *lefttype,
Oid *righttype)
@@ -103,6 +118,9 @@ get_op_opfamily_properties(Oid opno, Oid opfamily,
elog(ERROR, "operator %u is not a member of opfamily %u",
opno, opfamily);
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
+ if ((amop_tup->amoppurpose & purpose) == 0)
+ elog(ERROR, "operator %u in opfamily %u can't be used for purpose %d",
+ opno, opfamily, purpose);
*strategy = amop_tup->amopstrategy;
*lefttype = amop_tup->amoplefttype;
*righttype = amop_tup->amoprighttype;
@@ -114,11 +132,12 @@ get_op_opfamily_properties(Oid opno, Oid opfamily,
* Get the OID of the operator that implements the specified strategy
* with the specified datatypes for the specified opfamily.
*
- * Returns InvalidOid if there is no pg_amop entry for the given keys.
+ * Returns InvalidOid if there is no pg_amop entry for the given keys, or
+ * if the operator is not useful for the specified purpose.
*/
Oid
get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
- int16 strategy)
+ int16 strategy, int16 purpose)
{
HeapTuple tp;
Form_pg_amop amop_tup;
@@ -132,7 +151,10 @@ get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
if (!HeapTupleIsValid(tp))
return InvalidOid;
amop_tup = (Form_pg_amop) GETSTRUCT(tp);
- result = amop_tup->amopopr;
+ if ((amop_tup->amoppurpose & purpose) != 0)
+ result = amop_tup->amopopr;
+ else
+ result = InvalidOid;
ReleaseSysCache(tp);
return result;
}
@@ -181,8 +203,9 @@ get_ordering_op_properties(Oid opno,
HeapTuple tuple = &catlist->members[i]->tuple;
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
- /* must be btree */
- if (aform->amopmethod != BTREE_AM_OID)
+ /* must be btree search op */
+ if (aform->amopmethod != BTREE_AM_OID
+ && (aform->amoppurpose & AMOP_SEARCH) != 0)
continue;
if (aform->amopstrategy == BTLessStrategyNumber ||
@@ -276,7 +299,8 @@ get_equality_op_for_ordering_op(Oid opno, bool *reverse)
result = get_opfamily_member(opfamily,
opcintype,
opcintype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber,
+ AMOP_SEARCH);
if (reverse)
*reverse = (strategy == BTGreaterStrategyNumber);
}
@@ -316,8 +340,9 @@ get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
HeapTuple tuple = &catlist->members[i]->tuple;
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
- /* must be btree */
- if (aform->amopmethod != BTREE_AM_OID)
+ /* must be btree search op */
+ if (aform->amopmethod != BTREE_AM_OID
+ && (aform->amoppurpose & AMOP_SEARCH) != 0)
continue;
if (aform->amopstrategy == BTEqualStrategyNumber)
@@ -328,7 +353,8 @@ get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)
typid = use_lhs_type ? aform->amoplefttype : aform->amoprighttype;
result = get_opfamily_member(aform->amopfamily,
typid, typid,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
if (OidIsValid(result))
break;
/* failure probably shouldn't happen, but keep looking if so */
@@ -379,6 +405,7 @@ get_mergejoin_opfamilies(Oid opno)
/* must be btree equality */
if (aform->amopmethod == BTREE_AM_OID &&
+ (aform->amoppurpose & AMOP_SEARCH) != 0 &&
aform->amopstrategy == BTEqualStrategyNumber)
result = lappend_oid(result, aform->amopfamily);
}
@@ -430,6 +457,7 @@ get_compatible_hash_operators(Oid opno,
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
if (aform->amopmethod == HASH_AM_OID &&
+ (aform->amoppurpose & AMOP_SEARCH) != 0 &&
aform->amopstrategy == HTEqualStrategyNumber)
{
/* No extra lookup needed if given operator is single-type */
@@ -453,7 +481,8 @@ get_compatible_hash_operators(Oid opno,
*lhs_opno = get_opfamily_member(aform->amopfamily,
aform->amoplefttype,
aform->amoplefttype,
- HTEqualStrategyNumber);
+ HTEqualStrategyNumber,
+ AMOP_SEARCH);
if (!OidIsValid(*lhs_opno))
continue;
/* Matching LHS found, done if caller doesn't want RHS */
@@ -468,7 +497,8 @@ get_compatible_hash_operators(Oid opno,
*rhs_opno = get_opfamily_member(aform->amopfamily,
aform->amoprighttype,
aform->amoprighttype,
- HTEqualStrategyNumber);
+ HTEqualStrategyNumber,
+ AMOP_SEARCH);
if (!OidIsValid(*rhs_opno))
{
/* Forget any LHS operator from this opfamily */
@@ -530,6 +560,7 @@ get_op_hash_functions(Oid opno,
Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);
if (aform->amopmethod == HASH_AM_OID &&
+ (aform->amoppurpose & AMOP_SEARCH) != 0 &&
aform->amopstrategy == HTEqualStrategyNumber)
{
/*
@@ -635,8 +666,9 @@ get_op_btree_interpretation(Oid opno, List **opfamilies, List **opstrats)
Oid opfamily_id;
StrategyNumber op_strategy;
- /* must be btree */
- if (op_form->amopmethod != BTREE_AM_OID)
+ /* must be btree search op */
+ if (op_form->amopmethod != BTREE_AM_OID
+ && (op_form->amoppurpose & AMOP_SEARCH) != 0)
continue;
/* Get the operator's btree strategy number */
@@ -692,11 +724,12 @@ equality_ops_are_compatible(Oid opno1, Oid opno2)
HeapTuple op_tuple = &catlist->members[i]->tuple;
Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
- /* must be btree or hash */
- if (op_form->amopmethod == BTREE_AM_OID ||
- op_form->amopmethod == HASH_AM_OID)
+ /* must be btree or hash search op */
+ if ((op_form->amopmethod == BTREE_AM_OID ||
+ op_form->amopmethod == HASH_AM_OID) &&
+ (op_form->amoppurpose & AMOP_SEARCH) != 0)
{
- if (op_in_opfamily(opno2, op_form->amopfamily))
+ if (op_in_opfamily(opno2, op_form->amopfamily, AMOP_SEARCH))
{
result = true;
break;
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 2a44303..04e8f61 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -3828,7 +3828,8 @@ RelationGetExclusionInfo(Relation indexRelation,
{
funcs[i] = get_opcode(ops[i]);
strats[i] = get_op_opfamily_strategy(ops[i],
- indexRelation->rd_opfamily[i]);
+ indexRelation->rd_opfamily[i],
+ AMOP_SEARCH);
/* shouldn't fail, since it was checked at index creation */
if (strats[i] == InvalidStrategy)
elog(ERROR, "could not find strategy for operator %u in family %u",
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index bc4abc4..762fda8 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -48,6 +48,7 @@
#include "access/heapam.h"
#include "access/nbtree.h"
#include "catalog/indexing.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_enum.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
@@ -241,13 +242,15 @@ lookup_type_cache(Oid type_id, int flags)
typentry->eq_opr = get_opfamily_member(typentry->btree_opf,
typentry->btree_opintype,
typentry->btree_opintype,
- BTEqualStrategyNumber);
+ BTEqualStrategyNumber,
+ AMOP_SEARCH);
if (typentry->eq_opr == InvalidOid &&
typentry->hash_opf != InvalidOid)
typentry->eq_opr = get_opfamily_member(typentry->hash_opf,
typentry->hash_opintype,
typentry->hash_opintype,
- HTEqualStrategyNumber);
+ HTEqualStrategyNumber,
+ AMOP_SEARCH);
}
if ((flags & TYPECACHE_LT_OPR) && typentry->lt_opr == InvalidOid)
{
@@ -255,7 +258,8 @@ lookup_type_cache(Oid type_id, int flags)
typentry->lt_opr = get_opfamily_member(typentry->btree_opf,
typentry->btree_opintype,
typentry->btree_opintype,
- BTLessStrategyNumber);
+ BTLessStrategyNumber,
+ AMOP_SEARCH);
}
if ((flags & TYPECACHE_GT_OPR) && typentry->gt_opr == InvalidOid)
{
@@ -263,7 +267,8 @@ lookup_type_cache(Oid type_id, int flags)
typentry->gt_opr = get_opfamily_member(typentry->btree_opf,
typentry->btree_opintype,
typentry->btree_opintype,
- BTGreaterStrategyNumber);
+ BTGreaterStrategyNumber,
+ AMOP_SEARCH);
}
if ((flags & (TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO)) &&
typentry->cmp_proc == InvalidOid)
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 55ea684..5c9929e 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -45,6 +45,7 @@
#include "access/attnum.h"
#include "access/sysattr.h"
+#include "catalog/pg_amop.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_class.h"
#include "catalog/pg_default_acl.h"
@@ -198,6 +199,7 @@ static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
const char *tag, const char *nspname, const char *owner,
const char *acls);
+static void format_amoppurpose(PQExpBuffer q, int amoppurpose);
static void getDependencies(void);
static void getDomainConstraints(TypeInfo *tyinfo);
static void getTableData(TableInfo *tblinfo, int numTables, bool oids);
@@ -8820,6 +8822,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
int i_amopstrategy;
int i_amopreqcheck;
int i_amopopr;
+ int i_amoppurpose;
int i_amprocnum;
int i_amproc;
char *opcintype;
@@ -8831,6 +8834,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
char *amopstrategy;
char *amopreqcheck;
char *amopopr;
+ int amoppurpose;
char *amprocnum;
char *amproc;
bool needComma;
@@ -8957,7 +8961,20 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
*/
resetPQExpBuffer(query);
- if (g_fout->remoteVersion >= 80400)
+ if (g_fout->remoteVersion >= 90100)
+ {
+ /* amoppurpose is new in PostgreSQL 9.1 */
+ appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
+ "amopopr::pg_catalog.regoperator, amoppurpose "
+ "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
+ "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
+ "AND refobjid = '%u'::pg_catalog.oid "
+ "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
+ "AND objid = ao.oid "
+ "ORDER BY amopstrategy",
+ opcinfo->dobj.catId.oid);
+ }
+ else if (g_fout->remoteVersion >= 80400)
{
/*
* Print only those opfamily members that are tied to the opclass by
@@ -8970,7 +8987,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
* away once 8.3 is so old as to not be of interest to anyone.
*/
appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, 1 AS amoppurpose "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -8986,7 +9003,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
* pg_depend entries.
*/
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, 1 AS amoppurpose "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -8998,7 +9015,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
else
{
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, 1 AS amoppurpose "
"FROM pg_catalog.pg_amop "
"WHERE amopclaid = '%u'::pg_catalog.oid "
"ORDER BY amopstrategy",
@@ -9013,11 +9030,13 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
i_amopstrategy = PQfnumber(res, "amopstrategy");
i_amopreqcheck = PQfnumber(res, "amopreqcheck");
i_amopopr = PQfnumber(res, "amopopr");
+ i_amoppurpose = PQfnumber(res, "amoppurpose");
for (i = 0; i < ntups; i++)
{
amopstrategy = PQgetvalue(res, i, i_amopstrategy);
amopreqcheck = PQgetvalue(res, i, i_amopreqcheck);
+ amoppurpose = atoi(PQgetvalue(res, i, i_amoppurpose));
amopopr = PQgetvalue(res, i, i_amopopr);
if (needComma)
@@ -9027,6 +9046,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
amopstrategy, amopopr);
if (strcmp(amopreqcheck, "t") == 0)
appendPQExpBuffer(q, " RECHECK");
+ format_amoppurpose(q, amoppurpose);
needComma = true;
}
@@ -9134,6 +9154,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
int i_amopstrategy;
int i_amopreqcheck;
int i_amopopr;
+ int i_amoppurpose;
int i_amprocnum;
int i_amproc;
int i_amproclefttype;
@@ -9142,6 +9163,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
char *amopstrategy;
char *amopreqcheck;
char *amopopr;
+ int amoppurpose;
char *amprocnum;
char *amproc;
char *amproclefttype;
@@ -9173,7 +9195,20 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
* Fetch only those opfamily members that are tied directly to the
* opfamily by pg_depend entries.
*/
- if (g_fout->remoteVersion >= 80400)
+ if (g_fout->remoteVersion >= 90100)
+ {
+ /* amoppurpose is new in PostgreSQL 9.1 */
+ appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
+ "amopopr::pg_catalog.regoperator, amoppurpose "
+ "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
+ "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
+ "AND refobjid = '%u'::pg_catalog.oid "
+ "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
+ "AND objid = ao.oid "
+ "ORDER BY amopstrategy",
+ opfinfo->dobj.catId.oid);
+ }
+ else if (g_fout->remoteVersion >= 80400)
{
/*
* XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
@@ -9183,7 +9218,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
* away once 8.3 is so old as to not be of interest to anyone.
*/
appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, 1 AS amoppurpose "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -9195,7 +9230,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
else
{
appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
- "amopopr::pg_catalog.regoperator "
+ "amopopr::pg_catalog.regoperator, 1 AS amoppurpose "
"FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
"WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
"AND refobjid = '%u'::pg_catalog.oid "
@@ -9323,12 +9358,14 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
i_amopreqcheck = PQfnumber(res_ops, "amopreqcheck");
i_amopopr = PQfnumber(res_ops, "amopopr");
+ i_amoppurpose = PQfnumber(res_ops, "amoppurpose");
for (i = 0; i < ntups; i++)
{
amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
amopreqcheck = PQgetvalue(res_ops, i, i_amopreqcheck);
amopopr = PQgetvalue(res_ops, i, i_amopopr);
+ amoppurpose = atoi(PQgetvalue(res_ops, i, i_amoppurpose));
if (needComma)
appendPQExpBuffer(q, " ,\n ");
@@ -9337,6 +9374,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
amopstrategy, amopopr);
if (strcmp(amopreqcheck, "t") == 0)
appendPQExpBuffer(q, " RECHECK");
+ format_amoppurpose(q, amoppurpose);
needComma = true;
}
@@ -9399,6 +9437,30 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
destroyPQExpBuffer(delq);
}
+static void
+format_amoppurpose(PQExpBuffer q, int amoppurpose)
+{
+ bool didany = false;
+
+ /* Search is the default. */
+ if ((amoppurpose & (AMOP_SEARCH|AMOP_ORDER)) == AMOP_SEARCH)
+ return;
+
+ /* Otherwise go bit by bit. */
+ if ((amoppurpose & AMOP_SEARCH) != 0)
+ {
+ appendPQExpBuffer(q, didany ? ", SEARCH" : " FOR (SEARCH");
+ didany = true;
+ }
+ if ((amoppurpose & AMOP_ORDER) != 0)
+ {
+ appendPQExpBuffer(q, didany ? ", ORDER" : " FOR (ORDER");
+ didany = true;
+ }
+ if (didany)
+ appendPQExpBuffer(q, ")");
+}
+
/*
* dumpConversion
* write out a single conversion definition
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index d5cf859..baee0ff 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -22,6 +22,15 @@
* This implies that the same operator cannot be listed for multiple strategy
* numbers within a single opfamily.
*
+ * amoppurpose is specifies the purpose(s) of this operator within the
+ * operator family, and is interpreted as a bit-field. AMOP_SEARCH operators
+ * are useful for queries of the form SELECT ... FROM table WHERE col OP val;
+ * AMOP_ORDER operators are useful for queries of the form SELECT ... FROM
+ * table ORDER BY col OP val. In theory, an operator could be useful for
+ * both purposes, although in practice this is not very likely since a
+ * search operator must return bool, which is not necessarily useful for
+ * ordering.
+ *
* amopmethod is a copy of the owning opfamily's opfmethod field. This is an
* intentional denormalization of the catalogs to buy lookup speed.
*
@@ -49,12 +58,16 @@
*/
#define AccessMethodOperatorRelationId 2602
+#define AMOP_SEARCH 1
+#define AMOP_ORDER 2
+
CATALOG(pg_amop,2602)
{
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 */
+ int2 amoppurpose; /* operator's purpose */
Oid amopopr; /* the operator's pg_operator OID */
Oid amopmethod; /* the index access method this entry is for */
} FormData_pg_amop;
@@ -70,13 +83,14 @@ typedef FormData_pg_amop *Form_pg_amop;
* compiler constants for pg_amop
* ----------------
*/
-#define Natts_pg_amop 6
+#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_amopopr 5
-#define Anum_pg_amop_amopmethod 6
+#define Anum_pg_amop_amoppurpose 5
+#define Anum_pg_amop_amopopr 6
+#define Anum_pg_amop_amopmethod 7
/* ----------------
* initial contents of pg_amop
@@ -88,610 +102,610 @@ typedef FormData_pg_amop *Form_pg_amop;
*/
/* default operators int2 */
-DATA(insert ( 1976 21 21 1 95 403 ));
-DATA(insert ( 1976 21 21 2 522 403 ));
-DATA(insert ( 1976 21 21 3 94 403 ));
-DATA(insert ( 1976 21 21 4 524 403 ));
-DATA(insert ( 1976 21 21 5 520 403 ));
+DATA(insert ( 1976 21 21 1 1 95 403 ));
+DATA(insert ( 1976 21 21 2 1 522 403 ));
+DATA(insert ( 1976 21 21 3 1 94 403 ));
+DATA(insert ( 1976 21 21 4 1 524 403 ));
+DATA(insert ( 1976 21 21 5 1 520 403 ));
/* crosstype operators int24 */
-DATA(insert ( 1976 21 23 1 534 403 ));
-DATA(insert ( 1976 21 23 2 540 403 ));
-DATA(insert ( 1976 21 23 3 532 403 ));
-DATA(insert ( 1976 21 23 4 542 403 ));
-DATA(insert ( 1976 21 23 5 536 403 ));
+DATA(insert ( 1976 21 23 1 1 534 403 ));
+DATA(insert ( 1976 21 23 2 1 540 403 ));
+DATA(insert ( 1976 21 23 3 1 532 403 ));
+DATA(insert ( 1976 21 23 4 1 542 403 ));
+DATA(insert ( 1976 21 23 5 1 536 403 ));
/* crosstype operators int28 */
-DATA(insert ( 1976 21 20 1 1864 403 ));
-DATA(insert ( 1976 21 20 2 1866 403 ));
-DATA(insert ( 1976 21 20 3 1862 403 ));
-DATA(insert ( 1976 21 20 4 1867 403 ));
-DATA(insert ( 1976 21 20 5 1865 403 ));
+DATA(insert ( 1976 21 20 1 1 1864 403 ));
+DATA(insert ( 1976 21 20 2 1 1866 403 ));
+DATA(insert ( 1976 21 20 3 1 1862 403 ));
+DATA(insert ( 1976 21 20 4 1 1867 403 ));
+DATA(insert ( 1976 21 20 5 1 1865 403 ));
/* default operators int4 */
-DATA(insert ( 1976 23 23 1 97 403 ));
-DATA(insert ( 1976 23 23 2 523 403 ));
-DATA(insert ( 1976 23 23 3 96 403 ));
-DATA(insert ( 1976 23 23 4 525 403 ));
-DATA(insert ( 1976 23 23 5 521 403 ));
+DATA(insert ( 1976 23 23 1 1 97 403 ));
+DATA(insert ( 1976 23 23 2 1 523 403 ));
+DATA(insert ( 1976 23 23 3 1 96 403 ));
+DATA(insert ( 1976 23 23 4 1 525 403 ));
+DATA(insert ( 1976 23 23 5 1 521 403 ));
/* crosstype operators int42 */
-DATA(insert ( 1976 23 21 1 535 403 ));
-DATA(insert ( 1976 23 21 2 541 403 ));
-DATA(insert ( 1976 23 21 3 533 403 ));
-DATA(insert ( 1976 23 21 4 543 403 ));
-DATA(insert ( 1976 23 21 5 537 403 ));
+DATA(insert ( 1976 23 21 1 1 535 403 ));
+DATA(insert ( 1976 23 21 2 1 541 403 ));
+DATA(insert ( 1976 23 21 3 1 533 403 ));
+DATA(insert ( 1976 23 21 4 1 543 403 ));
+DATA(insert ( 1976 23 21 5 1 537 403 ));
/* crosstype operators int48 */
-DATA(insert ( 1976 23 20 1 37 403 ));
-DATA(insert ( 1976 23 20 2 80 403 ));
-DATA(insert ( 1976 23 20 3 15 403 ));
-DATA(insert ( 1976 23 20 4 82 403 ));
-DATA(insert ( 1976 23 20 5 76 403 ));
+DATA(insert ( 1976 23 20 1 1 37 403 ));
+DATA(insert ( 1976 23 20 2 1 80 403 ));
+DATA(insert ( 1976 23 20 3 1 15 403 ));
+DATA(insert ( 1976 23 20 4 1 82 403 ));
+DATA(insert ( 1976 23 20 5 1 76 403 ));
/* default operators int8 */
-DATA(insert ( 1976 20 20 1 412 403 ));
-DATA(insert ( 1976 20 20 2 414 403 ));
-DATA(insert ( 1976 20 20 3 410 403 ));
-DATA(insert ( 1976 20 20 4 415 403 ));
-DATA(insert ( 1976 20 20 5 413 403 ));
+DATA(insert ( 1976 20 20 1 1 412 403 ));
+DATA(insert ( 1976 20 20 2 1 414 403 ));
+DATA(insert ( 1976 20 20 3 1 410 403 ));
+DATA(insert ( 1976 20 20 4 1 415 403 ));
+DATA(insert ( 1976 20 20 5 1 413 403 ));
/* crosstype operators int82 */
-DATA(insert ( 1976 20 21 1 1870 403 ));
-DATA(insert ( 1976 20 21 2 1872 403 ));
-DATA(insert ( 1976 20 21 3 1868 403 ));
-DATA(insert ( 1976 20 21 4 1873 403 ));
-DATA(insert ( 1976 20 21 5 1871 403 ));
+DATA(insert ( 1976 20 21 1 1 1870 403 ));
+DATA(insert ( 1976 20 21 2 1 1872 403 ));
+DATA(insert ( 1976 20 21 3 1 1868 403 ));
+DATA(insert ( 1976 20 21 4 1 1873 403 ));
+DATA(insert ( 1976 20 21 5 1 1871 403 ));
/* crosstype operators int84 */
-DATA(insert ( 1976 20 23 1 418 403 ));
-DATA(insert ( 1976 20 23 2 420 403 ));
-DATA(insert ( 1976 20 23 3 416 403 ));
-DATA(insert ( 1976 20 23 4 430 403 ));
-DATA(insert ( 1976 20 23 5 419 403 ));
+DATA(insert ( 1976 20 23 1 1 418 403 ));
+DATA(insert ( 1976 20 23 2 1 420 403 ));
+DATA(insert ( 1976 20 23 3 1 416 403 ));
+DATA(insert ( 1976 20 23 4 1 430 403 ));
+DATA(insert ( 1976 20 23 5 1 419 403 ));
/*
* btree oid_ops
*/
-DATA(insert ( 1989 26 26 1 609 403 ));
-DATA(insert ( 1989 26 26 2 611 403 ));
-DATA(insert ( 1989 26 26 3 607 403 ));
-DATA(insert ( 1989 26 26 4 612 403 ));
-DATA(insert ( 1989 26 26 5 610 403 ));
+DATA(insert ( 1989 26 26 1 1 609 403 ));
+DATA(insert ( 1989 26 26 2 1 611 403 ));
+DATA(insert ( 1989 26 26 3 1 607 403 ));
+DATA(insert ( 1989 26 26 4 1 612 403 ));
+DATA(insert ( 1989 26 26 5 1 610 403 ));
/*
* btree tid_ops
*/
-DATA(insert ( 2789 27 27 1 2799 403 ));
-DATA(insert ( 2789 27 27 2 2801 403 ));
-DATA(insert ( 2789 27 27 3 387 403 ));
-DATA(insert ( 2789 27 27 4 2802 403 ));
-DATA(insert ( 2789 27 27 5 2800 403 ));
+DATA(insert ( 2789 27 27 1 1 2799 403 ));
+DATA(insert ( 2789 27 27 2 1 2801 403 ));
+DATA(insert ( 2789 27 27 3 1 387 403 ));
+DATA(insert ( 2789 27 27 4 1 2802 403 ));
+DATA(insert ( 2789 27 27 5 1 2800 403 ));
/*
* btree oidvector_ops
*/
-DATA(insert ( 1991 30 30 1 645 403 ));
-DATA(insert ( 1991 30 30 2 647 403 ));
-DATA(insert ( 1991 30 30 3 649 403 ));
-DATA(insert ( 1991 30 30 4 648 403 ));
-DATA(insert ( 1991 30 30 5 646 403 ));
+DATA(insert ( 1991 30 30 1 1 645 403 ));
+DATA(insert ( 1991 30 30 2 1 647 403 ));
+DATA(insert ( 1991 30 30 3 1 649 403 ));
+DATA(insert ( 1991 30 30 4 1 648 403 ));
+DATA(insert ( 1991 30 30 5 1 646 403 ));
/*
* btree float_ops
*/
/* default operators float4 */
-DATA(insert ( 1970 700 700 1 622 403 ));
-DATA(insert ( 1970 700 700 2 624 403 ));
-DATA(insert ( 1970 700 700 3 620 403 ));
-DATA(insert ( 1970 700 700 4 625 403 ));
-DATA(insert ( 1970 700 700 5 623 403 ));
+DATA(insert ( 1970 700 700 1 1 622 403 ));
+DATA(insert ( 1970 700 700 2 1 624 403 ));
+DATA(insert ( 1970 700 700 3 1 620 403 ));
+DATA(insert ( 1970 700 700 4 1 625 403 ));
+DATA(insert ( 1970 700 700 5 1 623 403 ));
/* crosstype operators float48 */
-DATA(insert ( 1970 700 701 1 1122 403 ));
-DATA(insert ( 1970 700 701 2 1124 403 ));
-DATA(insert ( 1970 700 701 3 1120 403 ));
-DATA(insert ( 1970 700 701 4 1125 403 ));
-DATA(insert ( 1970 700 701 5 1123 403 ));
+DATA(insert ( 1970 700 701 1 1 1122 403 ));
+DATA(insert ( 1970 700 701 2 1 1124 403 ));
+DATA(insert ( 1970 700 701 3 1 1120 403 ));
+DATA(insert ( 1970 700 701 4 1 1125 403 ));
+DATA(insert ( 1970 700 701 5 1 1123 403 ));
/* default operators float8 */
-DATA(insert ( 1970 701 701 1 672 403 ));
-DATA(insert ( 1970 701 701 2 673 403 ));
-DATA(insert ( 1970 701 701 3 670 403 ));
-DATA(insert ( 1970 701 701 4 675 403 ));
-DATA(insert ( 1970 701 701 5 674 403 ));
+DATA(insert ( 1970 701 701 1 1 672 403 ));
+DATA(insert ( 1970 701 701 2 1 673 403 ));
+DATA(insert ( 1970 701 701 3 1 670 403 ));
+DATA(insert ( 1970 701 701 4 1 675 403 ));
+DATA(insert ( 1970 701 701 5 1 674 403 ));
/* crosstype operators float84 */
-DATA(insert ( 1970 701 700 1 1132 403 ));
-DATA(insert ( 1970 701 700 2 1134 403 ));
-DATA(insert ( 1970 701 700 3 1130 403 ));
-DATA(insert ( 1970 701 700 4 1135 403 ));
-DATA(insert ( 1970 701 700 5 1133 403 ));
+DATA(insert ( 1970 701 700 1 1 1132 403 ));
+DATA(insert ( 1970 701 700 2 1 1134 403 ));
+DATA(insert ( 1970 701 700 3 1 1130 403 ));
+DATA(insert ( 1970 701 700 4 1 1135 403 ));
+DATA(insert ( 1970 701 700 5 1 1133 403 ));
/*
* btree char_ops
*/
-DATA(insert ( 429 18 18 1 631 403 ));
-DATA(insert ( 429 18 18 2 632 403 ));
-DATA(insert ( 429 18 18 3 92 403 ));
-DATA(insert ( 429 18 18 4 634 403 ));
-DATA(insert ( 429 18 18 5 633 403 ));
+DATA(insert ( 429 18 18 1 1 631 403 ));
+DATA(insert ( 429 18 18 2 1 632 403 ));
+DATA(insert ( 429 18 18 3 1 92 403 ));
+DATA(insert ( 429 18 18 4 1 634 403 ));
+DATA(insert ( 429 18 18 5 1 633 403 ));
/*
* btree name_ops
*/
-DATA(insert ( 1986 19 19 1 660 403 ));
-DATA(insert ( 1986 19 19 2 661 403 ));
-DATA(insert ( 1986 19 19 3 93 403 ));
-DATA(insert ( 1986 19 19 4 663 403 ));
-DATA(insert ( 1986 19 19 5 662 403 ));
+DATA(insert ( 1986 19 19 1 1 660 403 ));
+DATA(insert ( 1986 19 19 2 1 661 403 ));
+DATA(insert ( 1986 19 19 3 1 93 403 ));
+DATA(insert ( 1986 19 19 4 1 663 403 ));
+DATA(insert ( 1986 19 19 5 1 662 403 ));
/*
* btree text_ops
*/
-DATA(insert ( 1994 25 25 1 664 403 ));
-DATA(insert ( 1994 25 25 2 665 403 ));
-DATA(insert ( 1994 25 25 3 98 403 ));
-DATA(insert ( 1994 25 25 4 667 403 ));
-DATA(insert ( 1994 25 25 5 666 403 ));
+DATA(insert ( 1994 25 25 1 1 664 403 ));
+DATA(insert ( 1994 25 25 2 1 665 403 ));
+DATA(insert ( 1994 25 25 3 1 98 403 ));
+DATA(insert ( 1994 25 25 4 1 667 403 ));
+DATA(insert ( 1994 25 25 5 1 666 403 ));
/*
* btree bpchar_ops
*/
-DATA(insert ( 426 1042 1042 1 1058 403 ));
-DATA(insert ( 426 1042 1042 2 1059 403 ));
-DATA(insert ( 426 1042 1042 3 1054 403 ));
-DATA(insert ( 426 1042 1042 4 1061 403 ));
-DATA(insert ( 426 1042 1042 5 1060 403 ));
+DATA(insert ( 426 1042 1042 1 1 1058 403 ));
+DATA(insert ( 426 1042 1042 2 1 1059 403 ));
+DATA(insert ( 426 1042 1042 3 1 1054 403 ));
+DATA(insert ( 426 1042 1042 4 1 1061 403 ));
+DATA(insert ( 426 1042 1042 5 1 1060 403 ));
/*
* btree bytea_ops
*/
-DATA(insert ( 428 17 17 1 1957 403 ));
-DATA(insert ( 428 17 17 2 1958 403 ));
-DATA(insert ( 428 17 17 3 1955 403 ));
-DATA(insert ( 428 17 17 4 1960 403 ));
-DATA(insert ( 428 17 17 5 1959 403 ));
+DATA(insert ( 428 17 17 1 1 1957 403 ));
+DATA(insert ( 428 17 17 2 1 1958 403 ));
+DATA(insert ( 428 17 17 3 1 1955 403 ));
+DATA(insert ( 428 17 17 4 1 1960 403 ));
+DATA(insert ( 428 17 17 5 1 1959 403 ));
/*
* btree abstime_ops
*/
-DATA(insert ( 421 702 702 1 562 403 ));
-DATA(insert ( 421 702 702 2 564 403 ));
-DATA(insert ( 421 702 702 3 560 403 ));
-DATA(insert ( 421 702 702 4 565 403 ));
-DATA(insert ( 421 702 702 5 563 403 ));
+DATA(insert ( 421 702 702 1 1 562 403 ));
+DATA(insert ( 421 702 702 2 1 564 403 ));
+DATA(insert ( 421 702 702 3 1 560 403 ));
+DATA(insert ( 421 702 702 4 1 565 403 ));
+DATA(insert ( 421 702 702 5 1 563 403 ));
/*
* btree datetime_ops
*/
/* default operators date */
-DATA(insert ( 434 1082 1082 1 1095 403 ));
-DATA(insert ( 434 1082 1082 2 1096 403 ));
-DATA(insert ( 434 1082 1082 3 1093 403 ));
-DATA(insert ( 434 1082 1082 4 1098 403 ));
-DATA(insert ( 434 1082 1082 5 1097 403 ));
+DATA(insert ( 434 1082 1082 1 1 1095 403 ));
+DATA(insert ( 434 1082 1082 2 1 1096 403 ));
+DATA(insert ( 434 1082 1082 3 1 1093 403 ));
+DATA(insert ( 434 1082 1082 4 1 1098 403 ));
+DATA(insert ( 434 1082 1082 5 1 1097 403 ));
/* crosstype operators vs timestamp */
-DATA(insert ( 434 1082 1114 1 2345 403 ));
-DATA(insert ( 434 1082 1114 2 2346 403 ));
-DATA(insert ( 434 1082 1114 3 2347 403 ));
-DATA(insert ( 434 1082 1114 4 2348 403 ));
-DATA(insert ( 434 1082 1114 5 2349 403 ));
+DATA(insert ( 434 1082 1114 1 1 2345 403 ));
+DATA(insert ( 434 1082 1114 2 1 2346 403 ));
+DATA(insert ( 434 1082 1114 3 1 2347 403 ));
+DATA(insert ( 434 1082 1114 4 1 2348 403 ));
+DATA(insert ( 434 1082 1114 5 1 2349 403 ));
/* crosstype operators vs timestamptz */
-DATA(insert ( 434 1082 1184 1 2358 403 ));
-DATA(insert ( 434 1082 1184 2 2359 403 ));
-DATA(insert ( 434 1082 1184 3 2360 403 ));
-DATA(insert ( 434 1082 1184 4 2361 403 ));
-DATA(insert ( 434 1082 1184 5 2362 403 ));
+DATA(insert ( 434 1082 1184 1 1 2358 403 ));
+DATA(insert ( 434 1082 1184 2 1 2359 403 ));
+DATA(insert ( 434 1082 1184 3 1 2360 403 ));
+DATA(insert ( 434 1082 1184 4 1 2361 403 ));
+DATA(insert ( 434 1082 1184 5 1 2362 403 ));
/* default operators timestamp */
-DATA(insert ( 434 1114 1114 1 2062 403 ));
-DATA(insert ( 434 1114 1114 2 2063 403 ));
-DATA(insert ( 434 1114 1114 3 2060 403 ));
-DATA(insert ( 434 1114 1114 4 2065 403 ));
-DATA(insert ( 434 1114 1114 5 2064 403 ));
+DATA(insert ( 434 1114 1114 1 1 2062 403 ));
+DATA(insert ( 434 1114 1114 2 1 2063 403 ));
+DATA(insert ( 434 1114 1114 3 1 2060 403 ));
+DATA(insert ( 434 1114 1114 4 1 2065 403 ));
+DATA(insert ( 434 1114 1114 5 1 2064 403 ));
/* crosstype operators vs date */
-DATA(insert ( 434 1114 1082 1 2371 403 ));
-DATA(insert ( 434 1114 1082 2 2372 403 ));
-DATA(insert ( 434 1114 1082 3 2373 403 ));
-DATA(insert ( 434 1114 1082 4 2374 403 ));
-DATA(insert ( 434 1114 1082 5 2375 403 ));
+DATA(insert ( 434 1114 1082 1 1 2371 403 ));
+DATA(insert ( 434 1114 1082 2 1 2372 403 ));
+DATA(insert ( 434 1114 1082 3 1 2373 403 ));
+DATA(insert ( 434 1114 1082 4 1 2374 403 ));
+DATA(insert ( 434 1114 1082 5 1 2375 403 ));
/* crosstype operators vs timestamptz */
-DATA(insert ( 434 1114 1184 1 2534 403 ));
-DATA(insert ( 434 1114 1184 2 2535 403 ));
-DATA(insert ( 434 1114 1184 3 2536 403 ));
-DATA(insert ( 434 1114 1184 4 2537 403 ));
-DATA(insert ( 434 1114 1184 5 2538 403 ));
+DATA(insert ( 434 1114 1184 1 1 2534 403 ));
+DATA(insert ( 434 1114 1184 2 1 2535 403 ));
+DATA(insert ( 434 1114 1184 3 1 2536 403 ));
+DATA(insert ( 434 1114 1184 4 1 2537 403 ));
+DATA(insert ( 434 1114 1184 5 1 2538 403 ));
/* default operators timestamptz */
-DATA(insert ( 434 1184 1184 1 1322 403 ));
-DATA(insert ( 434 1184 1184 2 1323 403 ));
-DATA(insert ( 434 1184 1184 3 1320 403 ));
-DATA(insert ( 434 1184 1184 4 1325 403 ));
-DATA(insert ( 434 1184 1184 5 1324 403 ));
+DATA(insert ( 434 1184 1184 1 1 1322 403 ));
+DATA(insert ( 434 1184 1184 2 1 1323 403 ));
+DATA(insert ( 434 1184 1184 3 1 1320 403 ));
+DATA(insert ( 434 1184 1184 4 1 1325 403 ));
+DATA(insert ( 434 1184 1184 5 1 1324 403 ));
/* crosstype operators vs date */
-DATA(insert ( 434 1184 1082 1 2384 403 ));
-DATA(insert ( 434 1184 1082 2 2385 403 ));
-DATA(insert ( 434 1184 1082 3 2386 403 ));
-DATA(insert ( 434 1184 1082 4 2387 403 ));
-DATA(insert ( 434 1184 1082 5 2388 403 ));
+DATA(insert ( 434 1184 1082 1 1 2384 403 ));
+DATA(insert ( 434 1184 1082 2 1 2385 403 ));
+DATA(insert ( 434 1184 1082 3 1 2386 403 ));
+DATA(insert ( 434 1184 1082 4 1 2387 403 ));
+DATA(insert ( 434 1184 1082 5 1 2388 403 ));
/* crosstype operators vs timestamp */
-DATA(insert ( 434 1184 1114 1 2540 403 ));
-DATA(insert ( 434 1184 1114 2 2541 403 ));
-DATA(insert ( 434 1184 1114 3 2542 403 ));
-DATA(insert ( 434 1184 1114 4 2543 403 ));
-DATA(insert ( 434 1184 1114 5 2544 403 ));
+DATA(insert ( 434 1184 1114 1 1 2540 403 ));
+DATA(insert ( 434 1184 1114 2 1 2541 403 ));
+DATA(insert ( 434 1184 1114 3 1 2542 403 ));
+DATA(insert ( 434 1184 1114 4 1 2543 403 ));
+DATA(insert ( 434 1184 1114 5 1 2544 403 ));
/*
* btree time_ops
*/
-DATA(insert ( 1996 1083 1083 1 1110 403 ));
-DATA(insert ( 1996 1083 1083 2 1111 403 ));
-DATA(insert ( 1996 1083 1083 3 1108 403 ));
-DATA(insert ( 1996 1083 1083 4 1113 403 ));
-DATA(insert ( 1996 1083 1083 5 1112 403 ));
+DATA(insert ( 1996 1083 1083 1 1 1110 403 ));
+DATA(insert ( 1996 1083 1083 2 1 1111 403 ));
+DATA(insert ( 1996 1083 1083 3 1 1108 403 ));
+DATA(insert ( 1996 1083 1083 4 1 1113 403 ));
+DATA(insert ( 1996 1083 1083 5 1 1112 403 ));
/*
* btree timetz_ops
*/
-DATA(insert ( 2000 1266 1266 1 1552 403 ));
-DATA(insert ( 2000 1266 1266 2 1553 403 ));
-DATA(insert ( 2000 1266 1266 3 1550 403 ));
-DATA(insert ( 2000 1266 1266 4 1555 403 ));
-DATA(insert ( 2000 1266 1266 5 1554 403 ));
+DATA(insert ( 2000 1266 1266 1 1 1552 403 ));
+DATA(insert ( 2000 1266 1266 2 1 1553 403 ));
+DATA(insert ( 2000 1266 1266 3 1 1550 403 ));
+DATA(insert ( 2000 1266 1266 4 1 1555 403 ));
+DATA(insert ( 2000 1266 1266 5 1 1554 403 ));
/*
* btree interval_ops
*/
-DATA(insert ( 1982 1186 1186 1 1332 403 ));
-DATA(insert ( 1982 1186 1186 2 1333 403 ));
-DATA(insert ( 1982 1186 1186 3 1330 403 ));
-DATA(insert ( 1982 1186 1186 4 1335 403 ));
-DATA(insert ( 1982 1186 1186 5 1334 403 ));
+DATA(insert ( 1982 1186 1186 1 1 1332 403 ));
+DATA(insert ( 1982 1186 1186 2 1 1333 403 ));
+DATA(insert ( 1982 1186 1186 3 1 1330 403 ));
+DATA(insert ( 1982 1186 1186 4 1 1335 403 ));
+DATA(insert ( 1982 1186 1186 5 1 1334 403 ));
/*
* btree macaddr
*/
-DATA(insert ( 1984 829 829 1 1222 403 ));
-DATA(insert ( 1984 829 829 2 1223 403 ));
-DATA(insert ( 1984 829 829 3 1220 403 ));
-DATA(insert ( 1984 829 829 4 1225 403 ));
-DATA(insert ( 1984 829 829 5 1224 403 ));
+DATA(insert ( 1984 829 829 1 1 1222 403 ));
+DATA(insert ( 1984 829 829 2 1 1223 403 ));
+DATA(insert ( 1984 829 829 3 1 1220 403 ));
+DATA(insert ( 1984 829 829 4 1 1225 403 ));
+DATA(insert ( 1984 829 829 5 1 1224 403 ));
/*
* btree network
*/
-DATA(insert ( 1974 869 869 1 1203 403 ));
-DATA(insert ( 1974 869 869 2 1204 403 ));
-DATA(insert ( 1974 869 869 3 1201 403 ));
-DATA(insert ( 1974 869 869 4 1206 403 ));
-DATA(insert ( 1974 869 869 5 1205 403 ));
+DATA(insert ( 1974 869 869 1 1 1203 403 ));
+DATA(insert ( 1974 869 869 2 1 1204 403 ));
+DATA(insert ( 1974 869 869 3 1 1201 403 ));
+DATA(insert ( 1974 869 869 4 1 1206 403 ));
+DATA(insert ( 1974 869 869 5 1 1205 403 ));
/*
* btree numeric
*/
-DATA(insert ( 1988 1700 1700 1 1754 403 ));
-DATA(insert ( 1988 1700 1700 2 1755 403 ));
-DATA(insert ( 1988 1700 1700 3 1752 403 ));
-DATA(insert ( 1988 1700 1700 4 1757 403 ));
-DATA(insert ( 1988 1700 1700 5 1756 403 ));
+DATA(insert ( 1988 1700 1700 1 1 1754 403 ));
+DATA(insert ( 1988 1700 1700 2 1 1755 403 ));
+DATA(insert ( 1988 1700 1700 3 1 1752 403 ));
+DATA(insert ( 1988 1700 1700 4 1 1757 403 ));
+DATA(insert ( 1988 1700 1700 5 1 1756 403 ));
/*
* btree bool
*/
-DATA(insert ( 424 16 16 1 58 403 ));
-DATA(insert ( 424 16 16 2 1694 403 ));
-DATA(insert ( 424 16 16 3 91 403 ));
-DATA(insert ( 424 16 16 4 1695 403 ));
-DATA(insert ( 424 16 16 5 59 403 ));
+DATA(insert ( 424 16 16 1 1 58 403 ));
+DATA(insert ( 424 16 16 2 1 1694 403 ));
+DATA(insert ( 424 16 16 3 1 91 403 ));
+DATA(insert ( 424 16 16 4 1 1695 403 ));
+DATA(insert ( 424 16 16 5 1 59 403 ));
/*
* btree bit
*/
-DATA(insert ( 423 1560 1560 1 1786 403 ));
-DATA(insert ( 423 1560 1560 2 1788 403 ));
-DATA(insert ( 423 1560 1560 3 1784 403 ));
-DATA(insert ( 423 1560 1560 4 1789 403 ));
-DATA(insert ( 423 1560 1560 5 1787 403 ));
+DATA(insert ( 423 1560 1560 1 1 1786 403 ));
+DATA(insert ( 423 1560 1560 2 1 1788 403 ));
+DATA(insert ( 423 1560 1560 3 1 1784 403 ));
+DATA(insert ( 423 1560 1560 4 1 1789 403 ));
+DATA(insert ( 423 1560 1560 5 1 1787 403 ));
/*
* btree varbit
*/
-DATA(insert ( 2002 1562 1562 1 1806 403 ));
-DATA(insert ( 2002 1562 1562 2 1808 403 ));
-DATA(insert ( 2002 1562 1562 3 1804 403 ));
-DATA(insert ( 2002 1562 1562 4 1809 403 ));
-DATA(insert ( 2002 1562 1562 5 1807 403 ));
+DATA(insert ( 2002 1562 1562 1 1 1806 403 ));
+DATA(insert ( 2002 1562 1562 2 1 1808 403 ));
+DATA(insert ( 2002 1562 1562 3 1 1804 403 ));
+DATA(insert ( 2002 1562 1562 4 1 1809 403 ));
+DATA(insert ( 2002 1562 1562 5 1 1807 403 ));
/*
* btree text pattern
*/
-DATA(insert ( 2095 25 25 1 2314 403 ));
-DATA(insert ( 2095 25 25 2 2315 403 ));
-DATA(insert ( 2095 25 25 3 98 403 ));
-DATA(insert ( 2095 25 25 4 2317 403 ));
-DATA(insert ( 2095 25 25 5 2318 403 ));
+DATA(insert ( 2095 25 25 1 1 2314 403 ));
+DATA(insert ( 2095 25 25 2 1 2315 403 ));
+DATA(insert ( 2095 25 25 3 1 98 403 ));
+DATA(insert ( 2095 25 25 4 1 2317 403 ));
+DATA(insert ( 2095 25 25 5 1 2318 403 ));
/*
* btree bpchar pattern
*/
-DATA(insert ( 2097 1042 1042 1 2326 403 ));
-DATA(insert ( 2097 1042 1042 2 2327 403 ));
-DATA(insert ( 2097 1042 1042 3 1054 403 ));
-DATA(insert ( 2097 1042 1042 4 2329 403 ));
-DATA(insert ( 2097 1042 1042 5 2330 403 ));
+DATA(insert ( 2097 1042 1042 1 1 2326 403 ));
+DATA(insert ( 2097 1042 1042 2 1 2327 403 ));
+DATA(insert ( 2097 1042 1042 3 1 1054 403 ));
+DATA(insert ( 2097 1042 1042 4 1 2329 403 ));
+DATA(insert ( 2097 1042 1042 5 1 2330 403 ));
/*
* btree money_ops
*/
-DATA(insert ( 2099 790 790 1 902 403 ));
-DATA(insert ( 2099 790 790 2 904 403 ));
-DATA(insert ( 2099 790 790 3 900 403 ));
-DATA(insert ( 2099 790 790 4 905 403 ));
-DATA(insert ( 2099 790 790 5 903 403 ));
+DATA(insert ( 2099 790 790 1 1 902 403 ));
+DATA(insert ( 2099 790 790 2 1 904 403 ));
+DATA(insert ( 2099 790 790 3 1 900 403 ));
+DATA(insert ( 2099 790 790 4 1 905 403 ));
+DATA(insert ( 2099 790 790 5 1 903 403 ));
/*
* btree reltime_ops
*/
-DATA(insert ( 2233 703 703 1 568 403 ));
-DATA(insert ( 2233 703 703 2 570 403 ));
-DATA(insert ( 2233 703 703 3 566 403 ));
-DATA(insert ( 2233 703 703 4 571 403 ));
-DATA(insert ( 2233 703 703 5 569 403 ));
+DATA(insert ( 2233 703 703 1 1 568 403 ));
+DATA(insert ( 2233 703 703 2 1 570 403 ));
+DATA(insert ( 2233 703 703 3 1 566 403 ));
+DATA(insert ( 2233 703 703 4 1 571 403 ));
+DATA(insert ( 2233 703 703 5 1 569 403 ));
/*
* btree tinterval_ops
*/
-DATA(insert ( 2234 704 704 1 813 403 ));
-DATA(insert ( 2234 704 704 2 815 403 ));
-DATA(insert ( 2234 704 704 3 811 403 ));
-DATA(insert ( 2234 704 704 4 816 403 ));
-DATA(insert ( 2234 704 704 5 814 403 ));
+DATA(insert ( 2234 704 704 1 1 813 403 ));
+DATA(insert ( 2234 704 704 2 1 815 403 ));
+DATA(insert ( 2234 704 704 3 1 811 403 ));
+DATA(insert ( 2234 704 704 4 1 816 403 ));
+DATA(insert ( 2234 704 704 5 1 814 403 ));
/*
* btree array_ops
*/
-DATA(insert ( 397 2277 2277 1 1072 403 ));
-DATA(insert ( 397 2277 2277 2 1074 403 ));
-DATA(insert ( 397 2277 2277 3 1070 403 ));
-DATA(insert ( 397 2277 2277 4 1075 403 ));
-DATA(insert ( 397 2277 2277 5 1073 403 ));
+DATA(insert ( 397 2277 2277 1 1 1072 403 ));
+DATA(insert ( 397 2277 2277 2 1 1074 403 ));
+DATA(insert ( 397 2277 2277 3 1 1070 403 ));
+DATA(insert ( 397 2277 2277 4 1 1075 403 ));
+DATA(insert ( 397 2277 2277 5 1 1073 403 ));
/*
* btree record_ops
*/
-DATA(insert ( 2994 2249 2249 1 2990 403 ));
-DATA(insert ( 2994 2249 2249 2 2992 403 ));
-DATA(insert ( 2994 2249 2249 3 2988 403 ));
-DATA(insert ( 2994 2249 2249 4 2993 403 ));
-DATA(insert ( 2994 2249 2249 5 2991 403 ));
+DATA(insert ( 2994 2249 2249 1 1 2990 403 ));
+DATA(insert ( 2994 2249 2249 2 1 2992 403 ));
+DATA(insert ( 2994 2249 2249 3 1 2988 403 ));
+DATA(insert ( 2994 2249 2249 4 1 2993 403 ));
+DATA(insert ( 2994 2249 2249 5 1 2991 403 ));
/*
* btree uuid_ops
*/
-DATA(insert ( 2968 2950 2950 1 2974 403 ));
-DATA(insert ( 2968 2950 2950 2 2976 403 ));
-DATA(insert ( 2968 2950 2950 3 2972 403 ));
-DATA(insert ( 2968 2950 2950 4 2977 403 ));
-DATA(insert ( 2968 2950 2950 5 2975 403 ));
+DATA(insert ( 2968 2950 2950 1 1 2974 403 ));
+DATA(insert ( 2968 2950 2950 2 1 2976 403 ));
+DATA(insert ( 2968 2950 2950 3 1 2972 403 ));
+DATA(insert ( 2968 2950 2950 4 1 2977 403 ));
+DATA(insert ( 2968 2950 2950 5 1 2975 403 ));
/*
* hash index _ops
*/
/* bpchar_ops */
-DATA(insert ( 427 1042 1042 1 1054 405 ));
+DATA(insert ( 427 1042 1042 1 1 1054 405 ));
/* char_ops */
-DATA(insert ( 431 18 18 1 92 405 ));
+DATA(insert ( 431 18 18 1 1 92 405 ));
/* date_ops */
-DATA(insert ( 435 1082 1082 1 1093 405 ));
+DATA(insert ( 435 1082 1082 1 1 1093 405 ));
/* float_ops */
-DATA(insert ( 1971 700 700 1 620 405 ));
-DATA(insert ( 1971 701 701 1 670 405 ));
-DATA(insert ( 1971 700 701 1 1120 405 ));
-DATA(insert ( 1971 701 700 1 1130 405 ));
+DATA(insert ( 1971 700 700 1 1 620 405 ));
+DATA(insert ( 1971 701 701 1 1 670 405 ));
+DATA(insert ( 1971 700 701 1 1 1120 405 ));
+DATA(insert ( 1971 701 700 1 1 1130 405 ));
/* network_ops */
-DATA(insert ( 1975 869 869 1 1201 405 ));
+DATA(insert ( 1975 869 869 1 1 1201 405 ));
/* integer_ops */
-DATA(insert ( 1977 21 21 1 94 405 ));
-DATA(insert ( 1977 23 23 1 96 405 ));
-DATA(insert ( 1977 20 20 1 410 405 ));
-DATA(insert ( 1977 21 23 1 532 405 ));
-DATA(insert ( 1977 21 20 1 1862 405 ));
-DATA(insert ( 1977 23 21 1 533 405 ));
-DATA(insert ( 1977 23 20 1 15 405 ));
-DATA(insert ( 1977 20 21 1 1868 405 ));
-DATA(insert ( 1977 20 23 1 416 405 ));
+DATA(insert ( 1977 21 21 1 1 94 405 ));
+DATA(insert ( 1977 23 23 1 1 96 405 ));
+DATA(insert ( 1977 20 20 1 1 410 405 ));
+DATA(insert ( 1977 21 23 1 1 532 405 ));
+DATA(insert ( 1977 21 20 1 1 1862 405 ));
+DATA(insert ( 1977 23 21 1 1 533 405 ));
+DATA(insert ( 1977 23 20 1 1 15 405 ));
+DATA(insert ( 1977 20 21 1 1 1868 405 ));
+DATA(insert ( 1977 20 23 1 1 416 405 ));
/* interval_ops */
-DATA(insert ( 1983 1186 1186 1 1330 405 ));
+DATA(insert ( 1983 1186 1186 1 1 1330 405 ));
/* macaddr_ops */
-DATA(insert ( 1985 829 829 1 1220 405 ));
+DATA(insert ( 1985 829 829 1 1 1220 405 ));
/* name_ops */
-DATA(insert ( 1987 19 19 1 93 405 ));
+DATA(insert ( 1987 19 19 1 1 93 405 ));
/* oid_ops */
-DATA(insert ( 1990 26 26 1 607 405 ));
+DATA(insert ( 1990 26 26 1 1 607 405 ));
/* oidvector_ops */
-DATA(insert ( 1992 30 30 1 649 405 ));
+DATA(insert ( 1992 30 30 1 1 649 405 ));
/* text_ops */
-DATA(insert ( 1995 25 25 1 98 405 ));
+DATA(insert ( 1995 25 25 1 1 98 405 ));
/* time_ops */
-DATA(insert ( 1997 1083 1083 1 1108 405 ));
+DATA(insert ( 1997 1083 1083 1 1 1108 405 ));
/* timestamptz_ops */
-DATA(insert ( 1999 1184 1184 1 1320 405 ));
+DATA(insert ( 1999 1184 1184 1 1 1320 405 ));
/* timetz_ops */
-DATA(insert ( 2001 1266 1266 1 1550 405 ));
+DATA(insert ( 2001 1266 1266 1 1 1550 405 ));
/* timestamp_ops */
-DATA(insert ( 2040 1114 1114 1 2060 405 ));
+DATA(insert ( 2040 1114 1114 1 1 2060 405 ));
/* bool_ops */
-DATA(insert ( 2222 16 16 1 91 405 ));
+DATA(insert ( 2222 16 16 1 1 91 405 ));
/* bytea_ops */
-DATA(insert ( 2223 17 17 1 1955 405 ));
+DATA(insert ( 2223 17 17 1 1 1955 405 ));
/* int2vector_ops */
-DATA(insert ( 2224 22 22 1 386 405 ));
+DATA(insert ( 2224 22 22 1 1 386 405 ));
/* xid_ops */
-DATA(insert ( 2225 28 28 1 352 405 ));
+DATA(insert ( 2225 28 28 1 1 352 405 ));
/* cid_ops */
-DATA(insert ( 2226 29 29 1 385 405 ));
+DATA(insert ( 2226 29 29 1 1 385 405 ));
/* abstime_ops */
-DATA(insert ( 2227 702 702 1 560 405 ));
+DATA(insert ( 2227 702 702 1 1 560 405 ));
/* reltime_ops */
-DATA(insert ( 2228 703 703 1 566 405 ));
+DATA(insert ( 2228 703 703 1 1 566 405 ));
/* text_pattern_ops */
-DATA(insert ( 2229 25 25 1 98 405 ));
+DATA(insert ( 2229 25 25 1 1 98 405 ));
/* bpchar_pattern_ops */
-DATA(insert ( 2231 1042 1042 1 1054 405 ));
+DATA(insert ( 2231 1042 1042 1 1 1054 405 ));
/* aclitem_ops */
-DATA(insert ( 2235 1033 1033 1 974 405 ));
+DATA(insert ( 2235 1033 1033 1 1 974 405 ));
/* uuid_ops */
-DATA(insert ( 2969 2950 2950 1 2972 405 ));
+DATA(insert ( 2969 2950 2950 1 1 2972 405 ));
/* numeric_ops */
-DATA(insert ( 1998 1700 1700 1 1752 405 ));
+DATA(insert ( 1998 1700 1700 1 1 1752 405 ));
/*
* gist box_ops
*/
-DATA(insert ( 2593 603 603 1 493 783 ));
-DATA(insert ( 2593 603 603 2 494 783 ));
-DATA(insert ( 2593 603 603 3 500 783 ));
-DATA(insert ( 2593 603 603 4 495 783 ));
-DATA(insert ( 2593 603 603 5 496 783 ));
-DATA(insert ( 2593 603 603 6 499 783 ));
-DATA(insert ( 2593 603 603 7 498 783 ));
-DATA(insert ( 2593 603 603 8 497 783 ));
-DATA(insert ( 2593 603 603 9 2571 783 ));
-DATA(insert ( 2593 603 603 10 2570 783 ));
-DATA(insert ( 2593 603 603 11 2573 783 ));
-DATA(insert ( 2593 603 603 12 2572 783 ));
-DATA(insert ( 2593 603 603 13 2863 783 ));
-DATA(insert ( 2593 603 603 14 2862 783 ));
+DATA(insert ( 2593 603 603 1 1 493 783 ));
+DATA(insert ( 2593 603 603 2 1 494 783 ));
+DATA(insert ( 2593 603 603 3 1 500 783 ));
+DATA(insert ( 2593 603 603 4 1 495 783 ));
+DATA(insert ( 2593 603 603 5 1 496 783 ));
+DATA(insert ( 2593 603 603 6 1 499 783 ));
+DATA(insert ( 2593 603 603 7 1 498 783 ));
+DATA(insert ( 2593 603 603 8 1 497 783 ));
+DATA(insert ( 2593 603 603 9 1 2571 783 ));
+DATA(insert ( 2593 603 603 10 1 2570 783 ));
+DATA(insert ( 2593 603 603 11 1 2573 783 ));
+DATA(insert ( 2593 603 603 12 1 2572 783 ));
+DATA(insert ( 2593 603 603 13 1 2863 783 ));
+DATA(insert ( 2593 603 603 14 1 2862 783 ));
/*
* gist point_ops
*/
-DATA(insert ( 1029 600 600 11 506 783 ));
-DATA(insert ( 1029 600 600 1 507 783 ));
-DATA(insert ( 1029 600 600 5 508 783 ));
-DATA(insert ( 1029 600 600 10 509 783 ));
-DATA(insert ( 1029 600 600 6 510 783 ));
-DATA(insert ( 1029 603 600 27 433 783 ));
-DATA(insert ( 1029 600 603 28 511 783 ));
-DATA(insert ( 1029 604 600 47 757 783 ));
-DATA(insert ( 1029 600 604 48 756 783 ));
-DATA(insert ( 1029 718 600 67 759 783 ));
-DATA(insert ( 1029 600 718 68 758 783 ));
+DATA(insert ( 1029 600 600 11 1 506 783 ));
+DATA(insert ( 1029 600 600 1 1 507 783 ));
+DATA(insert ( 1029 600 600 5 1 508 783 ));
+DATA(insert ( 1029 600 600 10 1 509 783 ));
+DATA(insert ( 1029 600 600 6 1 510 783 ));
+DATA(insert ( 1029 603 600 27 1 433 783 ));
+DATA(insert ( 1029 600 603 28 1 511 783 ));
+DATA(insert ( 1029 604 600 47 1 757 783 ));
+DATA(insert ( 1029 600 604 48 1 756 783 ));
+DATA(insert ( 1029 718 600 67 1 759 783 ));
+DATA(insert ( 1029 600 718 68 1 758 783 ));
/*
* gist poly_ops (supports polygons)
*/
-DATA(insert ( 2594 604 604 1 485 783 ));
-DATA(insert ( 2594 604 604 2 486 783 ));
-DATA(insert ( 2594 604 604 3 492 783 ));
-DATA(insert ( 2594 604 604 4 487 783 ));
-DATA(insert ( 2594 604 604 5 488 783 ));
-DATA(insert ( 2594 604 604 6 491 783 ));
-DATA(insert ( 2594 604 604 7 490 783 ));
-DATA(insert ( 2594 604 604 8 489 783 ));
-DATA(insert ( 2594 604 604 9 2575 783 ));
-DATA(insert ( 2594 604 604 10 2574 783 ));
-DATA(insert ( 2594 604 604 11 2577 783 ));
-DATA(insert ( 2594 604 604 12 2576 783 ));
-DATA(insert ( 2594 604 604 13 2861 783 ));
-DATA(insert ( 2594 604 604 14 2860 783 ));
+DATA(insert ( 2594 604 604 1 1 485 783 ));
+DATA(insert ( 2594 604 604 2 1 486 783 ));
+DATA(insert ( 2594 604 604 3 1 492 783 ));
+DATA(insert ( 2594 604 604 4 1 487 783 ));
+DATA(insert ( 2594 604 604 5 1 488 783 ));
+DATA(insert ( 2594 604 604 6 1 491 783 ));
+DATA(insert ( 2594 604 604 7 1 490 783 ));
+DATA(insert ( 2594 604 604 8 1 489 783 ));
+DATA(insert ( 2594 604 604 9 1 2575 783 ));
+DATA(insert ( 2594 604 604 10 1 2574 783 ));
+DATA(insert ( 2594 604 604 11 1 2577 783 ));
+DATA(insert ( 2594 604 604 12 1 2576 783 ));
+DATA(insert ( 2594 604 604 13 1 2861 783 ));
+DATA(insert ( 2594 604 604 14 1 2860 783 ));
/*
* gist circle_ops
*/
-DATA(insert ( 2595 718 718 1 1506 783 ));
-DATA(insert ( 2595 718 718 2 1507 783 ));
-DATA(insert ( 2595 718 718 3 1513 783 ));
-DATA(insert ( 2595 718 718 4 1508 783 ));
-DATA(insert ( 2595 718 718 5 1509 783 ));
-DATA(insert ( 2595 718 718 6 1512 783 ));
-DATA(insert ( 2595 718 718 7 1511 783 ));
-DATA(insert ( 2595 718 718 8 1510 783 ));
-DATA(insert ( 2595 718 718 9 2589 783 ));
-DATA(insert ( 2595 718 718 10 1515 783 ));
-DATA(insert ( 2595 718 718 11 1514 783 ));
-DATA(insert ( 2595 718 718 12 2590 783 ));
-DATA(insert ( 2595 718 718 13 2865 783 ));
-DATA(insert ( 2595 718 718 14 2864 783 ));
+DATA(insert ( 2595 718 718 1 1 1506 783 ));
+DATA(insert ( 2595 718 718 2 1 1507 783 ));
+DATA(insert ( 2595 718 718 3 1 1513 783 ));
+DATA(insert ( 2595 718 718 4 1 1508 783 ));
+DATA(insert ( 2595 718 718 5 1 1509 783 ));
+DATA(insert ( 2595 718 718 6 1 1512 783 ));
+DATA(insert ( 2595 718 718 7 1 1511 783 ));
+DATA(insert ( 2595 718 718 8 1 1510 783 ));
+DATA(insert ( 2595 718 718 9 1 2589 783 ));
+DATA(insert ( 2595 718 718 10 1 1515 783 ));
+DATA(insert ( 2595 718 718 11 1 1514 783 ));
+DATA(insert ( 2595 718 718 12 1 2590 783 ));
+DATA(insert ( 2595 718 718 13 1 2865 783 ));
+DATA(insert ( 2595 718 718 14 1 2864 783 ));
/*
* gin array_ops (these anyarray operators are used with all the opclasses
* of the family)
*/
-DATA(insert ( 2745 2277 2277 1 2750 2742 ));
-DATA(insert ( 2745 2277 2277 2 2751 2742 ));
-DATA(insert ( 2745 2277 2277 3 2752 2742 ));
-DATA(insert ( 2745 2277 2277 4 1070 2742 ));
+DATA(insert ( 2745 2277 2277 1 1 2750 2742 ));
+DATA(insert ( 2745 2277 2277 2 1 2751 2742 ));
+DATA(insert ( 2745 2277 2277 3 1 2752 2742 ));
+DATA(insert ( 2745 2277 2277 4 1 1070 2742 ));
/*
* btree enum_ops
*/
-DATA(insert ( 3522 3500 3500 1 3518 403 ));
-DATA(insert ( 3522 3500 3500 2 3520 403 ));
-DATA(insert ( 3522 3500 3500 3 3516 403 ));
-DATA(insert ( 3522 3500 3500 4 3521 403 ));
-DATA(insert ( 3522 3500 3500 5 3519 403 ));
+DATA(insert ( 3522 3500 3500 1 1 3518 403 ));
+DATA(insert ( 3522 3500 3500 2 1 3520 403 ));
+DATA(insert ( 3522 3500 3500 3 1 3516 403 ));
+DATA(insert ( 3522 3500 3500 4 1 3521 403 ));
+DATA(insert ( 3522 3500 3500 5 1 3519 403 ));
/*
* hash enum_ops
*/
-DATA(insert ( 3523 3500 3500 1 3516 405 ));
+DATA(insert ( 3523 3500 3500 1 1 3516 405 ));
/*
* btree tsvector_ops
*/
-DATA(insert ( 3626 3614 3614 1 3627 403 ));
-DATA(insert ( 3626 3614 3614 2 3628 403 ));
-DATA(insert ( 3626 3614 3614 3 3629 403 ));
-DATA(insert ( 3626 3614 3614 4 3631 403 ));
-DATA(insert ( 3626 3614 3614 5 3632 403 ));
+DATA(insert ( 3626 3614 3614 1 1 3627 403 ));
+DATA(insert ( 3626 3614 3614 2 1 3628 403 ));
+DATA(insert ( 3626 3614 3614 3 1 3629 403 ));
+DATA(insert ( 3626 3614 3614 4 1 3631 403 ));
+DATA(insert ( 3626 3614 3614 5 1 3632 403 ));
/*
* GiST tsvector_ops
*/
-DATA(insert ( 3655 3614 3615 1 3636 783 ));
+DATA(insert ( 3655 3614 3615 1 1 3636 783 ));
/*
* GIN tsvector_ops
*/
-DATA(insert ( 3659 3614 3615 1 3636 2742 ));
-DATA(insert ( 3659 3614 3615 2 3660 2742 ));
+DATA(insert ( 3659 3614 3615 1 1 3636 2742 ));
+DATA(insert ( 3659 3614 3615 2 1 3660 2742 ));
/*
* btree tsquery_ops
*/
-DATA(insert ( 3683 3615 3615 1 3674 403 ));
-DATA(insert ( 3683 3615 3615 2 3675 403 ));
-DATA(insert ( 3683 3615 3615 3 3676 403 ));
-DATA(insert ( 3683 3615 3615 4 3678 403 ));
-DATA(insert ( 3683 3615 3615 5 3679 403 ));
+DATA(insert ( 3683 3615 3615 1 1 3674 403 ));
+DATA(insert ( 3683 3615 3615 2 1 3675 403 ));
+DATA(insert ( 3683 3615 3615 3 1 3676 403 ));
+DATA(insert ( 3683 3615 3615 4 1 3678 403 ));
+DATA(insert ( 3683 3615 3615 5 1 3679 403 ));
/*
* GiST tsquery_ops
*/
-DATA(insert ( 3702 3615 3615 7 3693 783 ));
-DATA(insert ( 3702 3615 3615 8 3694 783 ));
+DATA(insert ( 3702 3615 3615 7 1 3693 783 ));
+DATA(insert ( 3702 3615 3615 8 1 3694 783 ));
#endif /* PG_AMOP_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 3cac54b..5acc1b7 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1769,6 +1769,7 @@ typedef struct CreateOpClassItem
List *args; /* argument types */
int number; /* strategy num or support proc num */
List *class_args; /* only used for functions */
+ int purpose; /* purpose */
/* fields used for a storagetype item: */
TypeName *storedtype; /* datatype stored in index */
} CreateOpClassItem;
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 02c0219..92e5b65 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -30,14 +30,14 @@ typedef enum IOFuncSelector
typedef int32 (*get_attavgwidth_hook_type) (Oid relid, AttrNumber attnum);
extern PGDLLIMPORT get_attavgwidth_hook_type get_attavgwidth_hook;
-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,
+extern bool op_in_opfamily(Oid opno, Oid opfamily, int purpose);
+extern int get_op_opfamily_strategy(Oid opno, Oid opfamily, int purpose);
+extern void get_op_opfamily_properties(Oid opno, Oid opfamily, int purpose,
int *strategy,
Oid *lefttype,
Oid *righttype);
extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
- int16 strategy);
+ int16 strategy, int16 purpose);
extern bool get_ordering_op_properties(Oid opno,
Oid *opfamily, Oid *opcintype, int16 *strategy);
extern bool get_compare_function_for_ordering_op(Oid opno,