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,