Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

This file was deleted.

7 changes: 7 additions & 0 deletions crates/xtask/src/sync_pg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ const IGNORED_LINES: &[&str] = &[
r#"select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6;"#,
r#"select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, 'ab\\\'cd' as f5, '\\\\' as f6;"#,
"copy (select * from test1) (t,id) to stdout;",
"copy (select t into temp test3 from test1 where id=3) to stdout;",
"DECLARE foo CURSOR FOR SELECT 1 INTO int4_tbl;",
"COPY (SELECT 1 INTO frak UNION SELECT 2) TO 'blob';",
"SELECT * FROM (SELECT 1 INTO f) bar;",
"CREATE VIEW foo AS SELECT 1 INTO int4_tbl;",
"INSERT INTO int4_tbl SELECT 1 INTO f;",
"REPACK (CONCURRENTLY) :toast_rel;",
];

const VARIABLE_REPLACEMENTS: &[(&str, &str)] = &[
Expand Down
6 changes: 3 additions & 3 deletions postgres/kwlist.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// synced from:
// commit: 972c14fb9134fdfd76ea6ebcf98a55a945bbc988
// committed at: 2026-04-14T21:06:27-04:00
// file: https://github.com/postgres/postgres/blob/972c14fb9134fdfd76ea6ebcf98a55a945bbc988/src/include/parser/kwlist.h
// commit: c06d1a4ba6b26eef27b04074683cccade6c277ee
// committed at: 2026-05-03T20:23:50+03:00
// file: https://github.com/postgres/postgres/blob/c06d1a4ba6b26eef27b04074683cccade6c277ee/src/include/parser/kwlist.h
//
// update via:
// cargo xtask sync-pg
Expand Down
6 changes: 2 additions & 4 deletions postgres/plpgsql/plpgsql_trap.sql
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,11 @@ drop table foo;

create function trap_timeout() returns void as $$
begin
declare x int;
begin
-- we assume this will take longer than 1 second:
select count(*) into x from generate_series(1, 1_000_000_000_000);
perform pg_sleep(10);
exception
when others then
raise notice 'caught others?';
raise notice 'caught others: %', sqlerrm;
when query_canceled then
raise notice 'nyeah nyeah, can''t stop me';
end;
Expand Down
58 changes: 49 additions & 9 deletions postgres/regression_suite/cluster.sql
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,8 @@ REPACK clstrpart;
CREATE TEMP TABLE new_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid ;
SELECT relname, old.level, old.relkind, old.relfilenode = new.relfilenode FROM old_cluster_info AS old JOIN new_cluster_info AS new USING (relname) ORDER BY relname COLLATE "C";

-- CONCURRENTLY doesn't like partitioned tables
REPACK (CONCURRENTLY) clstrpart;

DROP TABLE clstrpart;

-- Ownership of partitions is checked
CREATE TABLE ptnowner(i int unique) PARTITION BY LIST (i);
CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
CREATE INDEX ptnowner_i_idx ON ptnowner(i);
CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
CREATE ROLE regress_ptnowner;
Expand All @@ -270,8 +265,6 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
SET SESSION AUTHORIZATION regress_ptnowner;
CLUSTER ptnowner USING ptnowner_i_idx;
RESET SESSION AUTHORIZATION;
SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
DROP TABLE ptnowner;
DROP ROLE regress_ptnowner;

Expand Down Expand Up @@ -339,6 +332,10 @@ COMMIT;
--
-- REPACK
--
-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
-- tests are sometimes run with wal_level=minimal. Tests for that appear
-- elsewhere.
--
----------------------------------------------------------------------

-- REPACK handles individual tables identically to CLUSTER, but it's worth
Expand Down Expand Up @@ -386,15 +383,58 @@ JOIN relnodes_new n ON o.relname = n.relname
WHERE o.relfilenode <> n.relfilenode
ORDER BY o.relname;

-- concurrently
--
-- Check concurrent mode requirements
--

-- Disallowed in catalogs
REPACK (CONCURRENTLY) pg_class;

-- Doesn't like partitioned tables
REPACK (CONCURRENTLY) clstrpart;

-- Doesn't support catalog tables
REPACK (CONCURRENTLY) pg_class;

-- Only support permanent tables, temp and unlogged tables are not supported
CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
REPACK (CONCURRENTLY) repack_conc_temp;
DROP TABLE repack_conc_temp;
CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
REPACK (CONCURRENTLY) repack_conc_unlogged;
DROP TABLE repack_conc_unlogged;

-- Doesn't support TOAST tables directly
CREATE TABLE repack_conc_toast (t text);
SELECT reltoastrelid::regclass AS toast_rel
FROM pg_class WHERE oid = 'repack_conc_toast'::regclass /* \gset */;
-- \set VERBOSITY sqlstate
-- REPACK (CONCURRENTLY) 'toast_rel';
-- \set VERBOSITY default
DROP TABLE repack_conc_toast;

-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
CREATE TABLE repack_conc_replident (i int PRIMARY KEY);
ALTER TABLE repack_conc_replident REPLICA IDENTITY NOTHING;
REPACK (CONCURRENTLY) repack_conc_replident;

-- Doesn't support tables without a primary key or replica identity index
ALTER TABLE repack_conc_replident DROP CONSTRAINT repack_conc_replident_pkey;
ALTER TABLE repack_conc_replident REPLICA IDENTITY DEFAULT;
REPACK (CONCURRENTLY) repack_conc_replident;

-- Doesn't support tables with deferrable primary keys
ALTER TABLE repack_conc_replident ADD PRIMARY KEY (i) DEFERRABLE;
REPACK (CONCURRENTLY) repack_conc_replident;

-- clean up
DROP TABLE repack_conc_replident;
DROP TABLE clustertest;
DROP TABLE clstr_1;
DROP TABLE clstr_2;
DROP TABLE clstr_3;
DROP TABLE clstr_4;
DROP TABLE clstr_expression;
DROP TABLE clstrpart;

DROP USER regress_clstr_user;
66 changes: 66 additions & 0 deletions postgres/regression_suite/collate.icu.utf8.sql
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,72 @@ CREATE UNIQUE INDEX ON test3ci (x); -- error
SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc');
SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b');

-- Test HAVING-to-WHERE pushdown with nondeterministic collations.
-- When a HAVING clause uses a different collation than the GROUP BY's
-- nondeterministic collation, it must not be pushed to WHERE, otherwise
-- aggregate results can change because the stricter filter eliminates rows
-- before grouping.

-- Negative: collation conflict, HAVING must not be pushed to WHERE
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive;

-- Positive: same collation, safe to push HAVING to WHERE
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive;

-- Negative: function applied to grouped column with conflicting collation
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_sensitive;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_sensitive;

-- Positive: function with same collation as GROUP BY
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_insensitive;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x) = 'ABC' COLLATE case_insensitive;

