aboutsummaryrefslogtreecommitdiff
path: root/src/include/access/gin_private.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-01-08 14:47:13 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2011-01-08 14:48:08 -0500
commit56a57473a999b0497e63bde3e303beda5a3c0ff3 (patch)
treec32f77b552cbd02ca16bbc9edc392cd0331c9c54 /src/include/access/gin_private.h
parent002c105a0706bd1c1e939fe0f47ecdceeae6c52d (diff)
downloadpostgresql-56a57473a999b0497e63bde3e303beda5a3c0ff3.tar.gz
postgresql-56a57473a999b0497e63bde3e303beda5a3c0ff3.zip
Refactor GIN's handling of duplicate search entries.
The original coding could combine duplicate entries only when they originated from the same qual condition. In particular it could not combine cases where multiple qual conditions all give rise to full-index scan requests, which is an expensive case well worth optimizing. Refactor so that duplicates are recognized across all the quals.
Diffstat (limited to 'src/include/access/gin_private.h')
-rw-r--r--src/include/access/gin_private.h52
1 files changed, 31 insertions, 21 deletions
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index 48531845e0a..6381bffb216 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -549,12 +549,19 @@ extern void ginPrepareDataScan(GinBtree btree, Relation index);
/* ginscan.c */
/*
- * GinScanKeyData describes a single GIN index qualification condition.
- * It contains one GinScanEntryData for each key datum extracted from
- * the qual by the extractQueryFn or added implicitly by ginFillScanKey.
- * nentries is the true number of entries, nuserentries is the number
- * that extractQueryFn returned (which is what we report to consistentFn).
- * The "user" entries must come first.
+ * GinScanKeyData describes a single GIN index qualifier expression.
+ *
+ * From each qual expression, we extract one or more specific index search
+ * conditions, which are represented by GinScanEntryData. It's quite
+ * possible for identical search conditions to be requested by more than
+ * one qual expression, in which case we merge such conditions to have just
+ * one unique GinScanEntry --- this is particularly important for efficiency
+ * when dealing with full-index-scan entries. So there can be multiple
+ * GinScanKeyData.scanEntry pointers to the same GinScanEntryData.
+ *
+ * In each GinScanKeyData, nentries is the true number of entries, while
+ * nuserentries is the number that extractQueryFn returned (which is what
+ * we report to consistentFn). The "user" entries must come first.
*/
typedef struct GinScanKeyData *GinScanKey;
@@ -567,10 +574,10 @@ typedef struct GinScanKeyData
/* Number of entries that extractQueryFn and consistentFn know about */
uint32 nuserentries;
- /* array of GinScanEntryData, one per key datum */
- GinScanEntry scanEntry;
+ /* array of GinScanEntry pointers, one per extracted search condition */
+ GinScanEntry *scanEntry;
- /* array of ItemPointer result, reported to consistentFn */
+ /* array of check flags, reported to consistentFn */
bool *entryRes;
/* other data needed for calling consistentFn */
@@ -583,22 +590,21 @@ typedef struct GinScanKeyData
int32 searchMode;
OffsetNumber attnum;
- /* scan status data */
+ /*
+ * Match status data. curItem is the TID most recently tested (could be
+ * a lossy-page pointer). curItemMatches is TRUE if it passes the
+ * consistentFn test; if so, recheckCurItem is the recheck flag.
+ * isFinished means that all the input entry streams are finished, so
+ * this key cannot succeed for any later TIDs.
+ */
ItemPointerData curItem;
+ bool curItemMatches;
bool recheckCurItem;
-
- bool firstCall;
bool isFinished;
} GinScanKeyData;
typedef struct GinScanEntryData
{
- /* link to any preceding identical entry in current scan key */
- GinScanEntry master;
-
- /* ptr to value reported to consistentFn, points to parent->entryRes[i] */
- bool *pval;
-
/* query key and other information from extractQueryFn */
Datum queryKey;
GinNullCategory queryCategory;
@@ -634,10 +640,14 @@ typedef struct GinScanOpaqueData
MemoryContext tempCtx;
GinState ginstate;
- GinScanKey keys;
+ GinScanKey keys; /* one per scan qualifier expr */
uint32 nkeys;
- bool isVoidRes; /* true if ginstate.extractQueryFn guarantees
- * that nothing will be found */
+
+ GinScanEntry *entries; /* one per index search condition */
+ uint32 totalentries;
+ uint32 allocentries; /* allocated length of entries[] */
+
+ bool isVoidRes; /* true if query is unsatisfiable */
} GinScanOpaqueData;
typedef GinScanOpaqueData *GinScanOpaque;