19.12.2019 18:19, Antonin Houska wrote:
Anastasia Lubennikova <a.lubennik...@postgrespro.ru> wrote:
I attached new version with pg_opclass documentation update.
One more thing I am uncertain about is array_ops. Arrays may contain bitwise
and not bitwise element types.
What is the correct value of opcisbitwise the array_ops itself?
How about setting opcisbitwise to false for the array_ops opclass and checking
opcisbitwise of the element type whenever we need to know whether the array is
"bitwise equal"? When checking array_eq(), I thought whether the existence of
"expanded array" format is a problem but it does not seem to be: the
conversion of "expanded" value to "flat" value and then back to the "expanded"
should not change the array contents.
Anyway, in the current version of the patch I see that array_ops opclasses
have opcisbitwise=true. It should be false even if you don't use the approach
of checking the element type.
Besides that, I think that record_ops is similar to array_ops and therefore it
should not set opcisbitwise to true.
I also remember that, when thinking about the problem in the context of the
aggregate push down patch, I considered some of the geometric types
problematic. For example, box_eq() uses this expression
#define FPeq(A,B) (fabs((A) - (B)) <= EPSILON)
so equality does not imply bitwise equality here. Maybe you should only set
the flag for btree opclasses for now.
Thank you for pointing out at the issue with geometric opclasses.
If I understand it correctly, regular float types are not bitwise as well.
I updated the patchset.
The first patch now contains only infrastructure changes
and the second one sets opcisbitwise for btree opclasses in pg_opclass.dat.
I've tried to be conservative and only mark types that are 100% bitwise
safe.
See attached v2-Opclass-isbitwise.out file.
Non-atomic types, such as record, range, json and enum depend on element
types.
Text can be considered bitwise (i.e. texteq uses memcmp) only when
specific collation clauses are satisfied.
We can make this 'opcisbitwise' parameter enum (or char) instead of
boolean to mark
"always bitwise", "never bitwise" and "maybe bitwise". Though, I doubt
if it will be helpful in any real use case.
What do you think?
--
Anastasia Lubennikova
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
commit 891c03c4b8f37cf6711d6ae84f4e75573c123ec8
Author: Anastasia <a.lubennik...@postgrespro.ru>
Date: Mon Dec 23 19:52:22 2019 +0300
v4-Opclass-bitwise-equality-0001.patch
Add new infrastracture to mark opclass as BITWISE. Actual values of this parameter will be added in the following patch.
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index c915885..9b5c33b 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -3111,7 +3111,7 @@ create operator public.>^ (
create operator family my_op_family using btree;
create function my_op_cmp(a int, b int) returns int as
$$begin return btint4cmp(a, b); end $$ language plpgsql;
-create operator class my_op_class for type int using btree family my_op_family as
+create operator class my_op_class bitwise for type int using btree family my_op_family as
operator 1 public.<^,
operator 3 public.=^,
operator 5 public.>^,
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 4f29e7c..48263d6 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -825,7 +825,7 @@ create operator family my_op_family using btree;
create function my_op_cmp(a int, b int) returns int as
$$begin return btint4cmp(a, b); end $$ language plpgsql;
-create operator class my_op_class for type int using btree family my_op_family as
+create operator class my_op_class bitwise for type int using btree family my_op_family as
operator 1 public.<^,
operator 3 public.=^,
operator 5 public.>^,
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 55694c4..87cc344 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -4544,6 +4544,13 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<entry>Type of data stored in index, or zero if same as <structfield>opcintype</structfield></entry>
</row>
+ <row>
+ <entry><structfield>opcisbitwise</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>True if the operator class equality is the same as equivalence</entry>
+ </row>
+
</tbody>
</tgroup>
</table>
diff --git a/doc/src/sgml/ref/create_opclass.sgml b/doc/src/sgml/ref/create_opclass.sgml
index dd5252f..8d0ddfc 100644
--- a/doc/src/sgml/ref/create_opclass.sgml
+++ b/doc/src/sgml/ref/create_opclass.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
-CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAULT ] FOR TYPE <replaceable class="parameter">data_type</replaceable>
+CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAULT | BITWISE ] FOR TYPE <replaceable class="parameter">data_type</replaceable>
USING <replaceable class="parameter">index_method</replaceable> [ FAMILY <replaceable class="parameter">family_name</replaceable> ] AS
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> [ ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) ] [ FOR SEARCH | FOR ORDER BY <replaceable class="parameter">sort_family_name</replaceable> ]
| FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
@@ -106,6 +106,20 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><literal>BITWISE</literal></term>
+ <listitem>
+ <para>
+ If present, the operator class equality is the same as equivalence.
+ For example, two integers that compare equal are also binary equal,
+ while, numerics can compare equal but have different scales,
+ thus numeric opclass is not <literal>BITWISE</literal>. Even though,
+ most opclasses implement bitwise equal comparison, this behaviour
+ must be set explicitly.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><replaceable class="parameter">data_type</replaceable></term>
<listitem>
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index cb7a6bd..c0fe187 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -653,6 +653,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
values[Anum_pg_opclass_opcintype - 1] = ObjectIdGetDatum(typeoid);
values[Anum_pg_opclass_opcdefault - 1] = BoolGetDatum(stmt->isDefault);
values[Anum_pg_opclass_opckeytype - 1] = ObjectIdGetDatum(storageoid);
+ values[Anum_pg_opclass_opcisbitwise - 1] = BoolGetDatum(stmt->isBitwise);
tup = heap_form_tuple(rel->rd_att, values, nulls);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index a9b8b84..73b076dd 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3790,6 +3790,7 @@ _copyCreateOpClassStmt(const CreateOpClassStmt *from)
COPY_NODE_FIELD(datatype);
COPY_NODE_FIELD(items);
COPY_SCALAR_FIELD(isDefault);
+ COPY_SCALAR_FIELD(isBitwise);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 2fcd4a3..8f4ece4 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1609,6 +1609,7 @@ _equalCreateOpClassStmt(const CreateOpClassStmt *a, const CreateOpClassStmt *b)
COMPARE_NODE_FIELD(datatype);
COMPARE_NODE_FIELD(items);
COMPARE_SCALAR_FIELD(isDefault);
+ COMPARE_SCALAR_FIELD(isBitwise);
return true;
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c508684..683f9b4 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -447,7 +447,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <boolean> opt_instead
%type <boolean> opt_unique opt_concurrently opt_verbose opt_full
-%type <boolean> opt_freeze opt_analyze opt_default opt_recheck
+%type <boolean> opt_freeze opt_analyze opt_default opt_recheck opt_bitwise
%type <defelt> opt_binary copy_delimiter
%type <boolean> copy_from opt_program
@@ -618,7 +618,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT ATTACH ATTRIBUTE AUTHORIZATION
- BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
+ BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT BITWISE
BOOLEAN_P BOTH BY
CACHE CALL CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P
@@ -5953,16 +5953,17 @@ opt_if_not_exists: IF_P NOT EXISTS { $$ = true; }
*****************************************************************************/
CreateOpClassStmt:
- CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
+ CREATE OPERATOR CLASS any_name opt_default opt_bitwise FOR TYPE_P Typename
USING access_method opt_opfamily AS opclass_item_list
{
CreateOpClassStmt *n = makeNode(CreateOpClassStmt);
n->opclassname = $4;
n->isDefault = $5;
- n->datatype = $8;
- n->amname = $10;
- n->opfamilyname = $11;
- n->items = $13;
+ n->isBitwise = $6;
+ n->datatype = $9;
+ n->amname = $11;
+ n->opfamilyname = $12;
+ n->items = $14;
$$ = (Node *) n;
}
;
@@ -6025,6 +6026,10 @@ opt_default: DEFAULT { $$ = true; }
| /*EMPTY*/ { $$ = false; }
;
+opt_bitwise: BITWISE { $$ = true; }
+ | /*EMPTY*/ { $$ = false; }
+ ;
+
opt_opfamily: FAMILY any_name { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
@@ -15129,6 +15134,7 @@ unreserved_keyword:
| BACKWARD
| BEFORE
| BEGIN_P
+ | BITWISE
| BY
| CACHE
| CALL
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 08658c8..00e248b 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12833,6 +12833,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
int i_opcintype;
int i_opckeytype;
int i_opcdefault;
+ int i_opcisbitwise;
int i_opcfamily;
int i_opcfamilyname;
int i_opcfamilynsp;
@@ -12849,6 +12850,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
char *opcintype;
char *opckeytype;
char *opcdefault;
+ char *opcisbitwise;
char *opcfamily;
char *opcfamilyname;
char *opcfamilynsp;
@@ -12875,11 +12877,25 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
nameusing = createPQExpBuffer();
/* Get additional fields from the pg_opclass row */
- if (fout->remoteVersion >= 80300)
+ if (fout->remoteVersion >= 13000)
+ {
+ appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
+ "opckeytype::pg_catalog.regtype, "
+ "opcdefault, opcisbitwise, 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 "
+ "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
+ "WHERE c.oid = '%u'::pg_catalog.oid",
+ opcinfo->dobj.catId.oid);
+ }
+ else if (fout->remoteVersion >= 80300)
{
appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
"opckeytype::pg_catalog.regtype, "
- "opcdefault, opcfamily, "
+ "opcdefault, 'f' as opcisbitwise, opcfamily, "
"opfname AS opcfamilyname, "
"nspname AS opcfamilynsp, "
"(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
@@ -12893,7 +12909,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
{
appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
"opckeytype::pg_catalog.regtype, "
- "opcdefault, NULL AS opcfamily, "
+ "opcdefault, 'f' as opcisbitwise, NULL AS opcfamily, "
"NULL AS opcfamilyname, "
"NULL AS opcfamilynsp, "
"(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname "
@@ -12907,6 +12923,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
i_opcintype = PQfnumber(res, "opcintype");
i_opckeytype = PQfnumber(res, "opckeytype");
i_opcdefault = PQfnumber(res, "opcdefault");
+ i_opcisbitwise = PQfnumber(res, "opcisbitwise");
i_opcfamily = PQfnumber(res, "opcfamily");
i_opcfamilyname = PQfnumber(res, "opcfamilyname");
i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
@@ -12916,6 +12933,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
opckeytype = PQgetvalue(res, 0, i_opckeytype);
opcdefault = PQgetvalue(res, 0, i_opcdefault);
+ opcisbitwise = PQgetvalue(res, 0, i_opcisbitwise);
/* opcfamily will still be needed after we PQclear res */
opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
@@ -12933,6 +12951,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
fmtQualifiedDumpable(opcinfo));
if (strcmp(opcdefault, "t") == 0)
appendPQExpBufferStr(q, "DEFAULT ");
+ if (strcmp(opcisbitwise, "t") == 0)
+ appendPQExpBufferStr(q, "BITWISE ");
appendPQExpBuffer(q, "FOR TYPE %s USING %s",
opcintype,
fmtId(amname));
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index 84853c1..9ab32b3 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -73,6 +73,9 @@ CATALOG(pg_opclass,2616,OperatorClassRelationId)
/* type of data in index, or InvalidOid */
Oid opckeytype BKI_DEFAULT(0) BKI_LOOKUP(pg_type);
+
+ /* T if opclass equality also means "bitwise equality" */
+ bool opcisbitwise BKI_DEFAULT(f);
} FormData_pg_opclass;
/* ----------------
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index ff626cb..47ad85f 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2577,6 +2577,7 @@ typedef struct CreateOpClassStmt
TypeName *datatype; /* datatype of indexed column */
List *items; /* List of CreateOpClassItem nodes */
bool isDefault; /* Should be marked as default for type? */
+ bool isBitwise; /* Is opclass equality bitwise? */
} CreateOpClassStmt;
#define OPCLASS_ITEM_OPERATOR 1
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 00ace84..d6a8e8f 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -58,6 +58,7 @@ PG_KEYWORD("between", BETWEEN, COL_NAME_KEYWORD)
PG_KEYWORD("bigint", BIGINT, COL_NAME_KEYWORD)
PG_KEYWORD("binary", BINARY, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("bit", BIT, COL_NAME_KEYWORD)
+PG_KEYWORD("bitwise", BITWISE, UNRESERVED_KEYWORD)
PG_KEYWORD("boolean", BOOLEAN_P, COL_NAME_KEYWORD)
PG_KEYWORD("both", BOTH, RESERVED_KEYWORD)
PG_KEYWORD("by", BY, UNRESERVED_KEYWORD)
commit 4b0eb505204b1be0bb7ba1171e288881e14a9b7c
Author: Anastasia <a.lubennik...@postgrespro.ru>
Date: Mon Dec 23 19:43:57 2019 +0300
v4-Opclass-bitwise-equality-0002.patch
Mark nbtree opclasses as bitwise in pg_opclass.dat
diff --git a/src/include/catalog/pg_opclass.dat b/src/include/catalog/pg_opclass.dat
index 2d57510..72b563d 100644
--- a/src/include/catalog/pg_opclass.dat
+++ b/src/include/catalog/pg_opclass.dat
@@ -21,26 +21,26 @@
{ opcmethod => 'hash', opcname => 'array_ops', opcfamily => 'hash/array_ops',
opcintype => 'anyarray' },
{ opcmethod => 'btree', opcname => 'bit_ops', opcfamily => 'btree/bit_ops',
- opcintype => 'bit' },
+ opcintype => 'bit', opcisbitwise => 't' },
{ opcmethod => 'btree', opcname => 'bool_ops', opcfamily => 'btree/bool_ops',
- opcintype => 'bool' },
+ opcintype => 'bool', opcisbitwise => 't' },
{ opcmethod => 'btree', opcname => 'bpchar_ops',
opcfamily => 'btree/bpchar_ops', opcintype => 'bpchar' },
{ opcmethod => 'hash', opcname => 'bpchar_ops', opcfamily => 'hash/bpchar_ops',
opcintype => 'bpchar' },
{ opcmethod => 'btree', opcname => 'bytea_ops', opcfamily => 'btree/bytea_ops',
- opcintype => 'bytea' },
+ opcintype => 'bytea', opcisbitwise => 't' },
{ opcmethod => 'btree', opcname => 'char_ops', opcfamily => 'btree/char_ops',
- opcintype => 'char' },
+ opcintype => 'char', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'char_ops', opcfamily => 'hash/char_ops',
opcintype => 'char' },
{ opcmethod => 'btree', opcname => 'cidr_ops', opcfamily => 'btree/network_ops',
- opcintype => 'inet', opcdefault => 'f' },
+ opcintype => 'inet', opcdefault => 'f', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'cidr_ops', opcfamily => 'hash/network_ops',
opcintype => 'inet', opcdefault => 'f' },
{ oid => '3122', oid_symbol => 'DATE_BTREE_OPS_OID',
opcmethod => 'btree', opcname => 'date_ops',
- opcfamily => 'btree/datetime_ops', opcintype => 'date' },
+ opcfamily => 'btree/datetime_ops', opcintype => 'date', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'date_ops', opcfamily => 'hash/date_ops',
opcintype => 'date' },
{ opcmethod => 'btree', opcname => 'float4_ops', opcfamily => 'btree/float_ops',
@@ -62,29 +62,29 @@
opcfamily => 'spgist/network_ops', opcintype => 'inet' },
{ oid => '1979', oid_symbol => 'INT2_BTREE_OPS_OID',
opcmethod => 'btree', opcname => 'int2_ops', opcfamily => 'btree/integer_ops',
- opcintype => 'int2' },
+ opcintype => 'int2', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'int2_ops', opcfamily => 'hash/integer_ops',
opcintype => 'int2' },
{ oid => '1978', oid_symbol => 'INT4_BTREE_OPS_OID',
opcmethod => 'btree', opcname => 'int4_ops', opcfamily => 'btree/integer_ops',
- opcintype => 'int4' },
+ opcintype => 'int4', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'int4_ops', opcfamily => 'hash/integer_ops',
opcintype => 'int4' },
{ oid => '3124', oid_symbol => 'INT8_BTREE_OPS_OID',
opcmethod => 'btree', opcname => 'int8_ops', opcfamily => 'btree/integer_ops',
- opcintype => 'int8' },
+ opcintype => 'int8', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'int8_ops', opcfamily => 'hash/integer_ops',
opcintype => 'int8' },
{ opcmethod => 'btree', opcname => 'interval_ops',
- opcfamily => 'btree/interval_ops', opcintype => 'interval' },
+ opcfamily => 'btree/interval_ops', opcintype => 'interval', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'interval_ops',
opcfamily => 'hash/interval_ops', opcintype => 'interval' },
{ opcmethod => 'btree', opcname => 'macaddr_ops',
- opcfamily => 'btree/macaddr_ops', opcintype => 'macaddr' },
+ opcfamily => 'btree/macaddr_ops', opcintype => 'macaddr', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'macaddr_ops',
opcfamily => 'hash/macaddr_ops', opcintype => 'macaddr' },
{ opcmethod => 'btree', opcname => 'macaddr8_ops',
- opcfamily => 'btree/macaddr8_ops', opcintype => 'macaddr8' },
+ opcfamily => 'btree/macaddr8_ops', opcintype => 'macaddr8', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'macaddr8_ops',
opcfamily => 'hash/macaddr8_ops', opcintype => 'macaddr8' },
@@ -105,11 +105,11 @@
opcfamily => 'hash/numeric_ops', opcintype => 'numeric' },
{ oid => '1981', oid_symbol => 'OID_BTREE_OPS_OID',
opcmethod => 'btree', opcname => 'oid_ops', opcfamily => 'btree/oid_ops',
- opcintype => 'oid' },
+ opcintype => 'oid', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'oid_ops', opcfamily => 'hash/oid_ops',
opcintype => 'oid' },
{ opcmethod => 'btree', opcname => 'oidvector_ops',
- opcfamily => 'btree/oidvector_ops', opcintype => 'oidvector' },
+ opcfamily => 'btree/oidvector_ops', opcintype => 'oidvector', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'oidvector_ops',
opcfamily => 'hash/oidvector_ops', opcintype => 'oidvector' },
{ opcmethod => 'btree', opcname => 'record_ops',
@@ -123,27 +123,27 @@
{ opcmethod => 'hash', opcname => 'text_ops', opcfamily => 'hash/text_ops',
opcintype => 'text' },
{ opcmethod => 'btree', opcname => 'time_ops', opcfamily => 'btree/time_ops',
- opcintype => 'time' },
+ opcintype => 'time', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'time_ops', opcfamily => 'hash/time_ops',
opcintype => 'time' },
{ oid => '3127', oid_symbol => 'TIMESTAMPTZ_BTREE_OPS_OID',
opcmethod => 'btree', opcname => 'timestamptz_ops',
- opcfamily => 'btree/datetime_ops', opcintype => 'timestamptz' },
+ opcfamily => 'btree/datetime_ops', opcintype => 'timestamptz', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'timestamptz_ops',
opcfamily => 'hash/timestamptz_ops', opcintype => 'timestamptz' },
{ opcmethod => 'btree', opcname => 'timetz_ops',
- opcfamily => 'btree/timetz_ops', opcintype => 'timetz' },
+ opcfamily => 'btree/timetz_ops', opcintype => 'timetz', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'timetz_ops', opcfamily => 'hash/timetz_ops',
opcintype => 'timetz' },
{ opcmethod => 'btree', opcname => 'varbit_ops',
- opcfamily => 'btree/varbit_ops', opcintype => 'varbit' },
+ opcfamily => 'btree/varbit_ops', opcintype => 'varbit', opcisbitwise => 't' },
{ opcmethod => 'btree', opcname => 'varchar_ops', opcfamily => 'btree/text_ops',
opcintype => 'text', opcdefault => 'f' },
{ opcmethod => 'hash', opcname => 'varchar_ops', opcfamily => 'hash/text_ops',
opcintype => 'text', opcdefault => 'f' },
{ oid => '3128', oid_symbol => 'TIMESTAMP_BTREE_OPS_OID',
opcmethod => 'btree', opcname => 'timestamp_ops',
- opcfamily => 'btree/datetime_ops', opcintype => 'timestamp' },
+ opcfamily => 'btree/datetime_ops', opcintype => 'timestamp', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'timestamp_ops',
opcfamily => 'hash/timestamp_ops', opcintype => 'timestamp' },
{ oid => '4217', oid_symbol => 'TEXT_BTREE_PATTERN_OPS_OID',
@@ -165,7 +165,7 @@
{ opcmethod => 'hash', opcname => 'bytea_ops', opcfamily => 'hash/bytea_ops',
opcintype => 'bytea' },
{ opcmethod => 'btree', opcname => 'tid_ops', opcfamily => 'btree/tid_ops',
- opcintype => 'tid' },
+ opcintype => 'tid', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'xid_ops', opcfamily => 'hash/xid_ops',
opcintype => 'xid' },
{ opcmethod => 'hash', opcname => 'cid_ops', opcfamily => 'hash/cid_ops',
@@ -194,11 +194,11 @@
{ opcmethod => 'gin', opcname => 'array_ops', opcfamily => 'gin/array_ops',
opcintype => 'anyarray', opckeytype => 'anyelement' },
{ opcmethod => 'btree', opcname => 'uuid_ops', opcfamily => 'btree/uuid_ops',
- opcintype => 'uuid' },
+ opcintype => 'uuid', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'uuid_ops', opcfamily => 'hash/uuid_ops',
opcintype => 'uuid' },
{ opcmethod => 'btree', opcname => 'pg_lsn_ops',
- opcfamily => 'btree/pg_lsn_ops', opcintype => 'pg_lsn' },
+ opcfamily => 'btree/pg_lsn_ops', opcintype => 'pg_lsn', opcisbitwise => 't' },
{ opcmethod => 'hash', opcname => 'pg_lsn_ops', opcfamily => 'hash/pg_lsn_ops',
opcintype => 'pg_lsn' },
{ opcmethod => 'btree', opcname => 'enum_ops', opcfamily => 'btree/enum_ops',
# 403 is btree am oid
select opcname from pg_opclass where opcmethod= 403 and opcisbitwise = true;
opcname
-----------------
bit_ops
bool_ops
bytea_ops
char_ops
cidr_ops
date_ops
int2_ops
int4_ops
int8_ops
interval_ops
macaddr_ops
macaddr8_ops
oid_ops
oidvector_ops
time_ops
timestamptz_ops
timetz_ops
varbit_ops
timestamp_ops
tid_ops
uuid_ops
pg_lsn_ops
(22 rows)
select opcname from pg_opclass where opcmethod= 403 and opcisbitwise = false;
opcname
---------------------
array_ops
bpchar_ops
float4_ops
float8_ops
inet_ops
name_ops
numeric_ops
record_ops
record_image_ops
text_ops
varchar_ops
text_pattern_ops
varchar_pattern_ops
bpchar_pattern_ops
money_ops
enum_ops
tsvector_ops
tsquery_ops
range_ops
jsonb_ops
(20 rows)