@@ -741,22 +741,28 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
741741/*
742742 * Update the tuple.
743743 *
744- * gistinserthere() might have to split the page to make the
745- * updated tuple fit. It will adjust the stack so that after
746- * the call, we'll be holding a lock on the page containing
747- * the tuple, which might have moved right.
748- *
749- * Except if this causes a root split, gistinserthere()
750- * returns 'true'. In that case, stack only holds the new
751- * root, and the child page was released. Have to start
752- * all over.
744+ * We still hold the lock after gistinserttuples(), but it
745+ * might have to split the page to make the updated tuple fit.
746+ * In that case the updated tuple might migrate to the other
747+ * half of the split, so we have to go back to the parent and
748+ * descend back to the half that's a better fit for the new
749+ * tuple.
753750 */
754751if (gistinserttuples (& state ,stack ,giststate ,& newtup ,1 ,
755752stack -> childoffnum ,InvalidBuffer ))
756753{
757- UnlockReleaseBuffer (stack -> buffer );
758- xlocked = false;
759- state .stack = stack = stack -> parent ;
754+ /*
755+ * If this was a root split, the root page continues to
756+ * be the parent and the updated tuple went to one of the
757+ * child pages, so we just need to retry from the root
758+ * page.
759+ */
760+ if (stack -> blkno != GIST_ROOT_BLKNO )
761+ {
762+ UnlockReleaseBuffer (stack -> buffer );
763+ xlocked = false;
764+ state .stack = stack = stack -> parent ;
765+ }
760766continue ;
761767}
762768}