From 966a865d60720db5e3570a7ce5eaaf8c59761499 Mon Sep 17 00:00:00 2001 From: Yugo Nagata Date: Tue, 11 Mar 2025 16:24:34 +0900 Subject: [PATCH] Support for PostgreSQL 15 or earlier - Not use List APIs for xid that are introduced from PostgreSQL 16 - Fix an error during isolation test ERROR: subquery in FROM must have an alias - Not use isolation test for PostgreSQL 13 --- Makefile | 10 +++++++++- expected/create_insert.out | 16 ++++++++-------- expected/create_insert2.out | 16 ++++++++-------- expected/create_insert3.out | 16 ++++++++-------- matview.c | 19 +++++++++++++++---- specs/create_insert.spec | 4 ++-- specs/create_insert2.spec | 2 +- specs/create_insert3.spec | 2 +- specs/insert_insert.spec | 2 +- specs/insert_insert2.spec | 2 +- specs/insert_insert3.spec | 2 +- specs/refresh_insert.spec | 2 +- specs/refresh_insert2.spec | 2 +- specs/refresh_insert3.spec | 2 +- 14 files changed, 58 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index f5d12f7..9f770f6 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ # contrib/pg_ivm/Makefile +PG_CONFIG ?= pg_config + MODULE_big = pg_ivm OBJS = \ $(WIN32RES) \ @@ -20,11 +22,17 @@ DATA = pg_ivm--1.0.sql \ REGRESS = pg_ivm create_immv refresh_immv +PGVER = $(shell $(PG_CONFIG) --version | sed "s/^[^ ]* \([0-9]*\).*$$/\1/" 2>/dev/null) + +# We assume PG13 is the only version that is supported by pg_ivm but +# missing pg_isolation_regress. + +ifneq ($(PGVER),13) ISOLATION = create_insert refresh_insert insert_insert \ create_insert2 refresh_insert2 insert_insert2 \ create_insert3 refresh_insert3 insert_insert3 ISOLATION_OPTS = --load-extension=pg_ivm +endif -PG_CONFIG ?= pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) diff --git a/expected/create_insert.out b/expected/create_insert.out index e6b2eac..024edb7 100644 --- a/expected/create_insert.out +++ b/expected/create_insert.out @@ -10,7 +10,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -51,7 +51,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -92,7 +92,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -131,7 +131,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; step c2: COMMIT; tx1: NOTICE: could not create an index on immv "mv" automatically @@ -174,7 +174,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -212,7 +212,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; step c2: COMMIT; tx1: NOTICE: could not create an index on immv "mv" automatically @@ -257,7 +257,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -297,7 +297,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- diff --git a/expected/create_insert2.out b/expected/create_insert2.out index 210edef..7a04804 100644 --- a/expected/create_insert2.out +++ b/expected/create_insert2.out @@ -13,7 +13,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -57,7 +57,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -101,7 +101,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -140,7 +140,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; step c2: COMMIT; tx1: NOTICE: could not create an index on immv "mv" automatically @@ -188,7 +188,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -226,7 +226,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; step c2: COMMIT; tx1: NOTICE: could not create an index on immv "mv" automatically @@ -276,7 +276,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -318,7 +318,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- diff --git a/expected/create_insert3.out b/expected/create_insert3.out index 238caae..1489be9 100644 --- a/expected/create_insert3.out +++ b/expected/create_insert3.out @@ -13,7 +13,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -53,7 +53,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -93,7 +93,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -128,7 +128,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; step c2: COMMIT; tx1: NOTICE: could not create an index on immv "mv" automatically @@ -176,7 +176,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -210,7 +210,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; step c2: COMMIT; tx1: NOTICE: could not create an index on immv "mv" automatically @@ -260,7 +260,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- @@ -302,7 +302,7 @@ step create: CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; create_immv ----------- diff --git a/matview.c b/matview.c index 717e764..d9b9db6 100644 --- a/matview.c +++ b/matview.c @@ -970,12 +970,19 @@ IVM_immediate_maintenance(PG_FUNCTION_ARGS) * If this is the last AFTER trigger call, continue and update the view. */ - /* record the subxid that updated the view incrementally */ + /* + * record the subxid that updated the view incrementally + * + * Note: + * PG16 or later has list_member_xid and lappend_xid. It would be better + * to use them, but we use integer for supporting older PGs since there + * is no problem or now. + */ subxid = GetCurrentSubTransactionId(); - if (!list_member_xid(entry->subxids, subxid)) + if (!list_member_int(entry->subxids, subxid)) { oldcxt = MemoryContextSwitchTo(TopTransactionContext); - entry->subxids = lappend_xid(entry->subxids, subxid); + entry->subxids = lappend_int(entry->subxids, subxid); MemoryContextSwitchTo(oldcxt); } @@ -3424,7 +3431,11 @@ clean_up_IVM_hash_entry(MV_TriggerHashEntry *entry, bool is_abort, { foreach(lc, entry->subxids) { - if (lfirst_xid(lc) == subxid) + /* Note: + * PG16 or later has lfirst_xid, but we use lfirst_int for + * supporting older PGs since there is no problem or now. + */ + if (lfirst_int(lc) == subxid) { entry->subxids = list_delete_cell(entry->subxids, lc); break; diff --git a/specs/create_insert.spec b/specs/create_insert.spec index 68c2631..d998f8f 100644 --- a/specs/create_insert.spec +++ b/specs/create_insert.spec @@ -24,7 +24,7 @@ step create { CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } step check1 {SELECT check_mv();} step c1 { COMMIT; } @@ -34,7 +34,7 @@ session tx2 setup { BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED; } step s2 { SELECT; } step insert { INSERT INTO a VALUES (2); } -step check2 {SELECT check_mv(); } +step check2 { SELECT check_mv(); } step c2 { COMMIT; } permutation s1 create s2 insert c1 check2 c2 mv diff --git a/specs/create_insert2.spec b/specs/create_insert2.spec index 0b0d033..eac1552 100644 --- a/specs/create_insert2.spec +++ b/specs/create_insert2.spec @@ -31,7 +31,7 @@ step create { CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } step check1 {SELECT check_mv();} step c1 { COMMIT; } diff --git a/specs/create_insert3.spec b/specs/create_insert3.spec index 953d93a..ad47334 100644 --- a/specs/create_insert3.spec +++ b/specs/create_insert3.spec @@ -31,7 +31,7 @@ step create { CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } step check1 {SELECT check_mv();} step c1 { COMMIT; } diff --git a/specs/insert_insert.spec b/specs/insert_insert.spec index 7cd5e75..15e055b 100644 --- a/specs/insert_insert.spec +++ b/specs/insert_insert.spec @@ -14,7 +14,7 @@ setup CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } teardown diff --git a/specs/insert_insert2.spec b/specs/insert_insert2.spec index e8ed6af..49797d5 100644 --- a/specs/insert_insert2.spec +++ b/specs/insert_insert2.spec @@ -14,7 +14,7 @@ setup CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } teardown diff --git a/specs/insert_insert3.spec b/specs/insert_insert3.spec index c2df23c..bee06ef 100644 --- a/specs/insert_insert3.spec +++ b/specs/insert_insert3.spec @@ -14,7 +14,7 @@ setup CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } teardown diff --git a/specs/refresh_insert.spec b/specs/refresh_insert.spec index a28eed8..ebb5bbb 100644 --- a/specs/refresh_insert.spec +++ b/specs/refresh_insert.spec @@ -10,7 +10,7 @@ setup CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } teardown diff --git a/specs/refresh_insert2.spec b/specs/refresh_insert2.spec index cf50f8f..6da4146 100644 --- a/specs/refresh_insert2.spec +++ b/specs/refresh_insert2.spec @@ -10,7 +10,7 @@ setup CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } teardown diff --git a/specs/refresh_insert3.spec b/specs/refresh_insert3.spec index b88403f..f8dfc0e 100644 --- a/specs/refresh_insert3.spec +++ b/specs/refresh_insert3.spec @@ -10,7 +10,7 @@ setup CREATE FUNCTION check_mv() RETURNS text AS $$ SELECT CASE WHEN count(*) = 0 THEN 'ok' ELSE 'ng' END FROM ((SELECT * FROM mv EXCEPT ALL SELECT * FROM v) UNION ALL - (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) $$ LANGUAGE sql; + (SELECT * FROM v EXCEPT ALL SELECT * FROM mv)) v $$ LANGUAGE sql; } teardown