Re: postgres_fdw: batch inserts vs. before row triggers
Etsuro Fujita <etsuro.fujita@gmail.com>
From: Etsuro Fujita <etsuro.fujita@gmail.com>
To: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Cc: Tomas Vondra <tomas.vondra@enterprisedb.com>
Date: 2022-04-19T09:16:03Z
Lists: pgsql-hackers
On Sun, Apr 17, 2022 at 6:20 PM Etsuro Fujita <etsuro.fujita@gmail.com> wrote: > Here > is an example using HEAD: > > create extension postgres_fdw; > create server loopback foreign data wrapper postgres_fdw options > (dbname 'postgres'); > create user mapping for current_user server loopback; > create table t (a int); > create foreign table ft (a int) server loopback options (table_name 't'); > create function ft_rowcount_tf() returns trigger as $$ begin raise > notice '%: rows = %', tg_name, (select count(*) from ft); return new; > end; $$ language plpgsql; > create trigger ft_rowcount before insert on ft for each row execute > function ft_rowcount_tf(); > > insert into ft select i from generate_series(1, 10) i; > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 1 > NOTICE: ft_rowcount: rows = 2 > NOTICE: ft_rowcount: rows = 3 > NOTICE: ft_rowcount: rows = 4 > NOTICE: ft_rowcount: rows = 5 > NOTICE: ft_rowcount: rows = 6 > NOTICE: ft_rowcount: rows = 7 > NOTICE: ft_rowcount: rows = 8 > NOTICE: ft_rowcount: rows = 9 > INSERT 0 10 > > This looks good, but when batch insert is enabled, the trigger > produces incorrect results: > > alter foreign table ft options (add batch_size '10'); > delete from ft; > > insert into ft select i from generate_series(1, 10) i; > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > NOTICE: ft_rowcount: rows = 0 > INSERT 0 10 Actually, the results are correct, as we do batch-insert here. But I just wanted to show that the trigger behaves *differently* when doing batch-insert. > So I think we should disable batch insert in such cases, just as we > disable multi insert when there are any before row triggers on the > target (local) tables/partitions in copyfrom.c. Attached is a patch > for that. If there are no objections from Tomas or anyone else, I'll commit the patch. Best regards, Etsuro Fujita
Commits
-
Remove new structure member from ResultRelInfo.
- d43a97ef493a 14.7 landed
- a0bf7a0eccbf 15.2 landed
- 4b3e37993254 16.0 landed
-
Fix handling of pending inserts in nodeModifyTable.c.
- e52245228ecf 14.7 landed
- fc02019c09fe 15.2 landed
- ffbb7e65a873 16.0 landed
-
postgres_fdw: Disable batch insertion when there are WCO constraints.
- 4a9bc2e0f522 14.5 landed
- 1d49db259884 15.0 landed
- 82593b9a3d5f 16.0 landed
-
postgres_fdw: Disable batch insert when BEFORE ROW INSERT triggers exist.
- 89d349b0a023 14.3 landed
- 4eea2202bead 15.0 landed
-
Implement support for bulk inserts in postgres_fdw
- b663a4136331 14.0 cited