/* * Compare two keys of possibly different index columns */ int ginCompareAttEntries(GinState *ginstate, OffsetNumber attnuma, Datum a, GinNullCategory categorya, OffsetNumber attnumb, Datum b, GinNullCategory categoryb) { /* attribute number is the first sort key */ if (attnuma != attnumb) return (attnuma < attnumb) ? -1 : 1; return ginCompareEntries(ginstate, attnuma, a, categorya, b, categoryb); }
/* * Create a new GinScanEntry, unless an equivalent one already exists, * in which case just return it */ static GinScanEntry ginFillScanEntry(GinScanOpaque so, OffsetNumber attnum, StrategyNumber strategy, int32 searchMode, Datum queryKey, GinNullCategory queryCategory, bool isPartialMatch, Pointer extra_data) { GinState *ginstate = &so->ginstate; GinScanEntry scanEntry; uint32 i; /* * Look for an existing equivalent entry. * * Entries with non-null extra_data are never considered identical, since * we can't know exactly what the opclass might be doing with that. */ if (extra_data == NULL) { for (i = 0; i < so->totalentries; i++) { GinScanEntry prevEntry = so->entries[i]; if (prevEntry->extra_data == NULL && prevEntry->isPartialMatch == isPartialMatch && prevEntry->strategy == strategy && prevEntry->searchMode == searchMode && prevEntry->attnum == attnum && ginCompareEntries(ginstate, attnum, prevEntry->queryKey, prevEntry->queryCategory, queryKey, queryCategory) == 0) { /* Successful match */ return prevEntry; } } } /* Nope, create a new entry */ scanEntry = (GinScanEntry) palloc(sizeof(GinScanEntryData)); scanEntry->queryKey = queryKey; scanEntry->queryCategory = queryCategory; scanEntry->isPartialMatch = isPartialMatch; scanEntry->extra_data = extra_data; scanEntry->strategy = strategy; scanEntry->searchMode = searchMode; scanEntry->attnum = attnum; scanEntry->buffer = InvalidBuffer; ItemPointerSetMin(&scanEntry->curItem); scanEntry->matchBitmap = NULL; scanEntry->matchIterator = NULL; scanEntry->matchResult = NULL; scanEntry->list = NULL; scanEntry->nlist = 0; scanEntry->offset = InvalidOffsetNumber; scanEntry->isFinished = false; scanEntry->reduceResult = false; /* Add it to so's array */ if (so->totalentries >= so->allocentries) { so->allocentries *= 2; so->entries = (GinScanEntry *) repalloc(so->entries, so->allocentries * sizeof(GinScanEntry)); } so->entries[so->totalentries++] = scanEntry; return scanEntry; }