Hi Antonin, Alberto,
On Wed, Jul 22, 2026 at 11:19 PM Alberto Piai
<[email protected]> wrote:
> Sorry, I could have been clearer. I was referring specifically to the
> Assert(), which would be hit in the edge case you mentioned (a command
> trying to report progress past the 2nd level of nesting).
v01 fixes a case not mentioned in this thread: ANALYZE of a file_fdw
table never shows in pg_stat_progress_analyze, on 14, 18 and master.
It makes other cases worse, and that edge case is reachable from a
plain trigger. I sampled both views every ~0.5 ms, on v01 and on its
base 994f770a0fd (same as master); script and results are attached.
Fixed: ANALYZE of a file_fdw table, of a partitioned table with a
file_fdw partition, a database-wide ANALYZE, and COPY FROM whose
trigger reads a file_fdw table.
Worse:
- COPY (SELECT a FROM ft) TO shows "COPY FROM FILE relid=ft", 0 bytes.
The scan starts in ExecutorStart (copyto.c:1039), before COPY TO
(copyto.c:1227); both levels are COPY, the view takes level 1
(pgstatfuncs.c:326), and all updates go to level 2.
- Two file_fdw scans in one statement show no row, and so does one
scan after an EXPLAIN of another file_fdw query: file_fdw.c:721
turns tracking off when fdw_nodes > 1, and fdw_nodes is counted at
plan time (file_fdw.c:634).
Three levels, on an assert-enabled build:
CREATE EXTENSION file_fdw;
CREATE SERVER s FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE ft (a int) SERVER s OPTIONS (program 'seq 3');
CREATE TABLE t (a int);
CREATE FUNCTION f() RETURNS trigger LANGUAGE plpgsql AS
$$BEGIN COPY (SELECT a FROM ft) TO '/dev/null'; RETURN NEW; END$$;
CREATE TRIGGER tr BEFORE INSERT ON t FOR EACH ROW EXECUTE FUNCTION f();
COPY t FROM PROGRAM 'echo 1';
TRAP: failed Assert("false"), File: "backend_progress.c", Line: 62,
from BeginCopyTo() in the trigger. Without asserts nothing crashes,
but each end then clears one level too high.
Fujii, Álvaro: for 14-19, would a fix at the call site like
4b445479f9e be acceptable while this goes on for master, i.e. file_fdw
not reporting COPY progress when another command is already reported?
I can write it.
Manu
#!/usr/bin/env bash
# cf6958-matrix.sh <bindir> <workdir>
#
# What pg_stat_progress_analyze and pg_stat_progress_copy show for a backend
# while it runs commands that nest one progress report inside another,
# mostly through file_fdw (ANALYZE of a foreign table, COPY TO over a foreign
# scan, a COPY FROM whose trigger reads a foreign table, two foreign scans in
# one query).
#
# It creates a throw-away cluster in <workdir> with the binaries in <bindir>
# (file_fdw must be installed there), writes the data files there (about
# 130 MB), and runs each command in one session while a second session
# samples both views for that backend every ~0.5 ms, calling
# pg_stat_clear_snapshot() between samples, until the backend goes idle.
# Takes about two minutes. The cluster is stopped at the end.
#
# Output, per command: how many samples showed each row, where "(none)" means
# the backend was active but neither view had a row for it; the largest
# bytes_processed seen in pg_stat_progress_copy; the bytes the command sent to
# the client; stderr; and "SERVER CRASH" plus the first TRAP line if the
# backend died (the script waits for crash recovery and goes on).
set -euo pipefail
trap 'kill $(jobs -p) 2>/dev/null; exit 143' TERM INT
BIN=$1 W=$2; rm -rf "$W"; mkdir -p "$W"
PGDATA=$W/data; PORT=$((61000 + RANDOM % 4000)); export PGHOST=$W PGPORT=$PORT
PGDATABASE=postgres
"$BIN/initdb" -A trust -N -D "$PGDATA" >/dev/null
"$BIN/pg_ctl" -D "$PGDATA" -o "-p $PORT -k $W -c autovacuum=off" -l "$W/log" -w
start >/dev/null
trap '"$BIN/pg_ctl" -D "$PGDATA" -w -m immediate stop >/dev/null 2>&1 || true'
EXIT
# big.txt: 1,500,000 rows x 8 columns; small.txt: 200,000 rows; bad.txt: one bad
# line at the end; three.txt: 3 rows.
awk 'BEGIN{for(i=1;i<=1500000;i++) printf
"%d,%d,%d,%d,%d,x%d,y%d,z%d\n",i,i%997,i%101,i*7%100003,i%13,i%5003,i%211,i}'
>"$W/big.txt"
head -200000 "$W/big.txt" >"$W/small.txt"
{ head -100000 "$W/big.txt"; echo 'oops,1,1,1,1,a,b,c'; } >"$W/bad.txt"
printf '1\n2\n3\n' >"$W/three.txt"
COLS='a int, b int, c int, d int, e int, f text, g text, h text'
SQ="$BIN/psql -X -q -v ON_ERROR_STOP=1"
$SQ <<SQL
CREATE EXTENSION file_fdw;
CREATE SERVER f FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE ft ($COLS) SERVER f OPTIONS (filename '$W/big.txt', format
'csv');
CREATE FOREIGN TABLE ft_small ($COLS) SERVER f OPTIONS (filename
'$W/small.txt', format 'csv');
CREATE FOREIGN TABLE ft_prog ($COLS) SERVER f OPTIONS (program 'cat
$W/big.txt', format 'csv');
CREATE FOREIGN TABLE ft_bad ($COLS) SERVER f OPTIONS (filename '$W/bad.txt',
format 'csv');
CREATE TABLE t ($COLS);
CREATE TABLE parted ($COLS) PARTITION BY RANGE (a);
CREATE TABLE p_heap PARTITION OF parted FOR VALUES FROM (2000000) TO (3000000);
INSERT INTO p_heap SELECT g, 1, 1, 1, 1, 'x', 'y', 'z' FROM
generate_series(2000000, 2300000) g;
CREATE FOREIGN TABLE p_ft PARTITION OF parted FOR VALUES FROM (1) TO (2000000)
SERVER f OPTIONS (filename '$W/big.txt', format 'csv');
CREATE TABLE t3 (a int);
CREATE FUNCTION read_ft() RETURNS trigger LANGUAGE plpgsql AS
\$\$ BEGIN PERFORM count(*) FROM ft_small; RETURN NEW; END \$\$;
CREATE TRIGGER t3_read_ft BEFORE INSERT ON t3 FOR EACH ROW EXECUTE FUNCTION
read_ft();
CREATE TABLE t4 (a int);
CREATE FUNCTION copy_ft() RETURNS trigger LANGUAGE plpgsql AS
\$\$ BEGIN COPY (SELECT a FROM ft_small) TO '/dev/null'; RETURN NEW; END \$\$;
CREATE TRIGGER t4_copy_ft BEFORE INSERT ON t4 FOR EACH ROW EXECUTE FUNCTION
copy_ft();
CREATE FUNCTION observe(app text) RETURNS TABLE (seen text, n bigint)
LANGUAGE plpgsql AS \$\$
DECLARE
p int;
t0 timestamptz := clock_timestamp();
st text;
o text;
b bigint;
maxb bigint := 0;
arr text[] := '{}';
BEGIN
LOOP
PERFORM pg_stat_clear_snapshot();
SELECT pid INTO p FROM pg_stat_activity
WHERE application_name = app AND state = 'active';
EXIT WHEN p IS NOT NULL;
IF clock_timestamp() - t0 > interval '30 s' THEN
RAISE EXCEPTION 'session % never became active', app;
END IF;
PERFORM pg_sleep(0.0005);
END LOOP;
LOOP
PERFORM pg_stat_clear_snapshot();
SELECT coalesce(
(SELECT 'analyze: ' || phase || ' relid=' || relid::regclass ||
CASE WHEN child_tables_total > 0
THEN ' children ' || child_tables_done || '/' ||
child_tables_total
ELSE '' END
FROM pg_stat_progress_analyze WHERE pid = p),
(SELECT 'copy: ' || command || ' ' || type || ' relid=' ||
relid::regclass ||
CASE WHEN bytes_total > 0 AND bytes_processed > bytes_total
THEN ' bytes_processed>bytes_total' ELSE '' END
FROM pg_stat_progress_copy WHERE pid = p),
'(none)'),
(SELECT state FROM pg_stat_activity WHERE pid = p),
(SELECT bytes_processed FROM pg_stat_progress_copy WHERE pid = p)
INTO o, st, b;
EXIT WHEN st IS DISTINCT FROM 'active';
arr := arr || o;
maxb := greatest(maxb, b);
PERFORM pg_sleep(0.0005);
END LOOP;
RETURN QUERY SELECT x, count(*) FROM unnest(arr) x GROUP BY x ORDER BY 2
DESC, 1;
RETURN QUERY SELECT 'max bytes_processed seen in pg_stat_progress_copy: ' ||
maxb, NULL::bigint;
END \$\$;
SQL
cell() { # cell <name> <sql>
local name=$1 sql=$2
$SQ -At -c "SELECT coalesce(n || ' ', '') || seen FROM observe('$name')"
>"$W/obs.$name" & local o=$!
PGAPPNAME=$name PGOPTIONS='-c default_statistics_target=1000' \
$BIN/psql -X -q -c "$sql" 2>"$W/err.$name" | wc -c >"$W/out.$name" || true
wait $o || true
echo "== $name: $sql"
sed 's/^/ /' "$W/obs.$name"
echo " bytes written to the client: $(cat "$W/out.$name")"
grep -v '^$' "$W/err.$name" | sed 's/^/ stderr: /' || true
if grep -q 'terminated by signal' "$W/log"; then
echo " SERVER CRASH: $(grep -m1 -E '^TRAP|terminated by signal' "$W/log")"
: >"$W/log.seen"; cat "$W/log" >>"$W/log.seen"; : >"$W/log"
for _ in $(seq 600); do $SQ -c 'SELECT 1' >/dev/null 2>&1 && break; sleep
0.1; done
fi
}
cell analyze_ft 'ANALYZE ft'
cell analyze_partitioned 'ANALYZE parted'
cell vacuum_analyze_parted 'VACUUM ANALYZE parted'
cell analyze_all 'ANALYZE'
cell copy_to_select_ft 'COPY (SELECT a FROM ft) TO STDOUT'
cell copy_from_trigger "COPY t3 FROM '$W/three.txt'"
cell copy_from_trigger_copy_to "COPY t4 FROM '$W/three.txt'"
cell copy_to_two_scans 'COPY (SELECT a FROM ft UNION ALL SELECT a FROM
ft_small) TO STDOUT'
cell insert_select_ft 'INSERT INTO t SELECT * FROM ft'
cell ctas_ft 'CREATE TABLE ctas AS SELECT * FROM ft'
cell select_ft 'SELECT count(*) FROM ft'
cell explain_then_select 'EXPLAIN SELECT * FROM ft_small; SELECT count(*) FROM
ft'
cell select_program 'SELECT count(*) FROM ft_prog'
cell copy_to_program 'COPY (SELECT a FROM ft_prog) TO STDOUT'
cell copy_to_plain 'COPY (SELECT a FROM t) TO STDOUT'
cell select_two_scans 'SELECT (SELECT count(*) FROM ft) + (SELECT count(*)
FROM ft_small)'
cell select_rescan 'SELECT count(*) FROM generate_series(1, 3) g(i),
LATERAL (SELECT a FROM ft WHERE a > i OFFSET 0) s'
cell select_error 'SELECT count(*) FROM ft_bad'
echo "== slot after an error, same session:"
$SQ -At <<'SQL' | sed 's/^/ /'
\set ON_ERROR_STOP 0
SELECT count(*) FROM ft_bad;
SELECT 'copy rows for own pid after error: ' || count(*) FROM
pg_stat_progress_copy WHERE pid = pg_backend_pid();
SQL
echo "== server: $("$BIN/postgres" --version)"
CF 6958 v01: what the progress views show, per command
Produced by cf6958-matrix.sh (attached) on 2026-10-29, one run per build.
Builds (all --enable-debug -O2):
master 61553eacadb, with asserts
base 994f770a0fd (where v01 applies), with asserts
v01 on base, asserts
v01 on base, no asserts
v01 does not apply to current master (conflicts in index.c, index.h,
toasting.c and backend_progress.c with 4b445479f9e), so it was measured on
its own base. The base behaves like master in every row below.
Each line: samples per row seen. A = pg_stat_progress_analyze row
(phase, relid), C = pg_stat_progress_copy row (command, type, relid),
"(none)" = backend active, no row in either view. acq = acquiring
sample rows, acq-inh = acquiring inherited sample rows, compute =
computing statistics, final = finalizing analyze. "max bytes" =
largest bytes_processed sampled; "sent" = bytes the client received.
Sample counts differ between builds because each run is timed by
the command itself; compare which rows appear, not the counts.
------------------------------------------------------------------------
analyze_ft: ANALYZE ft
master 61553eacadb: 727 (none); 332 C COPY FROM FILE relid=ft [max bytes
60940913; sent 0]
base 994f770a0fd: 743 (none); 336 C COPY FROM FILE relid=ft [max bytes
60875386; sent 0]
v01 on base, asserts: 728 A compute relid=ft; 329 A acq relid=ft; 4 A final
relid=ft [max bytes 61006441; sent 0]
v01 on base, no asserts: 715 A compute relid=ft; 253 A acq relid=ft; 2 A
final relid=ft [max bytes 61006441; sent 0]
------------------------------------------------------------------------
analyze_partitioned: ANALYZE parted
master 61553eacadb: 1379 (none); 638 C COPY FROM FILE relid=p_ft; 51 A
compute relid=p_heap; 25 A acq relid=p_heap; 24 A acq-inh relid=parted
children 0/2; 3 A final relid=p_heap [max bytes 60875386; sent 0]
base 994f770a0fd: 1413 (none); 661 C COPY FROM FILE relid=p_ft; 50 A compute
relid=p_heap; 29 A acq-inh relid=parted children 0/2; 20 A acq
relid=p_heap; 3 A final relid=p_heap [max bytes 61043138; sent 0]
v01 on base, asserts: 728 A compute relid=p_ft; 611 A compute relid=parted
children 2/2; 328 A acq relid=p_ft; 299 A acq-inh relid=parted children
1/2; 50 A compute relid=p_heap; 25 A acq-inh relid=parted children 0/2;
14 A acq relid=p_heap; 5 A final relid=p_ft; 4 A final relid=p_heap; 3 A
final relid=parted children 2/2; 1 (none) [max bytes 61006441; sent 0]
v01 on base, no asserts: 701 A compute relid=p_ft; 600 A compute
relid=parted children 2/2; 255 A acq relid=p_ft; 224 A acq-inh
relid=parted children 1/2; 30 A compute relid=p_heap; 21 A acq-inh
relid=parted children 0/2; 18 A acq relid=p_heap; 4 A final relid=p_ft;
2 A final relid=p_heap; 1 A final relid=parted children 2/2 [max bytes
61043138; sent 0]
------------------------------------------------------------------------
vacuum_analyze_parted: VACUUM ANALYZE parted
master 61553eacadb: 634 (none); 306 C COPY FROM FILE relid=p_ft; 50 A
compute relid=p_heap; 26 A acq-inh relid=parted children 0/2; 18 A acq
relid=p_heap; 4 A final relid=p_heap [max bytes 60940913; sent 0]
base 994f770a0fd: 624 (none); 309 C COPY FROM FILE relid=p_ft; 50 A compute
relid=p_heap; 26 A acq-inh relid=parted children 0/2; 21 A acq
relid=p_heap; 3 A final relid=p_heap [max bytes 60809859; sent 0]
v01 on base, asserts: 636 A compute relid=parted children 2/2; 299 A acq-inh
relid=parted children 1/2; 49 A compute relid=p_heap; 26 A acq-inh
relid=parted children 0/2; 23 A acq relid=p_heap; 8 (none); 5 A final
relid=parted children 2/2; 3 A final relid=p_heap [max bytes 60809859;
sent 0]
v01 on base, no asserts: 596 A compute relid=parted children 2/2; 236 A acq-
inh relid=parted children 1/2; 28 A compute relid=p_heap; 22 A acq
relid=p_heap; 19 A acq-inh relid=parted children 0/2; 5 (none); 2 A
final relid=parted children 2/2; 2 A final relid=p_heap [max bytes
61006441; sent 0]
------------------------------------------------------------------------
analyze_all: ANALYZE
master 61553eacadb: 617 (none); 295 C COPY FROM FILE relid=p_ft; 49 A
compute relid=p_heap; 36 A (catalogs); 24 A acq relid=p_heap; 21 A acq-
inh relid=parted children 0/2; 4 A final relid=p_heap; 1 A final
relid=t3 [max bytes 61043138; sent 0]
base 994f770a0fd: 621 (none); 323 C COPY FROM FILE relid=p_ft; 51 A compute
relid=p_heap; 35 A (catalogs); 28 A acq-inh relid=parted children 0/2;
19 A acq relid=p_heap; 3 A final relid=p_heap; 1 A final relid=t3 [max
bytes 61006441; sent 0]
v01 on base, asserts: 639 A compute relid=parted children 2/2; 301 A acq-inh
relid=parted children 1/2; 51 A compute relid=p_heap; 35 A (catalogs);
22 A acq-inh relid=parted children 0/2; 18 A acq relid=p_heap; 4 A final
relid=p_heap; 3 A final relid=parted children 2/2; 1 (none) [max bytes
60809859; sent 0]
v01 on base, no asserts: 600 A compute relid=parted children 2/2; 241 A acq-
inh relid=parted children 1/2; 30 A compute relid=p_heap; 30 A
(catalogs); 20 A acq-inh relid=parted children 0/2; 14 A acq
relid=p_heap; 2 A final relid=parted children 2/2; 1 A final
relid=p_heap [max bytes 60809859; sent 0]
------------------------------------------------------------------------
copy_to_select_ft: COPY (SELECT a FROM ft) TO STDOUT
master 61553eacadb: 208 C COPY TO PIPE relid=- [max bytes 55502101; sent
10888896]
base 994f770a0fd: 232 C COPY TO PIPE relid=- [max bytes 38596021; sent
10888896]
v01 on base, asserts: 230 C COPY FROM FILE relid=ft [max bytes 0; sent
10888896]
v01 on base, no asserts: 183 C COPY FROM FILE relid=ft [max bytes 0; sent
10888896]
------------------------------------------------------------------------
copy_from_trigger: COPY t3 FROM '<workdir>/three.txt'
master 61553eacadb: 94 C COPY FROM FILE relid=ft_small [max bytes 7797796;
sent 0]
base 994f770a0fd: 102 C COPY FROM FILE relid=ft_small; 2 (none) [max bytes
7732273; sent 0]
v01 on base, asserts: 96 C COPY FROM FILE relid=t3 [max bytes 6; sent 0]
v01 on base, no asserts: 75 C COPY FROM FILE relid=t3 [max bytes 6; sent 0]
------------------------------------------------------------------------
copy_from_trigger_copy_to: COPY t4 FROM
'<workdir>/three.txt'
master 61553eacadb: 81 C COPY TO FILE relid=- [max bytes 6421694; sent 0]
base 994f770a0fd: 105 C COPY TO FILE relid=-; 1 (none) [max bytes 1310569;
sent 0]
v01 on base, asserts: (no samples) [sent 0; CRASH TRAP: failed
Assert("false"), File: "backend_progress.c", Line: 62, PID: 510381]
v01 on base, no asserts: 25 (none); 23 C COPY FROM FILE relid=ft_small; 20 C
COPY FROM FILE relid=t4 [max bytes 6; sent 0]
------------------------------------------------------------------------
copy_to_two_scans: COPY (SELECT a FROM ft UNION ALL SELECT a FROM ft_small) TO
STDOUT
master 61553eacadb: 245 C COPY TO PIPE relid=- [max bytes 12169608; sent
12177791]
base 994f770a0fd: 279 C COPY TO PIPE relid=- [max bytes 12146613; sent
12177791]
v01 on base, asserts: 273 (none) [max bytes 0; sent 12177791]
v01 on base, no asserts: 203 (none) [max bytes 0; sent 12177791]
------------------------------------------------------------------------
insert_select_ft: INSERT INTO t SELECT * FROM ft
master 61553eacadb: 937 C COPY FROM FILE relid=ft [max bytes 61043138; sent
0]
base 994f770a0fd: 962 C COPY FROM FILE relid=ft; 1 (none) [max bytes
61006441; sent 0]
v01 on base, asserts: 937 C COPY FROM FILE relid=ft [max bytes 61043138;
sent 0]
v01 on base, no asserts: 624 C COPY FROM FILE relid=ft [max bytes 61006441;
sent 0]
------------------------------------------------------------------------
ctas_ft: CREATE TABLE ctas AS SELECT * FROM ft
master 61553eacadb: 774 C COPY FROM FILE relid=ft; 1 (none) [max bytes
61006441; sent 0]
base 994f770a0fd: 927 C COPY FROM FILE relid=ft [max bytes 61043138; sent 0]
v01 on base, asserts: 750 C COPY FROM FILE relid=ft; 1 (none) [max bytes
61006441; sent 0]
v01 on base, no asserts: 468 C COPY FROM FILE relid=ft; 1 (none) [max bytes
61006441; sent 0]
------------------------------------------------------------------------
select_ft: SELECT count(*) FROM ft
master 61553eacadb: 239 C COPY FROM FILE relid=ft [max bytes 61006441; sent
38]
base 994f770a0fd: 254 C COPY FROM FILE relid=ft [max bytes 60940913; sent
38]
v01 on base, asserts: 248 C COPY FROM FILE relid=ft [max bytes 61006441;
sent 38]
v01 on base, no asserts: 185 C COPY FROM FILE relid=ft; 1 (none) [max bytes
60744328; sent 38]
------------------------------------------------------------------------
explain_then_select: EXPLAIN SELECT * FROM ft_small; SELECT count(*) FROM ft
master 61553eacadb: 229 C COPY FROM FILE relid=ft [max bytes 60875386; sent
346]
base 994f770a0fd: 262 C COPY FROM FILE relid=ft [max bytes 60940913; sent
348]
v01 on base, asserts: 243 (none) [max bytes 0; sent 344]
v01 on base, no asserts: 186 (none) [max bytes 0; sent 346]
------------------------------------------------------------------------
select_program: SELECT count(*) FROM ft_prog
master 61553eacadb: 250 C COPY FROM PROGRAM relid=ft_prog [max bytes
61006441; sent 38]
base 994f770a0fd: 290 C COPY FROM PROGRAM relid=ft_prog; 1 (none) [max bytes
60875386; sent 38]
v01 on base, asserts: 255 C COPY FROM PROGRAM relid=ft_prog [max bytes
61006441; sent 38]
v01 on base, no asserts: 206 C COPY FROM PROGRAM relid=ft_prog [max bytes
61006441; sent 38]
------------------------------------------------------------------------
copy_to_program: COPY (SELECT a FROM ft_prog) TO STDOUT
master 61553eacadb: 225 C COPY TO PIPE relid=- [max bytes 10886576; sent
10888896]
base 994f770a0fd: 249 C COPY TO PIPE relid=- [max bytes 10886064; sent
10888896]
v01 on base, asserts: 278 C COPY FROM PROGRAM relid=ft_prog [max bytes 0;
sent 10888896]
v01 on base, no asserts: 197 C COPY FROM PROGRAM relid=ft_prog [max bytes 0;
sent 10888896]
------------------------------------------------------------------------
copy_to_plain: COPY (SELECT a FROM t) TO STDOUT
master 61553eacadb: 104 C COPY TO PIPE relid=- [max bytes 10838856; sent
10888896]
base 994f770a0fd: 105 C COPY TO PIPE relid=- [max bytes 10837992; sent
10888896]
v01 on base, asserts: 105 C COPY TO PIPE relid=-; 1 (none) [max bytes
10785880; sent 10888896]
v01 on base, no asserts: 81 C COPY TO PIPE relid=- [max bytes 10792984; sent
10888896]
------------------------------------------------------------------------
select_two_scans: SELECT (SELECT count(*) FROM ft) + (SELECT count(*) FROM
ft_small)
master 61553eacadb: 216 C COPY FROM FILE relid=ft_small bytes>total; 61 C
COPY FROM FILE relid=ft_small [max bytes 61043138; sent 41]
base 994f770a0fd: 229 C COPY FROM FILE relid=ft_small bytes>total; 67 C COPY
FROM FILE relid=ft_small; 1 (none) [max bytes 60940913; sent 41]
v01 on base, asserts: 282 (none) [max bytes 0; sent 41]
v01 on base, no asserts: 216 (none) [max bytes 0; sent 41]
------------------------------------------------------------------------
select_rescan: SELECT count(*) FROM generate_series(1, 3) g(i), LATERAL
(SELECT a FROM ft WHERE a > i OFFSET 0) s
master 61553eacadb: 567 C COPY FROM FILE relid=ft [max bytes 61043138; sent
38]
base 994f770a0fd: 588 C COPY FROM FILE relid=ft [max bytes 61006441; sent
38]
v01 on base, asserts: 627 C COPY FROM FILE relid=ft [max bytes 60940913;
sent 38]
v01 on base, no asserts: 479 C COPY FROM FILE relid=ft [max bytes 61006441;
sent 38]
------------------------------------------------------------------------
select_error: SELECT count(*) FROM ft_bad
master 61553eacadb: 14 C COPY FROM FILE relid=ft_bad [max bytes 3669540;
sent 0]
base 994f770a0fd: 17 C COPY FROM FILE relid=ft_bad [max bytes 3669540; sent
0]
v01 on base, asserts: 15 C COPY FROM FILE relid=ft_bad [max bytes 3735066;
sent 0]
v01 on base, no asserts: 11 C COPY FROM FILE relid=ft_bad [max bytes
3604005; sent 0]
------------------------------------------------------------------------
after_error: same session, after the error above
master 61553eacadb: (no samples) [rows for own pid: 0]
base 994f770a0fd: (no samples) [rows for own pid: 0]
v01 on base, asserts: (no samples) [rows for own pid: 0]
v01 on base, no asserts: (no samples) [rows for own pid: 0]