/* OK, do it */
FREEMEM(state, GetMemoryChunkSpace(state->memtuples));
- state->memtupsize = newmemtupsize;
state->memtuples = (void **)
repalloc_huge(state->memtuples,
- state->memtupsize * sizeof(void *));
+ newmemtupsize * sizeof(void *));
+ state->memtupsize = newmemtupsize;
USEMEM(state, GetMemoryChunkSpace(state->memtuples));
if (LACKMEM(state))
elog(ERROR, "unexpected out-of-memory situation in tuplestore");
if (i >= state->memtupcount)
break;
WRITETUP(state, state->memtuples[i]);
+
+ /*
+ * Increase memtupdeleted to track the fact that we just deleted that
+ * tuple. Think not to remove this on the grounds that we'll reset
+ * memtupdeleted to zero below. We might not reach that if some later
+ * WRITETUP fails (e.g. due to overrunning temp_file_limit). If so,
+ * we'd error out leaving an effectively-corrupt tuplestore, which
+ * would be quite bad if it's a persistent data structure such as a
+ * Portal's holdStore.
+ */
+ state->memtupdeleted++;
}
+ /* Now we can reset memtupdeleted along with memtupcount */
state->memtupdeleted = 0;
state->memtupcount = 0;
}
FREEMEM(state, GetMemoryChunkSpace(state->memtuples[i]));
pfree(state->memtuples[i]);
state->memtuples[i] = NULL;
+ /* As in dumptuples(), increment memtupdeleted synchronously */
+ state->memtupdeleted++;
}
- state->memtupdeleted = nremove;
+ Assert(state->memtupdeleted == nremove);
/* mark tuplestore as truncated (used for Assert crosschecks only) */
state->truncated = true;