/* * tuplestore_markpos - saves current position in the tuple sequence */ void tuplestore_markpos_pos(Tuplestorestate *state, TuplestorePos *pos) { Assert(state->eflags & EXEC_FLAG_MARK); switch (state->status) { case TSS_INMEM: pos->markpos_current = pos->current; /* * We can truncate the tuplestore if neither backward scan nor * rewind capability are required by the caller. There will never * be a need to back up past the mark point. * * Note: you might think we could remove all the tuples before * "current", since that one is the next to be returned. However, * since tuplestore_gettuple returns a direct pointer to our * internal copy of the tuple, it's likely that the caller has * still got the tuple just before "current" referenced in a slot. * Don't free it yet. */ if (!(state->eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_REWIND))) tuplestore_trim(state, 1); break; case TSS_WRITEFILE: if (pos->eof_reached) { /* Need to record the implicit read position */ BufFileTell(state->myfile, &pos->markpos_offset); } else { pos->markpos_offset = pos->readpos_offset; } break; case TSS_READFILE: BufFileTell(state->myfile, &pos->markpos_offset); break; default: elog(ERROR, "invalid tuplestore state"); break; } }
/* ---------------------------------------------------------------- * ExecMaterialMarkPos * * Calls tuplestore to save the current position in the stored file. * ---------------------------------------------------------------- */ void ExecMaterialMarkPos(MaterialState *node) { Assert(node->eflags & EXEC_FLAG_MARK); /* * if we haven't materialized yet, just return. */ if (!node->tuplestorestate) return; /* * copy the active read pointer to the mark. */ tuplestore_copy_read_pointer(node->tuplestorestate, 0, 1); /* * since we may have advanced the mark, try to truncate the tuplestore. */ tuplestore_trim(node->tuplestorestate); }