Commit db5f98ab authored by Alvaro Herrera's avatar Alvaro Herrera

Improve BRIN infra, minmax opclass and regression test

The minmax opclass was using the wrong support functions when
cross-datatypes queries were run.  Instead of trying to fix the
pg_amproc definitions (which apparently is not possible), use the
already correct pg_amop entries instead.  This requires jumping through
more hoops (read: extra syscache lookups) to obtain the underlying
functions to execute, but it is necessary for correctness.

Author: Emre Hasegeli, tweaked by Álvaro
Review: Andreas Karlsson

Also change BrinOpcInfo to record each stored type's typecache entry
instead of just the OID.  Turns out that the full type cache is
necessary in brin_deform_tuple: the original code used the indexed
type's byval and typlen properties to extract the stored tuple, which is
correct in Minmax; but in other implementations that want to store
something different, that's wrong.  The realization that this is a bug
comes from Emre also, but I did not use his patch.

I also adopted Emre's regression test code (with smallish changes),
which is more complete.
parent 7be47c56
...@@ -181,7 +181,7 @@ brin_page_items(PG_FUNCTION_ARGS) ...@@ -181,7 +181,7 @@ brin_page_items(PG_FUNCTION_ARGS)
column->nstored = opcinfo->oi_nstored; column->nstored = opcinfo->oi_nstored;
for (i = 0; i < opcinfo->oi_nstored; i++) for (i = 0; i < opcinfo->oi_nstored; i++)
{ {
getTypeOutputInfo(opcinfo->oi_typids[i], &output, &isVarlena); getTypeOutputInfo(opcinfo->oi_typcache[i]->type_id, &output, &isVarlena);
fmgr_info(output, &column->outputFn[i]); fmgr_info(output, &column->outputFn[i]);
} }
......
...@@ -428,8 +428,8 @@ typedef struct BrinOpcInfo ...@@ -428,8 +428,8 @@ typedef struct BrinOpcInfo
/* Opaque pointer for the opclass' private use */ /* Opaque pointer for the opclass' private use */
void *oi_opaque; void *oi_opaque;
/* Type IDs of the stored columns */ /* Type cache entries of the stored columns */
Oid oi_typids[FLEXIBLE_ARRAY_MEMBER]; TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo; } BrinOpcInfo;
</programlisting> </programlisting>
<structname>BrinOpcInfo</>.<structfield>oi_opaque</> can be used by the <structname>BrinOpcInfo</>.<structfield>oi_opaque</> can be used by the
......
...@@ -15,35 +15,21 @@ ...@@ -15,35 +15,21 @@
#include "access/brin_tuple.h" #include "access/brin_tuple.h"
#include "access/skey.h" #include "access/skey.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "catalog/pg_amop.h"
#include "utils/datum.h" #include "utils/datum.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h" #include "utils/syscache.h"
/*
* Procedure numbers must not collide with BRIN_PROCNUM defines in
* brin_internal.h. Note we only need inequality functions.
*/
#define MINMAX_NUM_PROCNUMS 4 /* # support procs we need */
#define PROCNUM_LESS 11
#define PROCNUM_LESSEQUAL 12
#define PROCNUM_GREATEREQUAL 13
#define PROCNUM_GREATER 14
/*
* Subtract this from procnum to obtain index in MinmaxOpaque arrays
* (Must be equal to minimum of private procnums)
*/
#define PROCNUM_BASE 11
typedef struct MinmaxOpaque typedef struct MinmaxOpaque
{ {
FmgrInfo operators[MINMAX_NUM_PROCNUMS]; Oid cached_subtype;
bool inited[MINMAX_NUM_PROCNUMS]; FmgrInfo strategy_procinfos[BTMaxStrategyNumber];
} MinmaxOpaque; } MinmaxOpaque;
static FmgrInfo *minmax_get_procinfo(BrinDesc *bdesc, uint16 attno, static FmgrInfo *minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno,
uint16 procnum); Oid subtype, uint16 strategynum);
Datum Datum
...@@ -53,8 +39,8 @@ brin_minmax_opcinfo(PG_FUNCTION_ARGS) ...@@ -53,8 +39,8 @@ brin_minmax_opcinfo(PG_FUNCTION_ARGS)
BrinOpcInfo *result; BrinOpcInfo *result;
/* /*
* opaque->operators is initialized lazily, as indicated by 'inited' which * opaque->strategy_procinfos is initialized lazily; here it is set to
* is initialized to all false by palloc0. * all-uninitialized by palloc0 which sets fn_oid to InvalidOid.
*/ */
result = palloc0(MAXALIGN(SizeofBrinOpcInfo(2)) + result = palloc0(MAXALIGN(SizeofBrinOpcInfo(2)) +
...@@ -62,8 +48,8 @@ brin_minmax_opcinfo(PG_FUNCTION_ARGS) ...@@ -62,8 +48,8 @@ brin_minmax_opcinfo(PG_FUNCTION_ARGS)
result->oi_nstored = 2; result->oi_nstored = 2;
result->oi_opaque = (MinmaxOpaque *) result->oi_opaque = (MinmaxOpaque *)
MAXALIGN((char *) result + SizeofBrinOpcInfo(2)); MAXALIGN((char *) result + SizeofBrinOpcInfo(2));
result->oi_typids[0] = typoid; result->oi_typcache[0] = result->oi_typcache[1] =
result->oi_typids[1] = typoid; lookup_type_cache(typoid, 0);
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }
...@@ -122,7 +108,8 @@ brin_minmax_add_value(PG_FUNCTION_ARGS) ...@@ -122,7 +108,8 @@ brin_minmax_add_value(PG_FUNCTION_ARGS)
* and update them accordingly. First check if it's less than the * and update them accordingly. First check if it's less than the
* existing minimum. * existing minimum.
*/ */
cmpFn = minmax_get_procinfo(bdesc, attno, PROCNUM_LESS); cmpFn = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
BTLessStrategyNumber);
compar = FunctionCall2Coll(cmpFn, colloid, newval, column->bv_values[0]); compar = FunctionCall2Coll(cmpFn, colloid, newval, column->bv_values[0]);
if (DatumGetBool(compar)) if (DatumGetBool(compar))
{ {
...@@ -135,7 +122,8 @@ brin_minmax_add_value(PG_FUNCTION_ARGS) ...@@ -135,7 +122,8 @@ brin_minmax_add_value(PG_FUNCTION_ARGS)
/* /*
* And now compare it to the existing maximum. * And now compare it to the existing maximum.
*/ */
cmpFn = minmax_get_procinfo(bdesc, attno, PROCNUM_GREATER); cmpFn = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
BTGreaterStrategyNumber);
compar = FunctionCall2Coll(cmpFn, colloid, newval, column->bv_values[1]); compar = FunctionCall2Coll(cmpFn, colloid, newval, column->bv_values[1]);
if (DatumGetBool(compar)) if (DatumGetBool(compar))
{ {
...@@ -159,10 +147,12 @@ brin_minmax_consistent(PG_FUNCTION_ARGS) ...@@ -159,10 +147,12 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
ScanKey key = (ScanKey) PG_GETARG_POINTER(2); ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
Oid colloid = PG_GET_COLLATION(); Oid colloid = PG_GET_COLLATION(),
subtype;
AttrNumber attno; AttrNumber attno;
Datum value; Datum value;
Datum matches; Datum matches;
FmgrInfo *finfo;
Assert(key->sk_attno == column->bv_attno); Assert(key->sk_attno == column->bv_attno);
...@@ -189,18 +179,16 @@ brin_minmax_consistent(PG_FUNCTION_ARGS) ...@@ -189,18 +179,16 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);
attno = key->sk_attno; attno = key->sk_attno;
subtype = key->sk_subtype;
value = key->sk_argument; value = key->sk_argument;
switch (key->sk_strategy) switch (key->sk_strategy)
{ {
case BTLessStrategyNumber: case BTLessStrategyNumber:
matches = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno,
PROCNUM_LESS),
colloid, column->bv_values[0], value);
break;
case BTLessEqualStrategyNumber: case BTLessEqualStrategyNumber:
matches = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno, finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
PROCNUM_LESSEQUAL), key->sk_strategy);
colloid, column->bv_values[0], value); matches = FunctionCall2Coll(finfo, colloid, column->bv_values[0],
value);
break; break;
case BTEqualStrategyNumber: case BTEqualStrategyNumber:
...@@ -209,25 +197,24 @@ brin_minmax_consistent(PG_FUNCTION_ARGS) ...@@ -209,25 +197,24 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
* the current page range if the minimum value in the range <= * the current page range if the minimum value in the range <=
* scan key, and the maximum value >= scan key. * scan key, and the maximum value >= scan key.
*/ */
matches = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno, finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
PROCNUM_LESSEQUAL), BTLessEqualStrategyNumber);
colloid, column->bv_values[0], value); matches = FunctionCall2Coll(finfo, colloid, column->bv_values[0],
value);
if (!DatumGetBool(matches)) if (!DatumGetBool(matches))
break; break;
/* max() >= scankey */ /* max() >= scankey */
matches = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno, finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
PROCNUM_GREATEREQUAL), BTGreaterEqualStrategyNumber);
colloid, column->bv_values[1], value); matches = FunctionCall2Coll(finfo, colloid, column->bv_values[1],
value);
break; break;
case BTGreaterEqualStrategyNumber: case BTGreaterEqualStrategyNumber:
matches = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno,
PROCNUM_GREATEREQUAL),
colloid, column->bv_values[1], value);
break;
case BTGreaterStrategyNumber: case BTGreaterStrategyNumber:
matches = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno, finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
PROCNUM_GREATER), key->sk_strategy);
colloid, column->bv_values[1], value); matches = FunctionCall2Coll(finfo, colloid, column->bv_values[1],
value);
break; break;
default: default:
/* shouldn't happen */ /* shouldn't happen */
...@@ -252,6 +239,7 @@ brin_minmax_union(PG_FUNCTION_ARGS) ...@@ -252,6 +239,7 @@ brin_minmax_union(PG_FUNCTION_ARGS)
Oid colloid = PG_GET_COLLATION(); Oid colloid = PG_GET_COLLATION();
AttrNumber attno; AttrNumber attno;
Form_pg_attribute attr; Form_pg_attribute attr;
FmgrInfo *finfo;
bool needsadj; bool needsadj;
Assert(col_a->bv_attno == col_b->bv_attno); Assert(col_a->bv_attno == col_b->bv_attno);
...@@ -284,9 +272,10 @@ brin_minmax_union(PG_FUNCTION_ARGS) ...@@ -284,9 +272,10 @@ brin_minmax_union(PG_FUNCTION_ARGS)
} }
/* Adjust minimum, if B's min is less than A's min */ /* Adjust minimum, if B's min is less than A's min */
needsadj = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno, finfo = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
PROCNUM_LESS), BTLessStrategyNumber);
colloid, col_b->bv_values[0], col_a->bv_values[0]); needsadj = FunctionCall2Coll(finfo, colloid, col_b->bv_values[0],
col_a->bv_values[0]);
if (needsadj) if (needsadj)
{ {
if (!attr->attbyval) if (!attr->attbyval)
...@@ -296,9 +285,10 @@ brin_minmax_union(PG_FUNCTION_ARGS) ...@@ -296,9 +285,10 @@ brin_minmax_union(PG_FUNCTION_ARGS)
} }
/* Adjust maximum, if B's max is greater than A's max */ /* Adjust maximum, if B's max is greater than A's max */
needsadj = FunctionCall2Coll(minmax_get_procinfo(bdesc, attno, finfo = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
PROCNUM_GREATER), BTGreaterStrategyNumber);
colloid, col_b->bv_values[1], col_a->bv_values[1]); needsadj = FunctionCall2Coll(finfo, colloid, col_b->bv_values[1],
col_a->bv_values[1]);
if (needsadj) if (needsadj)
{ {
if (!attr->attbyval) if (!attr->attbyval)
...@@ -311,27 +301,61 @@ brin_minmax_union(PG_FUNCTION_ARGS) ...@@ -311,27 +301,61 @@ brin_minmax_union(PG_FUNCTION_ARGS)
} }
/* /*
* Return the procedure corresponding to the given function support number. * Cache and return the procedure for the given strategy.
*/ */
static FmgrInfo * FmgrInfo *
minmax_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum) minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype,
uint16 strategynum)
{ {
MinmaxOpaque *opaque; MinmaxOpaque *opaque;
uint16 basenum = procnum - PROCNUM_BASE;
Assert(strategynum >= 1 &&
strategynum <= BTMaxStrategyNumber);
opaque = (MinmaxOpaque *) bdesc->bd_info[attno - 1]->oi_opaque; opaque = (MinmaxOpaque *) bdesc->bd_info[attno - 1]->oi_opaque;
/* /*
* We cache these in the opaque struct, to avoid repetitive syscache * We cache the procedures for the previous subtype in the opaque struct,
* lookups. * to avoid repetitive syscache lookups. If the subtype changed,
* invalidate all the cached entries.
*/ */
if (!opaque->inited[basenum]) if (opaque->cached_subtype != subtype)
{
uint16 i;
for (i = 1; i <= BTMaxStrategyNumber; i++)
opaque->strategy_procinfos[i - 1].fn_oid = InvalidOid;
opaque->cached_subtype = subtype;
}
if (opaque->strategy_procinfos[strategynum - 1].fn_oid == InvalidOid)
{ {
fmgr_info_copy(&opaque->operators[basenum], Form_pg_attribute attr;
index_getprocinfo(bdesc->bd_index, attno, procnum), HeapTuple tuple;
bdesc->bd_context); Oid opfamily,
opaque->inited[basenum] = true; oprid;
bool isNull;
opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
attr = bdesc->bd_tupdesc->attrs[attno - 1];
tuple = SearchSysCache4(AMOPSTRATEGY, ObjectIdGetDatum(opfamily),
ObjectIdGetDatum(attr->atttypid),
ObjectIdGetDatum(subtype),
Int16GetDatum(strategynum));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
strategynum, attr->atttypid, subtype, opfamily);
oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple,
Anum_pg_amop_amopopr, &isNull));
ReleaseSysCache(tuple);
Assert(!isNull && RegProcedureIsValid(oprid));
fmgr_info_cxt(get_opcode(oprid),
&opaque->strategy_procinfos[strategynum - 1],
bdesc->bd_context);
} }
return &opaque->operators[basenum]; return &opaque->strategy_procinfos[strategynum - 1];
} }
...@@ -68,7 +68,7 @@ brtuple_disk_tupdesc(BrinDesc *brdesc) ...@@ -68,7 +68,7 @@ brtuple_disk_tupdesc(BrinDesc *brdesc)
{ {
for (j = 0; j < brdesc->bd_info[i]->oi_nstored; j++) for (j = 0; j < brdesc->bd_info[i]->oi_nstored; j++)
TupleDescInitEntry(tupdesc, attno++, NULL, TupleDescInitEntry(tupdesc, attno++, NULL,
brdesc->bd_info[i]->oi_typids[j], brdesc->bd_info[i]->oi_typcache[j]->type_id,
-1, 0); -1, 0);
} }
...@@ -444,8 +444,8 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple) ...@@ -444,8 +444,8 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple)
for (i = 0; i < brdesc->bd_info[keyno]->oi_nstored; i++) for (i = 0; i < brdesc->bd_info[keyno]->oi_nstored; i++)
dtup->bt_columns[keyno].bv_values[i] = dtup->bt_columns[keyno].bv_values[i] =
datumCopy(values[valueno++], datumCopy(values[valueno++],
brdesc->bd_tupdesc->attrs[keyno]->attbyval, brdesc->bd_info[keyno]->oi_typcache[i]->typbyval,
brdesc->bd_tupdesc->attrs[keyno]->attlen); brdesc->bd_info[keyno]->oi_typcache[i]->typlen);
dtup->bt_columns[keyno].bv_hasnulls = hasnulls[keyno]; dtup->bt_columns[keyno].bv_hasnulls = hasnulls[keyno];
dtup->bt_columns[keyno].bv_allnulls = false; dtup->bt_columns[keyno].bv_allnulls = false;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "storage/bufpage.h" #include "storage/bufpage.h"
#include "storage/off.h" #include "storage/off.h"
#include "utils/relcache.h" #include "utils/relcache.h"
#include "utils/typcache.h"
/* /*
...@@ -32,13 +33,13 @@ typedef struct BrinOpcInfo ...@@ -32,13 +33,13 @@ typedef struct BrinOpcInfo
/* Opaque pointer for the opclass' private use */ /* Opaque pointer for the opclass' private use */
void *oi_opaque; void *oi_opaque;
/* Type IDs of the stored columns */ /* Type cache entries of the stored columns */
Oid oi_typids[FLEXIBLE_ARRAY_MEMBER]; TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo; } BrinOpcInfo;
/* the size of a BrinOpcInfo for the given number of columns */ /* the size of a BrinOpcInfo for the given number of columns */
#define SizeofBrinOpcInfo(ncols) \ #define SizeofBrinOpcInfo(ncols) \
(offsetof(BrinOpcInfo, oi_typids) + sizeof(Oid) * ncols) (offsetof(BrinOpcInfo, oi_typcache) + sizeof(TypeCacheEntry *) * ncols)
typedef struct BrinDesc typedef struct BrinDesc
{ {
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201505051 #define CATALOG_VERSION_NO 201505071
#endif #endif
This diff is collapsed.
...@@ -238,34 +238,34 @@ DATA(insert ( 2742 jsonb_path_ops PGNSP PGUID 4037 3802 f 23 )); ...@@ -238,34 +238,34 @@ DATA(insert ( 2742 jsonb_path_ops PGNSP PGUID 4037 3802 f 23 ));
/* BRIN operator classes */ /* BRIN operator classes */
/* no brin opclass for bool */ /* no brin opclass for bool */
DATA(insert ( 3580 bytea_minmax_ops PGNSP PGUID 4064 17 t 0 )); DATA(insert ( 3580 bytea_minmax_ops PGNSP PGUID 4064 17 t 17 ));
DATA(insert ( 3580 char_minmax_ops PGNSP PGUID 4062 18 t 0 )); DATA(insert ( 3580 char_minmax_ops PGNSP PGUID 4062 18 t 18 ));
DATA(insert ( 3580 name_minmax_ops PGNSP PGUID 4065 19 t 0 )); DATA(insert ( 3580 name_minmax_ops PGNSP PGUID 4065 19 t 19 ));
DATA(insert ( 3580 int8_minmax_ops PGNSP PGUID 4054 20 t 0 )); DATA(insert ( 3580 int8_minmax_ops PGNSP PGUID 4054 20 t 20 ));
DATA(insert ( 3580 int2_minmax_ops PGNSP PGUID 4054 21 t 0 )); DATA(insert ( 3580 int2_minmax_ops PGNSP PGUID 4054 21 t 21 ));
DATA(insert ( 3580 int4_minmax_ops PGNSP PGUID 4054 23 t 0 )); DATA(insert ( 3580 int4_minmax_ops PGNSP PGUID 4054 23 t 23 ));
DATA(insert ( 3580 text_minmax_ops PGNSP PGUID 4056 25 t 0 )); DATA(insert ( 3580 text_minmax_ops PGNSP PGUID 4056 25 t 25 ));
DATA(insert ( 3580 oid_minmax_ops PGNSP PGUID 4068 26 t 0 )); DATA(insert ( 3580 oid_minmax_ops PGNSP PGUID 4068 26 t 26 ));
DATA(insert ( 3580 tid_minmax_ops PGNSP PGUID 4069 27 t 0 )); DATA(insert ( 3580 tid_minmax_ops PGNSP PGUID 4069 27 t 27 ));
DATA(insert ( 3580 float4_minmax_ops PGNSP PGUID 4070 700 t 0 )); DATA(insert ( 3580 float4_minmax_ops PGNSP PGUID 4070 700 t 700 ));
DATA(insert ( 3580 float8_minmax_ops PGNSP PGUID 4070 701 t 0 )); DATA(insert ( 3580 float8_minmax_ops PGNSP PGUID 4070 701 t 701 ));
DATA(insert ( 3580 abstime_minmax_ops PGNSP PGUID 4072 702 t 0 )); DATA(insert ( 3580 abstime_minmax_ops PGNSP PGUID 4072 702 t 702 ));
DATA(insert ( 3580 reltime_minmax_ops PGNSP PGUID 4073 703 t 0 )); DATA(insert ( 3580 reltime_minmax_ops PGNSP PGUID 4073 703 t 703 ));
DATA(insert ( 3580 macaddr_minmax_ops PGNSP PGUID 4074 829 t 0 )); DATA(insert ( 3580 macaddr_minmax_ops PGNSP PGUID 4074 829 t 829 ));
DATA(insert ( 3580 inet_minmax_ops PGNSP PGUID 4075 869 f 0 )); DATA(insert ( 3580 inet_minmax_ops PGNSP PGUID 4075 869 f 869 ));
DATA(insert ( 3580 bpchar_minmax_ops PGNSP PGUID 4076 1042 t 0 )); DATA(insert ( 3580 bpchar_minmax_ops PGNSP PGUID 4076 1042 t 1042 ));
DATA(insert ( 3580 time_minmax_ops PGNSP PGUID 4077 1083 t 0 )); DATA(insert ( 3580 time_minmax_ops PGNSP PGUID 4077 1083 t 1083 ));
DATA(insert ( 3580 date_minmax_ops PGNSP PGUID 4059 1082 t 0 )); DATA(insert ( 3580 date_minmax_ops PGNSP PGUID 4059 1082 t 1082 ));
DATA(insert ( 3580 timestamp_minmax_ops PGNSP PGUID 4059 1114 t 0 )); DATA(insert ( 3580 timestamp_minmax_ops PGNSP PGUID 4059 1114 t 1114 ));
DATA(insert ( 3580 timestamptz_minmax_ops PGNSP PGUID 4059 1184 t 0 )); DATA(insert ( 3580 timestamptz_minmax_ops PGNSP PGUID 4059 1184 t 1184 ));
DATA(insert ( 3580 interval_minmax_ops PGNSP PGUID 4078 1186 t 0 )); DATA(insert ( 3580 interval_minmax_ops PGNSP PGUID 4078 1186 t 1186 ));
DATA(insert ( 3580 timetz_minmax_ops PGNSP PGUID 4058 1266 t 0 )); DATA(insert ( 3580 timetz_minmax_ops PGNSP PGUID 4058 1266 t 1266 ));
DATA(insert ( 3580 bit_minmax_ops PGNSP PGUID 4079 1560 t 0 )); DATA(insert ( 3580 bit_minmax_ops PGNSP PGUID 4079 1560 t 1560 ));
DATA(insert ( 3580 varbit_minmax_ops PGNSP PGUID 4080 1562 t 0 )); DATA(insert ( 3580 varbit_minmax_ops PGNSP PGUID 4080 1562 t 1562 ));
DATA(insert ( 3580 numeric_minmax_ops PGNSP PGUID 4055 1700 t 0 )); DATA(insert ( 3580 numeric_minmax_ops PGNSP PGUID 4055 1700 t 1700 ));
/* no brin opclass for record, anyarray */ /* no brin opclass for record, anyarray */
DATA(insert ( 3580 uuid_minmax_ops PGNSP PGUID 4081 2950 t 0 )); DATA(insert ( 3580 uuid_minmax_ops PGNSP PGUID 4081 2950 t 2950 ));
DATA(insert ( 3580 pg_lsn_minmax_ops PGNSP PGUID 4082 3220 t 0 )); DATA(insert ( 3580 pg_lsn_minmax_ops PGNSP PGUID 4082 3220 t 3220 ));
/* no brin opclass for enum, tsvector, tsquery, jsonb, range */ /* no brin opclass for enum, tsvector, tsquery, jsonb, range */
#endif /* PG_OPCLASS_H */ #endif /* PG_OPCLASS_H */
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment