diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index aba76eb0173..7d5067d90b5 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -119,8 +119,8 @@ static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot); static void CopyAttributeOutText(CopyToState cstate, const char *string); static void CopyAttributeOutCSV(CopyToState cstate, const char *string, bool use_quote); -static void CopyRelTo(CopyToState cstate, Relation rel, Relation root_rel, - uint64 *processed); +static void CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, + uint64 *processed); /* built-in format-specific routines */ static void CopyToTextLikeStart(CopyToState cstate, TupleDesc tupDesc); @@ -681,32 +681,30 @@ BeginCopyTo(ParseState *pstate, else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { /* - * Collect a list of partitions containing data, so that later + * Collect OIDs of relation containing data, so that later * DoCopyTo can copy the data from them. - */ - children = find_all_inheritors(RelationGetRelid(rel), - AccessShareLock, - NULL); + */ + children = find_all_inheritors(RelationGetRelid(rel), AccessShareLock, NULL); - foreach_oid(childreloid, children) + foreach_oid(child, children) { - char relkind = get_rel_relkind(childreloid); + char relkind = get_rel_relkind(child); if (relkind == RELKIND_FOREIGN_TABLE) { - char *relation_name; + char *relation_name = get_rel_name(child); - relation_name = get_rel_name(childreloid); ereport(ERROR, - errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot copy from foreign table \"%s\"", relation_name), - errdetail("Partition \"%s\" is a foreign table in the partitioned table \"%s\"", - relation_name, RelationGetRelationName(rel)), - errhint("Try the COPY (SELECT ...) TO variant.")); + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy from foreign table \"%s\"", relation_name), + errdetail("Partition \"%s\" is a foreign table in partitioned table \"%s\"", + relation_name, RelationGetRelationName(rel)), + errhint("Try the COPY (SELECT ...) TO variant."))); } + /* Exclude tables with no data */ if (RELKIND_HAS_PARTITIONS(relkind)) - children = foreach_delete_current(children, childreloid); + children = foreach_delete_current(children, child); } } else @@ -1106,21 +1104,21 @@ DoCopyTo(CopyToState cstate) /* * If COPY TO source table is a partitioned table, then open each * partition and process each individual partition. - */ + */ if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - foreach_oid(scan_oid, cstate->partitions) + foreach_oid(child, cstate->partitions) { - Relation scan_rel; + Relation scan_rel; - /* We already got the needed lock in BeginCopyTo */ - scan_rel = table_open(scan_oid, NoLock); - CopyRelTo(cstate, scan_rel, cstate->rel, &processed); + /* We already got the lock in BeginCopyTo */ + scan_rel = table_open(child, NoLock); + CopyRelationTo(cstate, scan_rel, cstate->rel, &processed); table_close(scan_rel, NoLock); } } else - CopyRelTo(cstate, cstate->rel, NULL, &processed); + CopyRelationTo(cstate, cstate->rel, NULL, &processed); } else { @@ -1140,22 +1138,19 @@ DoCopyTo(CopyToState cstate) } /* - * Scan a single table (which may be a partition) and export its rows to the - * COPY destination. + * Scans a single table and exports its rows to the COPY destination. * - * rel: the table from which the actual data will be copied. - * root_rel: if not NULL, it indicates that COPY TO command copy partitioned - * table data to the destination, and "rel" is the partition of "root_rel". - * processed: number of tuples processed. + * root_rel can be set to the root table of rel if rel is a partition + * table so that we can send tuples in root_rel's rowtype, which might + * differ from individual partitions. */ static void -CopyRelTo(CopyToState cstate, Relation rel, Relation root_rel, - uint64 *processed) +CopyRelationTo(CopyToState cstate, Relation rel, Relation root_rel, uint64 *processed) { TupleTableSlot *slot; TableScanDesc scandesc; - AttrMap *map = NULL; - TupleTableSlot *root_slot = NULL; + AttrMap *map = NULL; + TupleTableSlot *root_slot = NULL; scandesc = table_beginscan(rel, GetActiveSnapshot(), 0, NULL); slot = table_slot_create(rel, NULL); @@ -1164,7 +1159,7 @@ CopyRelTo(CopyToState cstate, Relation rel, Relation root_rel, * A partition's rowtype might differ from the root table's. If we are * exporting partition data here, we must convert it back to the root * table's rowtype. - */ + */ if (root_rel != NULL) { root_slot = table_slot_create(root_rel, NULL); @@ -1192,8 +1187,7 @@ CopyRelTo(CopyToState cstate, Relation rel, Relation root_rel, CopyOneRowTo(cstate, copyslot); /* - * Increment the number of processed tuples, and report the - * progress. + * Increment the number of processed tuples, and report the progress. */ pgstat_progress_update_param(PROGRESS_COPY_TUPLES_PROCESSED, ++(*processed));