-- Negative: inner function has conflicting collation, even though outer
-- operator's collation matches GROUP BY due to a COLLATE override
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x COLLATE case_sensitive) COLLATE case_insensitive = 'ABC';
SELECT x, count(*) FROM test3ci GROUP BY x HAVING upper(x COLLATE case_sensitive) COLLATE case_insensitive = 'ABC';

-- Mixed AND: conflicting clause stays in HAVING, safe clause pushed to WHERE
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND length(x) > 1;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive AND length(x) > 1;

-- Positive: AND of two safe clauses, both can be pushed
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND length(x) > 1;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_insensitive AND length(x) > 1;

-- Negative: OR with a conflicting clause: must stay in HAVING
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive OR x = 'def' COLLATE case_sensitive ORDER BY 1;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING x = 'abc' COLLATE case_sensitive OR x = 'def' COLLATE case_sensitive ORDER BY 1;

-- Negative: collation conflict inside a RowCompareExpr
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING ROW(x, 1) < ROW('ABC' COLLATE case_sensitive, 1) ORDER BY 1;
SELECT x, count(*) FROM test3ci GROUP BY x HAVING ROW(x, 1) < ROW('ABC' COLLATE case_sensitive, 1) ORDER BY 1;

-- Positive: conflicting collation but no grouping expression reference
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3ci GROUP BY x HAVING current_setting('server_version') = 'abc' COLLATE case_sensitive;

