if (reloid == InvalidOid &&
change->data.tp.newtuple == NULL &&
change->data.tp.oldtuple == NULL)
- continue;
+ goto change_done;
else if (reloid == InvalidOid)
elog(ERROR, "could not map filenode \"%s\" to relation OID",
relpathperm(change->data.tp.relnode,
relpathperm(change->data.tp.relnode,
MAIN_FORKNUM));
- if (RelationIsLogicallyLogged(relation))
+ if (!RelationIsLogicallyLogged(relation))
+ goto change_done;
+
+ /*
+ * For now ignore sequence changes entirely. Most of
+ * the time they don't log changes using records we
+ * understand, so it doesn't make sense to handle the
+ * few cases we do.
+ */
+ if (relation->rd_rel->relkind == RELKIND_SEQUENCE)
+ goto change_done;
+
+ /* user-triggered change */
+ if (!IsToastRelation(relation))
{
/*
- * For now ignore sequence changes entirely. Most of
- * the time they don't log changes using records we
- * understand, so it doesn't make sense to handle the
- * few cases we do.
+ * Previous speculative insertion's success
+ * affirmed by a new (non-superdelete) DML change
*/
- if (relation->rd_rel->relkind == RELKIND_SEQUENCE)
+ if (specinsert &&
+ change->action != REORDER_BUFFER_CHANGE_INTERNAL_DELETE)
{
+ /* Report as proper insert to client */
+ specinsert->action = REORDER_BUFFER_CHANGE_INSERT;
+ rb->apply_change(rb, txn, relation, specinsert);
+
+ /* Free memory from pending tuple */
+ Assert(specinsert->data.tp.oldtuple == NULL);
+ ReorderBufferReturnTupleBuf(rb, specinsert->data.tp.newtuple);
+ specinsert = NULL;
}
- /* user-triggered change */
- else if (!IsToastRelation(relation))
- {
- /*
- * Previous speculative insertion's success
- * affirmed by a new (non-superdelete) DML change
- */
- if (specinsert &&
- change->action !=
- REORDER_BUFFER_CHANGE_INTERNAL_DELETE)
- {
- /* Report as proper insert to client */
- specinsert->action = REORDER_BUFFER_CHANGE_INSERT;
- rb->apply_change(rb, txn, relation, specinsert);
-
- /* Free memory from pending tuple */
- Assert(specinsert->data.tp.oldtuple == NULL);
- ReorderBufferReturnTupleBuf(rb, specinsert->data.tp.newtuple);
- specinsert = NULL;
- }
-
- ReorderBufferToastReplace(rb, txn, relation, change);
+ ReorderBufferToastReplace(rb, txn, relation, change);
+
+ /*
+ * Kludge: Speculative insertion occasionally makes
+ * use of "super deletion" -- an implementation
+ * defined delete of a speculatively inserted tuple.
+ * Neither the super deletion, nor the insertion
+ * (which must be the prior record type) are included
+ * in the final assembly when the tuple was
+ * super-deleted. Otherwise, an ordinary insertion is
+ * assembled.
+ */
+ if (change->action == REORDER_BUFFER_CHANGE_INTERNAL_INSERT)
+ {
/*
- * Kludge: Speculative insertion occasionally
- * makes use of "super deletion" -- an
- * implementation defined delete of a speculatively
- * inserted tuple. Neither the super deletion, nor
- * the insertion (which must be the prior record
- * type) are included in the final assembly when
- * the tuple was super-deleted. Otherwise, an
- * ordinary insertion is assembled.
+ * Need to ensure the memory used by promise tuple
+ * isn't freed till we're done verifying that
+ * there is no super deletion that immediately
+ * follows. Otherwise it could get freed/reused
+ * while restoring spooled data from disk.
*/
- if (change->action == REORDER_BUFFER_CHANGE_INTERNAL_INSERT)
- {
- /*
- * Need to ensure the memory used by promise
- * tuple isn't freed till we're done verifying
- * that there is no super deletion that
- * immediately follows. Otherwise it could get
- * freed/reused while restoring spooled data
- * from disk.
- */
- dlist_delete(&change->node);
- specinsert = change;
- /* Don't clear reassembled toast chunks */
- continue;
- }
- else if (change->action ==
- REORDER_BUFFER_CHANGE_INTERNAL_DELETE)
- {
- Assert(RelFileNodeEquals(change->data.tp.relnode,
- specinsert->data.tp.relnode));
-
- /*
- * Free memory from pending tuple. Do not
- * report as logical delete to encoding plugin.
- */
- Assert(specinsert->data.tp.oldtuple == NULL);
- ReorderBufferReturnTupleBuf(rb, specinsert->data.tp.newtuple);
- specinsert = NULL;
- }
- else
- {
- /*
- * Handle non-speculative insertion related
- * changes
- */
- rb->apply_change(rb, txn, relation, change);
- }
+ dlist_delete(&change->node);
+ specinsert = change;
+ /* Don't clear reassembled toast chunks */
+ continue;
+ }
+ else if (change->action == REORDER_BUFFER_CHANGE_INTERNAL_DELETE)
+ {
+ Assert(RelFileNodeEquals(change->data.tp.relnode,
+ specinsert->data.tp.relnode));
/*
- * Only clear reassembled toast chunks if we're
- * sure they're not required anymore. The creator
- * of the tuple tells us.
+ * Free memory from pending tuple. Do not
+ * report as logical delete to encoding plugin.
*/
- if (change->data.tp.clear_toast_afterwards)
- ReorderBufferToastReset(rb, txn);
+ Assert(specinsert->data.tp.oldtuple == NULL);
+ ReorderBufferReturnTupleBuf(rb, specinsert->data.tp.newtuple);
+ specinsert = NULL;
}
- /* we're not interested in toast deletions */
- else if (change->action == REORDER_BUFFER_CHANGE_INSERT)
+ else
{
/*
- * Need to reassemble the full toasted Datum in
- * memory, to ensure the chunks don't get reused
- * till we're done remove it from the list of this
- * transaction's changes. Otherwise it will get
- * freed/reused while restoring spooled data from
- * disk.
+ * Handle non-speculative insertion related
+ * changes
*/
- dlist_delete(&change->node);
- ReorderBufferToastAppendChunk(rb, txn, relation,
- change);
+ rb->apply_change(rb, txn, relation, change);
}
+ /*
+ * Only clear reassembled toast chunks if we're
+ * sure they're not required anymore. The creator
+ * of the tuple tells us.
+ */
+ if (change->data.tp.clear_toast_afterwards)
+ ReorderBufferToastReset(rb, txn);
+ }
+ /* we're not interested in toast deletions */
+ else if (change->action == REORDER_BUFFER_CHANGE_INSERT)
+ {
+ /*
+ * Need to reassemble the full toasted Datum in
+ * memory, to ensure the chunks don't get reused till
+ * we're done remove it from the list of this
+ * transaction's changes. Otherwise it will get
+ * freed/reused while restoring spooled data from
+ * disk.
+ */
+ dlist_delete(&change->node);
+ ReorderBufferToastAppendChunk(rb, txn, relation,
+ change);
+ }
+
+ change_done:
+ if (relation != NULL)
+ {
+ RelationClose(relation);
+ relation = NULL;
}
- RelationClose(relation);
break;
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
/* get rid of the old */