#include "nodes/params.h"#include "nodes/parsenodes.h"#include "tcop/dest.h"

Go to the source code of this file.
Functions | |
| void | ExecCreateTableAs (CreateTableAsStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag) |
| int | GetIntoRelEFlags (IntoClause *intoClause) |
| DestReceiver * | CreateIntoRelDestReceiver (IntoClause *intoClause) |
| DestReceiver* CreateIntoRelDestReceiver | ( | IntoClause * | intoClause | ) |
Definition at line 205 of file createas.c.
References palloc0().
Referenced by CreateDestReceiver(), ExecCreateTableAs(), and ExplainOnePlan().
{
DR_intorel *self = (DR_intorel *) palloc0(sizeof(DR_intorel));
self->pub.receiveSlot = intorel_receive;
self->pub.rStartup = intorel_startup;
self->pub.rShutdown = intorel_shutdown;
self->pub.rDestroy = intorel_destroy;
self->pub.mydest = DestIntoRel;
self->into = intoClause;
/* other private fields will be set during intorel_startup */
return (DestReceiver *) self;
}
| void ExecCreateTableAs | ( | CreateTableAsStmt * | stmt, | |
| const char * | queryString, | |||
| ParamListInfo | params, | |||
| char * | completionTag | |||
| ) |
Definition at line 67 of file createas.c.
References Assert, CMD_SELECT, CMD_UTILITY, Query::commandType, COMPLETION_TAG_BUFSIZE, copyObject(), CreateIntoRelDestReceiver(), CreateQueryDesc(), elog, ERROR, ExecuteQuery(), ExecutorEnd(), ExecutorFinish(), ExecutorRun(), ExecutorStart(), FreeQueryDesc(), GetActiveSnapshot(), GetIntoRelEFlags(), CreateTableAsStmt::into, InvalidSnapshot, IsA, linitial, list_length(), pg_plan_query(), PopActiveSnapshot(), PushCopiedSnapshot(), CreateTableAsStmt::query, QueryRewrite(), snprintf(), UpdateActiveSnapshotCommandId(), and Query::utilityStmt.
Referenced by ProcessUtilitySlow().
{
Query *query = (Query *) stmt->query;
IntoClause *into = stmt->into;
DestReceiver *dest;
List *rewritten;
PlannedStmt *plan;
QueryDesc *queryDesc;
ScanDirection dir;
/*
* Create the tuple receiver object and insert info it will need
*/
dest = CreateIntoRelDestReceiver(into);
/*
* The contained Query could be a SELECT, or an EXECUTE utility command.
* If the latter, we just pass it off to ExecuteQuery.
*/
Assert(IsA(query, Query));
if (query->commandType == CMD_UTILITY &&
IsA(query->utilityStmt, ExecuteStmt))
{
ExecuteStmt *estmt = (ExecuteStmt *) query->utilityStmt;
ExecuteQuery(estmt, into, queryString, params, dest, completionTag);
return;
}
Assert(query->commandType == CMD_SELECT);
/*
* Parse analysis was done already, but we still have to run the rule
* rewriter. We do not do AcquireRewriteLocks: we assume the query either
* came straight from the parser, or suitable locks were acquired by
* plancache.c.
*
* Because the rewriter and planner tend to scribble on the input, we make
* a preliminary copy of the source querytree. This prevents problems in
* the case that CTAS is in a portal or plpgsql function and is executed
* repeatedly. (See also the same hack in EXPLAIN and PREPARE.)
*/
rewritten = QueryRewrite((Query *) copyObject(query));
/* SELECT should never rewrite to more or less than one SELECT query */
if (list_length(rewritten) != 1)
elog(ERROR, "unexpected rewrite result for CREATE TABLE AS SELECT");
query = (Query *) linitial(rewritten);
Assert(query->commandType == CMD_SELECT);
/* plan the query */
plan = pg_plan_query(query, 0, params);
/*
* Use a snapshot with an updated command ID to ensure this query sees
* results of any previously executed queries. (This could only matter if
* the planner executed an allegedly-stable function that changed the
* database contents, but let's do it anyway to be parallel to the EXPLAIN
* code path.)
*/
PushCopiedSnapshot(GetActiveSnapshot());
UpdateActiveSnapshotCommandId();
/* Create a QueryDesc, redirecting output to our tuple receiver */
queryDesc = CreateQueryDesc(plan, queryString,
GetActiveSnapshot(), InvalidSnapshot,
dest, params, 0);
/* call ExecutorStart to prepare the plan for execution */
ExecutorStart(queryDesc, GetIntoRelEFlags(into));
/*
* Normally, we run the plan to completion; but if skipData is specified,
* just do tuple receiver startup and shutdown.
*/
if (into->skipData)
dir = NoMovementScanDirection;
else
dir = ForwardScanDirection;
/* run the plan */
ExecutorRun(queryDesc, dir, 0L);
/* save the rowcount if we're given a completionTag to fill */
if (completionTag)
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
"SELECT %u", queryDesc->estate->es_processed);
/* and clean up */
ExecutorFinish(queryDesc);
ExecutorEnd(queryDesc);
FreeQueryDesc(queryDesc);
PopActiveSnapshot();
}
| int GetIntoRelEFlags | ( | IntoClause * | intoClause | ) |
Definition at line 174 of file createas.c.
References interpretOidsOption(), NULL, IntoClause::options, IntoClause::skipData, and IntoClause::viewQuery.
Referenced by ExecCreateTableAs(), ExecuteQuery(), and ExplainOnePlan().
{
int flags;
/*
* We need to tell the executor whether it has to produce OIDs or not,
* because it doesn't have enough information to do so itself (since we
* can't build the target relation until after ExecutorStart).
*
* Disallow the OIDS option for materialized views.
*/
if (interpretOidsOption(intoClause->options,
(intoClause->viewQuery == NULL)))
flags = EXEC_FLAG_WITH_OIDS;
else
flags = EXEC_FLAG_WITHOUT_OIDS;
if (intoClause->skipData)
flags |= EXEC_FLAG_WITH_NO_DATA;
return flags;
}
1.7.1