Add text-vs-name cross-type operators, and unify name_ops with text_ops.
authorTom Lane
Wed, 19 Dec 2018 22:46:07 +0000 (17:46 -0500)
committerTom Lane
Wed, 19 Dec 2018 22:46:25 +0000 (17:46 -0500)
Now that name comparison has effectively the same behavior as text
comparison, we might as well merge the name_ops opfamily into text_ops,
allowing cross-type comparisons to be processed without forcing a
datatype coercion first.  We need do little more than add cross-type
operators to make the opfamily complete, and fix one or two places
in the planner that assumed text_ops was a single-datatype opfamily.

I chose to unify hash name_ops into hash text_ops as well, since the
types have compatible hashing semantics.  This allows marking the
new cross-type equality operators as oprcanhash.

(Note: this doesn't remove the name_ops opclasses, so there's no
breakage of index definitions.  Those opclasses are just reparented
into the text_ops opfamily.)

Discussion: https://postgr.es/m/15938.1544377821@sss.pgh.pa.us

13 files changed:
src/backend/optimizer/path/indxpath.c
src/backend/utils/adt/selfuncs.c
src/backend/utils/adt/varlena.c
src/include/catalog/catversion.h
src/include/catalog/pg_amop.dat
src/include/catalog/pg_amproc.dat
src/include/catalog/pg_opclass.dat
src/include/catalog/pg_operator.dat
src/include/catalog/pg_opfamily.dat
src/include/catalog/pg_proc.dat
src/test/regress/expected/opr_sanity.out
src/test/regress/expected/regex.out
src/test/regress/expected/select_views.out

index 965d9648e5d35a6b54f431ff9357cb29bede05dc..ca46fb7525aa51086c376a014699e8a580b66542 100644 (file)
@@ -25,6 +25,7 @@
 #include "catalog/pg_opfamily.h"
 #include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/cost.h"
 #include "optimizer/pathnode.h"
@@ -3518,6 +3519,10 @@ match_special_index_operator(Expr *clause, Oid opfamily, Oid idxcollation,
        case OID_TEXT_ICLIKE_OP:
        case OID_TEXT_REGEXEQ_OP:
        case OID_TEXT_ICREGEXEQ_OP:
+       case OID_NAME_LIKE_OP:
+       case OID_NAME_ICLIKE_OP:
+       case OID_NAME_REGEXEQ_OP:
+       case OID_NAME_ICREGEXEQ_OP:
            isIndexable =
                (opfamily == TEXT_PATTERN_BTREE_FAM_OID) ||
                (opfamily == TEXT_SPGIST_FAM_OID) ||
@@ -3537,14 +3542,6 @@ match_special_index_operator(Expr *clause, Oid opfamily, Oid idxcollation,
                  lc_collate_is_c(idxcollation)));
            break;
 
-       case OID_NAME_LIKE_OP:
-       case OID_NAME_ICLIKE_OP:
-       case OID_NAME_REGEXEQ_OP:
-       case OID_NAME_ICREGEXEQ_OP:
-           /* name uses locale-insensitive sorting */
-           isIndexable = (opfamily == NAME_BTREE_FAM_OID);
-           break;
-
        case OID_BYTEA_LIKE_OP:
            isIndexable = (opfamily == BYTEA_BTREE_FAM_OID);
            break;
@@ -4097,7 +4094,8 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
             Const *prefix_const, Pattern_Prefix_Status pstatus)
 {
    List       *result;
-   Oid         datatype;
+   Oid         ldatatype = exprType(leftop);
+   Oid         rdatatype;
    Oid         oproid;
    Expr       *expr;
    FmgrInfo    ltproc;
@@ -4110,20 +4108,16 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
        case TEXT_BTREE_FAM_OID:
        case TEXT_PATTERN_BTREE_FAM_OID:
        case TEXT_SPGIST_FAM_OID:
-           datatype = TEXTOID;
+           rdatatype = TEXTOID;
            break;
 
        case BPCHAR_BTREE_FAM_OID:
        case BPCHAR_PATTERN_BTREE_FAM_OID:
-           datatype = BPCHAROID;
-           break;
-
-       case NAME_BTREE_FAM_OID:
-           datatype = NAMEOID;
+           rdatatype = BPCHAROID;
            break;
 
        case BYTEA_BTREE_FAM_OID:
-           datatype = BYTEAOID;
+           rdatatype = BYTEAOID;
            break;
 
        default:
@@ -4136,7 +4130,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
     * If necessary, coerce the prefix constant to the right type. The given
     * prefix constant is either text or bytea type.
     */
-   if (prefix_const->consttype != datatype)
+   if (prefix_const->consttype != rdatatype)
    {
        char       *prefix;
 
@@ -4154,7 +4148,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
                     prefix_const->consttype);
                return NIL;
        }
