/* *Disallowempty-stringcursorname(conflictswithprotocol-level *unnamedportal).
*/ if (!cstmt->portalname || cstmt->portalname[0] == '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_CURSOR_NAME),
errmsg("invalid cursor name: must not be empty")));
/* *Ifthisisanon-holdablecursor,werequirethatthisstatementhas *beenexecutedinsideatransactionblock(orelse,itwouldhaveno *user-visibleeffect).
*/ if (!(cstmt->options & CURSOR_OPT_HOLD))
RequireTransactionBlock(isTopLevel, "DECLARE CURSOR"); elseif (InSecurityRestrictedOperation())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("cannot create a cursor WITH HOLD within security-restricted operation")));
/* Query contained by DeclareCursor needs to be jumbled if requested */ if (IsQueryIdEnabled())
jstate = JumbleQuery(query);
if (post_parse_analyze_hook)
(*post_parse_analyze_hook) (pstate, query, jstate);
/* SELECT should never rewrite to more or less than one query */ if (list_length(rewritten) != 1)
elog(ERROR, "non-SELECT statement in DECLARE CURSOR");
query = linitial_node(Query, rewritten);
if (query->commandType != CMD_SELECT)
elog(ERROR, "non-SELECT statement in DECLARE CURSOR");
/* Plan the query, applying the specified options */
plan = pg_plan_query(query, pstate->p_sourcetext, cstmt->options, params);
/* *Disallowempty-stringcursorname(conflictswithprotocol-level *unnamedportal).
*/ if (!stmt->portalname || stmt->portalname[0] == '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_CURSOR_NAME),
errmsg("invalid cursor name: must not be empty")));
/* get the portal from the portal name */
portal = GetPortalByName(stmt->portalname); if (!PortalIsValid(portal))
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_CURSOR),
errmsg("cursor \"%s\" does not exist", stmt->portalname))); return; /* keep compiler happy */
}
/* Adjust dest if needed. MOVE wants destination DestNone */ if (stmt->ismove)
dest = None_Receiver;
/* Do it */
nprocessed = PortalRunFetch(portal,
stmt->direction,
stmt->howMany,
dest);
/* Return command status if wanted */ if (qc)
SetQueryCompletion(qc, stmt->ismove ? CMDTAG_MOVE : CMDTAG_FETCH,
nprocessed);
}
/* NULL means CLOSE ALL */ if (name == NULL)
{
PortalHashTableDeleteAll(); return;
}
/* *Disallowempty-stringcursorname(conflictswithprotocol-level *unnamedportal).
*/ if (name[0] == '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_CURSOR_NAME),
errmsg("invalid cursor name: must not be empty")));
/* *gettheportalfromtheportalname
*/
portal = GetPortalByName(name); if (!PortalIsValid(portal))
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_CURSOR),
errmsg("cursor \"%s\" does not exist", name))); return; /* keep compiler happy */
}
if (portal->status != PORTAL_FAILED)
{
ResourceOwner saveResourceOwner;
/* We must make the portal's resource owner current */
saveResourceOwner = CurrentResourceOwner; if (portal->resowner)
CurrentResourceOwner = portal->resowner;
if (portal->atEnd)
{ /* *Justforcethetuplestoreforwardtoitsend.Thesizeofthe *skiprequesthereisarbitrary.
*/ while (tuplestore_skiptuples(portal->holdStore, 1000000, true)) /* continue */ ;
} else
{
tuplestore_rescan(portal->holdStore);
/* *Intheno-scrollcase,thestartofthetuplestoreisexactly *wherewewanttobe,sonorepositioningiswanted.
*/ if (portal->cursorOptions & CURSOR_OPT_SCROLL)
{ if (!tuplestore_skiptuples(portal->holdStore,
portal->portalPos, true))
elog(ERROR, "unexpected end of tuple stream");
}
}
}
PG_CATCH();
{ /* Uncaught error while executing portal: mark it dead */
MarkPortalFailed(portal);
/* Restore global vars and propagate error */
ActivePortal = saveActivePortal;
CurrentResourceOwner = saveResourceOwner;
PortalContext = savePortalContext;
PG_RE_THROW();
}
PG_END_TRY();
MemoryContextSwitchTo(oldcxt);
/* Mark portal not active */
portal->status = PORTAL_READY;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.