Esempio n. 1
0
/*
 * Pre-commit processing for portals.
 *
 * Any holdable cursors created in this transaction need to be converted to
 * materialized form, since we are going to close down the executor and
 * release locks.  Other portals are not touched yet.
 *
 * Returns TRUE if any holdable cursors were processed, FALSE if not.
 */
bool
CommitHoldablePortals(void)
{
	bool result = false;
	HASH_SEQ_STATUS status;
	PortalHashEnt *hentry;

	hash_seq_init(&status, PortalHashTable);

	while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL)
	{
		Portal		portal = hentry->portal;

		/* Is it a holdable portal created in the current xact? */
		if ((portal->cursorOptions & CURSOR_OPT_HOLD) &&
			portal->createSubid != InvalidSubTransactionId &&
			portal->status == PORTAL_READY)
		{
			/*
			 * We are exiting the transaction that created a holdable
			 * cursor.	Instead of dropping the portal, prepare it for
			 * access by later transactions.
			 *
			 * Note that PersistHoldablePortal() must release all resources
			 * used by the portal that are local to the creating
			 * transaction.
			 */
			PortalCreateHoldStore(portal);
			PersistHoldablePortal(portal);

			/*
			 * Any resources belonging to the portal will be released in
			 * the upcoming transaction-wide cleanup; the portal will no
			 * longer have its own resources.
			 */
			portal->resowner = NULL;

			/*
			 * Having successfully exported the holdable cursor, mark it
			 * as not belonging to this transaction.
			 */
			portal->createSubid = InvalidSubTransactionId;

			result = true;
		}
	}

	return result;
}
Esempio n. 2
0
/*
 * Pre-commit processing for portals.
 *
 * Any holdable cursors created in this transaction need to be converted to
 * materialized form, since we are going to close down the executor and
 * release locks.  Remove all other portals created in this transaction.
 * Portals remaining from prior transactions should be left untouched.
 *
 * XXX This assumes that portals can be deleted in a random order, ie,
 * no portal has a reference to any other (at least not one that will be
 * exercised during deletion).	I think this is okay at the moment, but
 * we've had bugs of that ilk in the past.  Keep a close eye on cursor
 * references...
 */
void
AtCommit_Portals(void)
{
	HASH_SEQ_STATUS status;
	PortalHashEnt *hentry;
	TransactionId xact = GetCurrentTransactionId();

	hash_seq_init(&status, PortalHashTable);

	while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL)
	{
		Portal		portal = hentry->portal;

		/*
		 * Do not touch active portals --- this can only happen in the
		 * case of a multi-transaction utility command, such as VACUUM.
		 */
		if (portal->portalActive)
			continue;

		if (portal->cursorOptions & CURSOR_OPT_HOLD)
		{
			/*
			 * Do nothing to cursors held over from a previous
			 * transaction.
			 */
			if (portal->createXact != xact)
				continue;

			/*
			 * We are exiting the transaction that created a holdable
			 * cursor.	Instead of dropping the portal, prepare it for
			 * access by later transactions.
			 *
			 * Note that PersistHoldablePortal() must release all resources
			 * used by the portal that are local to the creating
			 * transaction.
			 */
			PortalCreateHoldStore(portal);
			PersistHoldablePortal(portal);
		}
		else
		{
			/* Zap all non-holdable portals */
			PortalDrop(portal, false);
		}
	}
}