PostgreSQL Source Code git master
ginscan.c File Reference
#include "postgres.h"
#include "access/gin_private.h"
#include "access/relscan.h"
#include "pgstat.h"
#include "utils/memutils.h"
#include "utils/rel.h"
Include dependency graph for ginscan.c:

Go to the source code of this file.

Functions

IndexScanDesc ginbeginscan (Relation rel, int nkeys, int norderbys)
 
static GinScanEntry ginFillScanEntry (GinScanOpaque so, OffsetNumber attnum, StrategyNumber strategy, int32 searchMode, Datum queryKey, GinNullCategory queryCategory, bool isPartialMatch, Pointer extra_data)
 
static void ginScanKeyAddHiddenEntry (GinScanOpaque so, GinScanKey key, GinNullCategory queryCategory)
 
static void ginFillScanKey (GinScanOpaque so, OffsetNumber attnum, StrategyNumber strategy, int32 searchMode, Datum query, uint32 nQueryValues, Datum *queryValues, GinNullCategory *queryCategories, bool *partial_matches, Pointer *extra_data)
 
void ginFreeScanKeys (GinScanOpaque so)
 
void ginNewScanKey (IndexScanDesc scan)
 
void ginrescan (IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
 
void ginendscan (IndexScanDesc scan)
 

Function Documentation

◆ ginbeginscan()

IndexScanDesc ginbeginscan ( Relation  rel,
int  nkeys,
int  norderbys 
)

Definition at line 25 of file ginscan.c.

26{
27 IndexScanDesc scan;
29
30 /* no order by operators allowed */
31 Assert(norderbys == 0);
32
33 scan = RelationGetIndexScan(rel, nkeys, norderbys);
34
35 /* allocate private workspace */
37 so->keys = NULL;
38 so->nkeys = 0;
40 "Gin scan temporary context",
43 "Gin scan key context",
46
47 scan->opaque = so;
48
49 return scan;
50}
#define Assert(condition)
Definition: c.h:815
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
Definition: genam.c:80
GinScanOpaqueData * GinScanOpaque
Definition: gin_private.h:386
void initGinState(GinState *state, Relation index)
Definition: ginutil.c:98
void * palloc(Size size)
Definition: mcxt.c:1317
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
GinScanKey keys
Definition: gin_private.h:374
MemoryContext keyCtx
Definition: gin_private.h:381
MemoryContext tempCtx
Definition: gin_private.h:371
Relation indexRelation
Definition: relscan.h:135

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, GinScanOpaqueData::ginstate, IndexScanDescData::indexRelation, initGinState(), GinScanOpaqueData::keyCtx, GinScanOpaqueData::keys, GinScanOpaqueData::nkeys, IndexScanDescData::opaque, palloc(), RelationGetIndexScan(), and GinScanOpaqueData::tempCtx.

Referenced by ginhandler().

◆ ginendscan()

void ginendscan ( IndexScanDesc  scan)

Definition at line 455 of file ginscan.c.

456{
458
459 ginFreeScanKeys(so);
460
463
464 pfree(so);
465}
void ginFreeScanKeys(GinScanOpaque so)
Definition: ginscan.c:233
void pfree(void *pointer)
Definition: mcxt.c:1521
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454

References ginFreeScanKeys(), GinScanOpaqueData::keyCtx, MemoryContextDelete(), IndexScanDescData::opaque, pfree(), and GinScanOpaqueData::tempCtx.

Referenced by ginhandler().

◆ ginFillScanEntry()

static GinScanEntry ginFillScanEntry ( GinScanOpaque  so,
OffsetNumber  attnum,
StrategyNumber  strategy,
int32  searchMode,
Datum  queryKey,
GinNullCategory  queryCategory,
bool  isPartialMatch,
Pointer  extra_data 
)
static

Definition at line 57 of file ginscan.c.

61{
62 GinState *ginstate = &so->ginstate;
63 GinScanEntry scanEntry;
64 uint32 i;
65
66 /*
67 * Look for an existing equivalent entry.
68 *
69 * Entries with non-null extra_data are never considered identical, since
70 * we can't know exactly what the opclass might be doing with that.
71 */
72 if (extra_data == NULL)
73 {
74 for (i = 0; i < so->totalentries; i++)
75 {
76 GinScanEntry prevEntry = so->entries[i];
77
78 if (prevEntry->extra_data == NULL &&
79 prevEntry->isPartialMatch == isPartialMatch &&
80 prevEntry->strategy == strategy &&
81 prevEntry->searchMode == searchMode &&
82 prevEntry->attnum == attnum &&
83 ginCompareEntries(ginstate, attnum,
84 prevEntry->queryKey,
85 prevEntry->queryCategory,
86 queryKey,
87 queryCategory) == 0)
88 {
89 /* Successful match */
90 return prevEntry;
91 }
92 }
93 }
94
95 /* Nope, create a new entry */
96 scanEntry = (GinScanEntry) palloc(sizeof(GinScanEntryData));
97 scanEntry->queryKey = queryKey;
98 scanEntry->queryCategory = queryCategory;
99 scanEntry->isPartialMatch = isPartialMatch;
100 scanEntry->extra_data = extra_data;
101 scanEntry->strategy = strategy;
102 scanEntry->searchMode = searchMode;
103 scanEntry->attnum = attnum;
104
105 scanEntry->buffer = InvalidBuffer;
106 ItemPointerSetMin(&scanEntry->curItem);
107 scanEntry->matchBitmap = NULL;
108 scanEntry->matchIterator = NULL;
109 scanEntry->matchResult = NULL;
110 scanEntry->list = NULL;
111 scanEntry->nlist = 0;
112 scanEntry->offset = InvalidOffsetNumber;
113 scanEntry->isFinished = false;
114 scanEntry->reduceResult = false;
115
116 /* Add it to so's array */
117 if (so->totalentries >= so->allocentries)
118 {
119 so->allocentries *= 2;
120 so->entries = (GinScanEntry *)
121 repalloc(so->entries, so->allocentries * sizeof(GinScanEntry));
122 }
123 so->entries[so->totalentries++] = scanEntry;
124
125 return scanEntry;
126}
#define InvalidBuffer
Definition: buf.h:25
uint32_t uint32
Definition: c.h:488
struct GinScanEntryData * GinScanEntry
Definition: gin_private.h:266
#define ItemPointerSetMin(p)
Definition: ginblock.h:166
int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, Datum a, GinNullCategory categorya, Datum b, GinNullCategory categoryb)
Definition: ginutil.c:389
int i
Definition: isn.c:72
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
#define InvalidOffsetNumber
Definition: off.h:26
int16 attnum
Definition: pg_attribute.h:74
ItemPointerData curItem
Definition: gin_private.h:351
TBMIterateResult * matchResult
Definition: gin_private.h:356
TIDBitmap * matchBitmap
Definition: gin_private.h:354
ItemPointerData * list
Definition: gin_private.h:359
TBMPrivateIterator * matchIterator
Definition: gin_private.h:355
GinNullCategory queryCategory
Definition: gin_private.h:340
StrategyNumber strategy
Definition: gin_private.h:343
Pointer extra_data
Definition: gin_private.h:342
OffsetNumber offset
Definition: gin_private.h:361
OffsetNumber attnum
Definition: gin_private.h:345
GinScanEntry * entries
Definition: gin_private.h:377

References GinScanOpaqueData::allocentries, GinScanEntryData::attnum, attnum, GinScanEntryData::buffer, GinScanEntryData::curItem, GinScanOpaqueData::entries, GinScanEntryData::extra_data, ginCompareEntries(), GinScanOpaqueData::ginstate, i, InvalidBuffer, InvalidOffsetNumber, GinScanEntryData::isFinished, GinScanEntryData::isPartialMatch, ItemPointerSetMin, GinScanEntryData::list, GinScanEntryData::matchBitmap, GinScanEntryData::matchIterator, GinScanEntryData::matchResult, GinScanEntryData::nlist, GinScanEntryData::offset, palloc(), GinScanEntryData::queryCategory, GinScanEntryData::queryKey, GinScanEntryData::reduceResult, repalloc(), GinScanEntryData::searchMode, GinScanEntryData::strategy, and GinScanOpaqueData::totalentries.

Referenced by ginFillScanKey(), and ginScanKeyAddHiddenEntry().

◆ ginFillScanKey()

static void ginFillScanKey ( GinScanOpaque  so,
OffsetNumber  attnum,
StrategyNumber  strategy,
int32  searchMode,
Datum  query,
uint32  nQueryValues,
Datum queryValues,
GinNullCategory queryCategories,
bool *  partial_matches,
Pointer extra_data 
)
static

Definition at line 153 of file ginscan.c.

158{
159 GinScanKey key = &(so->keys[so->nkeys++]);
160 GinState *ginstate = &so->ginstate;
161 uint32 i;
162
163 key->nentries = nQueryValues;
164 key->nuserentries = nQueryValues;
165
166 /* Allocate one extra array slot for possible "hidden" entry */
167 key->scanEntry = (GinScanEntry *) palloc(sizeof(GinScanEntry) *
168 (nQueryValues + 1));
169 key->entryRes = (GinTernaryValue *) palloc0(sizeof(GinTernaryValue) *
170 (nQueryValues + 1));
171
172 key->query = query;
173 key->queryValues = queryValues;
174 key->queryCategories = queryCategories;
175 key->extra_data = extra_data;
176 key->strategy = strategy;
177 key->searchMode = searchMode;
178 key->attnum = attnum;
179
180 /*
181 * Initially, scan keys of GIN_SEARCH_MODE_ALL mode are marked
182 * excludeOnly. This might get changed later.
183 */
184 key->excludeOnly = (searchMode == GIN_SEARCH_MODE_ALL);
185
186 ItemPointerSetMin(&key->curItem);
187 key->curItemMatches = false;
188 key->recheckCurItem = false;
189 key->isFinished = false;
190 key->nrequired = 0;
191 key->nadditional = 0;
192 key->requiredEntries = NULL;
193 key->additionalEntries = NULL;
194
196
197 /* Set up normal scan entries using extractQueryFn's outputs */
198 for (i = 0; i < nQueryValues; i++)
199 {
200 Datum queryKey;
201 GinNullCategory queryCategory;
202 bool isPartialMatch;
203 Pointer this_extra;
204
205 queryKey = queryValues[i];
206 queryCategory = queryCategories[i];
207 isPartialMatch =
208 (ginstate->canPartialMatch[attnum - 1] && partial_matches)
209 ? partial_matches[i] : false;
210 this_extra = (extra_data) ? extra_data[i] : NULL;
211
212 key->scanEntry[i] = ginFillScanEntry(so, attnum,
213 strategy, searchMode,
214 queryKey, queryCategory,
215 isPartialMatch, this_extra);
216 }
217
218 /*
219 * For GIN_SEARCH_MODE_INCLUDE_EMPTY and GIN_SEARCH_MODE_EVERYTHING search
220 * modes, we add the "hidden" entry immediately. GIN_SEARCH_MODE_ALL is
221 * handled later, since we might be able to omit the hidden entry for it.
222 */
223 if (searchMode == GIN_SEARCH_MODE_INCLUDE_EMPTY)
225 else if (searchMode == GIN_SEARCH_MODE_EVERYTHING)
227}
char * Pointer
Definition: c.h:479
#define GIN_SEARCH_MODE_ALL
Definition: gin.h:36
#define GIN_SEARCH_MODE_EVERYTHING
Definition: gin.h:37
char GinTernaryValue
Definition: gin.h:58
#define GIN_SEARCH_MODE_INCLUDE_EMPTY
Definition: gin.h:35
#define GIN_CAT_EMPTY_ITEM
Definition: ginblock.h:210
signed char GinNullCategory
Definition: ginblock.h:206
#define GIN_CAT_EMPTY_QUERY
Definition: ginblock.h:212
void ginInitConsistentFunction(GinState *ginstate, GinScanKey key)
Definition: ginlogic.c:217
static void ginScanKeyAddHiddenEntry(GinScanOpaque so, GinScanKey key, GinNullCategory queryCategory)
Definition: ginscan.c:137
static GinScanEntry ginFillScanEntry(GinScanOpaque so, OffsetNumber attnum, StrategyNumber strategy, int32 searchMode, Datum queryKey, GinNullCategory queryCategory, bool isPartialMatch, Pointer extra_data)
Definition: ginscan.c:57
void * palloc0(Size size)
Definition: mcxt.c:1347
uintptr_t Datum
Definition: postgres.h:69
bool canPartialMatch[INDEX_MAX_KEYS]
Definition: gin_private.h:86

References attnum, GinState::canPartialMatch, GIN_CAT_EMPTY_ITEM, GIN_CAT_EMPTY_QUERY, GIN_SEARCH_MODE_ALL, GIN_SEARCH_MODE_EVERYTHING, GIN_SEARCH_MODE_INCLUDE_EMPTY, ginFillScanEntry(), ginInitConsistentFunction(), ginScanKeyAddHiddenEntry(), GinScanOpaqueData::ginstate, i, ItemPointerSetMin, sort-test::key, GinScanOpaqueData::keys, GinScanOpaqueData::nkeys, palloc(), and palloc0().

◆ ginFreeScanKeys()

void ginFreeScanKeys ( GinScanOpaque  so)

Definition at line 233 of file ginscan.c.

234{
235 uint32 i;
236
237 if (so->keys == NULL)
238 return;
239
240 for (i = 0; i < so->totalentries; i++)
241 {
242 GinScanEntry entry = so->entries[i];
243
244 if (entry->buffer != InvalidBuffer)
245 ReleaseBuffer(entry->buffer);
246 if (entry->list)
247 pfree(entry->list);
248 if (entry->matchIterator)
250 if (entry->matchBitmap)
251 tbm_free(entry->matchBitmap);
252 }
253
255
256 so->keys = NULL;
257 so->nkeys = 0;
258 so->entries = NULL;
259 so->totalentries = 0;
260}
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4866
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
void tbm_free(TIDBitmap *tbm)
Definition: tidbitmap.c:322
void tbm_end_private_iterate(TBMPrivateIterator *iterator)
Definition: tidbitmap.c:1147

References GinScanEntryData::buffer, GinScanOpaqueData::entries, i, InvalidBuffer, GinScanOpaqueData::keyCtx, GinScanOpaqueData::keys, GinScanEntryData::list, GinScanEntryData::matchBitmap, GinScanEntryData::matchIterator, MemoryContextReset(), GinScanOpaqueData::nkeys, pfree(), ReleaseBuffer(), tbm_end_private_iterate(), tbm_free(), and GinScanOpaqueData::totalentries.

Referenced by ginendscan(), gingetbitmap(), and ginrescan().

◆ ginNewScanKey()

void ginNewScanKey ( IndexScanDesc  scan)

Definition at line 263 of file ginscan.c.

