226{
230 bool is_matview = (into->viewQuery != NULL);
231 bool do_refresh = false;
234
235 /* Check if the relation exists or not */
238
239 /*
240 * Create the tuple receiver object and insert info it will need
241 */
243
244 /* Query contained by CTAS needs to be jumbled if requested */
247
249 (*post_parse_analyze_hook) (pstate, query, jstate);
250
251 /*
252 * The contained Query could be a SELECT, or an EXECUTE utility command.
253 * If the latter, we just pass it off to ExecuteQuery.
254 */
257 {
259
260 Assert(!is_matview);
/* excluded by syntax */
262
263 /* get object address that intorel_startup saved for us */
265
266 return address;
267 }
269
270 /*
271 * For materialized views, always skip data during table creation, and use
272 * REFRESH instead (see below).
273 */
274 if (is_matview)
275 {
278 }
279
281 {
282 /*
283 * If WITH NO DATA was specified, do not go through the rewriter,
284 * planner and executor. Just define the relation using a code path
285 * similar to CREATE VIEW. This avoids dump/restore problems stemming
286 * from running the planner before all dependencies are set up.
287 */
289
290 /*
291 * For materialized views, reuse the REFRESH logic, which locks down
292 * security-restricted operations and restricts the search_path. This
293 * reduces the chance that a subsequent refresh will fail.
294 */
295 if (do_refresh)
297 pstate->p_sourcetext, qc);
298
299 }
300 else
301 {
305
307
308 /*
309 * Parse analysis was done already, but we still have to run the rule
310 * rewriter. We do not do AcquireRewriteLocks: we assume the query
311 * either came straight from the parser, or suitable locks were
312 * acquired by plancache.c.
313 */
315
316 /* SELECT should never rewrite to more or less than one SELECT query */
318 elog(
ERROR,
"unexpected rewrite result for CREATE TABLE AS SELECT");
321
322 /* plan the query */
325
326 /*
327 * Use a snapshot with an updated command ID to ensure this query sees
328 * results of any previously executed queries. (This could only
329 * matter if the planner executed an allegedly-stable function that
330 * changed the database contents, but let's do it anyway to be
331 * parallel to the EXPLAIN code path.)
332 */
335
336 /* Create a QueryDesc, redirecting output to our tuple receiver */
339 dest, params, queryEnv, 0);
340
341 /* call ExecutorStart to prepare the plan for execution */
343
344 /* run the plan to completion */
346
347 /* save the rowcount if we're given a qc to fill */
348 if (qc)
350
351 /* get object address that intorel_startup saved for us */
353
354 /* and clean up */
357
359
361 }
362
363 return address;
364}
void ExecuteQuery(ParseState *pstate, ExecuteStmt *stmt, IntoClause *intoClause, ParamListInfo params, DestReceiver *dest, QueryCompletion *qc)
static void SetQueryCompletion(QueryCompletion *qc, CommandTag commandTag, uint64 nprocessed)
bool CreateTableAsRelExists(CreateTableAsStmt *ctas)
static ObjectAddress create_ctas_nodata(List *tlist, IntoClause *into)
int GetIntoRelEFlags(IntoClause *intoClause)
DestReceiver * CreateIntoRelDestReceiver(IntoClause *intoClause)
void ExecutorEnd(QueryDesc *queryDesc)
void ExecutorFinish(QueryDesc *queryDesc)
void ExecutorStart(QueryDesc *queryDesc, int eflags)
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Assert(PointerIsAligned(start, uint64))
ObjectAddress RefreshMatViewByOid(Oid matviewOid, bool is_create, bool skipData, bool concurrent, const char *queryString, QueryCompletion *qc)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
const ObjectAddress InvalidObjectAddress
#define CURSOR_OPT_PARALLEL_OK
post_parse_analyze_hook_type post_parse_analyze_hook
static int list_length(const List *l)
#define linitial_node(type, l)
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams)
void FreeQueryDesc(QueryDesc *qdesc)
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
static bool IsQueryIdEnabled(void)
JumbleState * JumbleQuery(Query *query)
List * QueryRewrite(Query *parsetree)
void UpdateActiveSnapshotCommandId(void)
void PopActiveSnapshot(void)
void PushCopiedSnapshot(Snapshot snapshot)
Snapshot GetActiveSnapshot(void)