From d0e1091cfd2f69c0b1056c7e14281299f70b5679 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Tue, 15 May 2001 14:14:49 +0000
Subject: [PATCH] we found a problem in GiST with massive insert/update
 operations with many NULLs ( inserting of NULL into indexed field cause
 ERROR: MemoryContextAlloc: invalid request size) As a workaround 'vacuum
 analyze' could be used.

This patch resolves the problem, please upply to 7.1.1 sources and
current cvs tree.

Oleg Bartunov
---
 src/backend/access/gist/gist.c    | 16 ++++++++++------
 src/backend/access/gist/gistget.c | 13 ++++++++-----
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 8e7b530dea5..4b239c76c8b 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.75 2001/05/15 03:49:34 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.76 2001/05/15 14:14:49 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1199,13 +1199,17 @@ gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr, Relation r,
 	gistentryinit(*e, pr, r, pg, o, b, l);
 	if (giststate->haskeytype)
 	{
-		dep = (GISTENTRY *)
-			DatumGetPointer(FunctionCall1(&giststate->decompressFn,
+		if ( b ) {
+			dep = (GISTENTRY *)
+				DatumGetPointer(FunctionCall1(&giststate->decompressFn,
 										  PointerGetDatum(e)));
-		gistentryinit(*e, dep->pred, dep->rel, dep->page, dep->offset, dep->bytes,
+			gistentryinit(*e, dep->pred, dep->rel, dep->page, dep->offset, dep->bytes,
 					  dep->leafkey);
-		if (dep != e)
-			pfree(dep);
+			if (dep != e)
+				pfree(dep);
+		} else {
+			gistentryinit(*e, (char*)NULL, r, pg, o, 0, l);
+		}
 	}
 }
 
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 8f3b5dd475c..d6fac6f4e20 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -241,16 +241,16 @@ gistindex_keytest(IndexTuple tuple,
 							  1,
 							  tupdesc,
 							  &isNull);
-		gistdentryinit(giststate, &de, (char *) datum, r, p, offset,
-					   IndexTupleSize(tuple) - sizeof(IndexTupleData),
-					   FALSE);
-
-		if (isNull)
+		if (isNull || IndexTupleSize(tuple) == sizeof(IndexTupleData) )
 		{
 			/* XXX eventually should check if SK_ISNULL */
 			return false;
 		}
 
+		gistdentryinit(giststate, &de, (char *) datum, r, p, offset,
+					   IndexTupleSize(tuple) - sizeof(IndexTupleData),
+					   FALSE);
+
 		if (key[0].sk_flags & SK_COMMUTE)
 		{
 			test = FunctionCall3(&key[0].sk_func,
@@ -266,6 +266,9 @@ gistindex_keytest(IndexTuple tuple,
 								 ObjectIdGetDatum(key[0].sk_procedure));
 		}
 
+		if ( (char*)de.pred != (char*)datum )
+			if ( de.pred ) pfree( de.pred );
+
 		if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
 			return false;
 
-- 
GitLab