264{
265 ScanKey scankey = scan->keyData;
267 int i;
268 bool hasNullQuery = false;
269 bool attrHasNormalScan[INDEX_MAX_KEYS] = {false};
270 MemoryContext oldCtx;
271
272 /*
273 * Allocate all the scan key information in the key context. (If
274 * extractQuery leaks anything there, it won't be reset until the end of
275 * scan or rescan, but that's OK.)
276 */
277 oldCtx = MemoryContextSwitchTo(so->keyCtx);
278
279 /* if no scan keys provided, allocate extra EVERYTHING GinScanKey */
280 so->keys = (GinScanKey)
281 palloc(Max(scan->numberOfKeys, 1) * sizeof(GinScanKeyData));
282 so->nkeys = 0;
283
284 /* initialize expansible array of GinScanEntry pointers */
285 so->totalentries = 0;
286 so->allocentries = 32;
287 so->entries = (GinScanEntry *)
288 palloc(so->allocentries * sizeof(GinScanEntry));
289
290 so->isVoidRes = false;
291
292 for (i = 0; i < scan->numberOfKeys; i++)
293 {
294 ScanKey skey = &scankey[i];
295 Datum *queryValues;
296 int32 nQueryValues = 0;
297 bool *partial_matches = NULL;
298 Pointer *extra_data = NULL;
299 bool *nullFlags = NULL;
300 GinNullCategory *categories;
301 int32 searchMode = GIN_SEARCH_MODE_DEFAULT;
302
303 /*
304 * We assume that GIN-indexable operators are strict, so a null query
305 * argument means an unsatisfiable query.
306 */
307 if (skey->sk_flags & SK_ISNULL)
308 {
309 so->isVoidRes = true;
310 break;
311 }
312
313 /* OK to call the extractQueryFn */
314 queryValues = (Datum *)
315 DatumGetPointer(FunctionCall7Coll(&so->ginstate.extractQueryFn[skey->sk_attno - 1],
316 so->ginstate.supportCollation[skey->sk_attno - 1],
317 skey->sk_argument,
318 PointerGetDatum(&nQueryValues),
320 PointerGetDatum(&partial_matches),
321 PointerGetDatum(&extra_data),
322 PointerGetDatum(&nullFlags),
323 PointerGetDatum(&searchMode)));
324
325 /*
326 * If bogus searchMode is returned, treat as GIN_SEARCH_MODE_ALL; note
327 * in particular we don't allow extractQueryFn to select
328 * GIN_SEARCH_MODE_EVERYTHING.
329 */
330 if (searchMode < GIN_SEARCH_MODE_DEFAULT ||
331 searchMode > GIN_SEARCH_MODE_ALL)
332 searchMode = GIN_SEARCH_MODE_ALL;
333
334 /* Non-default modes require the index to have placeholders */
335 if (searchMode != GIN_SEARCH_MODE_DEFAULT)
336 hasNullQuery = true;
337
338 /*
339 * In default mode, no keys means an unsatisfiable query.
340 */
341 if (queryValues == NULL || nQueryValues <= 0)
342 {
343 if (searchMode == GIN_SEARCH_MODE_DEFAULT)
344 {
345 so->isVoidRes = true;
346 break;
347 }
348 nQueryValues = 0; /* ensure sane value */
349 }
350
351 /*
352 * Create GinNullCategory representation. If the extractQueryFn
353 * didn't create a nullFlags array, we assume everything is non-null.
354 * While at it, detect whether any null keys are present.
355 */
356 categories = (GinNullCategory *) palloc0(nQueryValues * sizeof(GinNullCategory));
357 if (nullFlags)
358 {
359 int32 j;
360
361 for (j = 0; j < nQueryValues; j++)
362 {
363 if (nullFlags[j])
364 {
365 categories[j] = GIN_CAT_NULL_KEY;
366 hasNullQuery = true;
367 }
368 }
369 }
370
371 ginFillScanKey(so, skey->sk_attno,
372 skey->sk_strategy, searchMode,
373 skey->sk_argument, nQueryValues,
374 queryValues, categories,
375 partial_matches, extra_data);
376
377 /* Remember if we had any non-excludeOnly keys */
378 if (searchMode != GIN_SEARCH_MODE_ALL)
379 attrHasNormalScan[skey->sk_attno - 1] = true;
380 }
381
382 /*
383 * Processing GIN_SEARCH_MODE_ALL scan keys requires us to make a second
384 * pass over the scan keys. Above we marked each such scan key as
385 * excludeOnly. If the involved column has any normal (not excludeOnly)
386 * scan key as well, then we can leave it like that. Otherwise, one
387 * excludeOnly scan key must receive a GIN_CAT_EMPTY_QUERY hidden entry
388 * and be set to normal (excludeOnly = false).
389 */
390 for (i = 0; i < so->nkeys; i++)
391 {
392 GinScanKey key = &so->keys[i];
393
394 if (key->searchMode != GIN_SEARCH_MODE_ALL)
395 continue;
396
397 if (!attrHasNormalScan[key->attnum - 1])
398 {
399 key->excludeOnly = false;
401 attrHasNormalScan[key->attnum - 1] = true;
402 }
403 }
404
405 /*
406 * If there are no regular scan keys, generate an EVERYTHING scankey to
407 * drive a full-index scan.
408 */
409 if (so->nkeys == 0 && !so->isVoidRes)
410 {
411 hasNullQuery = true;
414 (Datum) 0, 0,
415 NULL, NULL, NULL, NULL);
416 }
417
418 /*
419 * If the index is version 0, it may be missing null and placeholder
420 * entries, which would render searches for nulls and full-index scans
421 * unreliable. Throw an error if so.
422 */
423 if (hasNullQuery && !so->isVoidRes)
424 {
425 GinStatsData ginStats;
426
427 ginGetStats(scan->indexRelation, &ginStats);
428 if (ginStats.ginVersion < 1)
430 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
431 errmsg("old GIN indexes do not support whole-index scans nor searches for nulls"),
432 errhint("To fix this, do REINDEX INDEX \"%s\".",
434 }
435
436 MemoryContextSwitchTo(oldCtx);
437
439}
#define Max(x, y)
Definition: c.h:955
int32_t int32
Definition: c.h:484
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6, Datum arg7)
Definition: fmgr.c:1284
#define GIN_SEARCH_MODE_DEFAULT
Definition: gin.h:34
struct GinScanKeyData GinScanKeyData
struct GinScanKeyData * GinScanKey
Definition: gin_private.h:264
#define GIN_CAT_NULL_KEY
Definition: ginblock.h:209
static void ginFillScanKey(GinScanOpaque so, OffsetNumber attnum, StrategyNumber strategy, int32 searchMode, Datum query, uint32 nQueryValues, Datum *queryValues, GinNullCategory *queryCategories, bool *partial_matches, Pointer *extra_data)
Definition: ginscan.c:153
void ginGetStats(Relation index, GinStatsData *stats)
Definition: ginutil.c:624
int j
Definition: isn.c:73
#define FirstOffsetNumber
Definition: off.h:27
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define INDEX_MAX_KEYS
#define pgstat_count_index_scan(rel)
Definition: pgstat.h:691
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
static Datum UInt16GetDatum(uint16 X)
Definition: postgres.h:197
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
#define RelationGetRelationName(relation)
Definition: rel.h:546
#define SK_ISNULL
Definition: skey.h:115
#define InvalidStrategy
Definition: stratnum.h:24
int32 ginVersion
Definition: gin.h:49
struct ScanKeyData * keyData
Definition: relscan.h:139
int sk_flags
Definition: skey.h:66
Datum sk_argument
Definition: skey.h:72
StrategyNumber sk_strategy
Definition: skey.h:68
AttrNumber sk_attno
Definition: skey.h:67

