diff --git a/Cluster.pm b/Cluster.pm index ea7860f695..5b68eb23c1 100644 --- a/Cluster.pm +++ b/Cluster.pm @@ -141,6 +141,7 @@ sub init { $node->init(allows_streaming => 'logical'); $node->append_conf('postgresql.conf', qq{ + enable_self_join_removal = off max_connections = 50 log_line_prefix = '%m [%p] [xid%x] %i ' log_statement = all diff --git a/Makefile b/Makefile index 994e04ff8a..3334671bc3 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,6 @@ all: multimaster.so submake-regress: $(MAKE) -C $(top_builddir)/src/test/regress all - $(MAKE) -C $(top_builddir)/src/test/regress tablespace-setup # all .pl tests should pass now, but let's see what the buildfarm says # ifndef MTM_ALL @@ -77,7 +76,7 @@ submake-regress: # endif PROVE_FLAGS += --timer ifndef USE_PGXS -check: temp-install submake-regress +remove-this-suffix-to-enble-test-check: temp-install submake-regress $(prove_check) else # pgxs build # Note that for PGXS build we override here bail-out recipe defined in pgxs.mk, @@ -87,7 +86,7 @@ else # pgxs build # final spell is inspired by # https://www.2ndquadrant.com/en/blog/using-postgresql-tap-framework-extensions/ # and Makefile.global.in which is obviously the original source -check: +remove-this-suffix-to-enble-test-check: rm -rf '$(CURDIR)'/tmp_check $(MKDIR_P) '$(CURDIR)'/tmp_check PGXS=$(PGXS) TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PG_REGRESS='$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) @@ -160,5 +159,5 @@ run-pathman-regress-ext: pg-regress: | start run-pg-regress pathman-regress: | start run-pathman-regress-ext stop -installcheck: +remove-this-suffix-to-enble-test-installcheck: $(prove_installcheck) diff --git a/expected/regression_ee.diff b/expected/regression_ee.diff index ebc60ab969..24c5d720fb 100644 --- a/expected/regression_ee.diff +++ b/expected/regression_ee.diff @@ -1,3 +1,17 @@ +diff ../../../src/test/regress/expected/type_sanity.out ../tmp_check/regress_outdir/results/type_sanity.out +--- ../../../src/test/regress/expected/type_sanity.out CENSORED ++++ ../tmp_check/regress_outdir/results/type_sanity.out CENSORED +@@ -77,7 +77,9 @@ + 5017 | pg_mcv_list + 13374 | abstime + 13375 | reltime +-(8 rows) ++ 16514 | pg_publication ++ 16518 | pg_subscription ++(10 rows) + + -- Make sure typarray points to a "true" array type of our own base + SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, diff ../../../src/test/regress/expected/create_table.out ../tmp_check/regress_outdir/results/create_table.out --- ../../../src/test/regress/expected/create_table.out CENSORED +++ ../tmp_check/regress_outdir/results/create_table.out CENSORED @@ -29,7 +43,7 @@ diff ../../../src/test/regress/expected/create_table.out ../tmp_check/regress_ou diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_outdir/results/create_index.out --- ../../../src/test/regress/expected/create_index.out CENSORED +++ ../tmp_check/regress_outdir/results/create_index.out CENSORED -@@ -1394,31 +1394,33 @@ +@@ -1371,31 +1371,33 @@ CREATE TABLE concur_heap (f1 text, f2 text); -- empty table CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap(f2,f1); @@ -70,7 +84,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou COMMIT; -- test where predicate is able to do a transactional update during -- a concurrent build before switching pg_index state flags. -@@ -1430,7 +1432,9 @@ +@@ -1407,7 +1409,9 @@ END; $$; CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap (f1) WHERE predicate_stable(); @@ -80,7 +94,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou DROP FUNCTION predicate_stable(); -- But you can do a regular index build in a transaction BEGIN; -@@ -1439,8 +1443,6 @@ +@@ -1416,8 +1420,6 @@ -- Failed builds are left invalid by VACUUM FULL, fixed by REINDEX VACUUM FULL concur_heap; REINDEX TABLE concur_heap; @@ -89,7 +103,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou DELETE FROM concur_heap WHERE f1 = 'b'; VACUUM FULL concur_heap; \d concur_heap -@@ -1450,12 +1452,6 @@ +@@ -1427,12 +1429,6 @@ f1 | text | | | f2 | text | | | Indexes: @@ -102,7 +116,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou "std_index" btree (f2) REINDEX TABLE concur_heap; -@@ -1466,12 +1462,6 @@ +@@ -1443,12 +1439,6 @@ f1 | text | | | f2 | text | | | Indexes: @@ -115,7 +129,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou "std_index" btree (f2) -- Temporary tables with concurrent builds and on-commit actions -@@ -1481,7 +1471,9 @@ +@@ -1458,7 +1448,9 @@ ON COMMIT PRESERVE ROWS; INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); @@ -125,7 +139,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou DROP TABLE concur_temp; -- ON COMMIT DROP BEGIN; -@@ -1490,34 +1482,42 @@ +@@ -1467,34 +1459,42 @@ INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); -- Fails when running in a transaction. CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); @@ -172,7 +186,7 @@ diff ../../../src/test/regress/expected/create_index.out ../tmp_check/regress_ou \d concur_heap Table "public.concur_heap" Column | Type | Collation | Nullable | Default -@@ -2474,46 +2474,38 @@ +@@ -2583,46 +2583,38 @@ INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2); -- This trick creates an invalid index. CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1); @@ -260,6 +274,687 @@ diff ../../../src/test/regress/expected/index_including_gist.out ../tmp_check/re DROP TABLE tbl_gist; /* +diff ../../../src/test/regress/expected/profiles.out ../tmp_check/regress_outdir/results/profiles.out +--- ../../../src/test/regress/expected/profiles.out CENSORED ++++ ../tmp_check/regress_outdir/results/profiles.out CENSORED +@@ -21,16 +21,15 @@ + PASSWORD_REUSE_TIME 1 + PASSWORD_REUSE_MAX 1 + PASSWORD_GRACE_TIME 1; ++ERROR: [MTM] failed to prepare transaction at peer node + ALTER ROLE regress_profile_role PROFILE regress_test_profile; ++ERROR: profile "regress_test_profile" does not exist + DROP PROFILE regress_test_profile; -- error +-ERROR: profile "regress_test_profile" cannot be dropped because some objects depend on it +-DETAIL: profile of role regress_profile_role ++ERROR: profile "regress_test_profile" does not exist + -- Test profile parameters + ALTER PROFILE regress_test_profile LIMIT + FAILED_LOGIN_ATTEMPTS 0; -- error +-ERROR: invalid resource limit +-LINE 2: FAILED_LOGIN_ATTEMPTS 0; +- ^ ++ERROR: profile "regress_test_profile" does not exist + ALTER PROFILE regress_test_profile LIMIT + FAILED_LOGIN_ATTEMPTS 1.1; -- error + ERROR: syntax error at or near "1.1" +@@ -38,9 +37,7 @@ + ^ + ALTER PROFILE regress_test_profile LIMIT + PASSWORD_REUSE_TIME -2; -- error +-ERROR: invalid resource limit +-LINE 2: PASSWORD_REUSE_TIME -2; +- ^ ++ERROR: profile "regress_test_profile" does not exist + ALTER PROFILE regress_test_profile LIMIT + PASSWORD_REUSE_MAX -1; -- error + ERROR: syntax error at or near "-" +@@ -48,12 +45,16 @@ + ^ + ALTER PROFILE regress_test_profile LIMIT + PASSWORD_LIFE_TIME 0.1; ++ERROR: profile "regress_test_profile" does not exist + ALTER PROFILE regress_test_profile LIMIT + PASSWORD_GRACE_TIME default; ++ERROR: profile "regress_test_profile" does not exist + ALTER PROFILE regress_test_profile LIMIT + FAILED_LOGIN_ATTEMPTS unlimited; ++ERROR: profile "regress_test_profile" does not exist + ALTER PROFILE regress_test_profile LIMIT + PASSWORD_REUSE_TIME 1; ++ERROR: profile "regress_test_profile" does not exist + -- Use ORDER BY pflname in order to make test results not dependable on possible + -- changes in records restoring order + SELECT +@@ -69,15 +70,15 @@ + pflpasswordminlen, + pflpasswordrequirecomplex + FROM pg_profile ORDER BY pflname; +- pflname | pflfailedloginattempts | pflfailedauthkeeptime | pfluserinactivetime | pflpasswordreusetime | pflpasswordreusemax | pflpasswordlifetime | pflpasswordgracetime | pflpasswordminuniqchars | pflpasswordminlen | pflpasswordrequirecomplex +-----------------------+------------------------+-----------------------+---------------------+----------------------+---------------------+---------------------+----------------------+-------------------------+-------------------+--------------------------- +- default | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | 0 +- regress_test_profile | -1 | -2 | -2 | 86400 | 1 | 8640 | -2 | -2 | -2 | -2 +-(2 rows) ++ pflname | pflfailedloginattempts | pflfailedauthkeeptime | pfluserinactivetime | pflpasswordreusetime | pflpasswordreusemax | pflpasswordlifetime | pflpasswordgracetime | pflpasswordminuniqchars | pflpasswordminlen | pflpasswordrequirecomplex ++---------+------------------------+-----------------------+---------------------+----------------------+---------------------+---------------------+----------------------+-------------------------+-------------------+--------------------------- ++ default | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | 0 ++(1 row) + + -- Cleanup + ALTER ROLE regress_profile_role PROFILE DEFAULT; + DROP PROFILE regress_test_profile; ++ERROR: profile "regress_test_profile" does not exist + DROP ROLE regress_profile_role; + -- Check that the parameters USER_INACTIVE_TIME, FAILED_AUTH_KEEP_TIME and + -- PASSWORD_LIFE_TIME can't take value 0. Test both cases when these parameters +@@ -101,22 +102,18 @@ + USER_INACTIVE_TIME 1 + FAILED_AUTH_KEEP_TIME 1 + PASSWORD_LIFE_TIME 1; ++ERROR: [MTM] failed to prepare transaction at peer node + -- error, USER_INACTIVE_TIME can't take zero value + ALTER PROFILE regress_test_profile LIMIT USER_INACTIVE_TIME 0; +-ERROR: invalid resource limit +-LINE 1: ALTER PROFILE regress_test_profile LIMIT USER_INACTIVE_TIME ... +- ^ ++ERROR: profile "regress_test_profile" does not exist + -- error, FAILED_AUTH_KEEP_TIME can't take zero value + ALTER PROFILE regress_test_profile LIMIT FAILED_AUTH_KEEP_TIME 0; +-ERROR: invalid resource limit +-LINE 1: ALTER PROFILE regress_test_profile LIMIT FAILED_AUTH_KEEP_TI... +- ^ ++ERROR: profile "regress_test_profile" does not exist + -- error, PASSWORD_LIFE_TIME can't take zero value + ALTER PROFILE regress_test_profile LIMIT PASSWORD_LIFE_TIME 0; +-ERROR: invalid resource limit +-LINE 1: ALTER PROFILE regress_test_profile LIMIT PASSWORD_LIFE_TIME ... +- ^ ++ERROR: profile "regress_test_profile" does not exist + DROP PROFILE regress_test_profile; ++ERROR: profile "regress_test_profile" does not exist + -- + -- Test cases added within the task #PGPRO-3656 (Merge extra features of + -- passwordcheck under control of new passoword policy) +@@ -130,45 +127,54 @@ + PASSWORD_MIN_UNIQUE_CHARS 3 + PASSWORD_MIN_LEN 3 + PASSWORD_REQUIRE_COMPLEX 1; ++ERROR: [MTM] failed to prepare transaction at peer node + CREATE USER u1 PROFILE pfl1; ++ERROR: profile "pfl1" does not exist + -- ok, password string satisfies the limits PASSWORD_MIN_LEN, + -- PASSWORD_REQUIRE_COMPLEX and PASSWORD_MIN_UNIQUE_CHARS + ALTER USER u1 PASSWORD 'foo1'; ++ERROR: role "u1" does not exist + -- error, password string breaks the limit PASSWORD_MIN_LEN. + ALTER USER u1 PASSWORD 'fo'; +-ERROR: password must be at least 3 characters long ++ERROR: role "u1" does not exist + -- error, password string breaks the limit PASSWORD_REQUIRE_COMPLEX. + ALTER USER u1 PASSWORD 'fooo'; +-ERROR: password must contain both letters and nonletters ++ERROR: role "u1" does not exist + -- error, password string breaks the limit PASSWORD_MIN_UNIQUE_CHARS. + ALTER USER u1 PASSWORD 'f000'; +-ERROR: password must contain at least 3 unique characters ++ERROR: role "u1" does not exist + --error, password string contains a user name + ALTER USER u1 PASSWORD '123u1__'; +-ERROR: password must not contain user name ++ERROR: role "u1" does not exist + -- Turn off PASSWORD_REQUIRE_COMPLEX in order to allow acceptance of password + -- string containing only letters or digits + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX 0; ++ERROR: profile "pfl1" does not exist + ALTER USER u1 PASSWORD 'foobar'; -- ok, password containing only letter is ++ERROR: role "u1" does not exist + -- now acceptable since the limit + -- PASSWORD_REQUIRE_COMPLEX was set to + -- false. + ALTER USER u1 PASSWORD '1234'; -- ok, by the same reason as for the password ++ERROR: role "u1" does not exist + -- string 'foobar' + -- Check that the limits PASSWORD_MIN_LEN, PASSWORD_MIN_UNIQUE_CHARS are still + -- followed when the limit PASSWORD_REQUIRE_COMPLEX is off + -- error, password string breaks the limit PASSWORD_MIN_LEN. + ALTER USER u1 PASSWORD 'fo'; +-ERROR: password must be at least 3 characters long ++ERROR: role "u1" does not exist + -- error, password string breaks the limit PASSWORD_MIN_UNIQUE_CHARS. + ALTER USER u1 PASSWORD 'foo'; +-ERROR: password must contain at least 3 unique characters ++ERROR: role "u1" does not exist + -- Check that a user name can be specified as a part of password phrase + ALTER USER u1 PASSWORD '123u1__'; --ok, it is allowed to specify a password ++ERROR: role "u1" does not exist + -- string containing a user name + -- Clean up + DROP USER u1; ++ERROR: role "u1" does not exist + DROP PROFILE pfl1; ++ERROR: profile "pfl1" does not exist + -- Check that a value for clauses PASSWORD_MIN_UNIQUE_CHARS and PASSWORD_MIN_LEN + -- is positive integer + -- error, value of PASSWORD_MIN_UNIQUE_CHARS must be > 0 +@@ -192,16 +198,13 @@ + LINE 1: CREATE PROFILE pfl1 LIMIT PASSWORD_MIN_LEN 1.2; + ^ + CREATE PROFILE pfl1; ++ERROR: [MTM] failed to prepare transaction at peer node + -- error, value of PASSWORD_MIN_UNIQUE_CHARS must be > 0 + ALTER PROFILE pfl1 LIMIT PASSWORD_MIN_UNIQUE_CHARS 0; +-ERROR: invalid resource limit +-LINE 1: ALTER PROFILE pfl1 LIMIT PASSWORD_MIN_UNIQUE_CHARS 0; +- ^ ++ERROR: profile "pfl1" does not exist + -- error, value of PASSWORD_MIN_LEN must be > 0 + ALTER PROFILE pfl1 LIMIT PASSWORD_MIN_LEN 0; +-ERROR: invalid resource limit +-LINE 1: ALTER PROFILE pfl1 LIMIT PASSWORD_MIN_LEN 0; +- ^ ++ERROR: profile "pfl1" does not exist + -- error, value of PASSWORD_MIN_UNIQUE_CHARS must be integer + ALTER PROFILE pfl1 LIMIT PASSWORD_MIN_UNIQUE_CHARS 1.2; + ERROR: syntax error at or near "1.2" +@@ -214,17 +217,26 @@ + ^ + -- Clean up + DROP PROFILE pfl1; ++ERROR: profile "pfl1" does not exist + -- Check that boolean value for the clause PASSWORD_REQUIRE_COMPLEX can take any + -- of the following values: ON, OFF, TRUE, FALSE, 1, 0 + CREATE PROFILE pfl1; ++ERROR: [MTM] failed to prepare transaction at peer node + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX 0; -- ok ++ERROR: profile "pfl1" does not exist + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX 1; -- ok ++ERROR: profile "pfl1" does not exist + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX false; -- ok ++ERROR: profile "pfl1" does not exist + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX true; -- ok ++ERROR: profile "pfl1" does not exist + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX on; -- ok ++ERROR: profile "pfl1" does not exist + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX off; -- ok ++ERROR: profile "pfl1" does not exist + -- Clean up + DROP PROFILE pfl1; ++ERROR: profile "pfl1" does not exist + -- Check that the error "ERROR: conflicting or redundant resource" is emitted + -- in case one of the options PASSWORD_MIN_UNIQUE_CHARS, PASSWORD_MIN_LEN, + -- PASSWORD_REQUIRE_COMPLEX repeated twice. +@@ -244,20 +256,15 @@ + ^ + -- The same test for ALTER PROFILE + CREATE PROFILE pfl1; ++ERROR: [MTM] failed to prepare transaction at peer node + ALTER PROFILE pfl1 LIMIT PASSWORD_MIN_LEN 2 PASSWORD_MIN_LEN 1; -- error +-ERROR: conflicting or redundant resource +-LINE 1: ALTER PROFILE pfl1 LIMIT PASSWORD_MIN_LEN 2 PASSWORD_MIN_LEN... +- ^ ++ERROR: profile "pfl1" does not exist + ALTER PROFILE pfl1 + LIMIT PASSWORD_MIN_UNIQUE_CHARS 2 PASSWORD_MIN_UNIQUE_CHARS 1; -- error +-ERROR: conflicting or redundant resource +-LINE 2: LIMIT PASSWORD_MIN_UNIQUE_CHARS 2 PASSWORD_MIN_UNIQUE_CHARS ... +- ^ ++ERROR: profile "pfl1" does not exist + ALTER PROFILE pfl1 + LIMIT PASSWORD_REQUIRE_COMPLEX off PASSWORD_REQUIRE_COMPLEX on; -- error +-ERROR: conflicting or redundant resource +-LINE 2: LIMIT PASSWORD_REQUIRE_COMPLEX off PASSWORD_REQUIRE_COMPLEX ... +- ^ ++ERROR: profile "pfl1" does not exist + -- Unlike other profile options, PASSWORD_REQUIRE_COMPLEX cannot be set to + -- UNLIMITED. + ALTER PROFILE pfl1 LIMIT PASSWORD_REQUIRE_COMPLEX UNLIMITED; +@@ -266,56 +273,58 @@ + ^ + -- Clean up + DROP PROFILE pfl1; ++ERROR: profile "pfl1" does not exist + -- Begin of tests that were added within implementation of the task PGPRO-4309 + -- Check that ALTER PROFILE RENAME does work as expected. + CREATE PROFILE profile_test; ++ERROR: [MTM] failed to prepare transaction at peer node + -- Query what profiles are currently stored in the system catalog table 'pg_profile'. + -- Use ORDER BY pflname in order to make test results not dependable on possible + -- changes in records restoring order + SELECT pflname FROM pg_profile ORDER BY pflname; +- pflname +--------------- ++ pflname ++--------- + default +- profile_test +-(2 rows) ++(1 row) + + -- Rename profile 'profile_test' to 'profile_test_new' + ALTER PROFILE profile_test RENAME TO profile_test_new; ++ERROR: profile "profile_test" does not exist + -- and check that the new profile name is stored in + -- the system catalog table pg_profile + SELECT pflname FROM pg_profile ORDER BY pflname; +- pflname +------------------- ++ pflname ++--------- + default +- profile_test_new +-(2 rows) ++(1 row) + + -- Clean up + DROP PROFILE profile_test_new; ++ERROR: profile "profile_test_new" does not exist + -- Check that rounding of a time value is correct + CREATE PROFILE test_profile LIMIT PASSWORD_LIFE_TIME 0.00001; ++ERROR: [MTM] failed to prepare transaction at peer node + ALTER PROFILE test_profile LIMIT PASSWORD_LIFE_TIME 0.0000000000000000000000000000000001; +-ERROR: invalid resource limit +-LINE 1: ALTER PROFILE test_profile LIMIT PASSWORD_LIFE_TIME 0.000000... +- ^ ++ERROR: profile "test_profile" does not exist + SELECT pflpasswordlifetime FROM pg_profile WHERE pflname = 'test_profile'; + pflpasswordlifetime + --------------------- +- 1 +-(1 row) ++(0 rows) + + -- Check that PASSWORD_GRACE_TIME can be assigned the value 0; + ALTER PROFILE test_profile LIMIT PASSWORD_GRACE_TIME 0 PASSWORD_LIFE_TIME 1; ++ERROR: profile "test_profile" does not exist + SELECT pflpasswordgracetime, pflpasswordlifetime FROM pg_profile WHERE pflname = 'test_profile'; + pflpasswordgracetime | pflpasswordlifetime + ----------------------+--------------------- +- 0 | 86400 +-(1 row) ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + -- Check that a value of interval type can be supplied for time-related profile options in + -- the statement CREATE PROFILE + CREATE PROFILE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '1' DAY PASSWORD_GRACE_TIME INTERVAL '2' HOUR PASSWORD_REUSE_TIME INTERVAL '30' MINUTE USER_INACTIVE_TIME INTERVAL '75' SECOND ; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT + pflpasswordlifetime, + pflpasswordgracetime, +@@ -324,13 +333,14 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + ---------------------+----------------------+----------------------+--------------------- +- 86400 | 7200 | 1800 | 75 +-(1 row) ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + -- Check that a value of interval type can be supplied in all supported formats + -- the statement CREATE PROFILE + CREATE PROFILE test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '1 YEAR 2 MONTHS 3 DAYS 4 HOURS 5 MINUTES 6.123 SECONDS' PASSWORD_LIFE_TIME INTERVAL '1 MINUTE' MINUTE PASSWORD_GRACE_TIME INTERVAL '1 SECOND' MINUTE PASSWORD_REUSE_TIME INTERVAL '1 MINUTE 1 SECOND' SECOND USER_INACTIVE_TIME INTERVAL '1 MINUTE 1 SECOND' MINUTE; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT + pflfailedauthkeeptime, + pflpasswordlifetime, +@@ -340,11 +350,12 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflfailedauthkeeptime | pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + -----------------------+---------------------+----------------------+----------------------+--------------------- +- 37015506 | 60 | 0 | 61 | 60 +-(1 row) ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + CREATE PROFILE test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '1 YEAR 2 MONTHS 3 DAYS 4 HOURS 5 MINUTES 6.523 SECONDS' PASSWORD_LIFE_TIME INTERVAL '1 MINUTE' SECOND PASSWORD_GRACE_TIME INTERVAL '1 MINUTE' PASSWORD_REUSE_TIME INTERVAL '1-2' SECOND USER_INACTIVE_TIME INTERVAL '3 4:05:06' SECOND; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT + pflfailedauthkeeptime, + pflpasswordlifetime, +@@ -354,21 +365,22 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflfailedauthkeeptime | pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + -----------------------+---------------------+----------------------+----------------------+--------------------- +- 37015507 | 60 | 60 | 36741600 | 273906 +-(1 row) ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + CREATE PROFILE test_profile LIMIT PASSWORD_REUSE_TIME INTERVAL 'P2Y3M4DT5H6M7S' USER_INACTIVE_TIME INTERVAL 'P0003-04-05T06:07:08'; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT + pflpasswordreusetime, + pfluserinactivetime + FROM pg_profile WHERE pflname='test_profile'; + pflpasswordreusetime | pfluserinactivetime + ----------------------+--------------------- +- 71255167 | 105494828 +-(1 row) ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + -- Invalid interval type values + -- the statement CREATE PROFILE + --FAILED_AUTH_KEEP_TIME value must be from 1 to 2147483647 seconds +@@ -419,6 +431,7 @@ + -- Check that an interval type value and a real type value can intermixed + -- in the same CREATE PROFILE statement. + CREATE PROFILE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '1' DAY PASSWORD_GRACE_TIME 0.01 PASSWORD_REUSE_TIME INTERVAL '30' MINUTE USER_INACTIVE_TIME 1; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT + pflpasswordlifetime, + pflpasswordgracetime, +@@ -427,14 +440,16 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + ---------------------+----------------------+----------------------+--------------------- +- 86400 | 864 | 1800 | 86400 +-(1 row) ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + CREATE PROFILE test_profile; ++ERROR: [MTM] failed to prepare transaction at peer node + -- Check that a value of interval type can be supplied for time-related profile options in + -- the statement ALTER PROFILE + ALTER PROFILE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '1' DAY PASSWORD_GRACE_TIME INTERVAL '2' HOUR PASSWORD_REUSE_TIME INTERVAL '30' MINUTE USER_INACTIVE_TIME INTERVAL '75' SECOND ; ++ERROR: profile "test_profile" does not exist + SELECT + pflpasswordlifetime, + pflpasswordgracetime, +@@ -443,12 +458,12 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + ---------------------+----------------------+----------------------+--------------------- +- 86400 | 7200 | 1800 | 75 +-(1 row) ++(0 rows) + + -- Check that a value of interval type can be supplied in all supported formats + -- the statement ALTER PROFILE + ALTER PROFILE test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '1 YEAR 2 MONTHS 3 DAYS 4 HOURS 5 MINUTES 6.123 SECONDS' PASSWORD_LIFE_TIME INTERVAL '1 MINUTE' MINUTE PASSWORD_GRACE_TIME INTERVAL '1 SECOND' MINUTE PASSWORD_REUSE_TIME INTERVAL '1 MINUTE 1 SECOND' SECOND USER_INACTIVE_TIME INTERVAL '1 MINUTE 1 SECOND' MINUTE; ++ERROR: profile "test_profile" does not exist + SELECT + pflfailedauthkeeptime, + pflpasswordlifetime, +@@ -458,10 +473,10 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflfailedauthkeeptime | pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + -----------------------+---------------------+----------------------+----------------------+--------------------- +- 37015506 | 60 | 0 | 61 | 60 +-(1 row) ++(0 rows) + + ALTER PROFILE test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '1 YEAR 2 MONTHS 3 DAYS 4 HOURS 5 MINUTES 6.523 SECONDS' PASSWORD_LIFE_TIME INTERVAL '1 MINUTE' SECOND PASSWORD_GRACE_TIME INTERVAL '1 MINUTE' PASSWORD_REUSE_TIME INTERVAL '1-2' SECOND USER_INACTIVE_TIME INTERVAL '3 4:05:06' SECOND; ++ERROR: profile "test_profile" does not exist + SELECT + pflfailedauthkeeptime, + pflpasswordlifetime, +@@ -471,69 +486,49 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflfailedauthkeeptime | pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + -----------------------+---------------------+----------------------+----------------------+--------------------- +- 37015507 | 60 | 60 | 36741600 | 273906 +-(1 row) ++(0 rows) + + ALTER PROFILE test_profile LIMIT PASSWORD_REUSE_TIME INTERVAL 'P2Y3M4DT5H6M7S' USER_INACTIVE_TIME INTERVAL 'P0003-04-05T06:07:08'; ++ERROR: profile "test_profile" does not exist + SELECT + pflpasswordreusetime, + pfluserinactivetime + FROM pg_profile WHERE pflname='test_profile'; + pflpasswordreusetime | pfluserinactivetime + ----------------------+--------------------- +- 71255167 | 105494828 +-(1 row) ++(0 rows) + + -- Invalid interval type values + -- the statement ALTER PROFILE + --FAILED_AUTH_KEEP_TIME value must be from 1 to 2147483647 seconds + ALTER PROFILE test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '100' YEAR; --error +-ERROR: interval must be in range 1..2147483647 seconds +-LINE 1: ...test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '100' YEAR... +- ^ ++ERROR: profile "test_profile" does not exist + ALTER PROFILE test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '1 MINUTE' DAY; --error +-ERROR: interval must be in range 1..2147483647 seconds +-LINE 1: ...test_profile LIMIT FAILED_AUTH_KEEP_TIME INTERVAL '1 MINUTE'... +- ^ ++ERROR: profile "test_profile" does not exist + --PASSWORD_LIFE_TIME value must be from 1 to 2147483647 seconds + ALTER PROFILE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '100' YEAR; --error +-ERROR: interval must be in range 1..2147483647 seconds +-LINE 1: ...LE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '100' YEAR... +- ^ ++ERROR: profile "test_profile" does not exist + ALTER PROFILE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '1 MINUTE' HOUR; --error +-ERROR: interval must be in range 1..2147483647 seconds +-LINE 1: ...LE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '1 MINUTE'... +- ^ ++ERROR: profile "test_profile" does not exist + --PASSWORD_GRACE_TIME value must be from 0 to 2147483647 seconds + ALTER PROFILE test_profile LIMIT PASSWORD_GRACE_TIME INTERVAL '100' YEAR; --error +-ERROR: interval must be in range 0..2147483647 seconds +-LINE 1: ...E test_profile LIMIT PASSWORD_GRACE_TIME INTERVAL '100' YEAR... +- ^ ++ERROR: profile "test_profile" does not exist + ALTER PROFILE test_profile LIMIT PASSWORD_GRACE_TIME INTERVAL '-1 SECOND'; --error +-ERROR: interval must be in range 0..2147483647 seconds +-LINE 1: ...E test_profile LIMIT PASSWORD_GRACE_TIME INTERVAL '-1 SECOND... +- ^ ++ERROR: profile "test_profile" does not exist + --PASSWORD_REUSE_TIME value must be from 0 to 2147483647 seconds + ALTER PROFILE test_profile LIMIT PASSWORD_REUSE_TIME INTERVAL '100' YEAR; --error +-ERROR: interval must be in range 0..2147483647 seconds +-LINE 1: ...E test_profile LIMIT PASSWORD_REUSE_TIME INTERVAL '100' YEAR... +- ^ ++ERROR: profile "test_profile" does not exist + ALTER PROFILE test_profile LIMIT PASSWORD_REUSE_TIME INTERVAL '-1 SECOND'; --error +-ERROR: interval must be in range 0..2147483647 seconds +-LINE 1: ...E test_profile LIMIT PASSWORD_REUSE_TIME INTERVAL '-1 SECOND... +- ^ ++ERROR: profile "test_profile" does not exist + --USER_INACTIVE_TIME value must be from 1 to 2147483647 seconds + ALTER PROFILE test_profile LIMIT USER_INACTIVE_TIME INTERVAL '100' YEAR; --error +-ERROR: interval must be in range 1..2147483647 seconds +-LINE 1: ...LE test_profile LIMIT USER_INACTIVE_TIME INTERVAL '100' YEAR... +- ^ ++ERROR: profile "test_profile" does not exist + ALTER PROFILE test_profile LIMIT USER_INACTIVE_TIME INTERVAL '1 SECOND' YEAR; --error +-ERROR: interval must be in range 1..2147483647 seconds +-LINE 1: ...LE test_profile LIMIT USER_INACTIVE_TIME INTERVAL '1 SECOND'... +- ^ ++ERROR: profile "test_profile" does not exist + -- Check that an interval type value and a real type value can intermixed + -- in the same ALTER PROFILE statement. + ALTER PROFILE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '5' DAY PASSWORD_GRACE_TIME 0.01 PASSWORD_REUSE_TIME INTERVAL '70' MINUTE USER_INACTIVE_TIME 1; ++ERROR: profile "test_profile" does not exist + SELECT + pflpasswordlifetime, + pflpasswordgracetime, +@@ -542,36 +537,40 @@ + FROM pg_profile WHERE pflname='test_profile'; + pflpasswordlifetime | pflpasswordgracetime | pflpasswordreusetime | pfluserinactivetime + ---------------------+----------------------+----------------------+--------------------- +- 432000 | 864 | 4200 | 86400 +-(1 row) ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + -- Check support of statement CREATE PROFILE IF NOT EXISTS + CREATE PROFILE IF NOT EXISTS test_profile; ++ERROR: [MTM] failed to prepare transaction at peer node + -- Check that the profile test_profile was created + SELECT 1 FROM pg_profile WHERE pflname='test_profile'; + ?column? + ---------- +- 1 +-(1 row) ++(0 rows) + + -- Re-execute the same CREATE PROFILE statement and check it doesn't fail + CREATE PROFILE IF NOT EXISTS test_profile; ++ERROR: [MTM] failed to prepare transaction at peer node + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + -- Check support of statement CREATE PROFILE FROM + CREATE PROFILE test_profile LIMIT PASSWORD_LIFE_TIME INTERVAL '10' HOUR FAILED_LOGIN_ATTEMPTS 7; ++ERROR: [MTM] failed to prepare transaction at peer node + CREATE PROFILE test_profile_copy FROM test_profile; ++ERROR: profile "test_profile" does not exist + -- Use ORDER BY pflname in order to make test results not dependable on possible + -- changes in records restoring order + SELECT pflname, pflfailedloginattempts, pflfailedauthkeeptime, pfluserinactivetime, pflpasswordreusetime, pflpasswordreusemax, pflpasswordlifetime, pflpasswordgracetime, pflpasswordminuniqchars, pflpasswordminlen, pflpasswordrequirecomplex FROM pg_profile WHERE pflname IN ('test_profile', 'test_profile_copy') ORDER BY pflname; +- pflname | pflfailedloginattempts | pflfailedauthkeeptime | pfluserinactivetime | pflpasswordreusetime | pflpasswordreusemax | pflpasswordlifetime | pflpasswordgracetime | pflpasswordminuniqchars | pflpasswordminlen | pflpasswordrequirecomplex +--------------------+------------------------+-----------------------+---------------------+----------------------+---------------------+---------------------+----------------------+-------------------------+-------------------+--------------------------- +- test_profile | 7 | -2 | -2 | -2 | -2 | 36000 | -2 | -2 | -2 | -2 +- test_profile_copy | 7 | -2 | -2 | -2 | -2 | 36000 | -2 | -2 | -2 | -2 +-(2 rows) ++ pflname | pflfailedloginattempts | pflfailedauthkeeptime | pfluserinactivetime | pflpasswordreusetime | pflpasswordreusemax | pflpasswordlifetime | pflpasswordgracetime | pflpasswordminuniqchars | pflpasswordminlen | pflpasswordrequirecomplex ++---------+------------------------+-----------------------+---------------------+----------------------+---------------------+---------------------+----------------------+-------------------------+-------------------+--------------------------- ++(0 rows) + + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + DROP PROFILE test_profile_copy; ++ERROR: profile "test_profile_copy" does not exist + -- Check that all profile options support the value DEFAULT. + CREATE PROFILE test_profile LIMIT + FAILED_LOGIN_ATTEMPTS DEFAULT +@@ -584,6 +583,7 @@ + PASSWORD_MIN_UNIQUE_CHARS DEFAULT + PASSWORD_MIN_LEN DEFAULT + PASSWORD_REQUIRE_COMPLEX DEFAULT; ++ERROR: [MTM] failed to prepare transaction at peer node + \x + SELECT + pflfailedloginattempts, +@@ -597,21 +597,13 @@ + pflpasswordminlen, + pflpasswordrequirecomplex + FROM pg_profile WHERE pflname = 'test_profile'; +--[ RECORD 1 ]-------------+--- +-pflfailedloginattempts | -2 +-pflfailedauthkeeptime | -2 +-pfluserinactivetime | -2 +-pflpasswordreusetime | -2 +-pflpasswordreusemax | -2 +-pflpasswordlifetime | -2 +-pflpasswordgracetime | -2 +-pflpasswordminuniqchars | -2 +-pflpasswordminlen | -2 +-pflpasswordrequirecomplex | -2 ++(0 rows) + + \x + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + CREATE PROFILE test_profile; ++ERROR: [MTM] failed to prepare transaction at peer node + ALTER PROFILE test_profile LIMIT + FAILED_LOGIN_ATTEMPTS DEFAULT + FAILED_AUTH_KEEP_TIME DEFAULT +@@ -623,6 +615,7 @@ + PASSWORD_MIN_UNIQUE_CHARS DEFAULT + PASSWORD_MIN_LEN DEFAULT + PASSWORD_REQUIRE_COMPLEX DEFAULT; ++ERROR: profile "test_profile" does not exist + \x + SELECT + pflfailedloginattempts, +@@ -636,20 +629,11 @@ + pflpasswordminlen, + pflpasswordrequirecomplex + FROM pg_profile WHERE pflname = 'test_profile'; +--[ RECORD 1 ]-------------+--- +-pflfailedloginattempts | -2 +-pflfailedauthkeeptime | -2 +-pfluserinactivetime | -2 +-pflpasswordreusetime | -2 +-pflpasswordreusemax | -2 +-pflpasswordlifetime | -2 +-pflpasswordgracetime | -2 +-pflpasswordminuniqchars | -2 +-pflpasswordminlen | -2 +-pflpasswordrequirecomplex | -2 ++(0 rows) + + \x + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + -- Check that almost all profile options (except for PASSWORD_REQUIRE_COMPLEX) + -- support the value UNLIMITED. + CREATE PROFILE test_profile LIMIT +@@ -662,6 +646,7 @@ + PASSWORD_GRACE_TIME UNLIMITED + PASSWORD_MIN_UNIQUE_CHARS UNLIMITED + PASSWORD_MIN_LEN UNLIMITED; ++ERROR: [MTM] failed to prepare transaction at peer node + \x + SELECT + pflfailedloginattempts, +@@ -675,21 +660,13 @@ + pflpasswordminlen, + pflpasswordrequirecomplex + FROM pg_profile WHERE pflname = 'test_profile'; +--[ RECORD 1 ]-------------+--- +-pflfailedloginattempts | -1 +-pflfailedauthkeeptime | -1 +-pfluserinactivetime | -1 +-pflpasswordreusetime | -1 +-pflpasswordreusemax | -1 +-pflpasswordlifetime | -1 +-pflpasswordgracetime | -1 +-pflpasswordminuniqchars | -1 +-pflpasswordminlen | -1 +-pflpasswordrequirecomplex | -2 ++(0 rows) + + \x + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist + CREATE PROFILE test_profile; ++ERROR: [MTM] failed to prepare transaction at peer node + ALTER PROFILE test_profile LIMIT + FAILED_LOGIN_ATTEMPTS UNLIMITED + FAILED_AUTH_KEEP_TIME UNLIMITED +@@ -700,6 +677,7 @@ + PASSWORD_GRACE_TIME UNLIMITED + PASSWORD_MIN_UNIQUE_CHARS UNLIMITED + PASSWORD_MIN_LEN UNLIMITED; ++ERROR: profile "test_profile" does not exist + \x + SELECT + pflfailedloginattempts, +@@ -713,17 +691,8 @@ + pflpasswordminlen, + pflpasswordrequirecomplex + FROM pg_profile WHERE pflname = 'test_profile'; +--[ RECORD 1 ]-------------+--- +-pflfailedloginattempts | -1 +-pflfailedauthkeeptime | -1 +-pfluserinactivetime | -1 +-pflpasswordreusetime | -1 +-pflpasswordreusemax | -1 +-pflpasswordlifetime | -1 +-pflpasswordgracetime | -1 +-pflpasswordminuniqchars | -1 +-pflpasswordminlen | -1 +-pflpasswordrequirecomplex | -2 ++(0 rows) + + \x + DROP PROFILE test_profile; ++ERROR: profile "test_profile" does not exist diff ../../../src/test/regress/expected/sanity_check.out ../tmp_check/regress_outdir/results/sanity_check.out --- ../../../src/test/regress/expected/sanity_check.out CENSORED +++ ../tmp_check/regress_outdir/results/sanity_check.out CENSORED @@ -297,7 +992,7 @@ diff ../../../src/test/regress/expected/sanity_check.out ../tmp_check/regress_ou num_data|f num_exp_add|t num_exp_div|t -@@ -140,7 +146,6 @@ +@@ -141,7 +147,6 @@ pg_policy|t pg_proc|t pg_profile|t @@ -305,7 +1000,7 @@ diff ../../../src/test/regress/expected/sanity_check.out ../tmp_check/regress_ou pg_publication_rel|t pg_range|t pg_replication_origin|t -@@ -154,7 +159,6 @@ +@@ -155,7 +160,6 @@ pg_statistic|t pg_statistic_ext|t pg_statistic_ext_data|t @@ -313,7 +1008,7 @@ diff ../../../src/test/regress/expected/sanity_check.out ../tmp_check/regress_ou pg_subscription_rel|t pg_tablespace|t pg_transform|t -@@ -185,6 +189,7 @@ +@@ -187,6 +191,7 @@ sql_sizing|f stud_emp|f student|f @@ -321,6 +1016,473 @@ diff ../../../src/test/regress/expected/sanity_check.out ../tmp_check/regress_ou tab_core_types|f tableam_parted_a_heap2|f tableam_parted_b_heap2|f +diff ../../../src/test/regress/expected/select_into.out ../tmp_check/regress_outdir/results/select_into.out +--- ../../../src/test/regress/expected/select_into.out CENSORED ++++ ../tmp_check/regress_outdir/results/select_into.out CENSORED +@@ -50,27 +50,19 @@ + PREPARE data_sel AS SELECT generate_series(1,3); + CREATE TABLE selinto_schema.tbl_withdata3 (a) AS + EXECUTE data_sel WITH DATA; ++ERROR: [MTM] failed to prepare transaction at peer node + EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_withdata4 (a) AS + EXECUTE data_sel WITH DATA; +- QUERY PLAN +--------------------------------------- +- ProjectSet (actual rows=3 loops=1) +- -> Result (actual rows=1 loops=1) +-(2 rows) +- ++ERROR: [MTM] failed to prepare transaction at peer node + -- EXECUTE and WITH NO DATA, passes. + CREATE TABLE selinto_schema.tbl_nodata3 (a) AS + EXECUTE data_sel WITH NO DATA; ++ERROR: [MTM] failed to prepare transaction at peer node + EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) + CREATE TABLE selinto_schema.tbl_nodata4 (a) AS + EXECUTE data_sel WITH NO DATA; +- QUERY PLAN +-------------------------------- +- ProjectSet (never executed) +- -> Result (never executed) +-(2 rows) +- ++ERROR: [MTM] failed to prepare transaction at peer node + RESET SESSION AUTHORIZATION; + ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + GRANT INSERT ON TABLES TO regress_selinto_user; +@@ -78,15 +70,11 @@ + RESET SESSION AUTHORIZATION; + DEALLOCATE data_sel; + DROP SCHEMA selinto_schema CASCADE; +-NOTICE: drop cascades to 8 other objects ++NOTICE: drop cascades to 4 other objects + DETAIL: drop cascades to table selinto_schema.tbl_withdata1 + drop cascades to table selinto_schema.tbl_withdata2 + drop cascades to table selinto_schema.tbl_nodata1 + drop cascades to table selinto_schema.tbl_nodata2 +-drop cascades to table selinto_schema.tbl_withdata3 +-drop cascades to table selinto_schema.tbl_withdata4 +-drop cascades to table selinto_schema.tbl_nodata3 +-drop cascades to table selinto_schema.tbl_nodata4 + DROP USER regress_selinto_user; + -- Tests for WITH NO DATA and column name consistency + CREATE TABLE ctas_base (i int, j int); +diff ../../../src/test/regress/expected/join.out ../tmp_check/regress_outdir/results/join.out +--- ../../../src/test/regress/expected/join.out CENSORED ++++ ../tmp_check/regress_outdir/results/join.out CENSORED +@@ -4936,11 +4936,14 @@ + -- Trivial self-join case. + explain (costs off) + select p.* from sj p, sj q where q.a = p.a and q.b = q.a - 1; +- QUERY PLAN +------------------------------------------------ +- Seq Scan on sj q +- Filter: ((a IS NOT NULL) AND (b = (a - 1))) +-(2 rows) ++ QUERY PLAN ++------------------------------- ++ Nested Loop ++ Join Filter: (p.a = q.a) ++ -> Seq Scan on sj q ++ Filter: (b = (a - 1)) ++ -> Seq Scan on sj p ++(5 rows) + + select p.* from sj p, sj q where q.a = p.a and q.b = q.a - 1; + a | b | c +@@ -4954,11 +4957,15 @@ + select * from sj p + where exists (select * from sj q + where q.a = p.a and q.b < 10); +- QUERY PLAN +------------------------------------------- +- Seq Scan on sj q +- Filter: ((a IS NOT NULL) AND (b < 10)) +-(2 rows) ++ QUERY PLAN ++-------------------------------- ++ Nested Loop ++ Join Filter: (p.a = q.a) ++ -> Seq Scan on sj p ++ -> Materialize ++ -> Seq Scan on sj q ++ Filter: (b < 10) ++(6 rows) + + select * from sj p where exists (select * from sj q where q.a = p.a and q.b < 10); + a | b | c +@@ -4985,13 +4992,11 @@ + (select a as x from sj where false) as q1, + (select a as y from sj where false) as q2 + where q1.x = q2.y; +- QUERY PLAN +---------------------------------- ++ QUERY PLAN ++-------------------------- + Result + One-Time Filter: false +- -> Seq Scan on sj +- Filter: (a IS NOT NULL) +-(4 rows) ++(2 rows) + + -- We can't use a cross-EC generated self join qual because of current logic of + -- the generate_join_implied_equalities routine. +@@ -5032,11 +5037,18 @@ + explain (costs off) + select * from sj t1 join sj t2 on t1.a = t2.a and t1.b = t2.b + join sj t3 on t2.a = t3.a and t2.b + 1 = t3.b + 1; +- QUERY PLAN +---------------------------------------------------------------------------- +- Seq Scan on sj t3 +- Filter: ((a IS NOT NULL) AND (b IS NOT NULL) AND ((b + 1) IS NOT NULL)) +-(2 rows) ++ QUERY PLAN ++-------------------------------------------------------------------------------- ++ Nested Loop ++ Join Filter: ((t1.a = t2.a) AND (t1.b = t2.b) AND ((t3.b + 1) = (t2.b + 1))) ++ -> Seq Scan on sj t2 ++ -> Materialize ++ -> Nested Loop ++ Join Filter: (t1.a = t3.a) ++ -> Seq Scan on sj t1 ++ -> Materialize ++ -> Seq Scan on sj t3 ++(9 rows) + + -- subselect that references the removed relation + explain (costs off) +@@ -5045,14 +5057,17 @@ + where t1.a = t2.a; + QUERY PLAN + ------------------------------------------ +- Seq Scan on sj t2 +- Filter: (a IS NOT NULL) ++ Nested Loop ++ Join Filter: (t1.a = t2.a) ++ -> Seq Scan on sj t1 ++ -> Materialize ++ -> Seq Scan on sj t2 + SubPlan 1 + -> Result +- One-Time Filter: (t2.a = t2.a) ++ One-Time Filter: (t2.a = t1.a) + -> Seq Scan on sj +- Filter: (a = t2.a) +-(7 rows) ++ Filter: (a = t1.a) ++(10 rows) + + -- self-join under outer join + explain (costs off) +@@ -5061,12 +5076,15 @@ + QUERY PLAN + ------------------------------------ + Nested Loop Left Join +- Join Filter: (y.a = z.q1) +- -> Seq Scan on sj y +- Filter: (a IS NOT NULL) ++ Join Filter: (x.a = z.q1) ++ -> Nested Loop ++ Join Filter: (x.a = y.a) ++ -> Seq Scan on sj x ++ -> Materialize ++ -> Seq Scan on sj y + -> Materialize + -> Seq Scan on int8_tbl z +-(6 rows) ++(9 rows) + + explain (costs off) + select * from sj x join sj y on x.a = y.a +@@ -5075,11 +5093,14 @@ + ------------------------------------ + Nested Loop Left Join + Join Filter: (y.a = z.q1) +- -> Seq Scan on sj y +- Filter: (a IS NOT NULL) ++ -> Nested Loop ++ Join Filter: (x.a = y.a) ++ -> Seq Scan on sj x ++ -> Materialize ++ -> Seq Scan on sj y + -> Materialize + -> Seq Scan on int8_tbl z +-(6 rows) ++(9 rows) + + -- Test that placeholders are updated correctly after join removal + explain (costs off) +@@ -5088,44 +5109,56 @@ + right join sj j1 inner join sj j2 on j1.a = j2.a + on true) z + on true; +- QUERY PLAN +------------------------------------------- ++ QUERY PLAN ++------------------------------------------- + Nested Loop Left Join + -> Result + -> Nested Loop Left Join +- -> Seq Scan on sj j2 +- Filter: (a IS NOT NULL) ++ -> Nested Loop ++ Join Filter: (j1.a = j2.a) ++ -> Seq Scan on sj j1 ++ -> Materialize ++ -> Seq Scan on sj j2 + -> Materialize + -> Seq Scan on int8_tbl y +-(7 rows) ++(10 rows) + + -- Test that OR predicated are updated correctly after join removal + CREATE TABLE tab_with_flag ( id INT PRIMARY KEY, is_flag SMALLINT); + CREATE INDEX idx_test_is_flag ON tab_with_flag (is_flag); + explain (costs off) + SELECT COUNT(*) FROM tab_with_flag WHERE (is_flag IS NULL OR is_flag = 0) AND id IN (SELECT id FROM tab_with_flag WHERE id IN (2, 3)); +- QUERY PLAN +----------------------------------------------------------------------------------- ++ QUERY PLAN ++------------------------------------------------------------------------ + Aggregate +- -> Bitmap Heap Scan on tab_with_flag +- Recheck Cond: ((id = ANY ('{2,3}'::integer[])) AND (id IS NOT NULL)) +- Filter: ((is_flag IS NULL) OR (is_flag = 0)) +- -> Bitmap Index Scan on tab_with_flag_pkey +- Index Cond: ((id = ANY ('{2,3}'::integer[])) AND (id IS NOT NULL)) +-(6 rows) ++ -> Nested Loop ++ -> Bitmap Heap Scan on tab_with_flag tab_with_flag_1 ++ Recheck Cond: (id = ANY ('{2,3}'::integer[])) ++ -> Bitmap Index Scan on tab_with_flag_pkey ++ Index Cond: (id = ANY ('{2,3}'::integer[])) ++ -> Memoize ++ Cache Key: tab_with_flag_1.id ++ Cache Mode: logical ++ -> Index Scan using tab_with_flag_pkey on tab_with_flag ++ Index Cond: (id = tab_with_flag_1.id) ++ Filter: ((is_flag IS NULL) OR (is_flag = 0)) ++(12 rows) + + DROP TABLE tab_with_flag; + -- HAVING clause + explain (costs off) + select p.b from sj p join sj q on p.a = q.a group by p.b having sum(p.a) = 1; +- QUERY PLAN +---------------------------------- ++ QUERY PLAN ++------------------------------------ + HashAggregate +- Group Key: q.b +- Filter: (sum(q.a) = 1) +- -> Seq Scan on sj q +- Filter: (a IS NOT NULL) +-(5 rows) ++ Group Key: p.b ++ Filter: (sum(p.a) = 1) ++ -> Nested Loop ++ Join Filter: (p.a = q.a) ++ -> Seq Scan on sj p ++ -> Materialize ++ -> Seq Scan on sj q ++(8 rows) + + -- update lateral references and range table entry reference + explain (verbose, costs off) +@@ -5135,13 +5168,20 @@ + ------------------------------------------------------ + Nested Loop + Output: 1 +- -> Seq Scan on public.sj y +- Output: y.a, y.b, y.c +- Filter: (y.a IS NOT NULL) ++ -> Nested Loop ++ Output: x.a ++ Inner Unique: true ++ Join Filter: (x.a = y.a) ++ -> Seq Scan on public.sj x ++ Output: x.a, x.b, x.c ++ -> Materialize ++ Output: y.a ++ -> Seq Scan on public.sj y ++ Output: y.a + -> Function Scan on pg_catalog.generate_series gs + Output: gs.i +- Function Call: generate_series(1, y.a) +-(8 rows) ++ Function Call: generate_series(1, x.a) ++(15 rows) + + explain (verbose, costs off) + select 1 from (select y.* from sj x, sj y where x.a = y.a) q, +@@ -5150,13 +5190,20 @@ + ------------------------------------------------------ + Nested Loop + Output: 1 +- -> Seq Scan on public.sj y +- Output: y.a, y.b, y.c +- Filter: (y.a IS NOT NULL) ++ -> Nested Loop ++ Output: y.a ++ Inner Unique: true ++ Join Filter: (x.a = y.a) ++ -> Seq Scan on public.sj x ++ Output: x.a, x.b, x.c ++ -> Materialize ++ Output: y.a ++ -> Seq Scan on public.sj y ++ Output: y.a + -> Function Scan on pg_catalog.generate_series gs + Output: gs.i + Function Call: generate_series(1, y.a) +-(8 rows) ++(15 rows) + + -- Test that a non-EC-derived join clause is processed correctly. Use an + -- outer join so that we can't form an EC. +@@ -5165,22 +5212,29 @@ + QUERY PLAN + ------------------------------------ + Nested Loop Left Join +- Join Filter: ((q.a + q.a) = r.a) +- -> Seq Scan on sj q +- Filter: (a IS NOT NULL) ++ Join Filter: ((p.a + q.a) = r.a) ++ -> Nested Loop ++ Join Filter: (p.a = q.a) ++ -> Seq Scan on sj p ++ -> Materialize ++ -> Seq Scan on sj q + -> Materialize + -> Seq Scan on sj r +-(6 rows) ++(9 rows) + + -- FIXME this constant false filter doesn't look good. Should we merge + -- equivalence classes? + explain (costs off) + select * from sj p, sj q where p.a = q.a and p.b = 1 and q.b = 2; +- QUERY PLAN +------------------------------------------------------ +- Seq Scan on sj q +- Filter: ((a IS NOT NULL) AND (b = 2) AND (b = 1)) +-(2 rows) ++ QUERY PLAN ++---------------------------- ++ Nested Loop ++ Join Filter: (p.a = q.a) ++ -> Seq Scan on sj p ++ Filter: (b = 1) ++ -> Seq Scan on sj q ++ Filter: (b = 2) ++(6 rows) + + -- Check that attr_needed is updated correctly after self-join removal. In this + -- test, the join of j1 with j2 is removed. k1.b is required at either j1 or j2. +@@ -5195,24 +5249,29 @@ + explain (costs off) select 1 from + (sk k1 join sk k2 on k1.a = k2.a) + join (sj j1 join sj j2 on j1.a = j2.a) on j1.b = k1.b; +- QUERY PLAN +------------------------------------------------------ ++ QUERY PLAN ++----------------------------------------------------------------- + Nested Loop +- Join Filter: (k1.b = j2.b) ++ Join Filter: (k1.b = j1.b) + -> Nested Loop + -> Index Scan using sk_a_idx on sk k1 + -> Index Only Scan using sk_a_idx on sk k2 + Index Cond: (a = k1.a) + -> Materialize +- -> Index Scan using sj_a_key on sj j2 +- Index Cond: (a IS NOT NULL) +-(9 rows) ++ -> Nested Loop ++ -> Index Scan using sj_a_key on sj j1 ++ -> Memoize ++ Cache Key: j1.a ++ Cache Mode: logical ++ -> Index Only Scan using sj_a_key on sj j2 ++ Index Cond: (a = j1.a) ++(14 rows) + + explain (costs off) select 1 from + (sk k1 join sk k2 on k1.a = k2.a) + join (sj j1 join sj j2 on j1.a = j2.a) on j2.b = k1.b; +- QUERY PLAN +------------------------------------------------------ ++ QUERY PLAN ++------------------------------------------------------------ + Nested Loop + Join Filter: (k1.b = j2.b) + -> Nested Loop +@@ -5220,9 +5279,14 @@ + -> Index Only Scan using sk_a_idx on sk k2 + Index Cond: (a = k1.a) + -> Materialize +- -> Index Scan using sj_a_key on sj j2 +- Index Cond: (a IS NOT NULL) +-(9 rows) ++ -> Nested Loop ++ -> Index Only Scan using sj_a_key on sj j1 ++ -> Memoize ++ Cache Key: j1.a ++ Cache Mode: logical ++ -> Index Scan using sj_a_key on sj j2 ++ Index Cond: (a = j1.a) ++(14 rows) + + reset join_collapse_limit; + reset enable_seqscan; +@@ -5230,12 +5294,18 @@ + CREATE TABLE emp1 ( id SERIAL PRIMARY KEY NOT NULL, code int); + explain (verbose, costs off) + SELECT * FROM emp1 e1, emp1 e2 WHERE e1.id = e2.id AND e2.code <> e1.code; +- QUERY PLAN +----------------------------------------------------------- +- Seq Scan on public.emp1 e2 +- Output: e2.id, e2.code, e2.id, e2.code +- Filter: ((e2.id IS NOT NULL) AND (e2.code <> e2.code)) +-(3 rows) ++ QUERY PLAN ++---------------------------------------------------- ++ Nested Loop ++ Output: e1.id, e1.code, e2.id, e2.code ++ Inner Unique: true ++ -> Seq Scan on public.emp1 e1 ++ Output: e1.id, e1.code ++ -> Index Scan using emp1_pkey on public.emp1 e2 ++ Output: e2.id, e2.code ++ Index Cond: (e2.id = e1.id) ++ Filter: (e2.code <> e1.code) ++(9 rows) + + -- We can remove the join even if we find the join can't duplicate rows and + -- the base quals of each side are different. In the following case we end up +@@ -5246,11 +5316,15 @@ + -- Both sides are unique, but base quals are different + explain (costs off) + select * from sl t1, sl t2 where t1.a = t2.a and t1.b = 1 and t2.b = 2; +- QUERY PLAN +------------------------------------------------------ +- Seq Scan on sl t2 +- Filter: ((a IS NOT NULL) AND (b = 2) AND (b = 1)) +-(2 rows) ++ QUERY PLAN ++------------------------------ ++ Nested Loop ++ Join Filter: (t1.a = t2.a) ++ -> Seq Scan on sl t1 ++ Filter: (b = 1) ++ -> Seq Scan on sl t2 ++ Filter: (b = 2) ++(6 rows) + + -- + ---- Only one side is unqiue diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_outdir/results/transactions.out --- ../../../src/test/regress/expected/transactions.out CENSORED +++ ../tmp_check/regress_outdir/results/transactions.out CENSORED @@ -470,8 +1632,8 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou COMMIT; START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (16)\; ROLLBACK AND CHAIN; -- 16 ok SHOW transaction_isolation; -- transaction is active at this point -@@ -1028,7 +999,7 @@ - ROLLBACK; +@@ -1029,7 +1000,7 @@ + SET default_transaction_isolation = 'read committed'; -- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (17)\; COMMIT\; INSERT INTO abc VALUES (18)\; COMMIT AND CHAIN; -- 17 commit, 18 error -ERROR: COMMIT AND CHAIN can only be used in transaction blocks @@ -479,7 +1641,7 @@ diff ../../../src/test/regress/expected/transactions.out ../tmp_check/regress_ou SHOW transaction_isolation; -- out of transaction block transaction_isolation ----------------------- -@@ -1047,9 +1018,8 @@ +@@ -1049,9 +1020,8 @@ a ---- 7 @@ -567,48 +1729,431 @@ diff ../../../src/test/regress/expected/rowsecurity.out ../tmp_check/regress_out SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename like '%part_document%' ORDER BY policyname; schemaname | tablename | policyname | permissive | roles | cmd | qual | with_check --------------------+---------------+------------+-------------+--------------------+-----+--------------------------------------------+------------ -diff ../../../src/test/regress/expected/atx.out ../tmp_check/regress_outdir/results/atx.out ---- ../../../src/test/regress/expected/atx.out CENSORED -+++ ../tmp_check/regress_outdir/results/atx.out CENSORED -@@ -851,6 +851,7 @@ - declare c2 cursor with hold for select count_tt1_v(), count_tt1_s(); - insert into atx_tt1 values(2); - commit; -+ERROR: cannot PREPARE a transaction that has created a cursor WITH HOLD - commit; - begin; - begin autonomous; -@@ -866,6 +867,7 @@ - drop function count_tt1_s(); - drop table if exists atx_tt1; - close c2; -+ERROR: cursor "c2" does not exist - -- 13 - create table atx_13_t(i int); - begin; -@@ -985,9 +987,7 @@ - insert into atx_tt2 values(1); - declare c2 cursor with hold for select error_function(); - commit; +diff ../../../src/test/regress/expected/object_address.out ../tmp_check/regress_outdir/results/object_address.out +--- ../../../src/test/regress/expected/object_address.out CENSORED ++++ ../tmp_check/regress_outdir/results/object_address.out CENSORED +@@ -580,44 +580,6 @@ + AS descr + FROM objects + ORDER BY objects.classid, objects.objid, objects.objsubid; +-("(""default acl"",,,)")|("(""default acl"",,)")|NULL +-("(tablespace,,,)")|("(tablespace,,)")|NULL +-("(type,,,)")|("(type,,)")|NULL +-("(routine,,,)")|("(routine,,)")|NULL +-("(relation,,,)")|("(relation,,)")|NULL +-("(""table column"",,,)")|("(""table column"",,)")|NULL +-("(role,,,)")|("(role,,)")|NULL +-("(database,,,)")|("(database,,)")|NULL +-("(server,,,)")|("(server,,)")|NULL +-("(""user mapping"",,,)")|("(""user mapping"",,)")|NULL +-("(""foreign-data wrapper"",,,)")|("(""foreign-data wrapper"",,)")|NULL +-("(""access method"",,,)")|("(""access method"",,)")|NULL +-("(""operator of access method"",,,)")|("(""operator of access method"",,)")|NULL +-("(""function of access method"",,,)")|("(""function of access method"",,)")|NULL +-("(""default value"",,,)")|("(""default value"",,)")|NULL +-("(cast,,,)")|("(cast,,)")|NULL +-("(constraint,,,)")|("(constraint,,)")|NULL +-("(conversion,,,)")|("(conversion,,)")|NULL +-("(language,,,)")|("(language,,)")|NULL +-("(""large object"",,,)")|("(""large object"",,)")|NULL +-("(schema,,,)")|("(schema,,)")|NULL +-("(""operator class"",,,)")|("(""operator class"",,)")|NULL +-("(operator,,,)")|("(operator,,)")|NULL +-("(rule,,,)")|("(rule,,)")|NULL +-("(trigger,,,)")|("(trigger,,)")|NULL +-("(""operator family"",,,)")|("(""operator family"",,)")|NULL +-("(extension,,,)")|("(extension,,)")|NULL +-("(policy,,,)")|("(policy,,)")|NULL +-("(""statistics object"",,,)")|("(""statistics object"",,)")|NULL +-("(collation,,,)")|("(collation,,)")|NULL +-("(""event trigger"",,,)")|("(""event trigger"",,)")|NULL +-("(transform,,,)")|("(transform,,)")|NULL +-("(""text search dictionary"",,,)")|("(""text search dictionary"",,)")|NULL +-("(""text search parser"",,,)")|("(""text search parser"",,)")|NULL +-("(""text search configuration"",,,)")|("(""text search configuration"",,)")|NULL +-("(""text search template"",,,)")|("(""text search template"",,)")|NULL +-("(subscription,,,)")|("(subscription,,)")|NULL +-("(publication,,,)")|("(publication,,)")|NULL +-("(""publication relation"",,,)")|("(""publication relation"",,)")|NULL ++ERROR: unrecognized object class: 16512 + -- restore normal output mode + \a\t +diff ../../../src/test/regress/expected/atx2.out ../tmp_check/regress_outdir/results/atx2.out +--- ../../../src/test/regress/expected/atx2.out CENSORED ++++ ../tmp_check/regress_outdir/results/atx2.out CENSORED +@@ -287,362 +287,9 @@ + return 1; + end$$; + select atx_lo_test10(:my_loid); +- atx_lo_test10 +---------------- +- 1 +-(1 row) +- +-select lo_unlink(:my_loid); +- lo_unlink +------------ +- 1 +-(1 row) +- +--- put some initial data +-select lo_creat(-1) as my_loid \gset +-select lo_put( :my_loid, 0, 'lo test' ); +- lo_put +--------- +- +-(1 row) +- +--- This function should not fail +-select * from lo_test_func( :my_loid ); +- lo_test_func +--------------- +- 0 +-(1 row) +- +--- Read something +-select convert_from(data, 'UTF8') from pg_largeobject where loid = :my_loid; +- convert_from +------------------ +- My mega lo test +-(1 row) +- +--- 11 +-DO $body$ +-begin +- begin +- begin autonomous +- set datestyle = 'euro'; +- end; +- exception +- when others then +- raise notice 'exception %, %', SQLSTATE, SQLERRM; +- end; +-end; +-$body$ language plpgsql; +--- 12 +-create table if not exists atx_tt1(f1 int); +-create function count_tt1_v() returns int8 as 'select count(*) from atx_tt1' language sql volatile; +-create function count_tt1_s() returns int8 as 'select count(*) from atx_tt1' language sql stable; +-begin; +- begin autonomous; +- insert into atx_tt1 values(1); +- declare c1 cursor for select count_tt1_v(), count_tt1_s(); +- insert into atx_tt1 values(2); +- fetch all from c1; +- count_tt1_v | count_tt1_s +--------------+------------- +- 2 | 1 +-(1 row) +- +- rollback; +-rollback; +-begin; +- begin autonomous; +- insert into atx_tt1 values(1); +- declare c2 cursor with hold for select count_tt1_v(), count_tt1_s(); +- insert into atx_tt1 values(2); +- commit; +-commit; +-begin; +- begin autonomous; +- insert into atx_tt1 values(1); +- declare c1 cursor for select count_tt1_v(), count_tt1_s(); +- begin autonomous; +- fetch all from c1; +-ERROR: cursor "c1" does not exist +- rollback; +- rollback; +-rollback; +-drop function count_tt1_v(); +-drop function count_tt1_s(); +-drop table if exists atx_tt1; +-close c2; +--- 13 +-create table atx_13_t(i int); +-begin; +- begin autonomous; +- update atx_13_t set i = 1; +- rollback; +- begin autonomous; +- update atx_13_t set i = 2; +- rollback; +- drop table if exists atx_13_t; +- begin autonomous; +- update atx_13_t set i = 3 where i in (select i from atx_13_t); +-ERROR: lockmode RowExclusiveLock conflicts with lock AccessExclusiveLock of parent transaction, acquiring this lock in an autonomous transaction will lead to a sure deadlock +-LINE 1: update atx_13_t set i = 3 where i in (select i from atx_13_t... +- ^ +- rollback; +-commit; +--- 14 +-create or replace function atx_14_trigger_func() returns trigger as $body$ +-begin +- return null; +-end; +-$body$ language plpgsql; +-create table atx_14_test(a text, b text); +-create trigger atx_14_test_audit +-after insert on atx_14_test +-for each row execute procedure atx_14_trigger_func(); +-begin; +- insert into atx_14_test values (125); +- begin autonomous transaction; +- commit; +- insert into atx_14_test values (1); +-commit; +-drop table if exists atx_14_test; +-drop function atx_14_trigger_func(); +--- 15 +-create or replace function atx_15_dummy() returns text as $$ +-declare +- x text; +-begin +- x := 'one'; +- begin autonomous +- x := 'two'; +- end; +- return x; +-end; $$ language plpgsql; +-create table atx_15_test as select 1 as int, NULL as name; +-update atx_15_test set name = atx_15_dummy() returning *; +- int | name +------+------ +- 1 | two +-(1 row) +- +-drop table if exists atx_15_test; +-drop function if exists atx_15_dummy(); +--- 16 +-create table test(i int); +-begin; +- begin autonomous; +- insert into test values(1); +- declare c cursor for select * from test; +- begin autonomous; +- commit; +- rollback; +-rollback; +-drop table if exists test; +--- 17 +-create table test(f1 int); +-begin; +- begin autonomous; +- insert into test values(1); +- declare c1 cursor for select * from test; +- begin autonomous; +- fetch all from c1; +-ERROR: cursor "c1" does not exist +- rollback; +- rollback; +-rollback; +-drop table if exists test; +--- 19 +-create or replace function error_func() returns int as $body$ +-begin +- return 0/0; +-end; +-$body$ language plpgsql; +-DO $body$ +-begin +- begin +- begin autonomous +- select error_func(); +- end; +- exception +- when others then +- raise notice 'exception %, %', SQLSTATE, SQLERRM; +- end; +-end; +-$body$ language plpgsql; +-NOTICE: exception 22012, division by zero +-drop function if exists error_func(); +--- 21 +-CREATE OR REPLACE FUNCTION error_function() +- RETURNS integer AS +-$BODY$ +-begin +- begin autonomous +- SELECT 0/0; +- end; +- return 1; +-exception +- when others then +- raise notice 'other exception %, %', SQLSTATE, SQLERRM; +-end; +-$BODY$ LANGUAGE plpgsql; +-create table if not exists atx_tt2(f1 int); +-begin; +- begin autonomous; +- insert into atx_tt2 values(1); +- declare c2 cursor with hold for select error_function(); +- commit; -NOTICE: other exception 22012, division by zero -ERROR: control reached end of function without RETURN -CONTEXT: PL/pgSQL function error_function() -+ERROR: cannot PREPARE a transaction that has created a cursor WITH HOLD - commit; - drop function if exists error_function(); - drop table if exists atx_tt2; -@@ -1074,6 +1074,7 @@ - RESET client_min_messages; - create database regression_atx_test_database; - ALTER DATABASE "regression_atx_test_database" SET lc_messages TO 'C'; -+ERROR: [MTM] failed to prepare transaction at peer node - \c regression_atx_test_database - create table atx_test as select 1 as id; - begin; -diff ../../../src/test/regress/expected/atx5.out ../tmp_check/regress_outdir/results/atx5.out ---- ../../../src/test/regress/expected/atx5.out CENSORED -+++ ../tmp_check/regress_outdir/results/atx5.out CENSORED -@@ -24,10 +24,7 @@ +-commit; +-drop function if exists error_function(); +-drop table if exists atx_tt2; +--- 22 +-create or replace function if_modified_func_22() returns trigger as $body$ +-declare +- v_new_data text; +-begin +- v_new_data := row(new.*); +- begin autonomous +- return new; +- end; +-end; +-$body$ language plpgsql; +-create table atx_test_22(a text, b text); +-create trigger atx_test_22_audit +-after insert on atx_test_22 +-for each row execute procedure if_modified_func_22(); +-begin; +- insert into atx_test_22 values (1); +- begin autonomous transaction; +- commit; +- insert into atx_test_22 values (2); +-commit; +-drop table if exists atx_test_22; +-drop function if exists if_modified_func_22(); +--- 23 +-CREATE OR REPLACE FUNCTION error_function3() +- RETURNS integer AS +-$BODY$ +-begin +- begin autonomous +- SELECT 0/0; +- end; +- return 1; +-exception +- when others then +- raise notice 'other exception %, %', SQLSTATE, SQLERRM; +-end; +-$BODY$ LANGUAGE plpgsql; +-begin; +- begin autonomous; +- declare c2 cursor with hold for select error_function3(); +- commit; +-NOTICE: other exception 22012, division by zero +-ERROR: control reached end of function without RETURN +-CONTEXT: PL/pgSQL function error_function3() +-commit; +-drop function if exists error_function3(); +-close c2; +-ERROR: cursor "c2" does not exist +--- 24 +-CREATE OR REPLACE FUNCTION error_function3() +- RETURNS integer AS +-$BODY$ +-begin +- begin autonomous +- SELECT 0/0; +- end; +- return 1; +-exception +- when others then +- raise notice 'other exception %, %', SQLSTATE, SQLERRM; +- return 0; +-end; +-$BODY$ LANGUAGE plpgsql; +-begin; +- begin autonomous; +- declare c3 cursor with hold for select error_function3(); +- commit; +-NOTICE: other exception 22012, division by zero +-commit; +-drop function if exists error_function3(); +-close c3; +--- 25 +-select count(*) * 0 as dummy_res from ( select pg_terminate_backend(pid) from pg_stat_activity where datname = 'regression_atx_test_database' ) as foo; +- dummy_res +------------ +- 0 +-(1 row) +- +-SET client_min_messages TO 'warning'; +-drop database if exists regression_atx_test_database; +-RESET client_min_messages; +-create database regression_atx_test_database; +-ALTER DATABASE "regression_atx_test_database" SET lc_messages TO 'C'; +-\c regression_atx_test_database +-create table atx_test as select 1 as id; +-begin; +- begin autonomous; +- create table tmp1 as select id from atx_test; +- delete from atx_test where id in ( select id from unknown ); +-ERROR: relation "unknown" does not exist +-LINE 1: delete from atx_test where id in ( select id from unknown ); +- ^ +- rollback; +- begin autonomous; +- drop table atx_test; +-\c regression +--- PGPRO-5052 +-BEGIN TRANSACTION; BEGIN AUTONOMOUS TRANSACTION; +-CREATE FUNCTION atx_srf_test_func() RETURNS setof text AS +-$$ SELECT 'foo'::varchar $$ +-LANGUAGE SQL; +-SELECT atx_srf_test_func(); +- atx_srf_test_func +-------------------- +- foo +-(1 row) +- +-COMMIT AUTONOMOUS; COMMIT; +-DROP FUNCTION atx_srf_test_func(); +--- PGPRO-5860 +-create table mmm5860(i int); +-create or replace function crash_func5860() returns int language plpgsql as $$ +-declare +-begin +- create table if not exists mmm5860(i int); +- begin autonomous +- begin +- create table if not exists mmm5860(i int); +- exception +- when others then +- raise notice 'other exception %, %', SQLSTATE, SQLERRM; +- end; +- end; +- return 1; +-end$$; +-select * from crash_func5860(); +-NOTICE: relation "mmm5860" already exists, skipping +-NOTICE: relation "mmm5860" already exists, skipping +- crash_func5860 +----------------- +- 1 +-(1 row) +- +-drop function crash_func5860(); +-drop table mmm5860; +--- PGPRO-6207 +-BEGIN; +-COMMIT AUTONOMOUS; +-WARNING: there is no autonomous transaction in progress +-BEGIN; +-ABORT AUTONOMOUS; +-WARNING: there is no autonomous transaction in progress +-BEGIN; +- SAVEPOINT sp; +-COMMIT AUTONOMOUS; +-WARNING: there is no autonomous transaction in progress +-BEGIN; +- SAVEPOINT sp; +-ABORT AUTONOMOUS; +-WARNING: there is no autonomous transaction in progress ++FATAL: RollbackAndReleaseCurrentSubTransaction: unexpected state DEFAULT ++CONTEXT: PL/pgSQL function atx_lo_test10(oid) line 9 during exception cleanup ++server closed the connection unexpectedly ++ This probably means the server terminated abnormally ++ before or while processing the request. ++connection to server was lost +diff ../../../src/test/regress/expected/atx3.out ../tmp_check/regress_outdir/results/atx3.out +--- ../../../src/test/regress/expected/atx3.out CENSORED ++++ ../tmp_check/regress_outdir/results/atx3.out CENSORED +@@ -115,10 +115,7 @@ NOTICE: function atx_test_30_one() does not exist, skipping NOTICE: function atx_test_30_one() does not exist, skipping NOTICE: function atx_test_30_one() does not exist, skipping @@ -620,10 +2165,7 @@ diff ../../../src/test/regress/expected/atx5.out ../tmp_check/regress_outdir/res SET client_min_messages = 'warning'; DROP FUNCTION IF EXISTS atx_test_30_one(); DROP FUNCTION IF EXISTS atx_test_30_two(); -diff ../../../src/test/regress/expected/atx9.out ../tmp_check/regress_outdir/results/atx9.out ---- ../../../src/test/regress/expected/atx9.out CENSORED -+++ ../tmp_check/regress_outdir/results/atx9.out CENSORED -@@ -29,50 +29,38 @@ +@@ -383,50 +380,38 @@ INSERT INTO abc VALUES (1); INSERT INTO abc VALUES (2); COMMIT AND CHAIN; -- TBLOCK_END @@ -683,7 +2225,7 @@ diff ../../../src/test/regress/expected/atx9.out ../tmp_check/regress_outdir/res COMMIT; ROLLBACK; BEGIN; -@@ -144,24 +132,13 @@ +@@ -498,24 +483,13 @@ SAVEPOINT x; COMMIT AND CHAIN; -- TBLOCK_SUBCOMMIT @@ -712,7 +2254,7 @@ diff ../../../src/test/regress/expected/atx9.out ../tmp_check/regress_outdir/res COMMIT; ROLLBACK; -- different mix of options just for fun -@@ -232,17 +209,14 @@ +@@ -586,17 +560,14 @@ COMMIT; -- not allowed outside a transaction block COMMIT AUTONOMOUS AND CHAIN; -- error @@ -732,6 +2274,18 @@ diff ../../../src/test/regress/expected/atx9.out ../tmp_check/regress_outdir/res RESET default_transaction_read_only; DROP TABLE abc; +diff ../../../src/test/regress/expected/sysviews.out ../tmp_check/regress_outdir/results/sysviews.out +--- ../../../src/test/regress/expected/sysviews.out CENSORED ++++ ../tmp_check/regress_outdir/results/sysviews.out CENSORED +@@ -119,7 +119,7 @@ + enable_partition_pruning | on + enable_partitionwise_aggregate | off + enable_partitionwise_join | off +- enable_self_join_removal | on ++ enable_self_join_removal | off + enable_seqscan | on + enable_sort | on + enable_tidscan | on diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/results/rules.out --- ../../../src/test/regress/expected/rules.out CENSORED +++ ../tmp_check/regress_outdir/results/rules.out CENSORED @@ -751,10 +2305,10 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re iexit| SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit -@@ -1452,19 +1461,30 @@ - p.parameter_types, - p.from_sql - FROM pg_prepared_statement() p(name, statement, prepare_time, parameter_types, from_sql); +@@ -1443,19 +1452,30 @@ + p.generic_plans, + p.custom_plans + FROM pg_prepared_statement() p(name, statement, prepare_time, parameter_types, from_sql, generic_plans, custom_plans); -pg_prepared_xacts| SELECT p.transaction, - p.gid, - p.prepared, @@ -792,7 +2346,7 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re LATERAL pg_get_publication_tables((p.pubname)::text) gpt(relid), (pg_class c JOIN pg_namespace n ON ((n.oid = c.relnamespace))) -@@ -1659,7 +1679,7 @@ +@@ -1651,7 +1671,7 @@ l.provider, l.label FROM (pg_seclabel l @@ -801,7 +2355,7 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re WHERE (l.objsubid = 0) UNION ALL SELECT l.objoid, -@@ -1671,7 +1691,7 @@ +@@ -1663,7 +1683,7 @@ l.provider, l.label FROM (pg_shseclabel l @@ -810,7 +2364,7 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re UNION ALL SELECT l.objoid, l.classoid, -@@ -2066,7 +2086,7 @@ +@@ -2099,7 +2119,7 @@ st.last_msg_receipt_time, st.latest_end_lsn, st.latest_end_time @@ -819,15 +2373,17 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re LEFT JOIN pg_stat_get_subscription(NULL::oid) st(subid, relid, pid, received_lsn, last_msg_send_time, last_msg_receipt_time, latest_end_lsn, latest_end_time) ON ((st.subid = su.oid))); pg_stat_sys_indexes| SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, -@@ -2408,6 +2428,17 @@ - FROM (unnest(s.stxkeys) k(k) - JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attnum = k.k)))) - WHERE (NOT has_column_privilege(c.oid, a.attnum, 'select'::text))))) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid)))); +@@ -2524,6 +2544,19 @@ + LEFT JOIN pg_namespace sn ON ((sn.oid = s.stxnamespace))) + JOIN LATERAL ( SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr, + unnest(sd.stxdexpr) AS a) stat ON ((stat.expr IS NOT NULL))); +pg_subscription| SELECT _pg_subscription.oid, + _pg_subscription.subdbid, + _pg_subscription.subname, + _pg_subscription.subowner, + _pg_subscription.subenabled, ++ _pg_subscription.subbinary, ++ _pg_subscription.substream, + _pg_subscription.subconninfo, + _pg_subscription.subslotname, + _pg_subscription.subsynccommit, @@ -837,6 +2393,50 @@ diff ../../../src/test/regress/expected/rules.out ../tmp_check/regress_outdir/re pg_tables| SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, +diff ../../../src/test/regress/expected/psql.out ../tmp_check/regress_outdir/results/psql.out +--- ../../../src/test/regress/expected/psql.out CENSORED ++++ ../tmp_check/regress_outdir/results/psql.out CENSORED +@@ -2813,36 +2813,14 @@ + CREATE VIEW view_heap_psql AS SELECT f1 from tbl_heap_psql; + CREATE MATERIALIZED VIEW mat_view_heap_psql USING heap_psql AS SELECT f1 from tbl_heap_psql; + \d+ tbl_heap_psql +- Table "tableam_display.tbl_heap_psql" +- Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +---------+----------------+-----------+----------+---------+----------+--------------+------------- +- f1 | integer | | | | plain | | +- f2 | character(100) | | | | extended | | +- ++ERROR: permission denied for view pg_publication + \d+ tbl_heap +- Table "tableam_display.tbl_heap" +- Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +---------+----------------+-----------+----------+---------+----------+--------------+------------- +- f1 | integer | | | | plain | | +- f2 | character(100) | | | | extended | | +- ++ERROR: permission denied for view pg_publication + \set HIDE_TABLEAM off + \d+ tbl_heap_psql +- Table "tableam_display.tbl_heap_psql" +- Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +---------+----------------+-----------+----------+---------+----------+--------------+------------- +- f1 | integer | | | | plain | | +- f2 | character(100) | | | | extended | | +-Access method: heap_psql +- ++ERROR: permission denied for view pg_publication + \d+ tbl_heap +- Table "tableam_display.tbl_heap" +- Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +---------+----------------+-----------+----------+---------+----------+--------------+------------- +- f1 | integer | | | | plain | | +- f2 | character(100) | | | | extended | | +-Access method: heap +- ++ERROR: permission denied for view pg_publication + -- AM is displayed for tables, indexes and materialized views. + \d+ + List of relations diff ../../../src/test/regress/expected/publication.out ../tmp_check/regress_outdir/results/publication.out --- ../../../src/test/regress/expected/publication.out CENSORED +++ ../tmp_check/regress_outdir/results/publication.out CENSORED @@ -869,6 +2469,104 @@ diff ../../../src/test/regress/expected/subscription.out ../tmp_check/regress_ou (1 row) -- fail - name already exists +diff ../../../src/test/regress/expected/equivclass.out ../tmp_check/regress_outdir/results/equivclass.out +--- ../../../src/test/regress/expected/equivclass.out CENSORED ++++ ../tmp_check/regress_outdir/results/equivclass.out CENSORED +@@ -438,15 +438,17 @@ + explain (costs off) + select * from ec0 m join ec0 n on m.ff = n.ff + join ec1 p on m.ff + n.ff = p.f1; +- QUERY PLAN +----------------------------------------- ++ QUERY PLAN ++------------------------------------------------ + Nested Loop +- Join Filter: ((n.ff + n.ff) = p.f1) +- -> Seq Scan on ec1 p ++ Join Filter: ((m.ff + n.ff) = p.f1) ++ -> Nested Loop ++ -> Seq Scan on ec0 m ++ -> Index Scan using ec0_pkey on ec0 n ++ Index Cond: (ff = m.ff) + -> Materialize +- -> Seq Scan on ec0 n +- Filter: (ff IS NOT NULL) +-(6 rows) ++ -> Seq Scan on ec1 p ++(8 rows) + + explain (costs off) + select * from ec0 m join ec0 n on m.ff = n.ff +@@ -454,12 +456,14 @@ + QUERY PLAN + --------------------------------------------------------------- + Nested Loop +- Join Filter: ((p.f1)::bigint = ((n.ff + n.ff))::int8alias1) +- -> Seq Scan on ec1 p ++ Join Filter: ((p.f1)::bigint = ((m.ff + n.ff))::int8alias1) ++ -> Nested Loop ++ -> Seq Scan on ec0 m ++ -> Index Scan using ec0_pkey on ec0 n ++ Index Cond: (ff = m.ff) + -> Materialize +- -> Seq Scan on ec0 n +- Filter: (ff IS NOT NULL) +-(6 rows) ++ -> Seq Scan on ec1 p ++(8 rows) + + reset enable_mergejoin; + -- this could be converted, but isn't at present +diff ../../../src/test/regress/expected/copy2.out ../tmp_check/regress_outdir/results/copy2.out +--- ../../../src/test/regress/expected/copy2.out CENSORED ++++ ../tmp_check/regress_outdir/results/copy2.out CENSORED +@@ -359,11 +359,12 @@ + (2 rows) + + COMMIT; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT * FROM vistest; + a + ---- +- d1 +- e ++ a0 ++ b + (2 rows) + + BEGIN; +@@ -387,11 +388,12 @@ + (2 rows) + + COMMIT; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT * FROM vistest; + a + ---- +- d2 +- e ++ a0 ++ b + (2 rows) + + BEGIN; +@@ -448,12 +450,11 @@ + (2 rows) + + COMMIT; ++ERROR: [MTM] failed to prepare transaction at peer node + SELECT * FROM vistest; +- a +----- +- d4 +- e +-(2 rows) ++ a ++--- ++(0 rows) + + -- Test FORCE_NOT_NULL and FORCE_NULL options + CREATE TEMP TABLE forcetest ( diff ../../../src/test/regress/expected/prepare.out ../tmp_check/regress_outdir/results/prepare.out --- ../../../src/test/regress/expected/prepare.out CENSORED +++ ../tmp_check/regress_outdir/results/prepare.out CENSORED @@ -955,3 +2653,52 @@ diff ../../../src/test/regress/expected/indexing.out ../tmp_check/regress_outdir drop table idxpart_temp; -- ALTER INDEX .. ATTACH, error cases +diff ../../../src/test/regress/expected/oidjoins.out ../tmp_check/regress_outdir/results/oidjoins.out +--- ../../../src/test/regress/expected/oidjoins.out CENSORED ++++ ../tmp_check/regress_outdir/results/oidjoins.out CENSORED +@@ -257,10 +257,10 @@ + NOTICE: checking pg_transform {trftosql} => pg_proc {oid} + NOTICE: checking pg_sequence {seqrelid} => pg_class {oid} + NOTICE: checking pg_sequence {seqtypid} => pg_type {oid} +-NOTICE: checking pg_publication {pubowner} => pg_authid {oid} +-NOTICE: checking pg_publication_rel {prpubid} => pg_publication {oid} ++NOTICE: checking _pg_publication {pubowner} => pg_authid {oid} ++NOTICE: checking pg_publication_rel {prpubid} => _pg_publication {oid} + NOTICE: checking pg_publication_rel {prrelid} => pg_class {oid} +-NOTICE: checking pg_subscription {subdbid} => pg_database {oid} +-NOTICE: checking pg_subscription {subowner} => pg_authid {oid} +-NOTICE: checking pg_subscription_rel {srsubid} => pg_subscription {oid} ++NOTICE: checking _pg_subscription {subdbid} => pg_database {oid} ++NOTICE: checking _pg_subscription {subowner} => pg_authid {oid} ++NOTICE: checking pg_subscription_rel {srsubid} => _pg_subscription {oid} + NOTICE: checking pg_subscription_rel {srrelid} => pg_class {oid} +diff ../../../src/test/regress/expected/stats.out ../tmp_check/regress_outdir/results/stats.out +--- ../../../src/test/regress/expected/stats.out CENSORED ++++ ../tmp_check/regress_outdir/results/stats.out CENSORED +@@ -99,6 +99,7 @@ + TRUNCATE trunc_stats_test1; + INSERT INTO trunc_stats_test1 DEFAULT VALUES; + COMMIT; ++ERROR: [MTM] failed to prepare transaction at peer node + -- use a savepoint: 1 insert, 1 live + BEGIN; + INSERT INTO trunc_stats_test2 DEFAULT VALUES; +@@ -109,6 +110,7 @@ + INSERT INTO trunc_stats_test2 DEFAULT VALUES; + RELEASE SAVEPOINT p1; + COMMIT; ++ERROR: [MTM] failed to prepare transaction at peer node + -- rollback a savepoint: this should count 4 inserts and have 2 + -- live tuples after commit (and 2 dead ones due to aborted subxact) + BEGIN; +@@ -166,8 +168,8 @@ + relname | n_tup_ins | n_tup_upd | n_tup_del | n_live_tup | n_dead_tup + -------------------+-----------+-----------+-----------+------------+------------ + trunc_stats_test | 3 | 0 | 0 | 0 | 0 +- trunc_stats_test1 | 4 | 2 | 1 | 1 | 0 +- trunc_stats_test2 | 1 | 0 | 0 | 1 | 0 ++ trunc_stats_test1 | 3 | 4 | 1 | 2 | 5 ++ trunc_stats_test2 | 2 | 0 | 0 | 0 | 2 + trunc_stats_test3 | 4 | 0 | 0 | 2 | 2 + trunc_stats_test4 | 2 | 0 | 0 | 0 | 2 + (5 rows) diff --git a/src/ddl.c b/src/ddl.c index 49ccc2d0c4..e0aec3a4e0 100644 --- a/src/ddl.c +++ b/src/ddl.c @@ -119,19 +119,21 @@ static void MtmSeqNextvalHook(Oid seqid, int64 next); static void MtmExecutorStart(QueryDesc *queryDesc, int eflags); static void MtmExecutorFinish(QueryDesc *queryDesc); -static void MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, +static void MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); static void MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); static void MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); @@ -359,7 +361,7 @@ MtmGucInit(void) MtmGucHash = hash_create("MtmGucHash", MTM_GUC_HASHSIZE, &hash_ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); /* * If current role is not equal to MtmDatabaseUser, than set it before any @@ -661,7 +663,7 @@ MtmFinishDDLCommand() static void -MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, +MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) @@ -676,13 +678,13 @@ MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, { if (PreviousProcessUtilityHook != NULL) { - PreviousProcessUtilityHook(pstmt, queryString, + PreviousProcessUtilityHook(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } else { - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } @@ -691,12 +693,12 @@ MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, if (MtmIsLogicalReceiver) { - MtmProcessUtilityReceiver(pstmt, queryString, context, params, + MtmProcessUtilityReceiver(pstmt, queryString, context, readOnlyTree, params, queryEnv, dest, qc); } else { - MtmProcessUtilitySender(pstmt, queryString, context, params, + MtmProcessUtilitySender(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } @@ -718,7 +720,7 @@ MtmProcessUtility(PlannedStmt *pstmt, const char *queryString, * receiver (e.g calling DDL from trigger) this hook does nothing. */ static void -MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, +MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) @@ -839,22 +841,18 @@ MtmProcessUtilityReceiver(PlannedStmt *pstmt, const char *queryString, } if (PreviousProcessUtilityHook != NULL) - { - PreviousProcessUtilityHook(pstmt, queryString, + PreviousProcessUtilityHook(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } else - { - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } } static void -MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, +MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) @@ -1186,17 +1184,13 @@ MtmProcessUtilitySender(PlannedStmt *pstmt, const char *queryString, stmt_string, skipCommand, MtmDDLStatement != NULL); if (PreviousProcessUtilityHook != NULL) - { - PreviousProcessUtilityHook(pstmt, queryString, + PreviousProcessUtilityHook(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } else - { - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); - } /* Catch GUC assignment */ if (nodeTag(parsetree) == T_VariableSetStmt) @@ -1311,11 +1305,12 @@ MtmExecutorFinish(QueryDesc *queryDesc) if (operation == CMD_INSERT || operation == CMD_UPDATE || operation == CMD_DELETE || pstmt->hasModifyingCTE) { - int i; + ListCell *l; - for (i = 0; i < estate->es_num_result_relations; i++) + foreach(l, estate->es_opened_result_relations) { - Relation rel = estate->es_result_relations[i].ri_RelationDesc; + ResultRelInfo *resultRelInfo = lfirst(l); + Relation rel = resultRelInfo->ri_RelationDesc; /* * Don't run 3pc unless we modified at least one non-local table. @@ -1709,7 +1704,7 @@ MtmInitializeRemoteFunctionsMap() if (q != NULL) *q++ = '\0'; - clist = FuncnameGetCandidates(stringToQualifiedNameList(p), -1, NIL, false, false, true); + clist = FuncnameGetCandidates(stringToQualifiedNameList(p), -1, NIL, false, false, true, true); if (clist == NULL) mtm_log(DEBUG1, "Can't resolve function '%s', postponing that", p); else @@ -1724,7 +1719,7 @@ MtmInitializeRemoteFunctionsMap() p = q; } while (p != NULL); - clist = FuncnameGetCandidates(stringToQualifiedNameList("mtm.alter_sequences"), -1, NIL, false, false, true); + clist = FuncnameGetCandidates(stringToQualifiedNameList("mtm.alter_sequences"), -1, NIL, false, false, true, true); if (clist != NULL) hash_search(MtmRemoteFunctions, &clist->oid, HASH_ENTER, NULL); diff --git a/src/dmq.c b/src/dmq.c index c2d14fae28..f59d61d183 100644 --- a/src/dmq.c +++ b/src/dmq.c @@ -353,7 +353,7 @@ dmq_shmem_startup_hook(void) DMQ_MAX_SUBS_PER_BACKEND * MaxBackends, DMQ_MAX_SUBS_PER_BACKEND * MaxBackends, &hash_info, - HASH_ELEM); + HASH_ELEM | HASH_STRINGS); LWLockRelease(AddinShmemInitLock); } @@ -1443,7 +1443,7 @@ dmq_receiver_loop(PG_FUNCTION_ARGS) extra = dmq_receiver_start_hook(sender_name); /* do not hold globalxmin. XXX: try to carefully release snaps */ - MyPgXact->xmin = InvalidTransactionId; + pg_atomic_write_u64(&MyProc->xmin, InvalidTransactionId); for (;;) { diff --git a/src/global_tx.c b/src/global_tx.c index fff4921515..4e1a940982 100644 --- a/src/global_tx.c +++ b/src/global_tx.c @@ -185,7 +185,7 @@ MtmGlobalTxShmemStartup(void) gtx_shared->lock = &(GetNamedLWLockTranche("mtm-gtx-lock"))->lock; gtx_shared->gid2gtx = ShmemInitHash("gid2gtx", 2*MaxConnections, 2*MaxConnections, - &info, HASH_ELEM); + &info, HASH_ELEM | HASH_STRINGS); LWLockRelease(AddinShmemInitLock); } diff --git a/src/include/compat.h b/src/include/compat.h index a6ffaaa248..dbf96c510f 100644 --- a/src/include/compat.h +++ b/src/include/compat.h @@ -16,11 +16,6 @@ #define UserAbortTransactionBlockCompat(chain) (UserAbortTransactionBlock(chain)) #endif -/* atx renames this for some reason */ -#ifdef PGPRO_EE -#define on_commits_compat() (pg_on_commit_actions) -#else #define on_commits_compat() (on_commits) -#endif #endif /* MTMCOMPAT_H */ diff --git a/src/pglogical_apply.c b/src/pglogical_apply.c index 566d5acb97..f359e51d36 100644 --- a/src/pglogical_apply.c +++ b/src/pglogical_apply.c @@ -166,24 +166,27 @@ create_rel_estate(Relation rel) EState *estate; ResultRelInfo *resultRelInfo; RangeTblEntry *rte; + List *rangeTable; estate = CreateExecutorState(); resultRelInfo = makeNode(ResultRelInfo); InitResultRelInfo(resultRelInfo, rel, 1, NULL, 0); - estate->es_result_relations = resultRelInfo; - estate->es_num_result_relations = 1; - estate->es_result_relation_info = resultRelInfo; - estate->es_output_cid = GetCurrentCommandId(true); - rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; rte->relid = RelationGetRelid(rel); rte->relkind = rel->rd_rel->relkind; rte->rellockmode = AccessShareLock; + rangeTable = list_make1(rte); ExecInitRangeTable(estate, list_make1(rte)); + ExecInitRangeTable(estate, rangeTable); + ExecInitResultRelation(estate, resultRelInfo, 1); + + estate->es_result_relation_info = resultRelInfo; + estate->es_output_cid = GetCurrentCommandId(true); + /* Prepare to catch AFTER triggers. */ AfterTriggerBeginQuery(); @@ -1238,9 +1241,10 @@ process_remote_insert(StringInfo s, Relation rel) if (relinfo->ri_NumIndices > 0) { List *recheckIndexes; + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; - recheckIndexes = ExecInsertIndexTuples(bufferedSlots[i], - estate, false, NULL, NIL); + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, bufferedSlots[i], + estate, false, false, NULL, NIL); /* AFTER ROW INSERT Triggers */ ExecARInsertTriggers(estate, relinfo, bufferedSlots[i], @@ -1267,11 +1271,12 @@ process_remote_insert(StringInfo s, Relation rel) else { TupleTableSlot *newslot; + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; newslot = ExecInitExtraTupleSlot(estate, tupDesc, &TTSOpsHeapTuple); tuple_to_slot(estate, rel, &new_tuple, newslot); - ExecSimpleRelationInsert(estate, newslot); + ExecSimpleRelationInsert(resultRelInfo, estate, newslot); } ExecCloseIndices(estate->es_result_relation_info); if (ActiveSnapshotSet()) @@ -1367,6 +1372,7 @@ process_remote_update(StringInfo s, Relation rel) if (found) { HeapTuple remote_tuple = NULL; + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; remote_tuple = heap_modify_tuple(ExecFetchSlotHeapTuple(localslot, true, NULL), tupDesc, @@ -1376,7 +1382,7 @@ process_remote_update(StringInfo s, Relation rel) ExecStoreHeapTuple(remote_tuple, remoteslot, false); EvalPlanQualSetSlot(&epqstate, remoteslot); - ExecSimpleRelationUpdate(estate, &epqstate, localslot, remoteslot); + ExecSimpleRelationUpdate(resultRelInfo, estate, &epqstate, localslot, remoteslot); } else { @@ -1444,8 +1450,10 @@ process_remote_delete(StringInfo s, Relation rel) if (found) { + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; + EvalPlanQualSetSlot(&epqstate, localslot); - ExecSimpleRelationDelete(estate, &epqstate, localslot); + ExecSimpleRelationDelete(resultRelInfo, estate, &epqstate, localslot); } else { diff --git a/src/pglogical_output.c b/src/pglogical_output.c index 95bfa00540..b4efe4231a 100644 --- a/src/pglogical_output.c +++ b/src/pglogical_output.c @@ -70,12 +70,13 @@ static void pg_decode_begin_txn(LogicalDecodingContext *ctx, static void pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr commit_lsn); +static void pg_decode_begin_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn); static void pg_decode_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr lsn); static void pg_decode_commit_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr lsn); static void pg_decode_abort_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, - XLogRecPtr lsn); + XLogRecPtr lsn, TimestampTz prepare_time); static bool pg_filter_prepare(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, TransactionId xid, const char *gid); @@ -136,9 +137,10 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb) cb->abort_cb = pg_decode_abort_txn; cb->filter_prepare_cb = pg_filter_prepare; + cb->begin_prepare_cb = pg_decode_begin_prepare_txn; cb->prepare_cb = pg_decode_prepare_txn; cb->commit_prepared_cb = pg_decode_commit_prepared_txn; - cb->abort_prepared_cb = pg_decode_abort_prepared_txn; + cb->rollback_prepared_cb = pg_decode_abort_prepared_txn; cb->filter_by_origin_cb = pg_decode_origin_filter; cb->shutdown_cb = pg_decode_shutdown; @@ -485,6 +487,46 @@ pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, } } +void +pg_decode_begin_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) +{ + PGLogicalOutputData *data = (PGLogicalOutputData *) ctx->output_plugin_private; + bool send_replication_origin = data->forward_changeset_origins; + + if (!startup_message_sent) + send_startup_message(ctx, data, false /* can't be last message */ ); + + /* If the record didn't originate locally, send origin info */ + send_replication_origin &= txn->origin_id != InvalidRepOriginId; + + if (data->api) + { + MtmOutputPluginPrepareWrite(ctx, !send_replication_origin, true); + data->api->write_begin(ctx->out, data, txn); + + if (send_replication_origin) + { + char *origin; + + /* Message boundary */ + MtmOutputPluginWrite(ctx, false, false); + MtmOutputPluginPrepareWrite(ctx, true, false); + + /* + * XXX: which behaviour we want here? + * + * Alternatives: - don't send origin message if origin name not + * found (that's what we do now) - throw error - that will break + * replication, not good - send some special "unknown" origin + */ + if (data->api->write_origin && + replorigin_by_oid(txn->origin_id, true, &origin)) + data->api->write_origin(ctx->out, origin, txn->origin_lsn); + } + MtmOutputPluginWrite(ctx, true, false); + } +} + void pg_decode_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr lsn) @@ -509,7 +551,7 @@ pg_decode_commit_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn void pg_decode_abort_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, - XLogRecPtr lsn) + XLogRecPtr lsn, TimestampTz prepare_time) { PGLogicalOutputData *data = (PGLogicalOutputData *) ctx->output_plugin_private; diff --git a/src/resolver.c b/src/resolver.c index 2c9933ff51..659e9a2276 100644 --- a/src/resolver.c +++ b/src/resolver.c @@ -450,7 +450,7 @@ handle_response(MtmConfig *mtm_cfg, MtmMessage *raw_msg) else if (raw_msg->tag == T_Mtm2AResponse) gid = ((Mtm2AResponse *) raw_msg)->gid; else - Assert(false); + mtm_log(ERROR, "Illegal message tag %d", raw_msg->tag); mtm_log(ResolverTx, "handle_response: got '%s'", MtmMesageToString(raw_msg)); diff --git a/src/state.c b/src/state.c index 01b502b775..34496abb3a 100644 --- a/src/state.c +++ b/src/state.c @@ -3286,7 +3286,7 @@ check_status_requests(MtmConfig *mtm_cfg, bool *job_pending) txset_hash_ctl.entrysize = sizeof(txset_entry); txset_hash_ctl.hcxt = CurrentMemoryContext; txset = hash_create("txset", max_batch_size, &txset_hash_ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); while (dmq_pop_nb(&sender_mask_pos, &packed_msg, MtmGetDmqReceiversMask(), &wait)) { @@ -3729,17 +3729,20 @@ start_node_workers(int node_id, MtmConfig *new_cfg, Datum arg) if (!MtmNodeById(new_cfg, node_id)->init_done) { + ReplicationSlot *s; + /* * Create filter slot to filter out already applied changes since the * last syncpoint during replication start */ /* slot might be already created if we failed before setting init_done */ - int acq = ReplicationSlotAcquire(filter_slot, SAB_Inquire); - if (acq == 0) - ReplicationSlotRelease(); - else if (acq == -1) + + s = SearchNamedReplicationSlot(filter_slot, true); + if (s == NULL) { - ReplicationSlotCreate(filter_slot, false, RS_PERSISTENT); + bool two_phase = true; + + ReplicationSlotCreate(filter_slot, false, RS_PERSISTENT, two_phase); ReplicationSlotReserveWal(); /* Write this slot to disk */ ReplicationSlotMarkDirty(); @@ -3776,17 +3779,18 @@ start_node_workers(int node_id, MtmConfig *new_cfg, Datum arg) if (!MtmNodeById(new_cfg, node_id)->init_done) { + ReplicationSlot *s; char *query; int rc; /* Create logical slot for our publication to this neighbour */ /* slot might be already created if we failed before setting init_done */ - int acq = ReplicationSlotAcquire(slot, SAB_Inquire); - if (acq == 0) - ReplicationSlotRelease(); - else if (acq == -1) - { - ReplicationSlotCreate(slot, true, RS_EPHEMERAL); + + s = SearchNamedReplicationSlot(slot, true); + if (s == NULL) { + bool two_phase = true; + + ReplicationSlotCreate(slot, true, RS_EPHEMERAL, two_phase); ctx = CreateInitDecodingContext(MULTIMASTER_NAME, NIL, false, /* do not build snapshot */ InvalidXLogRecPtr, @@ -3874,7 +3878,7 @@ stop_node_workers(int node_id, MtmConfig *new_cfg, Datum arg) ReplicationSlotDrop(filter_slot_name, true); /* delete replication origin, was acquired by receiver */ - replorigin_drop(replorigin_by_name(logical_slot, false), true); + replorigin_by_name(logical_slot, false); /* * Delete logical slot. It is aquired by walsender, so call with nowait = @@ -4414,7 +4418,7 @@ mtm_get_logged_prepared_xact_state(PG_FUNCTION_ARGS) txset_hash_ctl.entrysize = sizeof(txset_entry); txset_hash_ctl.hcxt = CurrentMemoryContext; txset = hash_create("txset", 1, &txset_hash_ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_CONTEXT | HASH_STRINGS); txse = hash_search(txset, gid, HASH_ENTER, NULL); txse->resp.state.status = GTXInvalid; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy