forked from huawei/openGauss-server
167 lines
5.0 KiB
C++
167 lines
5.0 KiB
C++
/*
|
|
* contrib/intarray/_int_gin.c
|
|
*/
|
|
#include "postgres.h"
|
|
#include "knl/knl_variable.h"
|
|
|
|
#include "access/gin.h"
|
|
#include "access/gist.h"
|
|
#include "access/skey.h"
|
|
|
|
#include "_int.h"
|
|
|
|
PG_FUNCTION_INFO_V1(ginint4_queryextract);
|
|
extern "C" Datum ginint4_queryextract(PG_FUNCTION_ARGS);
|
|
|
|
Datum ginint4_queryextract(PG_FUNCTION_ARGS)
|
|
{
|
|
int32* nentries = (int32*)PG_GETARG_POINTER(1);
|
|
StrategyNumber strategy = PG_GETARG_UINT16(2);
|
|
int32* searchMode = (int32*)PG_GETARG_POINTER(6);
|
|
Datum* res = NULL;
|
|
|
|
*nentries = 0;
|
|
|
|
if (strategy == BooleanSearchStrategy) {
|
|
QUERYTYPE* query = PG_GETARG_QUERYTYPE_P(0);
|
|
ITEM* items = GETQUERY(query);
|
|
int i;
|
|
|
|
/* empty query must fail */
|
|
if (query->size <= 0)
|
|
PG_RETURN_POINTER(NULL);
|
|
|
|
/*
|
|
* If the query doesn't have any required primitive values (for
|
|
* instance, it's something like '! 42'), we have to do a full index
|
|
* scan.
|
|
*/
|
|
if (query_has_required_values(query))
|
|
*searchMode = GIN_SEARCH_MODE_DEFAULT;
|
|
else
|
|
*searchMode = GIN_SEARCH_MODE_ALL;
|
|
|
|
/*
|
|
* Extract all the VAL items as things we want GIN to check for.
|
|
*/
|
|
res = (Datum*)palloc(sizeof(Datum) * query->size);
|
|
*nentries = 0;
|
|
|
|
for (i = 0; i < query->size; i++) {
|
|
if (items[i].type == VAL) {
|
|
res[*nentries] = Int32GetDatum(items[i].val);
|
|
(*nentries)++;
|
|
}
|
|
}
|
|
} else {
|
|
ArrayType* query = PG_GETARG_ARRAYTYPE_P(0);
|
|
|
|
CHECKARRVALID(query);
|
|
*nentries = ARRNELEMS(query);
|
|
if (*nentries > 0) {
|
|
int4* arr = NULL;
|
|
int32 i;
|
|
|
|
res = (Datum*)palloc(sizeof(Datum) * (*nentries));
|
|
|
|
arr = ARRPTR(query);
|
|
for (i = 0; i < *nentries; i++)
|
|
res[i] = Int32GetDatum(arr[i]);
|
|
}
|
|
|
|
switch (strategy) {
|
|
case RTOverlapStrategyNumber:
|
|
*searchMode = GIN_SEARCH_MODE_DEFAULT;
|
|
break;
|
|
case RTContainedByStrategyNumber:
|
|
case RTOldContainedByStrategyNumber:
|
|
/* empty set is contained in everything */
|
|
*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
|
|
break;
|
|
case RTSameStrategyNumber:
|
|
if (*nentries > 0)
|
|
*searchMode = GIN_SEARCH_MODE_DEFAULT;
|
|
else
|
|
*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
|
|
break;
|
|
case RTContainsStrategyNumber:
|
|
case RTOldContainsStrategyNumber:
|
|
if (*nentries > 0)
|
|
*searchMode = GIN_SEARCH_MODE_DEFAULT;
|
|
else /* everything contains the empty set */
|
|
*searchMode = GIN_SEARCH_MODE_ALL;
|
|
break;
|
|
default:
|
|
elog(ERROR, "ginint4_queryextract: unknown strategy number: %d", strategy);
|
|
}
|
|
}
|
|
|
|
PG_RETURN_POINTER(res);
|
|
}
|
|
|
|
PG_FUNCTION_INFO_V1(ginint4_consistent);
|
|
extern "C" Datum ginint4_consistent(PG_FUNCTION_ARGS);
|
|
|
|
Datum ginint4_consistent(PG_FUNCTION_ARGS)
|
|
{
|
|
bool* check = (bool*)PG_GETARG_POINTER(0);
|
|
StrategyNumber strategy = PG_GETARG_UINT16(1);
|
|
int32 nkeys = PG_GETARG_INT32(3);
|
|
|
|
bool* recheck = (bool*)PG_GETARG_POINTER(5);
|
|
bool res = FALSE;
|
|
int32 i;
|
|
|
|
switch (strategy) {
|
|
case RTOverlapStrategyNumber:
|
|
/* result is not lossy */
|
|
*recheck = false;
|
|
/* at least one element in check[] is true, so result = true */
|
|
res = TRUE;
|
|
break;
|
|
case RTContainedByStrategyNumber:
|
|
case RTOldContainedByStrategyNumber:
|
|
/* we will need recheck */
|
|
*recheck = true;
|
|
/* at least one element in check[] is true, so result = true */
|
|
res = TRUE;
|
|
break;
|
|
case RTSameStrategyNumber:
|
|
/* we will need recheck */
|
|
*recheck = true;
|
|
/* Must have all elements in check[] true */
|
|
res = TRUE;
|
|
for (i = 0; i < nkeys; i++) {
|
|
if (!check[i]) {
|
|
res = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case RTContainsStrategyNumber:
|
|
case RTOldContainsStrategyNumber:
|
|
/* result is not lossy */
|
|
*recheck = false;
|
|
/* Must have all elements in check[] true */
|
|
res = TRUE;
|
|
for (i = 0; i < nkeys; i++) {
|
|
if (!check[i]) {
|
|
res = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case BooleanSearchStrategy: {
|
|
QUERYTYPE* query = PG_GETARG_QUERYTYPE_P(2);
|
|
|
|
/* result is not lossy */
|
|
*recheck = false;
|
|
res = gin_bool_consistent(query, check);
|
|
} break;
|
|
default:
|
|
elog(ERROR, "ginint4_consistent: unknown strategy number: %d", strategy);
|
|
}
|
|
|
|
PG_RETURN_BOOL(res);
|
|
}
|