aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/spgist
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2016-03-30 18:29:28 +0300
committerTeodor Sigaev <teodor@sigaev.ru>2016-03-30 18:29:28 +0300
commitccd6eb49a4ae924290ab7eba5540218f5beb48b8 (patch)
treea5c1a9d35b8dd70d7e8bb06a6370de599d64b15c /src/backend/access/spgist
parent3063e7a84026ced2aadd2262f75eebbe6240f85b (diff)
downloadpostgresql-ccd6eb49a4ae924290ab7eba5540218f5beb48b8.tar.gz
postgresql-ccd6eb49a4ae924290ab7eba5540218f5beb48b8.zip
Introduce traversalValue for SP-GiST scan
During scan sometimes it would be very helpful to know some information about parent node or all ancestor nodes. Right now reconstructedValue could be used but it's not a right usage of it (range opclass uses that). traversalValue is arbitrary piece of memory in separate MemoryContext while reconstructedVale should have the same type as indexed column. Subsequent patches for range opclass and quad4d tree will use it. Author: Alexander Lebedev, Teodor Sigaev
Diffstat (limited to 'src/backend/access/spgist')
-rw-r--r--src/backend/access/spgist/spgscan.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c
index 620e7461998..8aa28ecbc39 100644
--- a/src/backend/access/spgist/spgscan.c
+++ b/src/backend/access/spgist/spgscan.c
@@ -30,6 +30,7 @@ typedef void (*storeRes_func) (SpGistScanOpaque so, ItemPointer heapPtr,
typedef struct ScanStackEntry
{
Datum reconstructedValue; /* value reconstructed from parent */
+ void *traversalValue; /* opclass-specific traverse value */
int level; /* level of items on this page */
ItemPointerData ptr; /* block and offset to scan from */
} ScanStackEntry;
@@ -42,6 +43,9 @@ freeScanStackEntry(SpGistScanOpaque so, ScanStackEntry *stackEntry)
if (!so->state.attType.attbyval &&
DatumGetPointer(stackEntry->reconstructedValue) != NULL)
pfree(DatumGetPointer(stackEntry->reconstructedValue));
+ if (stackEntry->traversalValue)
+ pfree(stackEntry->traversalValue);
+
pfree(stackEntry);
}
@@ -239,6 +243,7 @@ static bool
spgLeafTest(Relation index, SpGistScanOpaque so,
SpGistLeafTuple leafTuple, bool isnull,
int level, Datum reconstructedValue,
+ void *traversalValue,
Datum *leafValue, bool *recheck)
{
bool result;
@@ -265,6 +270,7 @@ spgLeafTest(Relation index, SpGistScanOpaque so,
in.scankeys = so->keyData;
in.nkeys = so->numberOfKeys;
in.reconstructedValue = reconstructedValue;
+ in.traversalValue = traversalValue;
in.level = level;
in.returnData = so->want_itup;
in.leafDatum = leafDatum;
@@ -365,6 +371,7 @@ redirect:
leafTuple, isnull,
stackEntry->level,
stackEntry->reconstructedValue,
+ stackEntry->traversalValue,
&leafValue,
&recheck))
{
@@ -411,6 +418,7 @@ redirect:
leafTuple, isnull,
stackEntry->level,
stackEntry->reconstructedValue,
+ stackEntry->traversalValue,
&leafValue,
&recheck))
{
@@ -456,6 +464,8 @@ redirect:
in.scankeys = so->keyData;
in.nkeys = so->numberOfKeys;
in.reconstructedValue = stackEntry->reconstructedValue;
+ in.traversalMemoryContext = oldCtx;
+ in.traversalValue = stackEntry->traversalValue;
in.level = stackEntry->level;
in.returnData = so->want_itup;
in.allTheSame = innerTuple->allTheSame;
@@ -523,6 +533,14 @@ redirect:
else
newEntry->reconstructedValue = (Datum) 0;
+ /*
+ * Elements of out.traversalValues should be allocated in
+ * in.traversalMemoryContext, which is actually a long
+ * lived context of index scan.
+ */
+ newEntry->traversalValue = (out.traversalValues) ?
+ out.traversalValues[i] : NULL;
+
so->scanStack = lcons(newEntry, so->scanStack);
}
}