-- Positive: deterministic collation in GROUP BY: always safe to push, even if
-- HAVING uses a nondeterministic collation
EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3cs GROUP BY x HAVING x = 'abc' COLLATE case_sensitive;
SELECT x, count(*) FROM test3cs GROUP BY x HAVING x = 'abc' COLLATE case_sensitive;

EXPLAIN (COSTS OFF)
SELECT x, count(*) FROM test3cs GROUP BY x HAVING x = 'abc' COLLATE case_insensitive ORDER BY 1;
SELECT x, count(*) FROM test3cs GROUP BY x HAVING x = 'abc' COLLATE case_insensitive ORDER BY 1;

-- bpchar
CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive);
CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive);
Expand Down
2 changes: 1 addition & 1 deletion postgres/regression_suite/copyselect.sql
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ copy (select t from test1 where id=3 for update) to stdout;
--
-- This should fail
--
copy (select t into temp test3 from test1 where id=3) to stdout;
-- copy (select t into temp test3 from test1 where id=3) to stdout;
--
-- This should fail
--
Expand Down
26 changes: 26 additions & 0 deletions postgres/regression_suite/create_table_like.sql
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,32 @@ CREATE FOREIGN TABLE ctl_foreign_table2(LIKE ctl_table INCLUDING ALL) SERVER ctl
SELECT attname, attcompression FROM pg_attribute
WHERE attrelid = 'ctl_foreign_table2'::regclass and attnum > 0 ORDER BY attnum;

-- LIKE ... INCLUDING STATISTICS with dropped columns in the parent,
-- so stxkeys attnums are not contiguous.
CREATE TABLE ctl_stats3_parent (a int, b int, c int);
ALTER TABLE ctl_stats3_parent DROP COLUMN b;
CREATE STATISTICS ctl_stats3_stat ON a, c FROM ctl_stats3_parent;
CREATE TABLE ctl_stats3_child (LIKE ctl_stats3_parent INCLUDING STATISTICS);
CREATE TABLE ctl_stats4_parent (a int, b int, c int, d int);
ALTER TABLE ctl_stats4_parent DROP COLUMN b;
CREATE STATISTICS ctl_stats4_stat ON a, c FROM ctl_stats4_parent;
CREATE TABLE ctl_stats4_child (LIKE ctl_stats4_parent INCLUDING STATISTICS);
SELECT s.stxrelid::regclass AS relation,
array_agg(a.attname ORDER BY u.ord) AS stats_columns
FROM pg_statistic_ext s
CROSS JOIN LATERAL
unnest(s.stxkeys::int2[]) WITH ORDINALITY AS u(attnum, ord)
JOIN pg_attribute a
ON a.attrelid = s.stxrelid AND a.attnum = u.attnum
WHERE s.stxrelid IN ('ctl_stats3_child'::regclass,
'ctl_stats4_child'::regclass)
GROUP BY s.stxrelid
ORDER BY s.stxrelid::regclass::text;
DROP TABLE ctl_stats3_parent;
DROP TABLE ctl_stats3_child;
DROP TABLE ctl_stats4_parent;
DROP TABLE ctl_stats4_child;

DROP TABLE ctl_table;
DROP FOREIGN TABLE ctl_foreign_table1;
DROP FOREIGN TABLE ctl_foreign_table2;
Expand Down
66 changes: 0 additions & 66 deletions postgres/regression_suite/database_ddl.sql

This file was deleted.

Loading
Loading