diff options
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r-- | src/backend/executor/execMain.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 708831a5c34..d19e0978e4e 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -56,6 +56,7 @@ #include "storage/smgr.h" #include "tcop/utility.h" #include "utils/acl.h" +#include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/snapmgr.h" @@ -306,6 +307,13 @@ standard_ExecutorRun(QueryDesc *queryDesc, (*dest->rStartup) (dest, operation, queryDesc->tupDesc); /* + * if it's CREATE TABLE AS ... WITH NO DATA, skip plan execution + */ + if (estate->es_select_into && + queryDesc->plannedstmt->intoClause->skipData) + direction = NoMovementScanDirection; + + /* * run plan */ if (!ScanDirectionIsNoMovement(direction)) @@ -2388,6 +2396,7 @@ OpenIntoRel(QueryDesc *queryDesc) { IntoClause *into = queryDesc->plannedstmt->intoClause; EState *estate = queryDesc->estate; + TupleDesc intoTupDesc = queryDesc->tupDesc; Relation intoRelationDesc; char *intoName; Oid namespaceId; @@ -2416,6 +2425,31 @@ OpenIntoRel(QueryDesc *queryDesc) errmsg("ON COMMIT can only be used on temporary tables"))); /* + * If a column name list was specified in CREATE TABLE AS, override the + * column names derived from the query. (Too few column names are OK, too + * many are not.) It would probably be all right to scribble directly on + * the query's result tupdesc, but let's be safe and make a copy. + */ + if (into->colNames) + { + ListCell *lc; + + intoTupDesc = CreateTupleDescCopy(intoTupDesc); + attnum = 1; + foreach(lc, into->colNames) + { + char *colname = strVal(lfirst(lc)); + + if (attnum > intoTupDesc->natts) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("CREATE TABLE AS specifies too many column names"))); + namestrcpy(&(intoTupDesc->attrs[attnum - 1]->attname), colname); + attnum++; + } + } + + /* * Find namespace to create in, check its permissions */ intoName = into->rel->relname; @@ -2477,7 +2511,7 @@ OpenIntoRel(QueryDesc *queryDesc) InvalidOid, InvalidOid, GetUserId(), - queryDesc->tupDesc, + intoTupDesc, NIL, RELKIND_RELATION, into->rel->relpersistence, @@ -2519,7 +2553,7 @@ OpenIntoRel(QueryDesc *queryDesc) intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock); /* - * check INSERT permission on the constructed table. + * Check INSERT permission on the constructed table. */ rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; @@ -2527,7 +2561,7 @@ OpenIntoRel(QueryDesc *queryDesc) rte->relkind = RELKIND_RELATION; rte->requiredPerms = ACL_INSERT; - for (attnum = 1; attnum <= queryDesc->tupDesc->natts; attnum++) + for (attnum = 1; attnum <= intoTupDesc->natts; attnum++) rte->modifiedCols = bms_add_member(rte->modifiedCols, attnum - FirstLowInvalidHeapAttributeNumber); |