On 2025-Jul-02, jian he wrote: > @@ -673,11 +680,34 @@ BeginCopyTo(ParseState *pstate, > errmsg("cannot copy from sequence > \"%s\"", > > RelationGetRelationName(rel)))); > else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) > - ereport(ERROR, > - (errcode(ERRCODE_WRONG_OBJECT_TYPE), > - errmsg("cannot copy from partitioned > table \"%s\"", > - > RelationGetRelationName(rel)), > - errhint("Try the COPY (SELECT ...) TO > variant."))); > + { > + children = find_all_inheritors(RelationGetRelid(rel), > + > AccessShareLock, > + > NULL); > + > + foreach_oid(childreloid, children) > + { > + char relkind = > get_rel_relkind(childreloid); > + > + if (relkind == RELKIND_FOREIGN_TABLE) > + { > + char *relation_name; > + > + 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.")); > + }
This code looks like it's duplicating what you could obtain by using RelationGetPartitionDesc and then observe the ->isleaf bits. Maybe have a look at the function RelationHasForeignPartition() in the patch at https://postgr.es/m/canhcyew_s2ld6ridsmhtwqnpyb67ewxqf7n8mn7dornakmf...@mail.gmail.com which looks very similar to what you need here. I think that would also have the (maybe dubious) advantage that the rows will be output in partition bound order rather than breadth-first (partition hierarchy) OID order. -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/ "The saddest aspect of life right now is that science gathers knowledge faster than society gathers wisdom." (Isaac Asimov)