diff options
Diffstat (limited to 'src/backend/commands/copy.c')
-rw-r--r-- | src/backend/commands/copy.c | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index f6579b043cc..96ed21aae93 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -873,6 +873,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed) ColumnRef *cr; ResTarget *target; RangeVar *from; + List *targetList = NIL; if (is_from) ereport(ERROR, @@ -880,21 +881,59 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed) errmsg("COPY FROM not supported with row-level security"), errhint("Use INSERT statements instead."))); - /* Build target list */ - cr = makeNode(ColumnRef); - + /* + * Build target list + * + * If no columns are specified in the attribute list of the COPY + * command, then the target list is 'all' columns. Therefore, '*' + * should be used as the target list for the resulting SELECT + * statement. + * + * In the case that columns are specified in the attribute list, + * create a ColumnRef and ResTarget for each column and add them to + * the target list for the resulting SELECT statement. + */ if (!stmt->attlist) + { + cr = makeNode(ColumnRef); cr->fields = list_make1(makeNode(A_Star)); - else - cr->fields = stmt->attlist; + cr->location = -1; + + target = makeNode(ResTarget); + target->name = NULL; + target->indirection = NIL; + target->val = (Node *) cr; + target->location = -1; - cr->location = 1; + targetList = list_make1(target); + } + else + { + ListCell *lc; - target = makeNode(ResTarget); - target->name = NULL; - target->indirection = NIL; - target->val = (Node *) cr; - target->location = 1; + foreach(lc, stmt->attlist) + { + /* + * Build the ColumnRef for each column. The ColumnRef + * 'fields' property is a String 'Value' node (see + * nodes/value.h) that corresponds to the column name + * respectively. + */ + cr = makeNode(ColumnRef); + cr->fields = list_make1(lfirst(lc)); + cr->location = -1; + + /* Build the ResTarget and add the ColumnRef to it. */ + target = makeNode(ResTarget); + target->name = NULL; + target->indirection = NIL; + target->val = (Node *) cr; + target->location = -1; + + /* Add each column to the SELECT statement's target list */ + targetList = lappend(targetList, target); + } + } /* * Build RangeVar for from clause, fully qualified based on the @@ -905,7 +944,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed) /* Build query */ select = makeNode(SelectStmt); - select->targetList = list_make1(target); + select->targetList = targetList; select->fromClause = list_make1(from); query = (Node *) select; |