References i, INDEX_MAX_KEYS, IndexScanDescData::keyData, and IndexScanDescData::opaque.

Referenced by gingetbitmap().

◆ ginrescan()

void ginrescan ( IndexScanDesc  scan,
ScanKey  scankey,
int  nscankeys,
ScanKey  orderbys,
int  norderbys 
)

Definition at line 442 of file ginscan.c.

444{
446
447 ginFreeScanKeys(so);
448
449 if (scankey && scan->numberOfKeys > 0)
450 memcpy(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData));
451}

References ginFreeScanKeys(), IndexScanDescData::keyData, IndexScanDescData::numberOfKeys, and IndexScanDescData::opaque.

Referenced by ginhandler().

◆ ginScanKeyAddHiddenEntry()

static void ginScanKeyAddHiddenEntry ( GinScanOpaque  so,
GinScanKey  key,
GinNullCategory  queryCategory 
)
static

Definition at line 137 of file ginscan.c.

139{
140 int i = key->nentries++;
141
142 /* strategy is of no interest because this is not a partial-match item */
143 key->scanEntry[i] = ginFillScanEntry(so, key->attnum,
144 InvalidStrategy, key->searchMode,
145 (Datum) 0, queryCategory,
146 false, NULL);
147}

References ginFillScanEntry(), i, InvalidStrategy, and sort-test::key.

Referenced by ginFillScanKey().