]> granicus.if.org Git - postgresql/commitdiff
Check for GiST index tuples that don't fit on a page.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 3 Oct 2014 09:07:10 +0000 (12:07 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 3 Oct 2014 11:50:40 +0000 (14:50 +0300)
The page splitting code would go into infinite recursion if you try to
insert an index tuple that doesn't fit even on an empty page.

Per analysis and suggested fix by Andrew Gierth. Fixes bug #11555, reported
by Bryan Seitz (analysis happened over IRC). Backpatch to all supported
versions.

src/backend/access/gist/gist.c

index 240813898a97b8dbec87983d3238feea92e942f6..97eee905aac80d27dbc5082ccaccd51d3d2f910b 100644 (file)
@@ -1255,6 +1255,23 @@ gistSplit(Relation r,
        int                     i;
        SplitedPageLayout *res = NULL;
 
+       /* this should never recurse very deeply, but better safe than sorry */
+       check_stack_depth();
+
+       /* there's no point in splitting an empty page */
+       Assert(len > 0);
+
+       /*
+        * If a single tuple doesn't fit on a page, no amount of splitting will
+        * help.
+        */
+       if (len == 1)
+               ereport(ERROR,
+                               (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+                       errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
+                                  IndexTupleSize(itup[0]), GiSTPageSize,
+                                  RelationGetRelationName(r))));
+
        memset(v.spl_lisnull, TRUE, sizeof(bool) * giststate->tupdesc->natts);
        memset(v.spl_risnull, TRUE, sizeof(bool) * giststate->tupdesc->natts);
        gistSplitByKey(r, page, itup, len, giststate, &v, 0);