0003-opclass-parameters-GIN-v01.patch
text/x-patch
Filename: 0003-opclass-parameters-GIN-v01.patch
Type: text/x-patch
Part: 2
Message:
[PATCH] Opclass parameters
Patch
Format: unified
Series: patch v1-0003
| File | + | − |
|---|---|---|
| doc/src/sgml/xindex.sgml | 7 | 0 |
| src/backend/access/gin/ginget.c | 6 | 5 |
| src/backend/access/gin/ginlogic.c | 9 | 6 |
| src/backend/access/gin/ginscan.c | 4 | 2 |
| src/backend/access/gin/ginutil.c | 21 | 6 |
| src/backend/access/gin/ginvalidate.c | 20 | 12 |
| src/backend/utils/adt/selfuncs.c | 4 | 2 |
| src/include/access/gin.h | 2 | 1 |
| src/include/access/gin_private.h | 5 | 0 |
diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml
index 2f00930..10937bc 100644
--- a/doc/src/sgml/xindex.sgml
+++ b/doc/src/sgml/xindex.sgml
@@ -665,6 +665,13 @@
</entry>
<entry>6</entry>
</row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>
+ parse opclass-specific options (optional)
+ </entry>
+ <entry>7</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 6fe67f3..eb6b778 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -178,13 +178,13 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
* case cmp < 0 => not match and continue scan
*----------
*/
- cmp = DatumGetInt32(FunctionCall4Coll(&btree->ginstate->comparePartialFn[attnum - 1],
+ cmp = DatumGetInt32(FunctionCall5Coll(&btree->ginstate->comparePartialFn[attnum - 1],
btree->ginstate->supportCollation[attnum - 1],
scanEntry->queryKey,
idatum,
UInt16GetDatum(scanEntry->strategy),
- PointerGetDatum(scanEntry->extra_data)));
-
+ PointerGetDatum(scanEntry->extra_data),
+ PointerGetDatum(btree->ginstate->opclassOptions[attnum - 1])));
if (cmp > 0)
return true;
else if (cmp < 0)
@@ -1460,12 +1460,13 @@ matchPartialInPendingList(GinState *ginstate, Page page,
* case cmp < 0 => not match and continue scan
*----------
*/
- cmp = DatumGetInt32(FunctionCall4Coll(&ginstate->comparePartialFn[entry->attnum - 1],
+ cmp = DatumGetInt32(FunctionCall5Coll(&ginstate->comparePartialFn[entry->attnum - 1],
ginstate->supportCollation[entry->attnum - 1],
entry->queryKey,
datum[off - 1],
UInt16GetDatum(entry->strategy),
- PointerGetDatum(entry->extra_data)));
+ PointerGetDatum(entry->extra_data),
+ PointerGetDatum(ginstate->opclassOptions[entry->attnum - 1])));
if (cmp == 0)
return true;
else if (cmp > 0)
diff --git a/src/backend/access/gin/ginlogic.c b/src/backend/access/gin/ginlogic.c
index 2c42d1a..5ec3931 100644
--- a/src/backend/access/gin/ginlogic.c
+++ b/src/backend/access/gin/ginlogic.c
@@ -76,7 +76,7 @@ directBoolConsistentFn(GinScanKey key)
*/
key->recheckCurItem = true;
- return DatumGetBool(FunctionCall8Coll(key->consistentFmgrInfo,
+ return DatumGetBool(FunctionCall9Coll(key->consistentFmgrInfo,
key->collation,
PointerGetDatum(key->entryRes),
UInt16GetDatum(key->strategy),
@@ -85,7 +85,8 @@ directBoolConsistentFn(GinScanKey key)
PointerGetDatum(key->extra_data),
PointerGetDatum(&key->recheckCurItem),
PointerGetDatum(key->queryValues),
- PointerGetDatum(key->queryCategories)));
+ PointerGetDatum(key->queryCategories),
+ PointerGetDatum(key->opclassOptions)));
}
/*
@@ -94,7 +95,7 @@ directBoolConsistentFn(GinScanKey key)
static GinTernaryValue
directTriConsistentFn(GinScanKey key)
{
- return DatumGetGinTernaryValue(FunctionCall7Coll(
+ return DatumGetGinTernaryValue(FunctionCall8Coll(
key->triConsistentFmgrInfo,
key->collation,
PointerGetDatum(key->entryRes),
@@ -103,7 +104,8 @@ directTriConsistentFn(GinScanKey key)
UInt32GetDatum(key->nuserentries),
PointerGetDatum(key->extra_data),
PointerGetDatum(key->queryValues),
- PointerGetDatum(key->queryCategories)));
+ PointerGetDatum(key->queryCategories),
+ PointerGetDatum(key->opclassOptions)));
}
/*
@@ -116,7 +118,7 @@ shimBoolConsistentFn(GinScanKey key)
{
GinTernaryValue result;
- result = DatumGetGinTernaryValue(FunctionCall7Coll(
+ result = DatumGetGinTernaryValue(FunctionCall8Coll(
key->triConsistentFmgrInfo,
key->collation,
PointerGetDatum(key->entryRes),
@@ -125,7 +127,8 @@ shimBoolConsistentFn(GinScanKey key)
UInt32GetDatum(key->nuserentries),
PointerGetDatum(key->extra_data),
PointerGetDatum(key->queryValues),
- PointerGetDatum(key->queryCategories)));
+ PointerGetDatum(key->queryCategories),
+ PointerGetDatum(key->opclassOptions)));
if (result == GIN_MAYBE)
{
key->recheckCurItem = true;
diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
index 8ade431..6594a29 100644
--- a/src/backend/access/gin/ginscan.c
+++ b/src/backend/access/gin/ginscan.c
@@ -156,6 +156,7 @@ ginFillScanKey(GinScanOpaque so, OffsetNumber attnum,
key->strategy = strategy;
key->searchMode = searchMode;
key->attnum = attnum;
+ key->opclassOptions = ginstate->opclassOptions[attnum - 1];
ItemPointerSetMin(&key->curItem);
key->curItemMatches = false;
@@ -310,7 +311,7 @@ ginNewScanKey(IndexScanDesc scan)
/* OK to call the extractQueryFn */
queryValues = (Datum *)
- DatumGetPointer(FunctionCall7Coll(&so->ginstate.extractQueryFn[skey->sk_attno - 1],
+ DatumGetPointer(FunctionCall8Coll(&so->ginstate.extractQueryFn[skey->sk_attno - 1],
so->ginstate.supportCollation[skey->sk_attno - 1],
skey->sk_argument,
PointerGetDatum(&nQueryValues),
@@ -318,7 +319,8 @@ ginNewScanKey(IndexScanDesc scan)
PointerGetDatum(&partial_matches),
PointerGetDatum(&extra_data),
PointerGetDatum(&nullFlags),
- PointerGetDatum(&searchMode)));
+ PointerGetDatum(&searchMode),
+ PointerGetDatum(so->ginstate.opclassOptions[skey->sk_attno - 1])));
/*
* If bogus searchMode is returned, treat as GIN_SEARCH_MODE_ALL; note
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index 7bac7a1..c34b1bc 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -61,6 +61,7 @@ ginhandler(PG_FUNCTION_ARGS)
amroutine->amcanreturn = NULL;
amroutine->amcostestimate = gincostestimate;
amroutine->amoptions = ginoptions;
+ amroutine->amopclassoptions = ginopclassoptions;
amroutine->amproperty = NULL;
amroutine->amvalidate = ginvalidate;
amroutine->ambeginscan = ginbeginscan;
@@ -93,6 +94,7 @@ initGinState(GinState *state, Relation index)
state->index = index;
state->oneCol = (origTupdesc->natts == 1) ? true : false;
state->origTupdesc = origTupdesc;
+ state->opclassOptions = RelationGetParsedOpclassOptions(index);
for (i = 0; i < origTupdesc->natts; i++)
{
@@ -401,9 +403,10 @@ ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
return 0;
/* both not null, so safe to call the compareFn */
- return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attnum - 1],
+ return DatumGetInt32(FunctionCall3Coll(&ginstate->compareFn[attnum - 1],
ginstate->supportCollation[attnum - 1],
- a, b));
+ a, b,
+ PointerGetDatum(ginstate->opclassOptions[attnum - 1])));
}
/*
@@ -439,6 +442,7 @@ typedef struct
{
FmgrInfo *cmpDatumFunc;
Oid collation;
+ Datum options;
bool haveDups;
} cmpEntriesArg;
@@ -460,9 +464,10 @@ cmpEntries(const void *a, const void *b, void *arg)
else if (bb->isnull)
res = -1; /* not-NULL "<" NULL */
else
- res = DatumGetInt32(FunctionCall2Coll(data->cmpDatumFunc,
+ res = DatumGetInt32(FunctionCall3Coll(data->cmpDatumFunc,
data->collation,
- aa->datum, bb->datum));
+ aa->datum, bb->datum,
+ data->options));
/*
* Detect if we have any duplicates. If there are equal keys, qsort must
@@ -508,11 +513,12 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
/* OK, call the opclass's extractValueFn */
nullFlags = NULL; /* in case extractValue doesn't set it */
entries = (Datum *)
- DatumGetPointer(FunctionCall3Coll(&ginstate->extractValueFn[attnum - 1],
+ DatumGetPointer(FunctionCall4Coll(&ginstate->extractValueFn[attnum - 1],
ginstate->supportCollation[attnum - 1],
value,
PointerGetDatum(nentries),
- PointerGetDatum(&nullFlags)));
+ PointerGetDatum(&nullFlags),
+ PointerGetDatum(ginstate->opclassOptions[attnum - 1])));
/*
* Generate a placeholder if the item contained no keys.
@@ -555,6 +561,7 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
arg.cmpDatumFunc = &ginstate->compareFn[attnum - 1];
arg.collation = ginstate->supportCollation[attnum - 1];
+ arg.options = PointerGetDatum(ginstate->opclassOptions[attnum - 1]);
arg.haveDups = false;
qsort_arg(keydata, *nentries, sizeof(keyEntryData),
cmpEntries, (void *) &arg);
@@ -630,6 +637,14 @@ ginoptions(Datum reloptions, bool validate)
return (bytea *) rdopts;
}
+bytea *
+ginopclassoptions(Relation index, AttrNumber colno, Datum indoptions,
+ bool validate)
+{
+ return index_opclass_options_generic(index, colno, GIN_OPCLASSOPTIONS_PROC,
+ indoptions, validate);
+}
+
/*
* Fetch index's statistical data into *stats
*
diff --git a/src/backend/access/gin/ginvalidate.c b/src/backend/access/gin/ginvalidate.c
index 1035be4..3035c2c 100644
--- a/src/backend/access/gin/ginvalidate.c
+++ b/src/backend/access/gin/ginvalidate.c
@@ -108,40 +108,47 @@ ginvalidate(Oid opclassoid)
{
case GIN_COMPARE_PROC:
ok = check_amproc_signature(procform->amproc, INT4OID, false,
- 2, 2, opckeytype, opckeytype);
+ 2, 3, opckeytype, opckeytype,
+ INTERNALOID);
break;
case GIN_EXTRACTVALUE_PROC:
/* Some opclasses omit nullFlags */
ok = check_amproc_signature(procform->amproc, INTERNALOID, false,
- 2, 3, opcintype, INTERNALOID,
- INTERNALOID);
+ 2, 4, opcintype, INTERNALOID,
+ INTERNALOID, INTERNALOID);
break;
case GIN_EXTRACTQUERY_PROC:
/* Some opclasses omit nullFlags and searchMode */
ok = check_amproc_signature(procform->amproc, INTERNALOID, false,
- 5, 7, opcintype, INTERNALOID,
+ 5, 8, opcintype, INTERNALOID,
INT2OID, INTERNALOID, INTERNALOID,
- INTERNALOID, INTERNALOID);
+ INTERNALOID, INTERNALOID,
+ INTERNALOID);
break;
case GIN_CONSISTENT_PROC:
/* Some opclasses omit queryKeys and nullFlags */
ok = check_amproc_signature(procform->amproc, BOOLOID, false,
- 6, 8, INTERNALOID, INT2OID,
+ 6, 9, INTERNALOID, INT2OID,
opcintype, INT4OID,
INTERNALOID, INTERNALOID,
- INTERNALOID, INTERNALOID);
+ INTERNALOID, INTERNALOID,
+ INTERNALOID);
break;
case GIN_COMPARE_PARTIAL_PROC:
ok = check_amproc_signature(procform->amproc, INT4OID, false,
- 4, 4, opckeytype, opckeytype,
- INT2OID, INTERNALOID);
+ 4, 5, opckeytype, opckeytype,
+ INT2OID, INTERNALOID, INTERNALOID);
break;
case GIN_TRICONSISTENT_PROC:
ok = check_amproc_signature(procform->amproc, CHAROID, false,
- 7, 7, INTERNALOID, INT2OID,
+ 7, 8, INTERNALOID, INT2OID,
opcintype, INT4OID,
INTERNALOID, INTERNALOID,
- INTERNALOID);
+ INTERNALOID, INTERNALOID);
+ break;
+ case GIN_OPCLASSOPTIONS_PROC:
+ ok = check_amproc_signature(procform->amproc, INTERNALOID,
+ false, 2, 2, INTERNALOID, BOOLOID);
break;
default:
ereport(INFO,
@@ -238,7 +245,8 @@ ginvalidate(Oid opclassoid)
if (opclassgroup &&
(opclassgroup->functionset & (((uint64) 1) << i)) != 0)
continue; /* got it */
- if (i == GIN_COMPARE_PROC || i == GIN_COMPARE_PARTIAL_PROC)
+ if (i == GIN_COMPARE_PROC || i == GIN_COMPARE_PARTIAL_PROC ||
+ i == GIN_OPCLASSOPTIONS_PROC)
continue; /* optional method */
if (i == GIN_CONSISTENT_PROC || i == GIN_TRICONSISTENT_PROC)
continue; /* don't need both, see check below loop */
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index fcc8323..65ecf28 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -141,6 +141,7 @@
#include "utils/nabstime.h"
#include "utils/pg_locale.h"
#include "utils/rel.h"
+#include "utils/relcache.h"
#include "utils/selfuncs.h"
#include "utils/snapmgr.h"
#include "utils/spccache.h"
@@ -7410,7 +7411,7 @@ gincost_pattern(IndexOptInfo *index, int indexcol,
else
collation = DEFAULT_COLLATION_OID;
- OidFunctionCall7Coll(extractProcOid,
+ OidFunctionCall8Coll(extractProcOid,
collation,
query,
PointerGetDatum(&nentries),
@@ -7418,7 +7419,8 @@ gincost_pattern(IndexOptInfo *index, int indexcol,
PointerGetDatum(&partial_matches),
PointerGetDatum(&extra_data),
PointerGetDatum(&nullFlags),
- PointerGetDatum(&searchMode));
+ PointerGetDatum(&searchMode),
+ PointerGetDatum(index->opclassoptions[indexcol]));
if (nentries <= 0 && searchMode == GIN_SEARCH_MODE_DEFAULT)
{
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index 0acdb88..6240aab 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -25,7 +25,8 @@
#define GIN_CONSISTENT_PROC 4
#define GIN_COMPARE_PARTIAL_PROC 5
#define GIN_TRICONSISTENT_PROC 6
-#define GINNProcs 6
+#define GIN_OPCLASSOPTIONS_PROC 7
+#define GINNProcs 7
/*
* searchMode settings for extractQueryFn.
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index a709596..d371799 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -67,6 +67,8 @@ typedef struct GinState
TupleDesc origTupdesc;
TupleDesc tupdesc[INDEX_MAX_KEYS];
+ bytea **opclassOptions; /* per-index-column opclass options */
+
/*
* Per-index-column opclass support functions
*/
@@ -85,6 +87,8 @@ typedef struct GinState
/* ginutil.c */
extern bytea *ginoptions(Datum reloptions, bool validate);
+extern bytea *ginopclassoptions(Relation index, AttrNumber colno,
+ Datum indoptions, bool validate);
extern void initGinState(GinState *state, Relation index);
extern Buffer GinNewBuffer(Relation index);
extern void GinInitBuffer(Buffer b, uint32 f);
@@ -297,6 +301,7 @@ typedef struct GinScanKeyData
StrategyNumber strategy;
int32 searchMode;
OffsetNumber attnum;
+ bytea *opclassOptions;
/*
* Match status data. curItem is the TID most recently tested (could be a