PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
createas.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * createas.c
4 * Execution of CREATE TABLE ... AS, a/k/a SELECT INTO.
5 * Since CREATE MATERIALIZED VIEW shares syntax and most behaviors,
6 * we implement that here, too.
7 *
8 * We implement this by diverting the query's normal output to a
9 * specialized DestReceiver type.
10 *
11 * Formerly, CTAS was implemented as a variant of SELECT, which led
12 * to assorted legacy behaviors that we still try to preserve, notably that
13 * we must return a tuples-processed count in the QueryCompletion. (We no
14 * longer do that for CTAS ... WITH NO DATA, however.)
15 *
16 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
17 * Portions Copyright (c) 1994, Regents of the University of California
18 *
19 *
20 * IDENTIFICATION
21 * src/backend/commands/createas.c
22 *
23 *-------------------------------------------------------------------------
24 */
25#include "postgres.h"
26
27#include "access/heapam.h"
28#include "access/reloptions.h"
29#include "access/tableam.h"
30#include "access/xact.h"
31#include "catalog/namespace.h"
32#include "catalog/toasting.h"
33#include "commands/createas.h"
34#include "commands/matview.h"
35#include "commands/prepare.h"
36#include "commands/tablecmds.h"
37#include "commands/view.h"
38#include "nodes/makefuncs.h"
39#include "nodes/nodeFuncs.h"
40#include "nodes/queryjumble.h"
41#include "parser/analyze.h"
43#include "tcop/tcopprot.h"
44#include "utils/builtins.h"
45#include "utils/lsyscache.h"
46#include "utils/rls.h"
47#include "utils/snapmgr.h"
48
49typedef struct
50{
51 DestReceiver pub; /* publicly-known function pointers */
52 IntoClause *into; /* target relation specification */
53 /* These fields are filled by intorel_startup: */
54 Relation rel; /* relation to write to */
55 ObjectAddress reladdr; /* address of rel, for ExecCreateTableAs */
56 CommandId output_cid; /* cmin to insert in output tuples */
57 int ti_options; /* table_tuple_insert performance options */
58 BulkInsertState bistate; /* bulk insert state */
60
61/* utility functions for CTAS definition creation */
62static ObjectAddress create_ctas_internal(List *attrList, IntoClause *into);
64
65/* DestReceiver routines for collecting data */
66static void intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo);
67static bool intorel_receive(TupleTableSlot *slot, DestReceiver *self);
68static void intorel_shutdown(DestReceiver *self);
69static void intorel_destroy(DestReceiver *self);
70
71
72/*
73 * create_ctas_internal
74 *
75 * Internal utility used for the creation of the definition of a relation
76 * created via CREATE TABLE AS or a materialized view. Caller needs to
77 * provide a list of attributes (ColumnDef nodes).
78 */
79static ObjectAddress
81{
83 bool is_matview;
84 char relkind;
85 Datum toast_options;
86 const char *const validnsps[] = HEAP_RELOPT_NAMESPACES;
87 ObjectAddress intoRelationAddr;
88
89 /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */
90 is_matview = (into->viewQuery != NULL);
91 relkind = is_matview ? RELKIND_MATVIEW : RELKIND_RELATION;
92
93 /*
94 * Create the target relation by faking up a CREATE TABLE parsetree and
95 * passing it to DefineRelation.
96 */
97 create->relation = into->rel;
98 create->tableElts = attrList;
99 create->inhRelations = NIL;
100 create->ofTypename = NULL;
101 create->constraints = NIL;
102 create->options = into->options;
103 create->oncommit = into->onCommit;
104 create->tablespacename = into->tableSpaceName;
105 create->if_not_exists = false;
106 create->accessMethod = into->accessMethod;
107
108 /*
109 * Create the relation. (This will error out if there's an existing view,
110 * so we don't need more code to complain if "replace" is false.)
111 */
112 intoRelationAddr = DefineRelation(create, relkind, InvalidOid, NULL, NULL);
113
114 /*
115 * If necessary, create a TOAST table for the target table. Note that
116 * NewRelationCreateToastTable ends with CommandCounterIncrement(), so
117 * that the TOAST table will be visible for insertion.
118 */
120
121 /* parse and validate reloptions for the toast table */
122 toast_options = transformRelOptions((Datum) 0,
123 create->options,
124 "toast",
125 validnsps,
126 true, false);
127
128 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true);
129
130 NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options);
131
132 /* Create the "view" part of a materialized view. */
133 if (is_matview)
134 {
135 /* StoreViewQuery scribbles on tree, so make a copy */
136 Query *query = copyObject(into->viewQuery);
137
138 StoreViewQuery(intoRelationAddr.objectId, query, false);
140 }
141
142 return intoRelationAddr;
143}
144
145
146/*
147 * create_ctas_nodata
148 *
149 * Create CTAS or materialized view when WITH NO DATA is used, starting from
150 * the targetlist of the SELECT or view definition.
151 */
152static ObjectAddress
154{
155 List *attrList;
156 ListCell *t,
157 *lc;
158
159 /*
160 * Build list of ColumnDefs from non-junk elements of the tlist. If a
161 * column name list was specified in CREATE TABLE AS, override the column
162 * names in the query. (Too few column names are OK, too many are not.)
163 */
164 attrList = NIL;
165 lc = list_head(into->colNames);
166 foreach(t, tlist)
167 {
168 TargetEntry *tle = (TargetEntry *) lfirst(t);
169
170 if (!tle->resjunk)
171 {
172 ColumnDef *col;
173 char *colname;
174
175 if (lc)
176 {
177 colname = strVal(lfirst(lc));
178 lc = lnext(into->colNames, lc);
179 }
180 else
181 colname = tle->resname;
182
183 col = makeColumnDef(colname,
184 exprType((Node *) tle->expr),
185 exprTypmod((Node *) tle->expr),
186 exprCollation((Node *) tle->expr));
187
188 /*
189 * It's possible that the column is of a collatable type but the
190 * collation could not be resolved, so double-check. (We must
191 * check this here because DefineRelation would adopt the type's
192 * default collation rather than complaining.)
193 */
194 if (!OidIsValid(col->collOid) &&
197 (errcode(ERRCODE_INDETERMINATE_COLLATION),
198 errmsg("no collation was derived for column \"%s\" with collatable type %s",
199 col->colname,
201 errhint("Use the COLLATE clause to set the collation explicitly.")));
202
203 attrList = lappend(attrList, col);
204 }
205 }
206
207 if (lc != NULL)
209 (errcode(ERRCODE_SYNTAX_ERROR),
210 errmsg("too many column names were specified")));
211
212 /* Create the relation definition using the ColumnDef list */
213 return create_ctas_internal(attrList, into);
214}
215
216
217/*
218 * ExecCreateTableAs -- execute a CREATE TABLE AS command
219 */
222 ParamListInfo params, QueryEnvironment *queryEnv,
223 QueryCompletion *qc)
224{
225 Query *query = castNode(Query, stmt->query);
226 IntoClause *into = stmt->into;
227 JumbleState *jstate = NULL;
228 bool is_matview = (into->viewQuery != NULL);
229 bool do_refresh = false;
231 ObjectAddress address;
232
233 /* Check if the relation exists or not */
236
237 /*
238 * Create the tuple receiver object and insert info it will need
239 */
241
242 /* Query contained by CTAS needs to be jumbled if requested */
243 if (IsQueryIdEnabled())
244 jstate = JumbleQuery(query);
245
247 (*post_parse_analyze_hook) (pstate, query, jstate);
248
249 /*
250 * The contained Query could be a SELECT, or an EXECUTE utility command.
251 * If the latter, we just pass it off to ExecuteQuery.
252 */
253 if (query->commandType == CMD_UTILITY &&
254 IsA(query->utilityStmt, ExecuteStmt))
255 {
257
258 Assert(!is_matview); /* excluded by syntax */
259 ExecuteQuery(pstate, estmt, into, params, dest, qc);
260
261 /* get object address that intorel_startup saved for us */
262 address = ((DR_intorel *) dest)->reladdr;
263
264 return address;
265 }
266 Assert(query->commandType == CMD_SELECT);
267
268 /*
269 * For materialized views, always skip data during table creation, and use
270 * REFRESH instead (see below).
271 */
272 if (is_matview)
273 {
274 do_refresh = !into->skipData;
275 into->skipData = true;
276 }
277
278 if (into->skipData)
279 {
280 /*
281 * If WITH NO DATA was specified, do not go through the rewriter,
282 * planner and executor. Just define the relation using a code path
283 * similar to CREATE VIEW. This avoids dump/restore problems stemming
284 * from running the planner before all dependencies are set up.
285 */
286 address = create_ctas_nodata(query->targetList, into);
287
288 /*
289 * For materialized views, reuse the REFRESH logic, which locks down
290 * security-restricted operations and restricts the search_path. This
291 * reduces the chance that a subsequent refresh will fail.
292 */
293 if (do_refresh)
294 RefreshMatViewByOid(address.objectId, true, false, false,
295 pstate->p_sourcetext, qc);
296
297 }
298 else
299 {
300 List *rewritten;
302 QueryDesc *queryDesc;
303
304 Assert(!is_matview);
305
306 /*
307 * Parse analysis was done already, but we still have to run the rule
308 * rewriter. We do not do AcquireRewriteLocks: we assume the query
309 * either came straight from the parser, or suitable locks were
310 * acquired by plancache.c.
311 */
312 rewritten = QueryRewrite(query);
313
314 /* SELECT should never rewrite to more or less than one SELECT query */
315 if (list_length(rewritten) != 1)
316 elog(ERROR, "unexpected rewrite result for CREATE TABLE AS SELECT");
317 query = linitial_node(Query, rewritten);
318 Assert(query->commandType == CMD_SELECT);
319
320 /* plan the query */
321 plan = pg_plan_query(query, pstate->p_sourcetext,
322 CURSOR_OPT_PARALLEL_OK, params);
323
324 /*
325 * Use a snapshot with an updated command ID to ensure this query sees
326 * results of any previously executed queries. (This could only
327 * matter if the planner executed an allegedly-stable function that
328 * changed the database contents, but let's do it anyway to be
329 * parallel to the EXPLAIN code path.)
330 */
333
334 /* Create a QueryDesc, redirecting output to our tuple receiver */
335 queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
337 dest, params, queryEnv, 0);
338
339 /* call ExecutorStart to prepare the plan for execution */
340 ExecutorStart(queryDesc, GetIntoRelEFlags(into));
341
342 /* run the plan to completion */
343 ExecutorRun(queryDesc, ForwardScanDirection, 0);
344
345 /* save the rowcount if we're given a qc to fill */
346 if (qc)
347 SetQueryCompletion(qc, CMDTAG_SELECT, queryDesc->estate->es_processed);
348
349 /* get object address that intorel_startup saved for us */
350 address = ((DR_intorel *) dest)->reladdr;
351
352 /* and clean up */
353 ExecutorFinish(queryDesc);
354 ExecutorEnd(queryDesc);
355
356 FreeQueryDesc(queryDesc);
357
359 }
360
361 return address;
362}
363
364/*
365 * GetIntoRelEFlags --- compute executor flags needed for CREATE TABLE AS
366 *
367 * This is exported because EXPLAIN and PREPARE need it too. (Note: those
368 * callers still need to deal explicitly with the skipData flag; since they
369 * use different methods for suppressing execution, it doesn't seem worth
370 * trying to encapsulate that part.)
371 */
372int
374{
375 int flags = 0;
376
377 if (intoClause->skipData)
378 flags |= EXEC_FLAG_WITH_NO_DATA;
379
380 return flags;
381}
382
383/*
384 * CreateTableAsRelExists --- check existence of relation for CreateTableAsStmt
385 *
386 * Utility wrapper checking if the relation pending for creation in this
387 * CreateTableAsStmt query already exists or not. Returns true if the
388 * relation exists, otherwise false.
389 */
390bool
392{
393 Oid nspid;
394 Oid oldrelid;
395 ObjectAddress address;
396 IntoClause *into = ctas->into;
397
399
400 oldrelid = get_relname_relid(into->rel->relname, nspid);
401 if (OidIsValid(oldrelid))
402 {
403 if (!ctas->if_not_exists)
405 (errcode(ERRCODE_DUPLICATE_TABLE),
406 errmsg("relation \"%s\" already exists",
407 into->rel->relname)));
408
409 /*
410 * The relation exists and IF NOT EXISTS has been specified.
411 *
412 * If we are in an extension script, insist that the pre-existing
413 * object be a member of the extension, to avoid security risks.
414 */
415 ObjectAddressSet(address, RelationRelationId, oldrelid);
417
418 /* OK to skip */
420 (errcode(ERRCODE_DUPLICATE_TABLE),
421 errmsg("relation \"%s\" already exists, skipping",
422 into->rel->relname)));
423 return true;
424 }
425
426 /* Relation does not exist, it can be created */
427 return false;
428}
429
430/*
431 * CreateIntoRelDestReceiver -- create a suitable DestReceiver object
432 *
433 * intoClause will be NULL if called from CreateDestReceiver(), in which
434 * case it has to be provided later. However, it is convenient to allow
435 * self->into to be filled in immediately for other callers.
436 */
439{
440 DR_intorel *self = (DR_intorel *) palloc0(sizeof(DR_intorel));
441
446 self->pub.mydest = DestIntoRel;
447 self->into = intoClause;
448 /* other private fields will be set during intorel_startup */
449
450 return (DestReceiver *) self;
451}
452
453/*
454 * intorel_startup --- executor startup
455 */
456static void
457intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
458{
459 DR_intorel *myState = (DR_intorel *) self;
460 IntoClause *into = myState->into;
461 bool is_matview;
462 List *attrList;
463 ObjectAddress intoRelationAddr;
464 Relation intoRelationDesc;
465 ListCell *lc;
466 int attnum;
467
468 Assert(into != NULL); /* else somebody forgot to set it */
469
470 /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */
471 is_matview = (into->viewQuery != NULL);
472
473 /*
474 * Build column definitions using "pre-cooked" type and collation info. If
475 * a column name list was specified in CREATE TABLE AS, override the
476 * column names derived from the query. (Too few column names are OK, too
477 * many are not.)
478 */
479 attrList = NIL;
480 lc = list_head(into->colNames);
481 for (attnum = 0; attnum < typeinfo->natts; attnum++)
482 {
483 Form_pg_attribute attribute = TupleDescAttr(typeinfo, attnum);
484 ColumnDef *col;
485 char *colname;
486
487 if (lc)
488 {
489 colname = strVal(lfirst(lc));
490 lc = lnext(into->colNames, lc);
491 }
492 else
493 colname = NameStr(attribute->attname);
494
495 col = makeColumnDef(colname,
496 attribute->atttypid,
497 attribute->atttypmod,
498 attribute->attcollation);
499
500 /*
501 * It's possible that the column is of a collatable type but the
502 * collation could not be resolved, so double-check. (We must check
503 * this here because DefineRelation would adopt the type's default
504 * collation rather than complaining.)
505 */
506 if (!OidIsValid(col->collOid) &&
509 (errcode(ERRCODE_INDETERMINATE_COLLATION),
510 errmsg("no collation was derived for column \"%s\" with collatable type %s",
511 col->colname,
513 errhint("Use the COLLATE clause to set the collation explicitly.")));
514
515 attrList = lappend(attrList, col);
516 }
517
518 if (lc != NULL)
520 (errcode(ERRCODE_SYNTAX_ERROR),
521 errmsg("too many column names were specified")));
522
523 /*
524 * Actually create the target table
525 */
526 intoRelationAddr = create_ctas_internal(attrList, into);
527
528 /*
529 * Finally we can open the target table
530 */
531 intoRelationDesc = table_open(intoRelationAddr.objectId, AccessExclusiveLock);
532
533 /*
534 * Make sure the constructed table does not have RLS enabled.
535 *
536 * check_enable_rls() will ereport(ERROR) itself if the user has requested
537 * something invalid, and otherwise will return RLS_ENABLED if RLS should
538 * be enabled here. We don't actually support that currently, so throw
539 * our own ereport(ERROR) if that happens.
540 */
541 if (check_enable_rls(intoRelationAddr.objectId, InvalidOid, false) == RLS_ENABLED)
543 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
544 errmsg("policies not yet implemented for this command")));
545
546 /*
547 * Tentatively mark the target as populated, if it's a matview and we're
548 * going to fill it; otherwise, no change needed.
549 */
550 if (is_matview && !into->skipData)
551 SetMatViewPopulatedState(intoRelationDesc, true);
552
553 /*
554 * Fill private fields of myState for use by later routines
555 */
556 myState->rel = intoRelationDesc;
557 myState->reladdr = intoRelationAddr;
558 myState->output_cid = GetCurrentCommandId(true);
560
561 /*
562 * If WITH NO DATA is specified, there is no need to set up the state for
563 * bulk inserts as there are no tuples to insert.
564 */
565 if (!into->skipData)
566 myState->bistate = GetBulkInsertState();
567 else
568 myState->bistate = NULL;
569
570 /*
571 * Valid smgr_targblock implies something already wrote to the relation.
572 * This may be harmless, but this function hasn't planned for it.
573 */
575}
576
577/*
578 * intorel_receive --- receive one tuple
579 */
580static bool
582{
583 DR_intorel *myState = (DR_intorel *) self;
584
585 /* Nothing to insert if WITH NO DATA is specified. */
586 if (!myState->into->skipData)
587 {
588 /*
589 * Note that the input slot might not be of the type of the target
590 * relation. That's supported by table_tuple_insert(), but slightly
591 * less efficient than inserting with the right slot - but the
592 * alternative would be to copy into a slot of the right type, which
593 * would not be cheap either. This also doesn't allow accessing per-AM
594 * data (say a tuple's xmin), but since we don't do that here...
595 */
596 table_tuple_insert(myState->rel,
597 slot,
598 myState->output_cid,
599 myState->ti_options,
600 myState->bistate);
601 }
602
603 /* We know this is a newly created relation, so there are no indexes */
604
605 return true;
606}
607
608/*
609 * intorel_shutdown --- executor end
610 */
611static void
613{
614 DR_intorel *myState = (DR_intorel *) self;
615 IntoClause *into = myState->into;
616
617 if (!into->skipData)
618 {
620 table_finish_bulk_insert(myState->rel, myState->ti_options);
621 }
622
623 /* close rel, but keep lock until commit */
624 table_close(myState->rel, NoLock);
625 myState->rel = NULL;
626}
627
628/*
629 * intorel_destroy --- release DestReceiver object
630 */
631static void
633{
634 pfree(self);
635}
void ExecuteQuery(ParseState *pstate, ExecuteStmt *stmt, IntoClause *intoClause, ParamListInfo params, DestReceiver *dest, QueryCompletion *qc)
Definition: prepare.c:147
#define InvalidBlockNumber
Definition: block.h:33
#define NameStr(name)
Definition: c.h:700
#define Assert(condition)
Definition: c.h:812
uint32 CommandId
Definition: c.h:620
#define OidIsValid(objectId)
Definition: c.h:729
static void SetQueryCompletion(QueryCompletion *qc, CommandTag commandTag, uint64 nprocessed)
Definition: cmdtag.h:37
int nspid
static void intorel_shutdown(DestReceiver *self)
Definition: createas.c:612
static ObjectAddress create_ctas_internal(List *attrList, IntoClause *into)
Definition: createas.c:80
bool CreateTableAsRelExists(CreateTableAsStmt *ctas)
Definition: createas.c:391
static ObjectAddress create_ctas_nodata(List *tlist, IntoClause *into)
Definition: createas.c:153
int GetIntoRelEFlags(IntoClause *intoClause)
Definition: createas.c:373
static bool intorel_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: createas.c:581
DestReceiver * CreateIntoRelDestReceiver(IntoClause *intoClause)
Definition: createas.c:438
static void intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: createas.c:457
ObjectAddress ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, ParamListInfo params, QueryEnvironment *queryEnv, QueryCompletion *qc)
Definition: createas.c:221
static void intorel_destroy(DestReceiver *self)
Definition: createas.c:632
@ DestIntoRel
Definition: dest.h:94
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:149
void ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:463
void ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:403
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:119
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
Definition: execMain.c:294
#define EXEC_FLAG_WITH_NO_DATA
Definition: executor.h:71
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
BulkInsertState GetBulkInsertState(void)
Definition: heapam.c:1921
void FreeBulkInsertState(BulkInsertState bistate)
Definition: heapam.c:1938
#define stmt
Definition: indent_codes.h:59
List * lappend(List *list, void *datum)
Definition: list.c:339
#define NoLock
Definition: lockdefs.h:34
#define AccessExclusiveLock
Definition: lockdefs.h:43
bool type_is_collatable(Oid typid)
Definition: lsyscache.c:3081
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1885
ColumnDef * makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
Definition: makefuncs.c:515
void SetMatViewPopulatedState(Relation relation, bool newstate)
Definition: matview.c:79
ObjectAddress RefreshMatViewByOid(Oid matviewOid, bool is_create, bool skipData, bool concurrent, const char *queryString, QueryCompletion *qc)
Definition: matview.c:165
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
Oid RangeVarGetCreationNamespace(const RangeVar *newRelation)
Definition: namespace.c:654
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:298
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:816
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define copyObject(obj)
Definition: nodes.h:224
@ CMD_UTILITY
Definition: nodes.h:270
@ CMD_SELECT
Definition: nodes.h:265
#define makeNode(_type_)
Definition: nodes.h:155
#define castNode(_type_, nodeptr)
Definition: nodes.h:176
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:3317
post_parse_analyze_hook_type post_parse_analyze_hook
Definition: analyze.c:59
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
void checkMembershipInCurrentExtension(const ObjectAddress *object)
Definition: pg_depend.c:258
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial_node(type, l)
Definition: pg_list.h:181
#define NIL
Definition: pg_list.h:68
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
#define plan(x)
Definition: pg_regress.c:161
PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ParamListInfo boundParams)
Definition: postgres.c:881
uintptr_t Datum
Definition: postgres.h:64
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
void FreeQueryDesc(QueryDesc *qdesc)
Definition: pquery.c:105
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
Definition: pquery.c:67
static bool IsQueryIdEnabled(void)
Definition: queryjumble.h:77
JumbleState * JumbleQuery(Query *query)
#define RelationGetTargetBlock(relation)
Definition: rel.h:601
Datum transformRelOptions(Datum oldOptions, List *defList, const char *namspace, const char *const validnsps[], bool acceptOidsOff, bool isReset)
Definition: reloptions.c:1156
bytea * heap_reloptions(char relkind, Datum reloptions, bool validate)
Definition: reloptions.c:2019
#define HEAP_RELOPT_NAMESPACES
Definition: reloptions.h:61
List * QueryRewrite(Query *parsetree)
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
Definition: rls.c:52
@ RLS_ENABLED
Definition: rls.h:45
@ ForwardScanDirection
Definition: sdir.h:28
void UpdateActiveSnapshotCommandId(void)
Definition: snapmgr.c:672
void PopActiveSnapshot(void)
Definition: snapmgr.c:703
void PushCopiedSnapshot(Snapshot snapshot)
Definition: snapmgr.c:660
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:728
#define InvalidSnapshot
Definition: snapshot.h:119
char * colname
Definition: parsenodes.h:728
TypeName * typeName
Definition: parsenodes.h:729
Oid collOid
Definition: parsenodes.h:744
List * tableElts
Definition: parsenodes.h:2676
TypeName * ofTypename
Definition: parsenodes.h:2681
OnCommitAction oncommit
Definition: parsenodes.h:2685
List * options
Definition: parsenodes.h:2684
bool if_not_exists
Definition: parsenodes.h:2688
List * inhRelations
Definition: parsenodes.h:2677
RangeVar * relation
Definition: parsenodes.h:2675
char * tablespacename
Definition: parsenodes.h:2686
char * accessMethod
Definition: parsenodes.h:2687
List * constraints
Definition: parsenodes.h:2682
IntoClause * into
Definition: parsenodes.h:3920
Relation rel
Definition: createas.c:54
ObjectAddress reladdr
Definition: createas.c:55
BulkInsertState bistate
Definition: createas.c:58
IntoClause * into
Definition: createas.c:52
int ti_options
Definition: createas.c:57
CommandId output_cid
Definition: createas.c:56
DestReceiver pub
Definition: createas.c:51
uint64 es_processed
Definition: execnodes.h:679
List * colNames
Definition: primnodes.h:163
char * tableSpaceName
Definition: primnodes.h:167
bool skipData
Definition: primnodes.h:170
OnCommitAction onCommit
Definition: primnodes.h:166
List * options
Definition: primnodes.h:165
char * accessMethod
Definition: primnodes.h:164
RangeVar * rel
Definition: primnodes.h:162
Definition: pg_list.h:54
Definition: nodes.h:129
const char * p_sourcetext
Definition: parse_node.h:209
EState * estate
Definition: execdesc.h:48
CmdType commandType
Definition: parsenodes.h:121
Node * utilityStmt
Definition: parsenodes.h:136
List * targetList
Definition: parsenodes.h:193
char * relname
Definition: primnodes.h:82
Expr * expr
Definition: primnodes.h:2190
Oid typeOid
Definition: parsenodes.h:271
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
void(* rDestroy)(DestReceiver *self)
Definition: dest.h:126
CommandDest mydest
Definition: dest.h:128
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
#define TABLE_INSERT_SKIP_FSM
Definition: tableam.h:259
static void table_finish_bulk_insert(Relation rel, int options)
Definition: tableam.h:1600
static void table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, int options, struct BulkInsertStateData *bistate)
Definition: tableam.h:1407
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
Definition: tablecmds.c:713
void NewRelationCreateToastTable(Oid relOid, Datum reloptions)
Definition: toasting.c:71
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:152
#define strVal(v)
Definition: value.h:82
void StoreViewQuery(Oid viewOid, Query *viewParse, bool replace)
Definition: view.c:511
void CommandCounterIncrement(void)
Definition: xact.c:1099
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:828