Re: speedup COPY TO for partitioned table.

Álvaro Herrera <alvherre@kurilemu.de>

From: Álvaro Herrera <alvherre@kurilemu.de>
To: jian he <jian.universality@gmail.com>
Cc: torikoshia <torikoshia@oss.nttdata.com>, Kirill Reshke <reshkekirill@gmail.com>, vignesh C <vignesh21@gmail.com>, David Rowley <dgrowleyml@gmail.com>, Melih Mutlu <m.melihmutlu@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2025-07-14T14:02:35Z
Lists: pgsql-hackers
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_s2LD6RiDSMHtWQnpYB67EWXqf7N8mn7dOrnaKMfROg@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)



Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Support COPY TO for partitioned tables.

  2. Re-implement the ereport() macro using __VA_ARGS__.