aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/spgist/spgdoinsert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/spgist/spgdoinsert.c')
-rw-r--r--src/backend/access/spgist/spgdoinsert.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
index 7bd269fd2a0..e14c71abd07 100644
--- a/src/backend/access/spgist/spgdoinsert.c
+++ b/src/backend/access/spgist/spgdoinsert.c
@@ -731,13 +731,6 @@ doPickSplit(Relation index, SpGistState *state,
* also, count up the amount of space that will be freed from current.
* (Note that in the non-root case, we won't actually delete the old
* tuples, only replace them with redirects or placeholders.)
- *
- * Note: the SGLTDATUM calls here are safe even when dealing with a nulls
- * page. For a pass-by-value data type we will fetch a word that must
- * exist even though it may contain garbage (because of the fact that leaf
- * tuples must have size at least SGDTSIZE). For a pass-by-reference type
- * we are just computing a pointer that isn't going to get dereferenced.
- * So it's not worth guarding the calls with isNulls checks.
*/
nToInsert = 0;
nToDelete = 0;
@@ -757,7 +750,8 @@ doPickSplit(Relation index, SpGistState *state,
PageGetItemId(current->page, i));
if (it->tupstate == SPGIST_LIVE)
{
- in.datums[nToInsert] = SGLTDATUM(it, state);
+ in.datums[nToInsert] =
+ isNulls ? (Datum) 0 : SGLTDATUM(it, state);
heapPtrs[nToInsert] = it->heapPtr;
nToInsert++;
toDelete[nToDelete] = i;
@@ -782,7 +776,8 @@ doPickSplit(Relation index, SpGistState *state,
PageGetItemId(current->page, i));
if (it->tupstate == SPGIST_LIVE)
{
- in.datums[nToInsert] = SGLTDATUM(it, state);
+ in.datums[nToInsert] =
+ isNulls ? (Datum) 0 : SGLTDATUM(it, state);
heapPtrs[nToInsert] = it->heapPtr;
nToInsert++;
toDelete[nToDelete] = i;
@@ -814,7 +809,8 @@ doPickSplit(Relation index, SpGistState *state,
* space to include it; and in any case it has to be included in the input
* for the picksplit function. So don't increment nToInsert yet.
*/
- in.datums[in.nTuples] = SGLTDATUM(newLeafTuple, state);
+ in.datums[in.nTuples] =
+ isNulls ? (Datum) 0 : SGLTDATUM(newLeafTuple, state);
heapPtrs[in.nTuples] = newLeafTuple->heapPtr;
in.nTuples++;
@@ -1940,17 +1936,21 @@ spgdoinsert(Relation index, SpGistState *state,
leafDatum = (Datum) 0;
/*
- * Compute space needed for a leaf tuple containing the given datum.
- *
- * If it isn't gonna fit, and the opclass can't reduce the datum size by
- * suffixing, bail out now rather than getting into an endless loop.
+ * Compute space needed for a leaf tuple containing the given datum. This
+ * must match spgFormLeafTuple.
*/
+ leafSize = SGLTHDRSZ;
if (!isnull)
- leafSize = SGLTHDRSZ + sizeof(ItemIdData) +
- SpGistGetTypeSize(&state->attLeafType, leafDatum);
- else
- leafSize = SGDTSIZE + sizeof(ItemIdData);
+ leafSize += SpGistGetLeafTypeSize(&state->attLeafType, leafDatum);
+ if (leafSize < SGDTSIZE)
+ leafSize = SGDTSIZE;
+ /* Account for an item pointer, too */
+ leafSize += sizeof(ItemIdData);
+ /*
+ * If it isn't gonna fit, and the opclass can't reduce the datum size by
+ * suffixing, bail out now rather than getting into an endless loop.
+ */
if (leafSize > SPGIST_PAGE_CAPACITY && !state->config.longValuesOK)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
@@ -2161,8 +2161,9 @@ spgdoinsert(Relation index, SpGistState *state,
if (!isnull)
{
leafDatum = out.result.matchNode.restDatum;
- leafSize = SGLTHDRSZ + sizeof(ItemIdData) +
- SpGistGetTypeSize(&state->attLeafType, leafDatum);
+ leafSize = SGLTHDRSZ +
+ SpGistGetLeafTypeSize(&state->attLeafType, leafDatum);
+ leafSize += sizeof(ItemIdData);
}
/*