52 Datum *elems,
int nelems);
56 bool reverse,
Datum *elems,
int nelems);
59 Oid origelemtype,
Oid nextelemtype,
60 Datum *elems_orig,
int *nelems_orig,
61 Datum *elems_next,
int nelems_next);
157 int new_numberOfKeys;
158 int numberOfEqualCols;
164 int *keyDataMap = NULL;
180 if (numberOfKeys < 1)
198 inkeys = arrayKeyData;
202 numberOfKeys *
sizeof(
int));
208 if (inkeys[0].sk_attno < 1)
209 elog(
ERROR,
"btree index keys must be ordered by attribute");
212 if (numberOfKeys == 1)
220 if (inkeys[0].sk_attno == 1)
241 new_numberOfKeys = 0;
242 numberOfEqualCols = 0;
251 memset(xform, 0,
sizeof(xform));
258 for (
int i = 0;;
i++)
263 if (
i < numberOfKeys)
278 if (
i == numberOfKeys || inkey->
sk_attno != attno)
280 int priorNumberOfEqualCols = numberOfEqualCols;
283 if (i < numberOfKeys && inkey->sk_attno < attno)
284 elog(
ERROR,
"btree index keys must be ordered by attribute");
349 xform[
j].inkey = NULL;
350 xform[
j].inkeyi = -1;
405 keyDataMap[new_numberOfKeys - 1] = xform[
j].inkeyi;
406 if (priorNumberOfEqualCols == attno - 1)
414 if (
i == numberOfKeys)
419 memset(xform, 0,
sizeof(xform));
432 keyDataMap[new_numberOfKeys - 1] =
i;
433 if (numberOfEqualCols == attno - 1)
456 if (xform[
j].inkey == NULL)
459 xform[
j].inkey = inkey;
461 xform[
j].arrayidx = arrayidx;
487 array = &so->
arrayKeys[xform[
j].arrayidx - 1];
506 array, orderproc, &test_result))
519 xform[
j].inkey = inkey;
521 xform[
j].arrayidx = arrayidx;
560 keyDataMap[new_numberOfKeys - 1] = xform[
j].inkeyi;
561 if (numberOfEqualCols == attno - 1)
563 xform[
j].inkey = inkey;
565 xform[
j].arrayidx = arrayidx;
734 elog(
ERROR,
"unrecognized StrategyNumber: %d",
842 *result = (leftnull < rightnull);
845 *result = (leftnull <= rightnull);
848 *result = (leftnull == rightnull);
851 *result = (leftnull >= rightnull);
854 *result = (leftnull > rightnull);
857 elog(
ERROR,
"unrecognized StrategyNumber: %d", (
int) strat);
884 if (leftarray && rightarray)
898 orderproc, array, result);
901 orderproc, array, result);
920 lefttype = opcintype;
923 righttype = opcintype;
932 if (lefttype == opcintype && righttype == optype)
1033 Oid arraysk_elemtype;
1056 orderprocp = &crosstypeproc;
1063 arraysk, &cmpresult);
1071 if (cmpresult >= cmpexact)
1074 new_nelems = matchelem;
1093 if (cmpresult >= cmpexact)
1096 new_nelems = array->
num_elems - matchelem;
1098 sizeof(
Datum) * new_nelems);
1101 elog(
ERROR,
"unrecognized StrategyNumber: %d",
1107 Assert(new_nelems <= array->num_elems);
1110 *qual_ok = new_nelems > 0;
1156 int16 *indoption = rel->rd_indoption;
1170 for (
int i = 0;
i < numberOfKeys;
i++)
1187 if (numArrayKeys == 0)
1196 "BTree array context",
1214 for (
int input_ikey = 0; input_ikey < numberOfKeys; input_ikey++)
1234 cur = &arrayKeyData[output_ikey];
1249 &elmlen, &elmbyval, &elmalign);
1252 elmlen, elmbyval, elmalign,
1253 &elem_values, &elem_nulls, &num_elems);
1260 for (
j = 0;
j < num_elems;
j++)
1263 elem_values[num_nonnulls++] = elem_values[
j];
1269 if (num_nonnulls == 0)
1281 elemtype =
cur->sk_subtype;
1283 elemtype = rel->rd_opcintype[
cur->sk_attno - 1];
1290 switch (
cur->sk_strategy)
1297 elem_values, num_nonnulls);
1308 elem_values, num_nonnulls);
1312 elog(
ERROR,
"unrecognized StrategyNumber: %d",
1313 (
int)
cur->sk_strategy);
1334 reverse = (indoption[
cur->sk_attno - 1] & INDOPTION_DESC) != 0;
1336 elem_values, num_nonnulls);
1338 if (origarrayatt ==
cur->sk_attno)
1353 origelemtype, elemtype,
1355 elem_values, num_elems))
1390 origarrayatt =
cur->sk_attno;
1391 origarraykey = numArrayKeys;
1392 origelemtype = elemtype;
1411 *new_numberOfKeys = output_ikey;
1415 return arrayKeyData;
1457 for (
int output_ikey = 0; output_ikey < so->
numberOfKeys; output_ikey++)
1468 input_ikey = keyDataMap[output_ikey];
1470 Assert(last_equal_output_ikey < output_ikey);
1471 Assert(last_equal_output_ikey < input_ikey);
1472 last_equal_output_ikey = output_ikey;
1495 elemtype = rel->rd_opcintype[outkey->
sk_attno - 1];
1532 outkey->
sk_flags &= ~SK_SEARCHARRAY;
1541 memmove(array, array + 1,
1573 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1574 errmsg_internal(
"number of array scan keys left by preprocessing (%d) exceeds the maximum allowed by parallel btree index scans (%d)",
1588 Datum *elems,
int nelems)
1612 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
1613 strat, elemtype, elemtype,
1617 elog(
ERROR,
"missing oprcode for operator %u", cmp_op);
1623 for (
i = 1;
i < nelems;
i++)
1674 if (elemtype == opcintype)
1679 *sortprocp = orderproc;
1698 elog(
ERROR,
"missing support function %d(%u,%u) for attribute %d of index \"%s\"",
1720 elog(
ERROR,
"missing support function %d(%u,%u) for attribute %d of index \"%s\"",
1740 Datum *elems,
int nelems)
1784 bool reverse,
Oid origelemtype,
Oid nextelemtype,
1785 Datum *elems_orig,
int *nelems_orig,
1786 Datum *elems_next,
int nelems_next)
1791 int nelems_orig_start = *nelems_orig,
1792 nelems_orig_merged = 0;
1799 if (origelemtype != nextelemtype)
1816 mergeproc = &crosstypeproc;
1820 cxt.sortproc = mergeproc;
1822 cxt.reverse = reverse;
1824 for (
int i = 0,
j = 0;
i < nelems_orig_start &&
j < nelems_next;)
1826 Datum *oelem = elems_orig +
i,
1827 *nelem = elems_next +
j;
1832 elems_orig[nelems_orig_merged++] = *oelem;
1842 *nelems_orig = nelems_orig_merged;
#define DatumGetArrayTypeP(X)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define InvalidAttrNumber
#define RegProcedureIsValid(p)
#define INVERT_COMPARE_RESULT(var)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
#define OidIsValid(objectId)
static void PGresult * res
int errmsg_internal(const char *fmt,...)
int errcode(int sqlerrcode)
#define ereport(elevel,...)
Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
static int compare(const void *arg1, const void *arg2)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
if(TABLE==NULL||TABLE_index==NULL)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
RegProcedure get_opcode(Oid opno)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
void * MemoryContextAlloc(MemoryContext context, Size size)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
static bool _bt_merge_arrays(IndexScanDesc scan, ScanKey skey, FmgrInfo *sortproc, bool reverse, Oid origelemtype, Oid nextelemtype, Datum *elems_orig, int *nelems_orig, Datum *elems_next, int nelems_next)
struct BTScanKeyPreproc BTScanKeyPreproc
struct BTSortArrayContext BTSortArrayContext
static Datum _bt_find_extreme_element(IndexScanDesc scan, ScanKey skey, Oid elemtype, StrategyNumber strat, Datum *elems, int nelems)
static bool _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
static void _bt_mark_scankey_required(ScanKey skey)
static ScanKey _bt_preprocess_array_keys(IndexScanDesc scan, int *new_numberOfKeys)
static int _bt_compare_array_elements(const void *a, const void *b, void *arg)
static void _bt_preprocess_array_keys_final(IndexScanDesc scan, int *keyDataMap)
static void _bt_setup_array_cmp(IndexScanDesc scan, ScanKey skey, Oid elemtype, FmgrInfo *orderproc, FmgrInfo **sortprocp)
static int _bt_sort_array_elements(ScanKey skey, FmgrInfo *sortproc, bool reverse, Datum *elems, int nelems)
static bool _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op, ScanKey leftarg, ScanKey rightarg, BTArrayKeyInfo *array, FmgrInfo *orderproc, bool *result)
static bool _bt_compare_array_scankey_args(IndexScanDesc scan, ScanKey arraysk, ScanKey skey, FmgrInfo *orderproc, BTArrayKeyInfo *array, bool *qual_ok)
void _bt_preprocess_keys(IndexScanDesc scan)
#define SK_BT_INDOPTION_SHIFT
#define SK_BT_NULLS_FIRST
#define BTCommuteStrategyNumber(strat)
BTScanOpaqueData * BTScanOpaque
int _bt_binsrch_array_skey(FmgrInfo *orderproc, bool cur_elem_trig, ScanDirection dir, Datum tupdatum, bool tupnull, BTArrayKeyInfo *array, ScanKey cur, int32 *set_elem_result)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
static bool DatumGetBool(Datum X)
static Pointer DatumGetPointer(Datum X)
static int32 DatumGetInt32(Datum X)
static size_t qunique_arg(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *, void *), void *arg)
#define RelationGetRelationName(relation)
@ NoMovementScanDirection
#define BTGreaterStrategyNumber
#define BTMaxStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
BTArrayKeyInfo * arrayKeys
MemoryContext arrayContext
struct ScanKeyData * keyData
struct ParallelIndexScanDescData * parallel_scan
StrategyNumber sk_strategy