-       prefix_const = string_to_const(prefix, datatype);
+       prefix_const = string_to_const(prefix, rdatatype);
        pfree(prefix);
    }
 
@@ -4163,7 +4157,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
     */
    if (pstatus == Pattern_Prefix_Exact)
    {
-       oproid = get_opfamily_member(opfamily, datatype, datatype,
+       oproid = get_opfamily_member(opfamily, ldatatype, rdatatype,
                                     BTEqualStrategyNumber);
        if (oproid == InvalidOid)
            elog(ERROR, "no = operator for opfamily %u", opfamily);
@@ -4179,7 +4173,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
     *
     * We can always say "x >= prefix".
     */
-   oproid = get_opfamily_member(opfamily, datatype, datatype,
+   oproid = get_opfamily_member(opfamily, ldatatype, rdatatype,
                                 BTGreaterEqualStrategyNumber);
    if (oproid == InvalidOid)
        elog(ERROR, "no >= operator for opfamily %u", opfamily);
@@ -4196,7 +4190,7 @@ prefix_quals(Node *leftop, Oid opfamily, Oid collation,
     * using a C-locale index collation.
     *-------
     */
-   oproid = get_opfamily_member(opfamily, datatype, datatype,
+   oproid = get_opfamily_member(opfamily, ldatatype, rdatatype,
                                 BTLessStrategyNumber);
    if (oproid == InvalidOid)
        elog(ERROR, "no < operator for opfamily %u", opfamily);
index ebedb269832bf662a0f253d565800508923010aa..7155dc908754a3bfb9f51f02f55d854b73091a48 100644 (file)
@@ -1292,14 +1292,12 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
    switch (vartype)
    {
        case TEXTOID:
+       case NAMEOID:
            opfamily = TEXT_BTREE_FAM_OID;
            break;
        case BPCHAROID:
            opfamily = BPCHAR_BTREE_FAM_OID;
            break;
-       case NAMEOID:
-           opfamily = NAME_BTREE_FAM_OID;
-           break;
        case BYTEAOID:
            opfamily = BYTEA_BTREE_FAM_OID;
            break;
index a4fb5885c7e93e05d31750e844a749ae80fc6324..50a157df9fbcffb7c7b935c13df0f2a6a8a2d28f 100644 (file)
@@ -2693,6 +2693,167 @@ text_smaller(PG_FUNCTION_ARGS)
 }
 
 
+/*
+ * Cross-type comparison functions for types text and name.
+ */
+
+Datum
+nameeqtext(PG_FUNCTION_ARGS)
+{
+   Name        arg1 = PG_GETARG_NAME(0);
+   text       *arg2 = PG_GETARG_TEXT_PP(1);
+   size_t      len1 = strlen(NameStr(*arg1));
+   size_t      len2 = VARSIZE_ANY_EXHDR(arg2);
+   bool        result;
+
+   result = (len1 == len2 &&
+             memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
+
+   PG_FREE_IF_COPY(arg2, 1);
+
+   PG_RETURN_BOOL(result);
+}
+
+Datum
+texteqname(PG_FUNCTION_ARGS)
+{
+   text       *arg1 = PG_GETARG_TEXT_PP(0);
+   Name        arg2 = PG_GETARG_NAME(1);
+   size_t      len1 = VARSIZE_ANY_EXHDR(arg1);
+   size_t      len2 = strlen(NameStr(*arg2));
+   bool        result;
+
+   result = (len1 == len2 &&
+             memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
+
+   PG_FREE_IF_COPY(arg1, 0);
+
+   PG_RETURN_BOOL(result);
+}
+
+Datum
+namenetext(PG_FUNCTION_ARGS)
+{
+   Name        arg1 = PG_GETARG_NAME(0);
+   text       *arg2 = PG_GETARG_TEXT_PP(1);
+   size_t      len1 = strlen(NameStr(*arg1));
+   size_t      len2 = VARSIZE_ANY_EXHDR(arg2);
+   bool        result;
+
+   result = !(len1 == len2 &&
+              memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
+
+   PG_FREE_IF_COPY(arg2, 1);
+
+   PG_RETURN_BOOL(result);
+}
+
+Datum
+textnename(PG_FUNCTION_ARGS)
+{
+   text       *arg1 = PG_GETARG_TEXT_PP(0);
+   Name        arg2 = PG_GETARG_NAME(1);
+   size_t      len1 = VARSIZE_ANY_EXHDR(arg1);
+   size_t      len2 = strlen(NameStr(*arg2));
+   bool        result;
+
+   result = !(len1 == len2 &&
+              memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
+
+   PG_FREE_IF_COPY(arg1, 0);
+
+   PG_RETURN_BOOL(result);
+}
+
+Datum
+btnametextcmp(PG_FUNCTION_ARGS)
+{
+   Name        arg1 = PG_GETARG_NAME(0);
+   text       *arg2 = PG_GETARG_TEXT_PP(1);
+   int32       result;
+
+   result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
+                       VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
+                       PG_GET_COLLATION());
+
+   PG_FREE_IF_COPY(arg2, 1);
+
+   PG_RETURN_INT32(result);
+}
+
+Datum
+bttextnamecmp(PG_FUNCTION_ARGS)
+{
+   text       *arg1 = PG_GETARG_TEXT_PP(0);
+   Name        arg2 = PG_GETARG_NAME(1);
+   int32       result;
+
+   result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
+                       NameStr(*arg2), strlen(NameStr(*arg2)),
+                       PG_GET_COLLATION());
+
+   PG_FREE_IF_COPY(arg1, 0);
+
+   PG_RETURN_INT32(result);
+}
+
+#define CmpCall(cmpfunc) \
+   DatumGetInt32(DirectFunctionCall2Coll(cmpfunc, \
+                                         PG_GET_COLLATION(), \
+                                         PG_GETARG_DATUM(0), \
+                                         PG_GETARG_DATUM(1)))
+
+Datum
+namelttext(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(btnametextcmp) < 0);
+}
+
+Datum
+nameletext(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(btnametextcmp) <= 0);
+}
+
+Datum
+namegttext(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(btnametextcmp) > 0);
+}
+
+Datum
+namegetext(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(btnametextcmp) >= 0);
+}
+
+Datum
+textltname(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(bttextnamecmp) < 0);
+}
+
+Datum
+textlename(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(bttextnamecmp) <= 0);
+}
+
+Datum
+textgtname(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(bttextnamecmp) > 0);
+}
+
+Datum
+textgename(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_BOOL(CmpCall(bttextnamecmp) >= 0);
+}
+
+#undef CmpCall
+
+
 /*
  * The following operators support character-by-character comparison
  * of text datums, to allow building indexes suitable for LIKE clauses.
index 887a620d33f065024318638761924a601537093d..821bf5ba67524062d2cff557c5bcd6e12c91f0c0 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 201812191
+#define CATALOG_VERSION_NO 201812192
 
 #endif
index 075a54c4acc61fc1c9e7d95587b9dcf938dba258..e689c9b160ae4898eba7b0210b06d435196720fd 100644 (file)
   amoprighttype => 'char', amopstrategy => '5', amopopr => '>(char,char)',
   amopmethod => 'btree' },
 
-# btree name_ops
+# btree text_ops
 
-{ amopfamily => 'btree/name_ops', amoplefttype => 'name',
+{ amopfamily => 'btree/text_ops', amoplefttype => 'text',
+  amoprighttype => 'text', amopstrategy => '1', amopopr => '<(text,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'text',
+  amoprighttype => 'text', amopstrategy => '2', amopopr => '<=(text,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'text',
+  amoprighttype => 'text', amopstrategy => '3', amopopr => '=(text,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'text',
+  amoprighttype => 'text', amopstrategy => '4', amopopr => '>=(text,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'text',
+  amoprighttype => 'text', amopstrategy => '5', amopopr => '>(text,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
   amoprighttype => 'name', amopstrategy => '1', amopopr => '<(name,name)',
   amopmethod => 'btree' },
-{ amopfamily => 'btree/name_ops', amoplefttype => 'name',
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
   amoprighttype => 'name', amopstrategy => '2', amopopr => '<=(name,name)',
   amopmethod => 'btree' },
-{ amopfamily => 'btree/name_ops', amoplefttype => 'name',
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
   amoprighttype => 'name', amopstrategy => '3', amopopr => '=(name,name)',
   amopmethod => 'btree' },
-{ amopfamily => 'btree/name_ops', amoplefttype => 'name',
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
   amoprighttype => 'name', amopstrategy => '4', amopopr => '>=(name,name)',
   amopmethod => 'btree' },
-{ amopfamily => 'btree/name_ops', amoplefttype => 'name',
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
   amoprighttype => 'name', amopstrategy => '5', amopopr => '>(name,name)',
   amopmethod => 'btree' },
-
-# btree text_ops
-
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
+  amoprighttype => 'text', amopstrategy => '1', amopopr => '<(name,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
+  amoprighttype => 'text', amopstrategy => '2', amopopr => '<=(name,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
+  amoprighttype => 'text', amopstrategy => '3', amopopr => '=(name,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
+  amoprighttype => 'text', amopstrategy => '4', amopopr => '>=(name,text)',
+  amopmethod => 'btree' },
+{ amopfamily => 'btree/text_ops', amoplefttype => 'name',
+  amoprighttype => 'text', amopstrategy => '5', amopopr => '>(name,text)',
+  amopmethod => 'btree' },
 { amopfamily => 'btree/text_ops', amoplefttype => 'text',
-  amoprighttype => 'text', amopstrategy => '1', amopopr => '<(text,text)',
+  amoprighttype => 'name', amopstrategy => '1', amopopr => '<(text,name)',
   amopmethod => 'btree' },
 { amopfamily => 'btree/text_ops', amoplefttype => 'text',
-  amoprighttype => 'text', amopstrategy => '2', amopopr => '<=(text,text)',
+  amoprighttype => 'name', amopstrategy => '2', amopopr => '<=(text,name)',
   amopmethod => 'btree' },
 { amopfamily => 'btree/text_ops', amoplefttype => 'text',
-  amoprighttype => 'text', amopstrategy => '3', amopopr => '=(text,text)',
+  amoprighttype => 'name', amopstrategy => '3', amopopr => '=(text,name)',
   amopmethod => 'btree' },
 { amopfamily => 'btree/text_ops', amoplefttype => 'text',
-  amoprighttype => 'text', amopstrategy => '4', amopopr => '>=(text,text)',
+  amoprighttype => 'name', amopstrategy => '4', amopopr => '>=(text,name)',
   amopmethod => 'btree' },
 { amopfamily => 'btree/text_ops', amoplefttype => 'text',
-  amoprighttype => 'text', amopstrategy => '5', amopopr => '>(text,text)',
+  amoprighttype => 'name', amopstrategy => '5', amopopr => '>(text,name)',
   amopmethod => 'btree' },
 
 # btree bpchar_ops
   amoprighttype => 'macaddr8', amopstrategy => '1',
   amopopr => '=(macaddr8,macaddr8)', amopmethod => 'hash' },
 
-# name_ops
-{ amopfamily => 'hash/name_ops', amoplefttype => 'name',
-  amoprighttype => 'name', amopstrategy => '1', amopopr => '=(name,name)',
-  amopmethod => 'hash' },
-
 # oid_ops
 { amopfamily => 'hash/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid',
   amopstrategy => '1', amopopr => '=(oid,oid)', amopmethod => 'hash' },
 { amopfamily => 'hash/text_ops', amoplefttype => 'text',
   amoprighttype => 'text', amopstrategy => '1', amopopr => '=(text,text)',
   amopmethod => 'hash' },
+{ amopfamily => 'hash/text_ops', amoplefttype => 'name',
+  amoprighttype => 'name', amopstrategy => '1', amopopr => '=(name,name)',
+  amopmethod => 'hash' },
+{ amopfamily => 'hash/text_ops', amoplefttype => 'name',
+  amoprighttype => 'text', amopstrategy => '1', amopopr => '=(name,text)',
+  amopmethod => 'hash' },
+{ amopfamily => 'hash/text_ops', amoplefttype => 'text',
+  amoprighttype => 'name', amopstrategy => '1', amopopr => '=(text,name)',
+  amopmethod => 'hash' },
 
 # time_ops
 { amopfamily => 'hash/time_ops', amoplefttype => 'time',
index 0ef2c0885f2c6f99c11b5387d798e488af58c91d..bbcee26fa8b6929868df5d2ca8775135860e0d63 100644 (file)
 { amprocfamily => 'btree/macaddr_ops', amproclefttype => 'macaddr',
   amprocrighttype => 'macaddr', amprocnum => '2',
   amproc => 'macaddr_sortsupport' },
-{ amprocfamily => 'btree/name_ops', amproclefttype => 'name',
-  amprocrighttype => 'name', amprocnum => '1', amproc => 'btnamecmp' },
-{ amprocfamily => 'btree/name_ops', amproclefttype => 'name',
-  amprocrighttype => 'name', amprocnum => '2', amproc => 'btnamesortsupport' },
 { amprocfamily => 'btree/numeric_ops', amproclefttype => 'numeric',
   amprocrighttype => 'numeric', amprocnum => '1', amproc => 'numeric_cmp' },
 { amprocfamily => 'btree/numeric_ops', amproclefttype => 'numeric',
   amprocrighttype => 'text', amprocnum => '1', amproc => 'bttextcmp' },
 { amprocfamily => 'btree/text_ops', amproclefttype => 'text',
   amprocrighttype => 'text', amprocnum => '2', amproc => 'bttextsortsupport' },
+{ amprocfamily => 'btree/text_ops', amproclefttype => 'name',
+  amprocrighttype => 'name', amprocnum => '1', amproc => 'btnamecmp' },
+{ amprocfamily => 'btree/text_ops', amproclefttype => 'name',
+  amprocrighttype => 'name', amprocnum => '2', amproc => 'btnamesortsupport' },
+{ amprocfamily => 'btree/text_ops', amproclefttype => 'name',
+  amprocrighttype => 'text', amprocnum => '1', amproc => 'btnametextcmp' },
+{ amprocfamily => 'btree/text_ops', amproclefttype => 'text',
+  amprocrighttype => 'name', amprocnum => '1', amproc => 'bttextnamecmp' },
 { amprocfamily => 'btree/time_ops', amproclefttype => 'time',
   amprocrighttype => 'time', amprocnum => '1', amproc => 'time_cmp' },
 { amprocfamily => 'btree/time_ops', amproclefttype => 'time',
 { amprocfamily => 'hash/macaddr_ops', amproclefttype => 'macaddr',
   amprocrighttype => 'macaddr', amprocnum => '2',
   amproc => 'hashmacaddrextended' },
-{ amprocfamily => 'hash/name_ops', amproclefttype => 'name',
-  amprocrighttype => 'name', amprocnum => '1', amproc => 'hashname' },
-{ amprocfamily => 'hash/name_ops', amproclefttype => 'name',
-  amprocrighttype => 'name', amprocnum => '2', amproc => 'hashnameextended' },
 { amprocfamily => 'hash/oid_ops', amproclefttype => 'oid',
   amprocrighttype => 'oid', amprocnum => '1', amproc => 'hashoid' },
 { amprocfamily => 'hash/oid_ops', amproclefttype => 'oid',
   amprocrighttype => 'text', amprocnum => '1', amproc => 'hashtext' },
 { amprocfamily => 'hash/text_ops', amproclefttype => 'text',
   amprocrighttype => 'text', amprocnum => '2', amproc => 'hashtextextended' },
+{ amprocfamily => 'hash/text_ops', amproclefttype => 'name',
+  amprocrighttype => 'name', amprocnum => '1', amproc => 'hashname' },
+{ amprocfamily => 'hash/text_ops', amproclefttype => 'name',
+  amprocrighttype => 'name', amprocnum => '2', amproc => 'hashnameextended' },
 { amprocfamily => 'hash/time_ops', amproclefttype => 'time',
   amprocrighttype => 'time', amprocnum => '1', amproc => 'time_hash' },
 { amprocfamily => 'hash/time_ops', amproclefttype => 'time',
index 13928ba4a02bb7560b895a8732e0cf39858e3b42..5178d04337fa8ebab007cd7acb1d45e675ae9c58 100644 (file)
 # but cstring and name are the same thing except for trailing padding,
 # and we can safely omit that within an index entry.  So we declare the
 # btree opclass for name as using cstring storage type.
-{ opcmethod => 'btree', opcname => 'name_ops', opcfamily => 'btree/name_ops',
+{ opcmethod => 'btree', opcname => 'name_ops', opcfamily => 'btree/text_ops',
   opcintype => 'name', opckeytype => 'cstring' },
 
-{ opcmethod => 'hash', opcname => 'name_ops', opcfamily => 'hash/name_ops',
+{ opcmethod => 'hash', opcname => 'name_ops', opcfamily => 'hash/text_ops',
   opcintype => 'name' },
 { oid => '3125', oid_symbol => 'NUMERIC_BTREE_OPS_OID',
   opcmethod => 'btree', opcname => 'numeric_ops',
index ce23c2f0aa5ea53c2d8bb6ec5109e4fc34d0e4c4..2abd5311c3e5b59b25f329f3250da37413e6b446 100644 (file)
   oprcode => 'starts_with', oprrest => 'prefixsel',
   oprjoin => 'prefixjoinsel' },
 
+{ oid => '254', descr => 'equal',
+  oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'name',
+  oprright => 'text', oprresult => 'bool', oprcom => '=(text,name)',
+  oprnegate => '<>(name,text)', oprcode => 'nameeqtext', oprrest => 'eqsel',
+  oprjoin => 'eqjoinsel' },
+{ oid => '255', descr => 'less than',
+  oprname => '<', oprleft => 'name', oprright => 'text', oprresult => 'bool',
+  oprcom => '>(text,name)', oprnegate => '>=(name,text)',
+  oprcode => 'namelttext', oprrest => 'scalarltsel',
+  oprjoin => 'scalarltjoinsel' },
+{ oid => '256', descr => 'less than or equal',
+  oprname => '<=', oprleft => 'name', oprright => 'text', oprresult => 'bool',
+  oprcom => '>=(text,name)', oprnegate => '>(name,text)',
+  oprcode => 'nameletext', oprrest => 'scalarlesel',
+  oprjoin => 'scalarlejoinsel' },
+{ oid => '257', descr => 'greater than or equal',
+  oprname => '>=', oprleft => 'name', oprright => 'text', oprresult => 'bool',
+  oprcom => '<=(text,name)', oprnegate => '<(name,text)',
+  oprcode => 'namegetext', oprrest => 'scalargesel',
+  oprjoin => 'scalargejoinsel' },
+{ oid => '258', descr => 'greater than',
+  oprname => '>', oprleft => 'name', oprright => 'text', oprresult => 'bool',
+  oprcom => '<(text,name)', oprnegate => '<=(name,text)',
+  oprcode => 'namegttext', oprrest => 'scalargtsel',
+  oprjoin => 'scalargtjoinsel' },
+{ oid => '259', descr => 'not equal',
+  oprname => '<>', oprleft => 'name', oprright => 'text', oprresult => 'bool',
+  oprcom => '<>(text,name)', oprnegate => '=(name,text)',
+  oprcode => 'namenetext', oprrest => 'neqsel', oprjoin => 'neqjoinsel' },
+{ oid => '260', descr => 'equal',
+  oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'text',
+  oprright => 'name', oprresult => 'bool', oprcom => '=(name,text)',
+  oprnegate => '<>(text,name)', oprcode => 'texteqname', oprrest => 'eqsel',
+  oprjoin => 'eqjoinsel' },
+{ oid => '261', descr => 'less than',
+  oprname => '<', oprleft => 'text', oprright => 'name', oprresult => 'bool',
+  oprcom => '>(name,text)', oprnegate => '>=(text,name)',
+  oprcode => 'textltname', oprrest => 'scalarltsel',
+  oprjoin => 'scalarltjoinsel' },
+{ oid => '262', descr => 'less than or equal',
+  oprname => '<=', oprleft => 'text', oprright => 'name', oprresult => 'bool',
+  oprcom => '>=(name,text)', oprnegate => '>(text,name)',
+  oprcode => 'textlename', oprrest => 'scalarlesel',
+  oprjoin => 'scalarlejoinsel' },
+{ oid => '263', descr => 'greater than or equal',
+  oprname => '>=', oprleft => 'text', oprright => 'name', oprresult => 'bool',
+  oprcom => '<=(name,text)', oprnegate => '<(text,name)',
+  oprcode => 'textgename', oprrest => 'scalargesel',
+  oprjoin => 'scalargejoinsel' },
+{ oid => '264', descr => 'greater than',
+  oprname => '>', oprleft => 'text', oprright => 'name', oprresult => 'bool',
+  oprcom => '<(name,text)', oprnegate => '<=(text,name)',
+  oprcode => 'textgtname', oprrest => 'scalargtsel',
+  oprjoin => 'scalargtjoinsel' },
+{ oid => '265', descr => 'not equal',
+  oprname => '<>', oprleft => 'text', oprright => 'name', oprresult => 'bool',
+  oprcom => '<>(name,text)', oprnegate => '=(text,name)',
+  oprcode => 'textnename', oprrest => 'neqsel', oprjoin => 'neqjoinsel' },
+
 { oid => '349', descr => 'append element onto end of array',
   oprname => '||', oprleft => 'anyarray', oprright => 'anyelement',
   oprresult => 'anyarray', oprcode => 'array_append' },
index 21473acf348db02e0d4388647fc2aa7a03218a6a..fe8a32485f2742c36293562363115f4363cb1de9 100644 (file)
   opfmethod => 'btree', opfname => 'macaddr8_ops' },
 { oid => '3372',
   opfmethod => 'hash', opfname => 'macaddr8_ops' },
-{ oid => '1986', oid_symbol => 'NAME_BTREE_FAM_OID',
-  opfmethod => 'btree', opfname => 'name_ops' },
-{ oid => '1987',
-  opfmethod => 'hash', opfname => 'name_ops' },
 { oid => '1988',
   opfmethod => 'btree', opfname => 'numeric_ops' },
 { oid => '1998',
index f79fcfe029f1545599759c0f22e89a952bc86ea1..d0a571ef9569215fcdca36fd6b7500b7c45beb0d 100644 (file)
   proname => 'line_distance', prorettype => 'float8',
   proargtypes => 'line line', prosrc => 'line_distance' },
 
+{ oid => '240',
+  proname => 'nameeqtext', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'name text', prosrc => 'nameeqtext' },
+{ oid => '241',
+  proname => 'namelttext', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'name text', prosrc => 'namelttext' },
+{ oid => '242',
+  proname => 'nameletext', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'name text', prosrc => 'nameletext' },
+{ oid => '243',
+  proname => 'namegetext', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'name text', prosrc => 'namegetext' },
+{ oid => '244',
+  proname => 'namegttext', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'name text', prosrc => 'namegttext' },
+{ oid => '245',
+  proname => 'namenetext', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'name text', prosrc => 'namenetext' },
+{ oid => '246', descr => 'less-equal-greater',
+  proname => 'btnametextcmp', proleakproof => 't', prorettype => 'int4',
+  proargtypes => 'name text', prosrc => 'btnametextcmp' },
+{ oid => '247',
+  proname => 'texteqname', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'text name', prosrc => 'texteqname' },
+{ oid => '248',
+  proname => 'textltname', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'text name', prosrc => 'textltname' },
+{ oid => '249',
+  proname => 'textlename', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'text name', prosrc => 'textlename' },
+{ oid => '250',
+  proname => 'textgename', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'text name', prosrc => 'textgename' },
+{ oid => '251',
+  proname => 'textgtname', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'text name', prosrc => 'textgtname' },
+{ oid => '252',
+  proname => 'textnename', proleakproof => 't', prorettype => 'bool',
+  proargtypes => 'text name', prosrc => 'textnename' },
+{ oid => '253', descr => 'less-equal-greater',
+  proname => 'bttextnamecmp', proleakproof => 't', prorettype => 'int4',
+  proargtypes => 'text name', prosrc => 'bttextnamecmp' },
+
 { oid => '274',
   descr => 'current date and time - increments during transactions',
   proname => 'timeofday', provolatile => 'v', prorettype => 'text',
index 6dca1b7bf349225aa5ebe1c0bae5f3e250d2d2ae..214ad2d619c00a9ce2f38050ffea74d360849e4d 100644 (file)
@@ -525,6 +525,20 @@ int24ge(smallint,integer)
 int42ge(integer,smallint)
 oideq(oid,oid)
 oidne(oid,oid)
+nameeqtext(name,text)
+namelttext(name,text)
+nameletext(name,text)
+namegetext(name,text)
+namegttext(name,text)
+namenetext(name,text)
+btnametextcmp(name,text)
+texteqname(text,name)
+textltname(text,name)
+textlename(text,name)
+textgename(text,name)
+textgtname(text,name)
+textnename(text,name)
+bttextnamecmp(text,name)
 float4eq(real,real)
 float4ne(real,real)
 float4lt(real,real)
index 79a7fa7a845ec634554207f05bf15f3be2167ce8..c0bfa8a842c5d13422a2f95a6b06ec59a799711e 100644 (file)
@@ -299,7 +299,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abc';
                               QUERY PLAN                              
 ----------------------------------------------------------------------
  Index Scan using pg_proc_proname_args_nsp_index on pg_proc
-   Index Cond: ((proname >= 'abc'::name) AND (proname < 'abd'::name))
+   Index Cond: ((proname >= 'abc'::text) AND (proname < 'abd'::text))
    Filter: (proname ~ '^abc'::text)
 (3 rows)
 
@@ -307,7 +307,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abc$';
                          QUERY PLAN                         
 ------------------------------------------------------------
  Index Scan using pg_proc_proname_args_nsp_index on pg_proc
-   Index Cond: (proname = 'abc'::name)
+   Index Cond: (proname = 'abc'::text)
    Filter: (proname ~ '^abc$'::text)
 (3 rows)
 
@@ -315,7 +315,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abcd*e';
                               QUERY PLAN                              
 ----------------------------------------------------------------------
  Index Scan using pg_proc_proname_args_nsp_index on pg_proc
-   Index Cond: ((proname >= 'abc'::name) AND (proname < 'abd'::name))
+   Index Cond: ((proname >= 'abc'::text) AND (proname < 'abd'::text))
    Filter: (proname ~ '^abcd*e'::text)
 (3 rows)
 
@@ -323,7 +323,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abc+d';
                               QUERY PLAN                              
 ----------------------------------------------------------------------
  Index Scan using pg_proc_proname_args_nsp_index on pg_proc
-   Index Cond: ((proname >= 'abc'::name) AND (proname < 'abd'::name))
+   Index Cond: ((proname >= 'abc'::text) AND (proname < 'abd'::text))
    Filter: (proname ~ '^abc+d'::text)
 (3 rows)
 
@@ -331,7 +331,7 @@ explain (costs off) select * from pg_proc where proname ~ '^(abc)(def)';
                                  QUERY PLAN                                 
 ----------------------------------------------------------------------------
  Index Scan using pg_proc_proname_args_nsp_index on pg_proc
-   Index Cond: ((proname >= 'abcdef'::name) AND (proname < 'abcdeg'::name))
+   Index Cond: ((proname >= 'abcdef'::text) AND (proname < 'abcdeg'::text))
    Filter: (proname ~ '^(abc)(def)'::text)
 (3 rows)
 
@@ -339,7 +339,7 @@ explain (costs off) select * from pg_proc where proname ~ '^(abc)$';
                          QUERY PLAN                         
 ------------------------------------------------------------
  Index Scan using pg_proc_proname_args_nsp_index on pg_proc
-   Index Cond: (proname = 'abc'::name)
+   Index Cond: (proname = 'abc'::text)
    Filter: (proname ~ '^(abc)$'::text)
 (3 rows)
 
@@ -354,7 +354,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abcd(x|(?=\w\w)q)';
                                QUERY PLAN                               
 ------------------------------------------------------------------------
  Index Scan using pg_proc_proname_args_nsp_index on pg_proc
-   Index Cond: ((proname >= 'abcd'::name) AND (proname < 'abce'::name))
+   Index Cond: ((proname >= 'abcd'::text) AND (proname < 'abce'::text))
    Filter: (proname ~ '^abcd(x|(?=\w\w)q)'::text)
 (3 rows)
 
index bf003adf243255d5d9418ba1b7c90a575749c5aa..1aeed8452bde840cac92590fd1eb0b8d6285e92d 100644 (file)
@@ -1326,10 +1326,10 @@ NOTICE:  f_leak => hamburger
 (1 row)
 
 EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal WHERE f_leak(passwd);
-                          QUERY PLAN                          
---------------------------------------------------------------
+                      QUERY PLAN                      
+------------------------------------------------------
  Seq Scan on customer
-   Filter: (f_leak(passwd) AND (name = (CURRENT_USER)::text))
+   Filter: (f_leak(passwd) AND (name = CURRENT_USER))
 (2 rows)
 
 SELECT * FROM my_property_secure WHERE f_leak(passwd);
@@ -1340,12 +1340,12 @@ NOTICE:  f_leak => passwd123
 (1 row)
 
 EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd);
-                  QUERY PLAN                   
------------------------------------------------
+                 QUERY PLAN                  
+---------------------------------------------
  Subquery Scan on my_property_secure
    Filter: f_leak(my_property_secure.passwd)
    ->  Seq Scan on customer
-         Filter: (name = (CURRENT_USER)::text)
+         Filter: (name = CURRENT_USER)
 (4 rows)
 
 --
@@ -1367,10 +1367,10 @@ NOTICE:  f_leak => hamburger
 
 EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v
        WHERE f_leak('passwd') AND f_leak(passwd);
-                                       QUERY PLAN                                        
------------------------------------------------------------------------------------------
+                                   QUERY PLAN                                    
+---------------------------------------------------------------------------------
  Seq Scan on customer
-   Filter: (f_leak('passwd'::text) AND f_leak(passwd) AND (name = (CURRENT_USER)::text))
+   Filter: (f_leak('passwd'::text) AND f_leak(passwd) AND (name = CURRENT_USER))
 (2 rows)
 
 SELECT * FROM my_property_secure v
@@ -1386,12 +1386,12 @@ NOTICE:  f_leak => passwd
 
 EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v
        WHERE f_leak('passwd') AND f_leak(passwd);
-                                 QUERY PLAN                                 
-----------------------------------------------------------------------------
+                             QUERY PLAN                             
+--------------------------------------------------------------------
  Subquery Scan on v
    Filter: f_leak(v.passwd)
    ->  Seq Scan on customer
-         Filter: (f_leak('passwd'::text) AND (name = (CURRENT_USER)::text))
+         Filter: (f_leak('passwd'::text) AND (name = CURRENT_USER))
 (4 rows)
 
 --
@@ -1409,15 +1409,15 @@ NOTICE:  f_leak => 9801-2345-6789-0123
 (1 row)
 
 EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_normal WHERE f_leak(cnum);
-                     QUERY PLAN                      
------------------------------------------------------
+                 QUERY PLAN                  
+---------------------------------------------
  Hash Join
    Hash Cond: (r.cid = l.cid)
    ->  Seq Scan on credit_card r
          Filter: f_leak(cnum)
    ->  Hash
          ->  Seq Scan on customer l
-               Filter: (name = (CURRENT_USER)::text)
+               Filter: (name = CURRENT_USER)
 (7 rows)
 
 SELECT * FROM my_credit_card_secure WHERE f_leak(cnum);
@@ -1428,8 +1428,8 @@ NOTICE:  f_leak => 1111-2222-3333-4444
 (1 row)
 
 EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum);
-                        QUERY PLAN                         
------------------------------------------------------------
+                    QUERY PLAN                     
+---------------------------------------------------
  Subquery Scan on my_credit_card_secure
    Filter: f_leak(my_credit_card_secure.cnum)
    ->  Hash Join
@@ -1437,7 +1437,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum);
          ->  Seq Scan on credit_card r
          ->  Hash
                ->  Seq Scan on customer l
-                     Filter: (name = (CURRENT_USER)::text)
+                     Filter: (name = CURRENT_USER)
 (8 rows)
 
 --
@@ -1471,7 +1471,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_normal
                      ->  Seq Scan on credit_card r_1
                      ->  Hash
                            ->  Seq Scan on customer l_1
-                                 Filter: (name = (CURRENT_USER)::text)
+                                 Filter: (name = CURRENT_USER)
 (13 rows)
 
 SELECT * FROM my_credit_card_usage_secure
@@ -1502,7 +1502,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_secure
                      ->  Seq Scan on credit_card r_1
                      ->  Hash
                            ->  Seq Scan on customer l
-                                 Filter: (name = (CURRENT_USER)::text)
+                                 Filter: (name = CURRENT_USER)
 (13 rows)
 
 --