From 725d52d0c27cffe8c99bb78e2b0d2480d5cd702b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 24 Nov 2010 14:20:39 -0500 Subject: [PATCH] Create the system catalog infrastructure needed for KNNGIST. This commit adds columns amoppurpose and amopsortfamily to pg_amop, and column amcanorderbyop to pg_am. For the moment all the entries in amcanorderbyop are "false", since the underlying support isn't there yet. Also, extend the CREATE OPERATOR CLASS/ALTER OPERATOR FAMILY commands with [ FOR SEARCH | FOR ORDER BY sort_operator_family ] clauses to allow the new columns of pg_amop to be populated, and create pg_dump support for dumping that information. I also added some documentation, although it's perhaps a bit premature given that the feature doesn't do anything useful yet. Teodor Sigaev, Robert Haas, Tom Lane --- doc/src/sgml/catalogs.sgml | 69 ++- doc/src/sgml/ref/alter_opfamily.sgml | 18 +- doc/src/sgml/ref/create_opclass.sgml | 18 +- doc/src/sgml/xindex.sgml | 65 ++- src/backend/commands/opclasscmds.c | 78 +++- src/backend/nodes/copyfuncs.c | 1 + src/backend/nodes/equalfuncs.c | 1 + src/backend/optimizer/util/plancat.c | 1 + src/backend/optimizer/util/predtest.c | 8 +- src/backend/parser/gram.y | 14 +- src/backend/utils/cache/lsyscache.c | 15 +- src/backend/utils/cache/syscache.c | 4 +- src/bin/pg_dump/pg_dump.c | 163 +++++-- src/include/catalog/catversion.h | 2 +- src/include/catalog/indexing.h | 2 +- src/include/catalog/pg_am.h | 58 +-- src/include/catalog/pg_amop.h | 746 ++++++++++++++++--------------- src/include/nodes/parsenodes.h | 1 + src/include/nodes/relation.h | 1 + src/test/regress/expected/opr_sanity.out | 69 ++- src/test/regress/sql/opr_sanity.sql | 54 ++- 21 files changed, 913 insertions(+), 475 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 9a8729b8b3..54a6dcc102 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -423,7 +423,16 @@ amcanorder bool - Does the access method support ordered scans? + Does the access method support ordered scans sorted by the + indexed column's value? + + + + amcanorderbyop + bool + + Does the access method support ordered scans sorted by the result + of an operator on the indexed column? @@ -598,9 +607,13 @@ The catalog pg_amop stores information about operators associated with access method operator families. There is one - row for each operator that is a member of an operator family. An operator + row for each operator that is a member of an operator family. A family + member can be either a search operator or an + ordering operator. An operator can appear in more than one family, but cannot appear in more than one - position within a family. + search position nor more than one ordering position within a family. + (It is allowed, though unlikely, for an operator to be used for both + search and ordering purposes.) @@ -646,6 +659,14 @@ + amoppurpose + char + + Operator purpose, either s for search or + o for ordering + + + amopopr oid pg_operator.oid @@ -659,11 +680,53 @@ Index access method operator family is for + + amopsortfamily + oid + pg_opfamily.oid + The btree operator family this entry sorts according to, if an + ordering operator; zero if a search operator + +
+ A search operator entry indicates that an index of this operator + family can be searched to find all rows satisfying + WHERE + indexed_column + operator + constant. + Obviously, such an operator must return boolean, and its left-hand input + type must match the index's column data type. + + + + An ordering operator entry indicates that an index of this + operator family can be scanned to return rows in the order represented by + ORDER BY + indexed_column + operator + constant. + Such an operator could return any sortable data type, though again + its left-hand input type must match the index's column data type. + The exact semantics of the ORDER BY are specified by the + amopsortfamily column, which must reference + a btree operator family for the operator's result type. + + + + + At present, it's assumed that the sort order for an ordering operator + is the default for the referenced opfamily, i.e., ASC NULLS + LAST. This might someday be relaxed by adding additional columns + to specify sort options explicitly. + + + + An entry's amopmethod must match the opfmethod of its containing operator family (including amopmethod here is an intentional denormalization of the diff --git a/doc/src/sgml/ref/alter_opfamily.sgml b/doc/src/sgml/ref/alter_opfamily.sgml index 1018af8412..3c8ca21f61 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 SEARCH | FOR ORDER BY sort_family_name ] | FUNCTION support_number [ ( op_type [ , op_type ] ) ] function_name ( argument_type [, ...] ) } [, ... ] ALTER OPERATOR FAMILY name USING index_method DROP @@ -155,6 +155,22 @@ ALTER OPERATOR FAMILY name USING sort_family_name + + + The name (optionally schema-qualified) of an existing btree operator + family that describes the sort ordering associated with an ordering + operator. + + + + If neither FOR SEARCH nor FOR ORDER BY is + specified, FOR SEARCH is the default. + + + + + support_number diff --git a/doc/src/sgml/ref/create_opclass.sgml b/doc/src/sgml/ref/create_opclass.sgml index f12f13dc08..eff585405c 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 SEARCH | FOR ORDER BY sort_family_name ] | FUNCTION support_number [ ( op_type [ , op_type ] ) ] function_name ( argument_type [, ...] ) | STORAGE storage_type } [, ... ] @@ -181,6 +181,22 @@ CREATE OPERATOR CLASS name [ DEFAUL + sort_family_name + + + The name (optionally schema-qualified) of an existing btree operator + family that describes the sort ordering associated with an ordering + operator. + + + + If neither FOR SEARCH nor FOR ORDER BY is + specified, FOR SEARCH is the default. + + + + + support_number diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml index 8f9fd21f38..6d059bda70 100644 --- a/doc/src/sgml/xindex.sgml +++ b/doc/src/sgml/xindex.sgml @@ -276,10 +276,13 @@ - Notice that all strategy operators return Boolean values. In - practice, all operators defined as index method strategies must + Notice that all the operators listed above return Boolean values. In + practice, all operators defined as index method search operators must return type boolean, since they must appear at the top level of a WHERE clause to be used with an index. + (Some index access methods also support ordering operators, + which typically don't return Boolean values; that feature is discussed + in .) @@ -464,7 +467,7 @@ - Unlike strategy operators, support functions return whichever data + Unlike search operators, support functions return whichever data type the particular index method expects; for example in the case of the comparison function for B-trees, a signed integer. The number and types of the arguments to each support function are likewise @@ -921,6 +924,62 @@ ALTER OPERATOR FAMILY integer_ops USING btree ADD + + Ordering Operators + + + Some index access methods (currently, only GiST) support the concept of + ordering operators. What we have been discussing so far + are search operators. A search operator is one for which + the index can be searched to find all rows satisfying + WHERE + indexed_column + operator + constant. + Note that nothing is promised about the order in which the matching rows + will be returned. In contrast, an ordering operator does not restrict the + set of rows that can be returned, but instead determines their order. + An ordering operator is one for which the index can be scanned to return + rows in the order represented by + ORDER BY + indexed_column + operator + constant. + The reason for defining ordering operators that way is that it supports + nearest-neighbor searches, if the operator is one that measures distance. + For example, a query like + point '(101,456)' LIMIT 10; +]]> + + finds the ten places closest to a given target point. A GiST index + on the location column can do this efficiently because + <-> is an ordering operator. + + + + While search operators have to return Boolean results, ordering operators + usually return some other type, such as float or numeric for distances. + This type is normally not the same as the data type being indexed. + To avoid hard-wiring assumptions about the behavior of different data + types, the definition of an ordering operator is required to name + a B-tree operator family that specifies the sort ordering of the result + data type. As was stated in the previous section, B-tree operator families + define PostgreSQL's notion of ordering, so + this is a natural representation. Since the point <-> + operator returns float8, it could be specified in an operator + class creation command like this: + (point, point) FOR ORDER BY float_ops +]]> + + where float_ops is the built-in operator family that includes + operations on float8. This declaration states that the index + is able to return rows in order of increasing values of the + <-> operator. + + + Special Features of Operator Classes diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 8c49336316..132c4ee1e5 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 */ + Oid sortfamily; /* ordering operator's sort opfamily, or 0 */ } OpFamilyMember; @@ -457,6 +458,7 @@ DefineOpClass(CreateOpClassStmt *stmt) CreateOpClassItem *item = lfirst(l); Oid operOid; Oid funcOid; + Oid sortfamilyOid; OpFamilyMember *member; Assert(IsA(item, CreateOpClassItem)); @@ -486,6 +488,13 @@ DefineOpClass(CreateOpClassStmt *stmt) false, -1); } + if (item->order_family) + sortfamilyOid = get_opfamily_oid(BTREE_AM_OID, + item->order_family, + false); + else + sortfamilyOid = InvalidOid; + #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Caller must own operator and its underlying function */ @@ -502,6 +511,7 @@ DefineOpClass(CreateOpClassStmt *stmt) member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); member->object = operOid; member->number = item->number; + member->sortfamily = sortfamilyOid; assignOperTypes(member, amoid, typeoid); addFamilyMember(&operators, member, false); break; @@ -825,6 +835,7 @@ AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid, CreateOpClassItem *item = lfirst(l); Oid operOid; Oid funcOid; + Oid sortfamilyOid; OpFamilyMember *member; Assert(IsA(item, CreateOpClassItem)); @@ -854,6 +865,13 @@ AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid, operOid = InvalidOid; /* keep compiler quiet */ } + if (item->order_family) + sortfamilyOid = get_opfamily_oid(BTREE_AM_OID, + item->order_family, + false); + else + sortfamilyOid = InvalidOid; + #ifdef NOT_USED /* XXX this is unnecessary given the superuser check above */ /* Caller must own operator and its underlying function */ @@ -870,6 +888,7 @@ AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid, member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember)); member->object = operOid; member->number = item->number; + member->sortfamily = sortfamilyOid; assignOperTypes(member, amoid, InvalidOid); addFamilyMember(&operators, member, false); break; @@ -1043,16 +1062,51 @@ assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) opform = (Form_pg_operator) GETSTRUCT(optup); /* - * Opfamily operators must be binary ops returning boolean. + * Opfamily operators must be binary. */ if (opform->oprkind != 'b') ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("index operators must be binary"))); - if (opform->oprresult != BOOLOID) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("index operators must return boolean"))); + + if (OidIsValid(member->sortfamily)) + { + /* + * Ordering op, check index supports that. (We could perhaps also + * check that the operator returns a type supported by the sortfamily, + * but that seems more trouble than it's worth here. If it does not, + * the operator will never be matchable to any ORDER BY clause, but + * no worse consequences can ensue. Also, trying to check that would + * create an ordering hazard during dump/reload: it's possible that + * the family has been created but not yet populated with the required + * operators.) + */ + HeapTuple amtup; + Form_pg_am pg_am; + + amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amoid)); + if (amtup == NULL) + elog(ERROR, "cache lookup failed for access method %u", amoid); + pg_am = (Form_pg_am) GETSTRUCT(amtup); + + if (!pg_am->amcanorderbyop) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("access method \"%s\" does not support ordering operators", + NameStr(pg_am->amname)))); + + ReleaseSysCache(amtup); + } + else + { + /* + * Search operators must return boolean. + */ + if (opform->oprresult != BOOLOID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("index search operators must return boolean"))); + } /* * If lefttype/righttype isn't specified, use the operator's input types @@ -1206,6 +1260,7 @@ storeOperators(List *opfamilyname, Oid amoid, foreach(l, operators) { OpFamilyMember *op = (OpFamilyMember *) lfirst(l); + char oppurpose; /* * If adding to an existing family, check for conflict with an @@ -1225,6 +1280,8 @@ storeOperators(List *opfamilyname, Oid amoid, format_type_be(op->righttype), NameListToString(opfamilyname)))); + oppurpose = OidIsValid(op->sortfamily) ? AMOP_ORDER : AMOP_SEARCH; + /* Create the pg_amop entry */ memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); @@ -1233,8 +1290,10 @@ storeOperators(List *opfamilyname, Oid amoid, values[Anum_pg_amop_amoplefttype - 1] = ObjectIdGetDatum(op->lefttype); values[Anum_pg_amop_amoprighttype - 1] = ObjectIdGetDatum(op->righttype); values[Anum_pg_amop_amopstrategy - 1] = Int16GetDatum(op->number); + values[Anum_pg_amop_amoppurpose - 1] = CharGetDatum(oppurpose); values[Anum_pg_amop_amopopr - 1] = ObjectIdGetDatum(op->object); values[Anum_pg_amop_amopmethod - 1] = ObjectIdGetDatum(amoid); + values[Anum_pg_amop_amopsortfamily - 1] = ObjectIdGetDatum(op->sortfamily); tup = heap_form_tuple(rel->rd_att, values, nulls); @@ -1275,6 +1334,15 @@ storeOperators(List *opfamilyname, Oid amoid, referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); } + + /* A search operator also needs a dep on the referenced opfamily */ + if (OidIsValid(op->sortfamily)) + { + referenced.classId = OperatorFamilyRelationId; + referenced.objectId = op->sortfamily; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } } heap_close(rel, RowExclusiveLock); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index bbfbab2e39..0e0b4dc598 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2991,6 +2991,7 @@ _copyCreateOpClassItem(CreateOpClassItem *from) COPY_NODE_FIELD(name); COPY_NODE_FIELD(args); COPY_SCALAR_FIELD(number); + COPY_NODE_FIELD(order_family); COPY_NODE_FIELD(class_args); COPY_NODE_FIELD(storedtype); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index be4b835585..2d2b8c7763 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1464,6 +1464,7 @@ _equalCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b) COMPARE_NODE_FIELD(name); COMPARE_NODE_FIELD(args); COMPARE_SCALAR_FIELD(number); + COMPARE_NODE_FIELD(order_family); COMPARE_NODE_FIELD(class_args); COMPARE_NODE_FIELD(storedtype); diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 73132ddf5c..908b4f7205 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -212,6 +212,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, info->relam = indexRelation->rd_rel->relam; info->amcostestimate = indexRelation->rd_am->amcostestimate; + info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop; info->amoptionalkey = indexRelation->rd_am->amoptionalkey; info->amsearchnulls = indexRelation->rd_am->amsearchnulls; info->amhasgettuple = OidIsValid(indexRelation->rd_am->amgettuple); diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c index 5ab4a31e15..d7ccba0a11 100644 --- a/src/backend/optimizer/util/predtest.c +++ b/src/backend/optimizer/util/predtest.c @@ -1661,8 +1661,9 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it) * From the same opfamily, find a strategy number for the clause_op, * if possible */ - clause_tuple = SearchSysCache2(AMOPOPID, + clause_tuple = SearchSysCache3(AMOPOPID, ObjectIdGetDatum(clause_op), + CharGetDatum(AMOP_SEARCH), ObjectIdGetDatum(opfamily_id)); if (HeapTupleIsValid(clause_tuple)) { @@ -1677,8 +1678,9 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it) } else if (OidIsValid(clause_op_negator)) { - clause_tuple = SearchSysCache2(AMOPOPID, - ObjectIdGetDatum(clause_op_negator), + clause_tuple = SearchSysCache3(AMOPOPID, + ObjectIdGetDatum(clause_op_negator), + CharGetDatum(AMOP_SEARCH), ObjectIdGetDatum(opfamily_id)); if (HeapTupleIsValid(clause_tuple)) { diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index f0c2cd06ea..1c17be8921 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -295,7 +295,7 @@ static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_ ctext_expr_list ctext_row def_list indirection opt_indirection reloption_list group_clause TriggerFuncArgs select_limit opt_select_limit opclass_item_list opclass_drop_list - opt_opfamily transaction_mode_list_or_empty + opclass_purpose opt_opfamily transaction_mode_list_or_empty OptTableFuncElementList TableFuncElementList opt_type_modifiers prep_type_clause execute_param_clause using_clause returning_clause @@ -3935,22 +3935,25 @@ opclass_item_list: ; opclass_item: - OPERATOR Iconst any_operator opt_recheck + OPERATOR Iconst any_operator opclass_purpose opt_recheck { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_OPERATOR; n->name = $3; n->args = NIL; n->number = $2; + n->order_family = $4; $$ = (Node *) n; } - | OPERATOR Iconst any_operator oper_argtypes opt_recheck + | OPERATOR Iconst any_operator oper_argtypes opclass_purpose + opt_recheck { CreateOpClassItem *n = makeNode(CreateOpClassItem); n->itemtype = OPCLASS_ITEM_OPERATOR; n->name = $3; n->args = $4; n->number = $2; + n->order_family = $5; $$ = (Node *) n; } | FUNCTION Iconst func_name func_args @@ -3989,6 +3992,11 @@ opt_opfamily: FAMILY any_name { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; +opclass_purpose: FOR SEARCH { $$ = NIL; } + | FOR ORDER BY any_name { $$ = $4; } + | /*EMPTY*/ { $$ = NIL; } + ; + opt_recheck: RECHECK { /* diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index df765e9d5e..9beae0d9ef 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -46,12 +46,15 @@ get_attavgwidth_hook_type get_attavgwidth_hook = NULL; * op_in_opfamily * * Return t iff operator 'opno' is in operator family 'opfamily'. + * + * This function only considers search operators, not ordering operators. */ bool op_in_opfamily(Oid opno, Oid opfamily) { - return SearchSysCacheExists2(AMOPOPID, + return SearchSysCacheExists3(AMOPOPID, ObjectIdGetDatum(opno), + CharGetDatum(AMOP_SEARCH), ObjectIdGetDatum(opfamily)); } @@ -60,6 +63,8 @@ op_in_opfamily(Oid opno, Oid opfamily) * * Get the operator's strategy number within the specified opfamily, * or 0 if it's not a member of the opfamily. + * + * This function only considers search operators, not ordering operators. */ int get_op_opfamily_strategy(Oid opno, Oid opfamily) @@ -68,8 +73,9 @@ get_op_opfamily_strategy(Oid opno, Oid opfamily) Form_pg_amop amop_tup; int result; - tp = SearchSysCache2(AMOPOPID, + tp = SearchSysCache3(AMOPOPID, ObjectIdGetDatum(opno), + CharGetDatum(AMOP_SEARCH), ObjectIdGetDatum(opfamily)); if (!HeapTupleIsValid(tp)) return 0; @@ -85,6 +91,8 @@ get_op_opfamily_strategy(Oid opno, Oid opfamily) * Get the operator's strategy number and declared input data types * within the specified opfamily. * + * This function only considers search operators, not ordering operators. + * * Caller should already have verified that opno is a member of opfamily, * therefore we raise an error if the tuple is not found. */ @@ -97,8 +105,9 @@ get_op_opfamily_properties(Oid opno, Oid opfamily, HeapTuple tp; Form_pg_amop amop_tup; - tp = SearchSysCache2(AMOPOPID, + tp = SearchSysCache3(AMOPOPID, ObjectIdGetDatum(opno), + CharGetDatum(AMOP_SEARCH), ObjectIdGetDatum(opfamily)); if (!HeapTupleIsValid(tp)) elog(ERROR, "operator %u is not a member of opfamily %u", diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 94bef7dd01..08a14431b1 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -135,11 +135,11 @@ static const struct cachedesc cacheinfo[] = { }, {AccessMethodOperatorRelationId, /* AMOPOPID */ AccessMethodOperatorIndexId, - 2, + 3, { Anum_pg_amop_amopopr, + Anum_pg_amop_amoppurpose, Anum_pg_amop_amopfamily, - 0, 0 }, 64 diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 3bca417cef..66274b442e 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -8815,22 +8815,28 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) int i_opckeytype; int i_opcdefault; int i_opcfamily; + int i_opcfamilyname; int i_opcfamilynsp; int i_amname; int i_amopstrategy; int i_amopreqcheck; int i_amopopr; + int i_sortfamily; + int i_sortfamilynsp; int i_amprocnum; int i_amproc; char *opcintype; char *opckeytype; char *opcdefault; char *opcfamily; + char *opcfamilyname; char *opcfamilynsp; char *amname; char *amopstrategy; char *amopreqcheck; char *amopopr; + char *sortfamily; + char *sortfamilynsp; char *amprocnum; char *amproc; bool needComma; @@ -8860,8 +8866,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) { appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, " "opckeytype::pg_catalog.regtype, " - "opcdefault, " - "opfname AS opcfamily, " + "opcdefault, opcfamily, " + "opfname AS opcfamilyname, " "nspname AS opcfamilynsp, " "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname " "FROM pg_catalog.pg_opclass c " @@ -8874,8 +8880,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) { appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, " "opckeytype::pg_catalog.regtype, " - "opcdefault, " - "NULL AS opcfamily, " + "opcdefault, NULL AS opcfamily, " + "NULL AS opcfamilyname, " "NULL AS opcfamilynsp, " "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname " "FROM pg_catalog.pg_opclass " @@ -8901,13 +8907,16 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) i_opckeytype = PQfnumber(res, "opckeytype"); i_opcdefault = PQfnumber(res, "opcdefault"); i_opcfamily = PQfnumber(res, "opcfamily"); + i_opcfamilyname = PQfnumber(res, "opcfamilyname"); i_opcfamilynsp = PQfnumber(res, "opcfamilynsp"); i_amname = PQfnumber(res, "amname"); opcintype = PQgetvalue(res, 0, i_opcintype); opckeytype = PQgetvalue(res, 0, i_opckeytype); opcdefault = PQgetvalue(res, 0, i_opcdefault); - opcfamily = PQgetvalue(res, 0, i_opcfamily); + /* opcfamily will still be needed after we PQclear res */ + opcfamily = strdup(PQgetvalue(res, 0, i_opcfamily)); + opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname); opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp); /* amname will still be needed after we PQclear res */ amname = strdup(PQgetvalue(res, 0, i_amname)); @@ -8930,14 +8939,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) appendPQExpBuffer(q, "FOR TYPE %s USING %s", opcintype, fmtId(amname)); - if (strlen(opcfamily) > 0 && - (strcmp(opcfamily, opcinfo->dobj.name) != 0 || + if (strlen(opcfamilyname) > 0 && + (strcmp(opcfamilyname, opcinfo->dobj.name) != 0 || strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)) { appendPQExpBuffer(q, " FAMILY "); if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0) appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp)); - appendPQExpBuffer(q, "%s", fmtId(opcfamily)); + appendPQExpBuffer(q, "%s", fmtId(opcfamilyname)); } appendPQExpBuffer(q, " AS\n "); @@ -8954,23 +8963,41 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) /* * Now fetch and print the OPERATOR entries (pg_amop rows). + * + * Print only those opfamily members that are tied to the opclass by + * pg_depend entries. + * + * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping + * an older server's opclass in which it is used. This is to avoid + * hard-to-detect breakage if a newer pg_dump is used to dump from an + * older server and then reload into that old version. This can go + * away once 8.3 is so old as to not be of interest to anyone. */ resetPQExpBuffer(query); - if (g_fout->remoteVersion >= 80400) + if (g_fout->remoteVersion >= 90100) + { + appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, " + "amopopr::pg_catalog.regoperator, " + "opfname AS sortfamily, " + "nspname AS sortfamilynsp " + "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON " + "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) " + "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily " + "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace " + "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass " + "AND refobjid = '%u'::pg_catalog.oid " + "AND amopfamily = '%s'::pg_catalog.oid " + "ORDER BY amopstrategy", + opcinfo->dobj.catId.oid, + opcfamily); + } + else if (g_fout->remoteVersion >= 80400) { - /* - * Print only those opfamily members that are tied to the opclass by - * pg_depend entries. - * - * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping - * an older server's opclass in which it is used. This is to avoid - * hard-to-detect breakage if a newer pg_dump is used to dump from an - * older server and then reload into that old version. This can go - * 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, " + "NULL AS sortfamily, " + "NULL AS sortfamilynsp " "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 " @@ -8981,12 +9008,10 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) } else if (g_fout->remoteVersion >= 80300) { - /* - * Print only those opfamily members that are tied to the opclass by - * pg_depend entries. - */ appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, " - "amopopr::pg_catalog.regoperator " + "amopopr::pg_catalog.regoperator, " + "NULL AS sortfamily, " + "NULL AS sortfamilynsp " "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 " @@ -8997,8 +9022,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) } else { + /* + * Here, we print all entries since there are no opfamilies and + * hence no loose operators to worry about. + */ appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, " - "amopopr::pg_catalog.regoperator " + "amopopr::pg_catalog.regoperator, " + "NULL AS sortfamily, " + "NULL AS sortfamilynsp " "FROM pg_catalog.pg_amop " "WHERE amopclaid = '%u'::pg_catalog.oid " "ORDER BY amopstrategy", @@ -9013,18 +9044,31 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) i_amopstrategy = PQfnumber(res, "amopstrategy"); i_amopreqcheck = PQfnumber(res, "amopreqcheck"); i_amopopr = PQfnumber(res, "amopopr"); + i_sortfamily = PQfnumber(res, "sortfamily"); + i_sortfamilynsp = PQfnumber(res, "sortfamilynsp"); for (i = 0; i < ntups; i++) { amopstrategy = PQgetvalue(res, i, i_amopstrategy); amopreqcheck = PQgetvalue(res, i, i_amopreqcheck); amopopr = PQgetvalue(res, i, i_amopopr); + sortfamily = PQgetvalue(res, i, i_sortfamily); + sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp); if (needComma) appendPQExpBuffer(q, " ,\n "); appendPQExpBuffer(q, "OPERATOR %s %s", amopstrategy, amopopr); + + if (strlen(sortfamily) > 0) + { + appendPQExpBuffer(q, " FOR ORDER BY "); + if (strcmp(sortfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0) + appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp)); + appendPQExpBuffer(q, "%s", fmtId(sortfamily)); + } + if (strcmp(amopreqcheck, "t") == 0) appendPQExpBuffer(q, " RECHECK"); @@ -9035,15 +9079,14 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) /* * Now fetch and print the FUNCTION entries (pg_amproc rows). + * + * Print only those opfamily members that are tied to the opclass by + * pg_depend entries. */ resetPQExpBuffer(query); if (g_fout->remoteVersion >= 80300) { - /* - * Print only those opfamily members that are tied to the opclass by - * pg_depend entries. - */ appendPQExpBuffer(query, "SELECT amprocnum, " "amproc::pg_catalog.regprocedure " "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend " @@ -9119,6 +9162,9 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) /* * dumpOpfamily * write out a single operator family definition + * + * Note: this also dumps any "loose" operator members that aren't bound to a + * specific opclass within the opfamily. */ static void dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) @@ -9134,6 +9180,8 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) int i_amopstrategy; int i_amopreqcheck; int i_amopopr; + int i_sortfamily; + int i_sortfamilynsp; int i_amprocnum; int i_amproc; int i_amproclefttype; @@ -9142,6 +9190,8 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) char *amopstrategy; char *amopreqcheck; char *amopopr; + char *sortfamily; + char *sortfamilynsp; char *amprocnum; char *amproc; char *amproclefttype; @@ -9172,18 +9222,36 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) /* * Fetch only those opfamily members that are tied directly to the * opfamily by pg_depend entries. + * + * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping + * an older server's opclass in which it is used. This is to avoid + * hard-to-detect breakage if a newer pg_dump is used to dump from an + * older server and then reload into that old version. This can go + * away once 8.3 is so old as to not be of interest to anyone. */ - if (g_fout->remoteVersion >= 80400) + if (g_fout->remoteVersion >= 90100) { - /* - * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping - * an older server's opclass in which it is used. This is to avoid - * hard-to-detect breakage if a newer pg_dump is used to dump from an - * older server and then reload into that old version. This can go - * 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, " + "opfname AS sortfamily, " + "nspname AS sortfamilynsp " + "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON " + "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) " + "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily " + "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace " + "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass " + "AND refobjid = '%u'::pg_catalog.oid " + "AND amopfamily = '%u'::pg_catalog.oid " + "ORDER BY amopstrategy", + opfinfo->dobj.catId.oid, + opfinfo->dobj.catId.oid); + } + else if (g_fout->remoteVersion >= 80400) + { + appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, " + "amopopr::pg_catalog.regoperator, " + "NULL AS sortfamily, " + "NULL AS sortfamilynsp " "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 +9263,9 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) else { appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, " - "amopopr::pg_catalog.regoperator " + "amopopr::pg_catalog.regoperator, " + "NULL AS sortfamily, " + "NULL AS sortfamilynsp " "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,18 +9393,31 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) i_amopstrategy = PQfnumber(res_ops, "amopstrategy"); i_amopreqcheck = PQfnumber(res_ops, "amopreqcheck"); i_amopopr = PQfnumber(res_ops, "amopopr"); + i_sortfamily = PQfnumber(res_ops, "sortfamily"); + i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp"); 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); + sortfamily = PQgetvalue(res_ops, i, i_sortfamily); + sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp); if (needComma) appendPQExpBuffer(q, " ,\n "); appendPQExpBuffer(q, "OPERATOR %s %s", amopstrategy, amopopr); + + if (strlen(sortfamily) > 0) + { + appendPQExpBuffer(q, " FOR ORDER BY "); + if (strcmp(sortfamilynsp, opfinfo->dobj.namespace->dobj.name) != 0) + appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp)); + appendPQExpBuffer(q, "%s", fmtId(sortfamily)); + } + if (strcmp(amopreqcheck, "t") == 0) appendPQExpBuffer(q, " RECHECK"); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 69f76aae0e..8698a43371 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201011211 +#define CATALOG_VERSION_NO 201011241 #endif diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index a3839e1e25..1542c8d5f4 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -67,7 +67,7 @@ DECLARE_UNIQUE_INDEX(pg_am_oid_index, 2652, on pg_am using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_amop_fam_strat_index, 2653, on pg_amop using btree(amopfamily oid_ops, amoplefttype oid_ops, amoprighttype oid_ops, amopstrategy int2_ops)); #define AccessMethodStrategyIndexId 2653 -DECLARE_UNIQUE_INDEX(pg_amop_opr_fam_index, 2654, on pg_amop using btree(amopopr oid_ops, amopfamily oid_ops)); +DECLARE_UNIQUE_INDEX(pg_amop_opr_fam_index, 2654, on pg_amop using btree(amopopr oid_ops, amoppurpose char_ops, amopfamily oid_ops)); #define AccessMethodOperatorIndexId 2654 DECLARE_UNIQUE_INDEX(pg_amop_oid_index, 2756, on pg_amop using btree(oid oid_ops)); #define AccessMethodOperatorOidIndexId 2756 diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index c9b8e2d766..5a18dee0bd 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -40,7 +40,8 @@ CATALOG(pg_am,2601) * assignments. */ int2 amsupport; /* total number of support functions that this * AM uses */ - bool amcanorder; /* does AM support ordered scan results? */ + bool amcanorder; /* does AM support order by column value? */ + bool amcanorderbyop; /* does AM support order by operator result? */ bool amcanbackward; /* does AM support backward scan? */ bool amcanunique; /* does AM support UNIQUE indexes? */ bool amcanmulticol; /* does AM support multi-column indexes? */ @@ -76,49 +77,50 @@ typedef FormData_pg_am *Form_pg_am; * compiler constants for pg_am * ---------------- */ -#define Natts_pg_am 26 +#define Natts_pg_am 27 #define Anum_pg_am_amname 1 #define Anum_pg_am_amstrategies 2 #define Anum_pg_am_amsupport 3 #define Anum_pg_am_amcanorder 4 -#define Anum_pg_am_amcanbackward 5 -#define Anum_pg_am_amcanunique 6 -#define Anum_pg_am_amcanmulticol 7 -#define Anum_pg_am_amoptionalkey 8 -#define Anum_pg_am_amindexnulls 9 -#define Anum_pg_am_amsearchnulls 10 -#define Anum_pg_am_amstorage 11 -#define Anum_pg_am_amclusterable 12 -#define Anum_pg_am_amkeytype 13 -#define Anum_pg_am_aminsert 14 -#define Anum_pg_am_ambeginscan 15 -#define Anum_pg_am_amgettuple 16 -#define Anum_pg_am_amgetbitmap 17 -#define Anum_pg_am_amrescan 18 -#define Anum_pg_am_amendscan 19 -#define Anum_pg_am_ammarkpos 20 -#define Anum_pg_am_amrestrpos 21 -#define Anum_pg_am_ambuild 22 -#define Anum_pg_am_ambulkdelete 23 -#define Anum_pg_am_amvacuumcleanup 24 -#define Anum_pg_am_amcostestimate 25 -#define Anum_pg_am_amoptions 26 +#define Anum_pg_am_amcanorderbyop 5 +#define Anum_pg_am_amcanbackward 6 +#define Anum_pg_am_amcanunique 7 +#define Anum_pg_am_amcanmulticol 8 +#define Anum_pg_am_amoptionalkey 9 +#define Anum_pg_am_amindexnulls 10 +#define Anum_pg_am_amsearchnulls 11 +#define Anum_pg_am_amstorage 12 +#define Anum_pg_am_amclusterable 13 +#define Anum_pg_am_amkeytype 14 +#define Anum_pg_am_aminsert 15 +#define Anum_pg_am_ambeginscan 16 +#define Anum_pg_am_amgettuple 17 +#define Anum_pg_am_amgetbitmap 18 +#define Anum_pg_am_amrescan 19 +#define Anum_pg_am_amendscan 20 +#define Anum_pg_am_ammarkpos 21 +#define Anum_pg_am_amrestrpos 22 +#define Anum_pg_am_ambuild 23 +#define Anum_pg_am_ambulkdelete 24 +#define Anum_pg_am_amvacuumcleanup 25 +#define Anum_pg_am_amcostestimate 26 +#define Anum_pg_am_amoptions 27 /* ---------------- * initial contents of pg_am * ---------------- */ -DATA(insert OID = 403 ( btree 5 1 t t t t t t t f t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate btoptions )); +DATA(insert OID = 403 ( btree 5 1 t f t t t t t t f t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate btoptions )); DESCR("b-tree index access method"); #define BTREE_AM_OID 403 -DATA(insert OID = 405 ( hash 1 1 f t f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions )); +DATA(insert OID = 405 ( hash 1 1 f f t f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions )); DESCR("hash index access method"); #define HASH_AM_OID 405 -DATA(insert OID = 783 ( gist 0 7 f f f t t t t t t 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions )); +DATA(insert OID = 783 ( gist 0 7 f f f f t t t t t t 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions )); DESCR("GiST index access method"); #define GIST_AM_OID 783 -DATA(insert OID = 2742 ( gin 0 5 f f f t t f f t f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoptions )); +DATA(insert OID = 2742 ( gin 0 5 f f f f t t f f t f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoptions )); DESCR("GIN index access method"); #define GIN_AM_OID 2742 diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index a9e70a2d6a..951f9cd6f2 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -5,7 +5,9 @@ * along with the relation's initial contents. * * The amop table identifies the operators associated with each index operator - * family and operator class (classes are subsets of families). + * family and operator class (classes are subsets of families). An associated + * operator can be either a search operator or an ordering operator, as + * identified by amoppurpose. * * The primary key for this table is . amoplefttype and amoprighttype are just copies of the @@ -16,11 +18,13 @@ * operators within a family are supposed to be compatible, in a way that is * defined by each individual index AM. * - * We also keep a unique index on , so that we can use a - * syscache to quickly answer questions of the form "is this operator in this - * opfamily, and if so what are its semantics with respect to the family?" - * This implies that the same operator cannot be listed for multiple strategy - * numbers within a single opfamily. + * We also keep a unique index on , so that + * we can use a syscache to quickly answer questions of the form "is this + * operator in this opfamily, and if so what are its semantics with respect to + * the family?" This implies that the same operator cannot be listed for + * multiple strategy numbers within a single opfamily, with the exception that + * it's possible to list it for both search and ordering purposes (with + * different strategy numbers for the two purposes). * * amopmethod is a copy of the owning opfamily's opfmethod field. This is an * intentional denormalization of the catalogs to buy lookup speed. @@ -55,10 +59,16 @@ CATALOG(pg_amop,2602) Oid amoplefttype; /* operator's left input data type */ Oid amoprighttype; /* operator's right input data type */ int2 amopstrategy; /* operator strategy number */ + char amoppurpose; /* is operator for 's'earch or 'o'rdering? */ Oid amopopr; /* the operator's pg_operator OID */ Oid amopmethod; /* the index access method this entry is for */ + Oid amopsortfamily; /* ordering opfamily OID, or 0 if search op */ } FormData_pg_amop; +/* allowed values of amoppurpose: */ +#define AMOP_SEARCH 's' /* operator is for search */ +#define AMOP_ORDER 'o' /* operator is for ordering */ + /* ---------------- * Form_pg_amop corresponds to a pointer to a tuple with * the format of pg_amop relation. @@ -70,13 +80,15 @@ typedef FormData_pg_amop *Form_pg_amop; * compiler constants for pg_amop * ---------------- */ -#define Natts_pg_amop 6 +#define Natts_pg_amop 8 #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 +#define Anum_pg_amop_amopsortfamily 8 /* ---------------- * initial contents of pg_amop @@ -88,612 +100,612 @@ 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 s 95 403 0 )); +DATA(insert ( 1976 21 21 2 s 522 403 0 )); +DATA(insert ( 1976 21 21 3 s 94 403 0 )); +DATA(insert ( 1976 21 21 4 s 524 403 0 )); +DATA(insert ( 1976 21 21 5 s 520 403 0 )); /* 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 s 534 403 0 )); +DATA(insert ( 1976 21 23 2 s 540 403 0 )); +DATA(insert ( 1976 21 23 3 s 532 403 0 )); +DATA(insert ( 1976 21 23 4 s 542 403 0 )); +DATA(insert ( 1976 21 23 5 s 536 403 0 )); /* 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 s 1864 403 0 )); +DATA(insert ( 1976 21 20 2 s 1866 403 0 )); +DATA(insert ( 1976 21 20 3 s 1862 403 0 )); +DATA(insert ( 1976 21 20 4 s 1867 403 0 )); +DATA(insert ( 1976 21 20 5 s 1865 403 0 )); /* 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 s 97 403 0 )); +DATA(insert ( 1976 23 23 2 s 523 403 0 )); +DATA(insert ( 1976 23 23 3 s 96 403 0 )); +DATA(insert ( 1976 23 23 4 s 525 403 0 )); +DATA(insert ( 1976 23 23 5 s 521 403 0 )); /* 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 s 535 403 0 )); +DATA(insert ( 1976 23 21 2 s 541 403 0 )); +DATA(insert ( 1976 23 21 3 s 533 403 0 )); +DATA(insert ( 1976 23 21 4 s 543 403 0 )); +DATA(insert ( 1976 23 21 5 s 537 403 0 )); /* 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 s 37 403 0 )); +DATA(insert ( 1976 23 20 2 s 80 403 0 )); +DATA(insert ( 1976 23 20 3 s 15 403 0 )); +DATA(insert ( 1976 23 20 4 s 82 403 0 )); +DATA(insert ( 1976 23 20 5 s 76 403 0 )); /* 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 s 412 403 0 )); +DATA(insert ( 1976 20 20 2 s 414 403 0 )); +DATA(insert ( 1976 20 20 3 s 410 403 0 )); +DATA(insert ( 1976 20 20 4 s 415 403 0 )); +DATA(insert ( 1976 20 20 5 s 413 403 0 )); /* 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 s 1870 403 0 )); +DATA(insert ( 1976 20 21 2 s 1872 403 0 )); +DATA(insert ( 1976 20 21 3 s 1868 403 0 )); +DATA(insert ( 1976 20 21 4 s 1873 403 0 )); +DATA(insert ( 1976 20 21 5 s 1871 403 0 )); /* 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 s 418 403 0 )); +DATA(insert ( 1976 20 23 2 s 420 403 0 )); +DATA(insert ( 1976 20 23 3 s 416 403 0 )); +DATA(insert ( 1976 20 23 4 s 430 403 0 )); +DATA(insert ( 1976 20 23 5 s 419 403 0 )); /* * 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 s 609 403 0 )); +DATA(insert ( 1989 26 26 2 s 611 403 0 )); +DATA(insert ( 1989 26 26 3 s 607 403 0 )); +DATA(insert ( 1989 26 26 4 s 612 403 0 )); +DATA(insert ( 1989 26 26 5 s 610 403 0 )); /* * 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 s 2799 403 0 )); +DATA(insert ( 2789 27 27 2 s 2801 403 0 )); +DATA(insert ( 2789 27 27 3 s 387 403 0 )); +DATA(insert ( 2789 27 27 4 s 2802 403 0 )); +DATA(insert ( 2789 27 27 5 s 2800 403 0 )); /* * 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 s 645 403 0 )); +DATA(insert ( 1991 30 30 2 s 647 403 0 )); +DATA(insert ( 1991 30 30 3 s 649 403 0 )); +DATA(insert ( 1991 30 30 4 s 648 403 0 )); +DATA(insert ( 1991 30 30 5 s 646 403 0 )); /* * 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 s 622 403 0 )); +DATA(insert ( 1970 700 700 2 s 624 403 0 )); +DATA(insert ( 1970 700 700 3 s 620 403 0 )); +DATA(insert ( 1970 700 700 4 s 625 403 0 )); +DATA(insert ( 1970 700 700 5 s 623 403 0 )); /* 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 s 1122 403 0 )); +DATA(insert ( 1970 700 701 2 s 1124 403 0 )); +DATA(insert ( 1970 700 701 3 s 1120 403 0 )); +DATA(insert ( 1970 700 701 4 s 1125 403 0 )); +DATA(insert ( 1970 700 701 5 s 1123 403 0 )); /* 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 s 672 403 0 )); +DATA(insert ( 1970 701 701 2 s 673 403 0 )); +DATA(insert ( 1970 701 701 3 s 670 403 0 )); +DATA(insert ( 1970 701 701 4 s 675 403 0 )); +DATA(insert ( 1970 701 701 5 s 674 403 0 )); /* 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 s 1132 403 0 )); +DATA(insert ( 1970 701 700 2 s 1134 403 0 )); +DATA(insert ( 1970 701 700 3 s 1130 403 0 )); +DATA(insert ( 1970 701 700 4 s 1135 403 0 )); +DATA(insert ( 1970 701 700 5 s 1133 403 0 )); /* * 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 s 631 403 0 )); +DATA(insert ( 429 18 18 2 s 632 403 0 )); +DATA(insert ( 429 18 18 3 s 92 403 0 )); +DATA(insert ( 429 18 18 4 s 634 403 0 )); +DATA(insert ( 429 18 18 5 s 633 403 0 )); /* * 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 s 660 403 0 )); +DATA(insert ( 1986 19 19 2 s 661 403 0 )); +DATA(insert ( 1986 19 19 3 s 93 403 0 )); +DATA(insert ( 1986 19 19 4 s 663 403 0 )); +DATA(insert ( 1986 19 19 5 s 662 403 0 )); /* * 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 s 664 403 0 )); +DATA(insert ( 1994 25 25 2 s 665 403 0 )); +DATA(insert ( 1994 25 25 3 s 98 403 0 )); +DATA(insert ( 1994 25 25 4 s 667 403 0 )); +DATA(insert ( 1994 25 25 5 s 666 403 0 )); /* * 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 s 1058 403 0 )); +DATA(insert ( 426 1042 1042 2 s 1059 403 0 )); +DATA(insert ( 426 1042 1042 3 s 1054 403 0 )); +DATA(insert ( 426 1042 1042 4 s 1061 403 0 )); +DATA(insert ( 426 1042 1042 5 s 1060 403 0 )); /* * 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 s 1957 403 0 )); +DATA(insert ( 428 17 17 2 s 1958 403 0 )); +DATA(insert ( 428 17 17 3 s 1955 403 0 )); +DATA(insert ( 428 17 17 4 s 1960 403 0 )); +DATA(insert ( 428 17 17 5 s 1959 403 0 )); /* * 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 s 562 403 0 )); +DATA(insert ( 421 702 702 2 s 564 403 0 )); +DATA(insert ( 421 702 702 3 s 560 403 0 )); +DATA(insert ( 421 702 702 4 s 565 403 0 )); +DATA(insert ( 421 702 702 5 s 563 403 0 )); /* * 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 s 1095 403 0 )); +DATA(insert ( 434 1082 1082 2 s 1096 403 0 )); +DATA(insert ( 434 1082 1082 3 s 1093 403 0 )); +DATA(insert ( 434 1082 1082 4 s 1098 403 0 )); +DATA(insert ( 434 1082 1082 5 s 1097 403 0 )); /* 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 s 2345 403 0 )); +DATA(insert ( 434 1082 1114 2 s 2346 403 0 )); +DATA(insert ( 434 1082 1114 3 s 2347 403 0 )); +DATA(insert ( 434 1082 1114 4 s 2348 403 0 )); +DATA(insert ( 434 1082 1114 5 s 2349 403 0 )); /* 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 s 2358 403 0 )); +DATA(insert ( 434 1082 1184 2 s 2359 403 0 )); +DATA(insert ( 434 1082 1184 3 s 2360 403 0 )); +DATA(insert ( 434 1082 1184 4 s 2361 403 0 )); +DATA(insert ( 434 1082 1184 5 s 2362 403 0 )); /* 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 s 2062 403 0 )); +DATA(insert ( 434 1114 1114 2 s 2063 403 0 )); +DATA(insert ( 434 1114 1114 3 s 2060 403 0 )); +DATA(insert ( 434 1114 1114 4 s 2065 403 0 )); +DATA(insert ( 434 1114 1114 5 s 2064 403 0 )); /* 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 s 2371 403 0 )); +DATA(insert ( 434 1114 1082 2 s 2372 403 0 )); +DATA(insert ( 434 1114 1082 3 s 2373 403 0 )); +DATA(insert ( 434 1114 1082 4 s 2374 403 0 )); +DATA(insert ( 434 1114 1082 5 s 2375 403 0 )); /* 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 s 2534 403 0 )); +DATA(insert ( 434 1114 1184 2 s 2535 403 0 )); +DATA(insert ( 434 1114 1184 3 s 2536 403 0 )); +DATA(insert ( 434 1114 1184 4 s 2537 403 0 )); +DATA(insert ( 434 1114 1184 5 s 2538 403 0 )); /* 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 s 1322 403 0 )); +DATA(insert ( 434 1184 1184 2 s 1323 403 0 )); +DATA(insert ( 434 1184 1184 3 s 1320 403 0 )); +DATA(insert ( 434 1184 1184 4 s 1325 403 0 )); +DATA(insert ( 434 1184 1184 5 s 1324 403 0 )); /* 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 s 2384 403 0 )); +DATA(insert ( 434 1184 1082 2 s 2385 403 0 )); +DATA(insert ( 434 1184 1082 3 s 2386 403 0 )); +DATA(insert ( 434 1184 1082 4 s 2387 403 0 )); +DATA(insert ( 434 1184 1082 5 s 2388 403 0 )); /* 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 s 2540 403 0 )); +DATA(insert ( 434 1184 1114 2 s 2541 403 0 )); +DATA(insert ( 434 1184 1114 3 s 2542 403 0 )); +DATA(insert ( 434 1184 1114 4 s 2543 403 0 )); +DATA(insert ( 434 1184 1114 5 s 2544 403 0 )); /* * 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 s 1110 403 0 )); +DATA(insert ( 1996 1083 1083 2 s 1111 403 0 )); +DATA(insert ( 1996 1083 1083 3 s 1108 403 0 )); +DATA(insert ( 1996 1083 1083 4 s 1113 403 0 )); +DATA(insert ( 1996 1083 1083 5 s 1112 403 0 )); /* * 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 s 1552 403 0 )); +DATA(insert ( 2000 1266 1266 2 s 1553 403 0 )); +DATA(insert ( 2000 1266 1266 3 s 1550 403 0 )); +DATA(insert ( 2000 1266 1266 4 s 1555 403 0 )); +DATA(insert ( 2000 1266 1266 5 s 1554 403 0 )); /* * 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 s 1332 403 0 )); +DATA(insert ( 1982 1186 1186 2 s 1333 403 0 )); +DATA(insert ( 1982 1186 1186 3 s 1330 403 0 )); +DATA(insert ( 1982 1186 1186 4 s 1335 403 0 )); +DATA(insert ( 1982 1186 1186 5 s 1334 403 0 )); /* * 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 s 1222 403 0 )); +DATA(insert ( 1984 829 829 2 s 1223 403 0 )); +DATA(insert ( 1984 829 829 3 s 1220 403 0 )); +DATA(insert ( 1984 829 829 4 s 1225 403 0 )); +DATA(insert ( 1984 829 829 5 s 1224 403 0 )); /* * 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 s 1203 403 0 )); +DATA(insert ( 1974 869 869 2 s 1204 403 0 )); +DATA(insert ( 1974 869 869 3 s 1201 403 0 )); +DATA(insert ( 1974 869 869 4 s 1206 403 0 )); +DATA(insert ( 1974 869 869 5 s 1205 403 0 )); /* * 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 s 1754 403 0 )); +DATA(insert ( 1988 1700 1700 2 s 1755 403 0 )); +DATA(insert ( 1988 1700 1700 3 s 1752 403 0 )); +DATA(insert ( 1988 1700 1700 4 s 1757 403 0 )); +DATA(insert ( 1988 1700 1700 5 s 1756 403 0 )); /* * 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 s 58 403 0 )); +DATA(insert ( 424 16 16 2 s 1694 403 0 )); +DATA(insert ( 424 16 16 3 s 91 403 0 )); +DATA(insert ( 424 16 16 4 s 1695 403 0 )); +DATA(insert ( 424 16 16 5 s 59 403 0 )); /* * 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 s 1786 403 0 )); +DATA(insert ( 423 1560 1560 2 s 1788 403 0 )); +DATA(insert ( 423 1560 1560 3 s 1784 403 0 )); +DATA(insert ( 423 1560 1560 4 s 1789 403 0 )); +DATA(insert ( 423 1560 1560 5 s 1787 403 0 )); /* * 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 s 1806 403 0 )); +DATA(insert ( 2002 1562 1562 2 s 1808 403 0 )); +DATA(insert ( 2002 1562 1562 3 s 1804 403 0 )); +DATA(insert ( 2002 1562 1562 4 s 1809 403 0 )); +DATA(insert ( 2002 1562 1562 5 s 1807 403 0 )); /* * 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 s 2314 403 0 )); +DATA(insert ( 2095 25 25 2 s 2315 403 0 )); +DATA(insert ( 2095 25 25 3 s 98 403 0 )); +DATA(insert ( 2095 25 25 4 s 2317 403 0 )); +DATA(insert ( 2095 25 25 5 s 2318 403 0 )); /* * 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 s 2326 403 0 )); +DATA(insert ( 2097 1042 1042 2 s 2327 403 0 )); +DATA(insert ( 2097 1042 1042 3 s 1054 403 0 )); +DATA(insert ( 2097 1042 1042 4 s 2329 403 0 )); +DATA(insert ( 2097 1042 1042 5 s 2330 403 0 )); /* * 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 s 902 403 0 )); +DATA(insert ( 2099 790 790 2 s 904 403 0 )); +DATA(insert ( 2099 790 790 3 s 900 403 0 )); +DATA(insert ( 2099 790 790 4 s 905 403 0 )); +DATA(insert ( 2099 790 790 5 s 903 403 0 )); /* * 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 s 568 403 0 )); +DATA(insert ( 2233 703 703 2 s 570 403 0 )); +DATA(insert ( 2233 703 703 3 s 566 403 0 )); +DATA(insert ( 2233 703 703 4 s 571 403 0 )); +DATA(insert ( 2233 703 703 5 s 569 403 0 )); /* * 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 s 813 403 0 )); +DATA(insert ( 2234 704 704 2 s 815 403 0 )); +DATA(insert ( 2234 704 704 3 s 811 403 0 )); +DATA(insert ( 2234 704 704 4 s 816 403 0 )); +DATA(insert ( 2234 704 704 5 s 814 403 0 )); /* * 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 s 1072 403 0 )); +DATA(insert ( 397 2277 2277 2 s 1074 403 0 )); +DATA(insert ( 397 2277 2277 3 s 1070 403 0 )); +DATA(insert ( 397 2277 2277 4 s 1075 403 0 )); +DATA(insert ( 397 2277 2277 5 s 1073 403 0 )); /* * 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 s 2990 403 0 )); +DATA(insert ( 2994 2249 2249 2 s 2992 403 0 )); +DATA(insert ( 2994 2249 2249 3 s 2988 403 0 )); +DATA(insert ( 2994 2249 2249 4 s 2993 403 0 )); +DATA(insert ( 2994 2249 2249 5 s 2991 403 0 )); /* * 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 s 2974 403 0 )); +DATA(insert ( 2968 2950 2950 2 s 2976 403 0 )); +DATA(insert ( 2968 2950 2950 3 s 2972 403 0 )); +DATA(insert ( 2968 2950 2950 4 s 2977 403 0 )); +DATA(insert ( 2968 2950 2950 5 s 2975 403 0 )); /* * hash index _ops */ /* bpchar_ops */ -DATA(insert ( 427 1042 1042 1 1054 405 )); +DATA(insert ( 427 1042 1042 1 s 1054 405 0 )); /* char_ops */ -DATA(insert ( 431 18 18 1 92 405 )); +DATA(insert ( 431 18 18 1 s 92 405 0 )); /* date_ops */ -DATA(insert ( 435 1082 1082 1 1093 405 )); +DATA(insert ( 435 1082 1082 1 s 1093 405 0 )); /* 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 s 620 405 0 )); +DATA(insert ( 1971 701 701 1 s 670 405 0 )); +DATA(insert ( 1971 700 701 1 s 1120 405 0 )); +DATA(insert ( 1971 701 700 1 s 1130 405 0 )); /* network_ops */ -DATA(insert ( 1975 869 869 1 1201 405 )); +DATA(insert ( 1975 869 869 1 s 1201 405 0 )); /* 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 s 94 405 0 )); +DATA(insert ( 1977 23 23 1 s 96 405 0 )); +DATA(insert ( 1977 20 20 1 s 410 405 0 )); +DATA(insert ( 1977 21 23 1 s 532 405 0 )); +DATA(insert ( 1977 21 20 1 s 1862 405 0 )); +DATA(insert ( 1977 23 21 1 s 533 405 0 )); +DATA(insert ( 1977 23 20 1 s 15 405 0 )); +DATA(insert ( 1977 20 21 1 s 1868 405 0 )); +DATA(insert ( 1977 20 23 1 s 416 405 0 )); /* interval_ops */ -DATA(insert ( 1983 1186 1186 1 1330 405 )); +DATA(insert ( 1983 1186 1186 1 s 1330 405 0 )); /* macaddr_ops */ -DATA(insert ( 1985 829 829 1 1220 405 )); +DATA(insert ( 1985 829 829 1 s 1220 405 0 )); /* name_ops */ -DATA(insert ( 1987 19 19 1 93 405 )); +DATA(insert ( 1987 19 19 1 s 93 405 0 )); /* oid_ops */ -DATA(insert ( 1990 26 26 1 607 405 )); +DATA(insert ( 1990 26 26 1 s 607 405 0 )); /* oidvector_ops */ -DATA(insert ( 1992 30 30 1 649 405 )); +DATA(insert ( 1992 30 30 1 s 649 405 0 )); /* text_ops */ -DATA(insert ( 1995 25 25 1 98 405 )); +DATA(insert ( 1995 25 25 1 s 98 405 0 )); /* time_ops */ -DATA(insert ( 1997 1083 1083 1 1108 405 )); +DATA(insert ( 1997 1083 1083 1 s 1108 405 0 )); /* timestamptz_ops */ -DATA(insert ( 1999 1184 1184 1 1320 405 )); +DATA(insert ( 1999 1184 1184 1 s 1320 405 0 )); /* timetz_ops */ -DATA(insert ( 2001 1266 1266 1 1550 405 )); +DATA(insert ( 2001 1266 1266 1 s 1550 405 0 )); /* timestamp_ops */ -DATA(insert ( 2040 1114 1114 1 2060 405 )); +DATA(insert ( 2040 1114 1114 1 s 2060 405 0 )); /* bool_ops */ -DATA(insert ( 2222 16 16 1 91 405 )); +DATA(insert ( 2222 16 16 1 s 91 405 0 )); /* bytea_ops */ -DATA(insert ( 2223 17 17 1 1955 405 )); +DATA(insert ( 2223 17 17 1 s 1955 405 0 )); /* int2vector_ops */ -DATA(insert ( 2224 22 22 1 386 405 )); +DATA(insert ( 2224 22 22 1 s 386 405 0 )); /* xid_ops */ -DATA(insert ( 2225 28 28 1 352 405 )); +DATA(insert ( 2225 28 28 1 s 352 405 0 )); /* cid_ops */ -DATA(insert ( 2226 29 29 1 385 405 )); +DATA(insert ( 2226 29 29 1 s 385 405 0 )); /* abstime_ops */ -DATA(insert ( 2227 702 702 1 560 405 )); +DATA(insert ( 2227 702 702 1 s 560 405 0 )); /* reltime_ops */ -DATA(insert ( 2228 703 703 1 566 405 )); +DATA(insert ( 2228 703 703 1 s 566 405 0 )); /* text_pattern_ops */ -DATA(insert ( 2229 25 25 1 98 405 )); +DATA(insert ( 2229 25 25 1 s 98 405 0 )); /* bpchar_pattern_ops */ -DATA(insert ( 2231 1042 1042 1 1054 405 )); +DATA(insert ( 2231 1042 1042 1 s 1054 405 0 )); /* aclitem_ops */ -DATA(insert ( 2235 1033 1033 1 974 405 )); +DATA(insert ( 2235 1033 1033 1 s 974 405 0 )); /* uuid_ops */ -DATA(insert ( 2969 2950 2950 1 2972 405 )); +DATA(insert ( 2969 2950 2950 1 s 2972 405 0 )); /* numeric_ops */ -DATA(insert ( 1998 1700 1700 1 1752 405 )); +DATA(insert ( 1998 1700 1700 1 s 1752 405 0 )); /* array_ops */ -DATA(insert ( 627 2277 2277 1 1070 405 )); +DATA(insert ( 627 2277 2277 1 s 1070 405 0 )); /* * 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 s 493 783 0 )); +DATA(insert ( 2593 603 603 2 s 494 783 0 )); +DATA(insert ( 2593 603 603 3 s 500 783 0 )); +DATA(insert ( 2593 603 603 4 s 495 783 0 )); +DATA(insert ( 2593 603 603 5 s 496 783 0 )); +DATA(insert ( 2593 603 603 6 s 499 783 0 )); +DATA(insert ( 2593 603 603 7 s 498 783 0 )); +DATA(insert ( 2593 603 603 8 s 497 783 0 )); +DATA(insert ( 2593 603 603 9 s 2571 783 0 )); +DATA(insert ( 2593 603 603 10 s 2570 783 0 )); +DATA(insert ( 2593 603 603 11 s 2573 783 0 )); +DATA(insert ( 2593 603 603 12 s 2572 783 0 )); +DATA(insert ( 2593 603 603 13 s 2863 783 0 )); +DATA(insert ( 2593 603 603 14 s 2862 783 0 )); /* * 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 s 506 783 0 )); +DATA(insert ( 1029 600 600 1 s 507 783 0 )); +DATA(insert ( 1029 600 600 5 s 508 783 0 )); +DATA(insert ( 1029 600 600 10 s 509 783 0 )); +DATA(insert ( 1029 600 600 6 s 510 783 0 )); +DATA(insert ( 1029 603 600 27 s 433 783 0 )); +DATA(insert ( 1029 600 603 28 s 511 783 0 )); +DATA(insert ( 1029 604 600 47 s 757 783 0 )); +DATA(insert ( 1029 600 604 48 s 756 783 0 )); +DATA(insert ( 1029 718 600 67 s 759 783 0 )); +DATA(insert ( 1029 600 718 68 s 758 783 0 )); /* * 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 s 485 783 0 )); +DATA(insert ( 2594 604 604 2 s 486 783 0 )); +DATA(insert ( 2594 604 604 3 s 492 783 0 )); +DATA(insert ( 2594 604 604 4 s 487 783 0 )); +DATA(insert ( 2594 604 604 5 s 488 783 0 )); +DATA(insert ( 2594 604 604 6 s 491 783 0 )); +DATA(insert ( 2594 604 604 7 s 490 783 0 )); +DATA(insert ( 2594 604 604 8 s 489 783 0 )); +DATA(insert ( 2594 604 604 9 s 2575 783 0 )); +DATA(insert ( 2594 604 604 10 s 2574 783 0 )); +DATA(insert ( 2594 604 604 11 s 2577 783 0 )); +DATA(insert ( 2594 604 604 12 s 2576 783 0 )); +DATA(insert ( 2594 604 604 13 s 2861 783 0 )); +DATA(insert ( 2594 604 604 14 s 2860 783 0 )); /* * 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 s 1506 783 0 )); +DATA(insert ( 2595 718 718 2 s 1507 783 0 )); +DATA(insert ( 2595 718 718 3 s 1513 783 0 )); +DATA(insert ( 2595 718 718 4 s 1508 783 0 )); +DATA(insert ( 2595 718 718 5 s 1509 783 0 )); +DATA(insert ( 2595 718 718 6 s 1512 783 0 )); +DATA(insert ( 2595 718 718 7 s 1511 783 0 )); +DATA(insert ( 2595 718 718 8 s 1510 783 0 )); +DATA(insert ( 2595 718 718 9 s 2589 783 0 )); +DATA(insert ( 2595 718 718 10 s 1515 783 0 )); +DATA(insert ( 2595 718 718 11 s 1514 783 0 )); +DATA(insert ( 2595 718 718 12 s 2590 783 0 )); +DATA(insert ( 2595 718 718 13 s 2865 783 0 )); +DATA(insert ( 2595 718 718 14 s 2864 783 0 )); /* * 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 s 2750 2742 0 )); +DATA(insert ( 2745 2277 2277 2 s 2751 2742 0 )); +DATA(insert ( 2745 2277 2277 3 s 2752 2742 0 )); +DATA(insert ( 2745 2277 2277 4 s 1070 2742 0 )); /* * 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 s 3518 403 0 )); +DATA(insert ( 3522 3500 3500 2 s 3520 403 0 )); +DATA(insert ( 3522 3500 3500 3 s 3516 403 0 )); +DATA(insert ( 3522 3500 3500 4 s 3521 403 0 )); +DATA(insert ( 3522 3500 3500 5 s 3519 403 0 )); /* * hash enum_ops */ -DATA(insert ( 3523 3500 3500 1 3516 405 )); +DATA(insert ( 3523 3500 3500 1 s 3516 405 0 )); /* * 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 s 3627 403 0 )); +DATA(insert ( 3626 3614 3614 2 s 3628 403 0 )); +DATA(insert ( 3626 3614 3614 3 s 3629 403 0 )); +DATA(insert ( 3626 3614 3614 4 s 3631 403 0 )); +DATA(insert ( 3626 3614 3614 5 s 3632 403 0 )); /* * GiST tsvector_ops */ -DATA(insert ( 3655 3614 3615 1 3636 783 )); +DATA(insert ( 3655 3614 3615 1 s 3636 783 0 )); /* * 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 s 3636 2742 0 )); +DATA(insert ( 3659 3614 3615 2 s 3660 2742 0 )); /* * 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 s 3674 403 0 )); +DATA(insert ( 3683 3615 3615 2 s 3675 403 0 )); +DATA(insert ( 3683 3615 3615 3 s 3676 403 0 )); +DATA(insert ( 3683 3615 3615 4 s 3678 403 0 )); +DATA(insert ( 3683 3615 3615 5 s 3679 403 0 )); /* * 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 s 3693 783 0 )); +DATA(insert ( 3702 3615 3615 8 s 3694 783 0 )); #endif /* PG_AMOP_H */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index d6cfafea71..8b34b76300 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1776,6 +1776,7 @@ typedef struct CreateOpClassItem List *name; /* operator or function name */ List *args; /* argument types */ int number; /* strategy num or support proc num */ + List *order_family; /* only used for ordering operators */ List *class_args; /* only used for functions */ /* fields used for a storagetype item: */ TypeName *storedtype; /* datatype stored in index */ diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 677134dcec..785acc955a 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -469,6 +469,7 @@ typedef struct IndexOptInfo bool predOK; /* true if predicate matches query */ bool unique; /* true if a unique index */ + bool amcanorderbyop; /* does AM support order by operator result? */ bool amoptionalkey; /* can query omit key for the first column? */ bool amsearchnulls; /* can AM search for NULL/NOT NULL entries? */ bool amhasgettuple; /* does AM have amgettuple interface? */ diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 4703d497c1..2176ea47da 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -849,6 +849,14 @@ WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0 ------------+-------------- (0 rows) +SELECT p1.amopfamily, p1.amopstrategy +FROM pg_amop as p1 +WHERE NOT ((p1.amoppurpose = 's' AND p1.amopsortfamily = 0) OR + (p1.amoppurpose = 'o' AND p1.amopsortfamily <> 0)); + amopfamily | amopstrategy +------------+-------------- +(0 rows) + -- amoplefttype/amoprighttype must match the operator SELECT p1.oid, p2.oid FROM pg_amop AS p1, pg_operator AS p2 @@ -866,6 +874,25 @@ WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod; -----+----- (0 rows) +-- amopsortfamily, if present, must reference a btree family +SELECT p1.amopfamily, p1.amopstrategy +FROM pg_amop AS p1 +WHERE p1.amopsortfamily <> 0 AND NOT EXISTS + (SELECT 1 from pg_opfamily op WHERE op.oid = p1.amopsortfamily + AND op.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')); + amopfamily | amopstrategy +------------+-------------- +(0 rows) + +-- check for ordering operators not supported by parent AM +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname +FROM pg_amop AS p1, pg_am AS p2 +WHERE p1.amopmethod = p2.oid AND + p1.amoppurpose = 'o' AND NOT p2.amcanorderbyop; + amopfamily | amopopr | oid | amname +------------+---------+-----+-------- +(0 rows) + -- Cross-check amopstrategy index against parent AM SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname FROM pg_amop AS p1, pg_am AS p2 @@ -885,17 +912,45 @@ WHERE p2.amopmethod = p1.oid AND p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3 WHERE p3.amopfamily = p2.amopfamily AND p3.amoplefttype = p2.amoplefttype AND - p3.amoprighttype = p2.amoprighttype); + p3.amoprighttype = p2.amoprighttype AND + p3.amoppurpose = 's'); amname | amoplefttype | amoprighttype --------+--------------+--------------- (0 rows) +-- Currently, none of the AMs with fixed strategy sets support ordering ops. +SELECT p1.amname, p2.amopfamily, p2.amopstrategy +FROM pg_am AS p1, pg_amop AS p2 +WHERE p2.amopmethod = p1.oid AND + p1.amstrategies <> 0 AND p2.amoppurpose <> 's'; + amname | amopfamily | amopstrategy +--------+------------+-------------- +(0 rows) + -- Check that amopopr points at a reasonable-looking operator, ie a binary --- operator yielding boolean. +-- operator. If it's a search operator it had better yield boolean, +-- otherwise an input type of its sort opfamily. SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 WHERE p1.amopopr = p2.oid AND - (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype); + p2.oprkind != 'b'; + amopfamily | amopopr | oid | oprname +------------+---------+-----+--------- +(0 rows) + +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname +FROM pg_amop AS p1, pg_operator AS p2 +WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND + p2.oprresult != 'bool'::regtype; + amopfamily | amopopr | oid | oprname +------------+---------+-----+--------- +(0 rows) + +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname +FROM pg_amop AS p1, pg_operator AS p2 +WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 'o' AND NOT EXISTS + (SELECT 1 FROM pg_opclass op + WHERE opcfamily = p1.amopsortfamily AND opcintype = p2.oprresult); amopfamily | amopopr | oid | oprname ------------+---------+-----+--------- (0 rows) @@ -950,12 +1005,12 @@ ORDER BY 1, 2, 3; 2742 | 4 | = (39 rows) --- Check that all operators linked to by opclass entries have selectivity --- estimators. This is not absolutely required, but it seems a reasonable --- thing to insist on for all standard datatypes. +-- Check that all opclass search operators have selectivity estimators. +-- This is not absolutely required, but it seems a reasonable thing +-- to insist on for all standard datatypes. SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 -WHERE p1.amopopr = p2.oid AND +WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND (p2.oprrest = 0 OR p2.oprjoin = 0); amopfamily | amopopr | oid | oprname ------------+---------+-----+--------- diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql index 0d084a1f7a..1a023a088e 100644 --- a/src/test/regress/sql/opr_sanity.sql +++ b/src/test/regress/sql/opr_sanity.sql @@ -685,6 +685,11 @@ FROM pg_amop as p1 WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0 OR p1.amopopr = 0 OR p1.amopmethod = 0 OR p1.amopstrategy < 1; +SELECT p1.amopfamily, p1.amopstrategy +FROM pg_amop as p1 +WHERE NOT ((p1.amoppurpose = 's' AND p1.amopsortfamily = 0) OR + (p1.amoppurpose = 'o' AND p1.amopsortfamily <> 0)); + -- amoplefttype/amoprighttype must match the operator SELECT p1.oid, p2.oid @@ -698,6 +703,21 @@ SELECT p1.oid, p2.oid FROM pg_amop AS p1, pg_opfamily AS p2 WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod; +-- amopsortfamily, if present, must reference a btree family + +SELECT p1.amopfamily, p1.amopstrategy +FROM pg_amop AS p1 +WHERE p1.amopsortfamily <> 0 AND NOT EXISTS + (SELECT 1 from pg_opfamily op WHERE op.oid = p1.amopsortfamily + AND op.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')); + +-- check for ordering operators not supported by parent AM + +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname +FROM pg_amop AS p1, pg_am AS p2 +WHERE p1.amopmethod = p2.oid AND + p1.amoppurpose = 'o' AND NOT p2.amcanorderbyop; + -- Cross-check amopstrategy index against parent AM SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname @@ -716,15 +736,35 @@ WHERE p2.amopmethod = p1.oid AND p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3 WHERE p3.amopfamily = p2.amopfamily AND p3.amoplefttype = p2.amoplefttype AND - p3.amoprighttype = p2.amoprighttype); + p3.amoprighttype = p2.amoprighttype AND + p3.amoppurpose = 's'); + +-- Currently, none of the AMs with fixed strategy sets support ordering ops. + +SELECT p1.amname, p2.amopfamily, p2.amopstrategy +FROM pg_am AS p1, pg_amop AS p2 +WHERE p2.amopmethod = p1.oid AND + p1.amstrategies <> 0 AND p2.amoppurpose <> 's'; -- Check that amopopr points at a reasonable-looking operator, ie a binary --- operator yielding boolean. +-- operator. If it's a search operator it had better yield boolean, +-- otherwise an input type of its sort opfamily. SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 WHERE p1.amopopr = p2.oid AND - (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype); + p2.oprkind != 'b'; + +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname +FROM pg_amop AS p1, pg_operator AS p2 +WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND + p2.oprresult != 'bool'::regtype; + +SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname +FROM pg_amop AS p1, pg_operator AS p2 +WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 'o' AND NOT EXISTS + (SELECT 1 FROM pg_opclass op + WHERE opcfamily = p1.amopsortfamily AND opcintype = p2.oprresult); -- Make a list of all the distinct operator names being used in particular -- strategy slots. This is a bit hokey, since the list might need to change @@ -735,13 +775,13 @@ SELECT DISTINCT amopmethod, amopstrategy, oprname FROM pg_amop p1 LEFT JOIN pg_operator p2 ON amopopr = p2.oid ORDER BY 1, 2, 3; --- Check that all operators linked to by opclass entries have selectivity --- estimators. This is not absolutely required, but it seems a reasonable --- thing to insist on for all standard datatypes. +-- Check that all opclass search operators have selectivity estimators. +-- This is not absolutely required, but it seems a reasonable thing +-- to insist on for all standard datatypes. SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 -WHERE p1.amopopr = p2.oid AND +WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND (p2.oprrest = 0 OR p2.oprjoin = 0); -- Check that each opclass in an opfamily has associated operators, that is -- 2.11.0