mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +03:00
Adjust the APIs for GIN opclass support functions to allow the extractQuery()
method to pass extra data to the consistent() and comparePartial() methods. This is the core infrastructure needed to support the soon-to-appear contrib/btree_gin module. The APIs are still upward compatible with the definitions used in 8.3 and before, although *not* with the previous 8.4devel function definitions. catversion bump for changes in pg_proc entries (although these are just cosmetic, since GIN doesn't actually look at the function signature before calling it...) Teodor Sigaev and Oleg Bartunov
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/tsginidx.c,v 1.14 2009/01/01 17:23:50 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/tsginidx.c,v 1.15 2009/03/25 22:19:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -43,8 +43,9 @@ gin_cmp_prefix(PG_FUNCTION_ARGS)
|
||||
text *b = PG_GETARG_TEXT_PP(1);
|
||||
#ifdef NOT_USED
|
||||
StrategyNumber strategy = PG_GETARG_UINT16(2);
|
||||
Pointer extra_data = PG_GETARG_POINTER(3);
|
||||
#endif
|
||||
int cmp;
|
||||
int cmp;
|
||||
|
||||
cmp = tsCompareString(
|
||||
VARDATA_ANY(a), VARSIZE_ANY_EXHDR(a),
|
||||
@@ -96,6 +97,7 @@ gin_extract_tsquery(PG_FUNCTION_ARGS)
|
||||
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
|
||||
/* StrategyNumber strategy = PG_GETARG_UINT16(2); */
|
||||
bool **ptr_partialmatch = (bool**) PG_GETARG_POINTER(3);
|
||||
Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4);
|
||||
Datum *entries = NULL;
|
||||
bool *partialmatch;
|
||||
|
||||
@@ -108,6 +110,7 @@ gin_extract_tsquery(PG_FUNCTION_ARGS)
|
||||
len;
|
||||
QueryItem *item;
|
||||
bool use_fullscan=false;
|
||||
int *map_item_operand;
|
||||
|
||||
item = clean_NOT(GETQUERY(query), &len);
|
||||
if (!item)
|
||||
@@ -125,6 +128,15 @@ gin_extract_tsquery(PG_FUNCTION_ARGS)
|
||||
entries = (Datum *) palloc(sizeof(Datum) * (*nentries));
|
||||
partialmatch = *ptr_partialmatch = (bool*) palloc(sizeof(bool) * (*nentries));
|
||||
|
||||
/*
|
||||
* Make map to convert item's number to corresponding
|
||||
* operand's (the same, entry's) number. Entry's number
|
||||
* is used in check array in consistent method. We use
|
||||
* the same map for each entry.
|
||||
*/
|
||||
*extra_data = (Pointer*) palloc0(sizeof(Pointer)*(*nentries));
|
||||
map_item_operand = palloc0(sizeof(int) * (query->size + 1));
|
||||
|
||||
for (i = 0; i < query->size; i++)
|
||||
if (item[i].type == QI_VAL)
|
||||
{
|
||||
@@ -133,12 +145,18 @@ gin_extract_tsquery(PG_FUNCTION_ARGS)
|
||||
|
||||
txt = cstring_to_text_with_len(GETOPERAND(query) + val->distance,
|
||||
val->length);
|
||||
(*extra_data)[j] = (Pointer)map_item_operand;
|
||||
map_item_operand[i] = j;
|
||||
partialmatch[j] = val->prefix;
|
||||
entries[j++] = PointerGetDatum(txt);
|
||||
}
|
||||
|
||||
if ( use_fullscan )
|
||||
{
|
||||
(*extra_data)[j] = (Pointer)map_item_operand;
|
||||
map_item_operand[i] = j;
|
||||
entries[j++] = PointerGetDatum(cstring_to_text_with_len("", 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
*nentries = -1; /* nothing can be found */
|
||||
@@ -150,8 +168,9 @@ gin_extract_tsquery(PG_FUNCTION_ARGS)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
QueryItem *frst;
|
||||
bool *mapped_check;
|
||||
QueryItem *first_item;
|
||||
bool *check;
|
||||
int *map_item_operand;
|
||||
bool *need_recheck;
|
||||
} GinChkVal;
|
||||
|
||||
@@ -159,12 +178,17 @@ static bool
|
||||
checkcondition_gin(void *checkval, QueryOperand *val)
|
||||
{
|
||||
GinChkVal *gcv = (GinChkVal *) checkval;
|
||||
int j;
|
||||
|
||||
/* if any val requiring a weight is used, set recheck flag */
|
||||
if (val->weight != 0)
|
||||
*(gcv->need_recheck) = true;
|
||||
|
||||
return gcv->mapped_check[((QueryItem *) val) - gcv->frst];
|
||||
/* convert item's number to corresponding entry's (operand's) number */
|
||||
j = gcv->map_item_operand[ ((QueryItem *) val) - gcv->first_item ];
|
||||
|
||||
/* return presence of current entry in indexed value */
|
||||
return gcv->check[j];
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -173,7 +197,9 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS)
|
||||
bool *check = (bool *) PG_GETARG_POINTER(0);
|
||||
/* StrategyNumber strategy = PG_GETARG_UINT16(1); */
|
||||
TSQuery query = PG_GETARG_TSQUERY(2);
|
||||
bool *recheck = (bool *) PG_GETARG_POINTER(3);
|
||||
/* int32 nkeys = PG_GETARG_INT32(3); */
|
||||
Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4);
|
||||
bool *recheck = (bool *) PG_GETARG_POINTER(5);
|
||||
bool res = FALSE;
|
||||
|
||||
/* The query requires recheck only if it involves weights */
|
||||
@@ -181,27 +207,18 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS)
|
||||
|
||||
if (query->size > 0)
|
||||
{
|
||||
int i,
|
||||
j = 0;
|
||||
QueryItem *item;
|
||||
GinChkVal gcv;
|
||||
|
||||
/*
|
||||
* check-parameter array has one entry for each value (operand) in the
|
||||
* query. We expand that array into mapped_check, so that there's one
|
||||
* entry in mapped_check for every node in the query, including
|
||||
* operators, to allow quick lookups in checkcondition_gin. Only the
|
||||
* entries corresponding operands are actually used.
|
||||
* query.
|
||||
*/
|
||||
|
||||
gcv.frst = item = GETQUERY(query);
|
||||
gcv.mapped_check = (bool *) palloc(sizeof(bool) * query->size);
|
||||
gcv.first_item = item = GETQUERY(query);
|
||||
gcv.check = check;
|
||||
gcv.map_item_operand = (int*)(extra_data[0]);
|
||||
gcv.need_recheck = recheck;
|
||||
|
||||
for (i = 0; i < query->size; i++)
|
||||
if (item[i].type == QI_VAL)
|
||||
gcv.mapped_check[i] = check[j++];
|
||||
|
||||
res = TS_execute(
|
||||
GETQUERY(query),
|
||||
&gcv,
|
||||
|
||||
Reference in New Issue
Block a user