v16_fix_masahiko.patch.txt
text/plain
Filename: v16_fix_masahiko.patch.txt
Type: text/plain
Part: 0
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));