diff options
author | Pavan Deolasee | 2016-10-25 08:44:12 +0000 |
---|---|---|
committer | Pavan Deolasee | 2016-10-26 05:24:00 +0000 |
commit | 8895fa07ba93b7b36e618b8f7e40dc81dc3bc37e (patch) | |
tree | d14b3799225403d55cebe10a5bcfb6a6098e5e1c | |
parent | 85b492b8e1cc0a668f3abcd33ab51df8f5e14bbb (diff) |
Fix a few regression test failures post cherry picking of patches.
20 files changed, 421 insertions, 543 deletions
diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out index 652687f2e4..dc76957a49 100644 --- a/src/test/regress/expected/brin.out +++ b/src/test/regress/expected/brin.out @@ -645,10 +645,10 @@ WARNING: did not get bitmap indexscan plan for (int4col,<=,int8,1999,100) WARNING: did not get seqscan plan for (int4col,<=,int8,1999,100) WARNING: did not get bitmap indexscan plan for (int4col,<,int8,1428427143,100) WARNING: did not get seqscan plan for (int4col,<,int8,1428427143,100) -WARNING: did not get bitmap indexscan plan for (textcol,>,text,ABABAB,100) -WARNING: did not get seqscan plan for (textcol,>,text,ABABAB,100) -WARNING: did not get bitmap indexscan plan for (textcol,>=,text,ABABAB,100) -WARNING: did not get seqscan plan for (textcol,>=,text,ABABAB,100) +WARNING: did not get bitmap indexscan plan for (textcol,>,text,AAAAAA,100) +WARNING: did not get seqscan plan for (textcol,>,text,AAAAAA,100) +WARNING: did not get bitmap indexscan plan for (textcol,>=,text,AAAAAA,100) +WARNING: did not get seqscan plan for (textcol,>=,text,AAAAAA,100) WARNING: did not get bitmap indexscan plan for (textcol,=,text,BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA,1) WARNING: did not get seqscan plan for (textcol,=,text,BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA,1) WARNING: did not get bitmap indexscan plan for (textcol,<=,text,ZZAAAA,100) diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out index a1e3728fb7..4ebb5a3c70 100644 --- a/src/test/regress/expected/create_view.out +++ b/src/test/regress/expected/create_view.out @@ -1503,6 +1503,34 @@ explain (costs off) select * from tt18v; -> Seq Scan on int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1 (4 rows) +-- check display of ScalarArrayOp with a sub-select +select 'foo'::text = any(array['abc','def','foo']::text[]); + ?column? +---------- + t +(1 row) + +select 'foo'::text = any((select array['abc','def','foo']::text[])); -- fail +ERROR: operator does not exist: text = text[] +LINE 1: select 'foo'::text = any((select array['abc','def','foo']::t... + ^ +HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +select 'foo'::text = any((select array['abc','def','foo']::text[])::text[]); + ?column? +---------- + t +(1 row) + +create view tt19v as +select 'foo'::text = any(array['abc','def','foo']::text[]) c1, + 'foo'::text = any((select array['abc','def','foo']::text[])::text[]) c2; +select pg_get_viewdef('tt19v', true); + pg_get_viewdef +---------------------------------------------------------------------------------------------------- + SELECT 'foo'::text = ANY (ARRAY['abc'::text, 'def'::text, 'foo'::text]) AS c1, + + 'foo'::text = ANY ((( SELECT ARRAY['abc'::text, 'def'::text, 'foo'::text] AS "array"))) AS c2; +(1 row) + -- clean up all the random objects we made above set client_min_messages = warning; DROP SCHEMA temp_view_test CASCADE; diff --git a/src/test/regress/expected/foreign_data_1.out b/src/test/regress/expected/foreign_data_1.out index 5575f590c8..541b058c96 100644 --- a/src/test/regress/expected/foreign_data_1.out +++ b/src/test/regress/expected/foreign_data_1.out @@ -1411,15 +1411,15 @@ DROP FOREIGN TABLE IF EXISTS no_table; NOTICE: foreign table "no_table" does not exist, skipping DROP FOREIGN TABLE foreign_schema.foreign_table_1; ERROR: foreign table "foreign_table_1" does not exist --- REASSIGN OWNED/DROP OWNED of foreign objects -REASSIGN OWNED BY regress_test_role TO regress_test_role2; -DROP OWNED BY regress_test_role2; -DROP OWNED BY regress_test_role2 CASCADE; -- Cleanup DROP SCHEMA foreign_schema CASCADE; DROP ROLE regress_test_role; -- ERROR +DROP SERVER s5 CASCADE; +ERROR: server "s5" does not exist DROP SERVER t1 CASCADE; ERROR: server "t1" does not exist +DROP SERVER t2; +ERROR: server "t2" does not exist DROP USER MAPPING FOR regress_test_role SERVER s6; ERROR: role "regress_test_role" does not exist -- This test causes some order dependent cascade detail output, diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index 8bf5c42df5..f2ff91d898 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -63,7 +63,7 @@ select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)); -- Also test an index-only knn-search explain (costs off) select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) -order by p <-> point(0.201, 0.201); +order by p <-> point(0.2, 0.2); QUERY PLAN -------------------------------------------------------------- Remote Subquery Scan on all (datanode_1,datanode_2) @@ -92,7 +92,7 @@ order by p <-> point(0.2, 0.2); -- Check commuted case as well explain (costs off) select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) -order by point(0.101, 0.101) <-> p; +order by point(0.1, 0.1) <-> p; QUERY PLAN -------------------------------------------------------------- Remote Subquery Scan on all (datanode_1,datanode_2) diff --git a/src/test/regress/expected/groupingsets.out b/src/test/regress/expected/groupingsets.out index 0cb9dea220..84e0ba4259 100644 --- a/src/test/regress/expected/groupingsets.out +++ b/src/test/regress/expected/groupingsets.out @@ -198,6 +198,39 @@ select ten, sum(distinct four) from onek a group by grouping sets((ten,four),(ten)) having exists (select 1 from onek b where sum(distinct a.four) = b.four); ERROR: GROUPING SETS, ROLLUP or CUBE is not yet supported +-- Tests around pushdown of HAVING clauses, partially testing against previous bugs +select a,count(*) from gstest2 group by rollup(a) order by a; +ERROR: GROUPING SETS, ROLLUP or CUBE is not yet supported +select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; +ERROR: GROUPING SETS, ROLLUP or CUBE is not yet supported +explain (costs off) + select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; +ERROR: GROUPING SETS, ROLLUP or CUBE is not yet supported +select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c; + c | count +---+------- + f | + t | 9 +(2 rows) + +explain (costs off) + select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c; + QUERY PLAN +------------------------------------------------------------------------- + Sort + Sort Key: "*VALUES*".column1 + -> Values Scan on "*VALUES*" + SubPlan 1 + -> Aggregate + Group Key: () + Filter: "*VALUES*".column1 + -> Remote Subquery Scan on all (datanode_1,datanode_2) + -> Aggregate + -> Seq Scan on gstest2 +(10 rows) + -- HAVING with GROUPING queries select ten, grouping(ten) from onek group by grouping sets(ten) having grouping(ten) >= 0 diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out index 4a4c2ea4b1..71e3cda8aa 100644 --- a/src/test/regress/expected/insert_conflict.out +++ b/src/test/regress/expected/insert_conflict.out @@ -404,64 +404,6 @@ ERROR: there is no unique or exclusion constraint matching the ON CONFLICT spec insert into insertconflicttest values (23, 'Blackberry') on conflict (fruit) where fruit like '%berry' do update set fruit = excluded.fruit; ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification drop index partial_key_index; --- --- Test that wholerow references to ON CONFLICT's EXCLUDED work --- -create unique index plain on insertconflicttest(key); --- Succeeds, updates existing row: -insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit - where i.* != excluded.* returning *; - key | fruit ------+----------- - 23 | Jackfruit -(1 row) - --- No update this time, though: -insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit - where i.* != excluded.* returning *; - key | fruit ------+------- -(0 rows) - --- Predicate changed to require match rather than non-match, so updates once more: -insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit - where i.* = excluded.* returning *; - key | fruit ------+----------- - 23 | Jackfruit -(1 row) - --- Assign: -insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text - returning *; - key | fruit ------+-------------- - 23 | (23,Avocado) -(1 row) - --- deparse whole row var in WHERE and SET clauses: -explain (costs off) insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.fruit where excluded.* is null; - QUERY PLAN ------------------------------------------------ - Remote Subquery Scan on all (datanode_1) - -> Insert on insertconflicttest i - Conflict Resolution: UPDATE - Conflict Arbiter Indexes: plain - Conflict Filter: (excluded.* IS NULL) - -> Result -(6 rows) - -explain (costs off) insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text; - QUERY PLAN ------------------------------------------- - Remote Subquery Scan on all (datanode_1) - -> Insert on insertconflicttest i - Conflict Resolution: UPDATE - Conflict Arbiter Indexes: plain - -> Result -(5 rows) - -drop index plain; -- Cleanup drop table insertconflicttest; -- ****************************************************************** diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out index 751815c517..3942c3bee9 100644 --- a/src/test/regress/expected/json.out +++ b/src/test/regress/expected/json.out @@ -474,18 +474,6 @@ SELECT json_agg(q) {"x":3,"y":"txt3"}] (1 row) -UPDATE rows SET x = NULL WHERE x = 1; -ERROR: could not plan this distributed update -DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. -SELECT json_agg(q ORDER BY x NULLS FIRST, y) - FROM rows q; - json_agg ------------------------ - [{"x":1,"y":"txt1"}, + - {"x":2,"y":"txt2"}, + - {"x":3,"y":"txt3"}] -(1 row) - -- non-numeric output SELECT row_to_json(q) FROM (SELECT 'NaN'::float8 AS "float8field") q; diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out index 3ef40f821e..171520275d 100644 --- a/src/test/regress/expected/jsonb.out +++ b/src/test/regress/expected/jsonb.out @@ -376,16 +376,6 @@ SELECT jsonb_agg(q) [{"x": 1, "y": "txt1"}, {"x": 2, "y": "txt2"}, {"x": 3, "y": "txt3"}] (1 row) -UPDATE rows SET x = NULL WHERE x = 1; -ERROR: could not plan this distributed update -DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. -SELECT jsonb_agg(q ORDER BY x NULLS FIRST, y) - FROM rows q; - jsonb_agg ------------------------------------------------------------------------ - [{"x": 1, "y": "txt1"}, {"x": 2, "y": "txt2"}, {"x": 3, "y": "txt3"}] -(1 row) - -- jsonb extraction functions CREATE TEMP TABLE test_jsonb ( json_type text, diff --git a/src/test/regress/expected/plpgsql_1.out b/src/test/regress/expected/plpgsql_1.out index 45936927e3..a337e4a440 100644 --- a/src/test/regress/expected/plpgsql_1.out +++ b/src/test/regress/expected/plpgsql_1.out @@ -2036,7 +2036,7 @@ select trap_matching_test(1); ERROR: Internal subtransactions not supported in Postgres-XL CONTEXT: PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry create temp table foo (f1 int); -create function subxact_rollback_semantics() returns int as $$ +create function blockme() returns int as $$ declare x int; begin x := 1; @@ -2044,46 +2044,31 @@ begin begin x := x + 1; insert into foo values(x); - raise exception 'inner'; + -- we assume this will take longer than 2 seconds: + select count(*) into x from tenk1 a, tenk1 b, tenk1 c; exception when others then + raise notice 'caught others?'; + return -1; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; x := x * 10; end; insert into foo values(x); return x; end$$ language plpgsql; -select subxact_rollback_semantics(); +set statement_timeout to 2000; +select blockme(); ERROR: Internal subtransactions not supported in Postgres-XL -CONTEXT: PL/pgSQL function subxact_rollback_semantics() line 6 during statement block entry -select * from foo; +CONTEXT: PL/pgSQL function blockme() line 6 during statement block entry +reset statement_timeout; +select * from foo order by 1; f1 ---- 1 (1 row) drop table foo; -create function trap_timeout() returns void as $$ -begin - declare x int; - begin - -- we assume this will take longer than 2 seconds: - select count(*) into x from tenk1 a, tenk1 b, tenk1 c; - exception - when others then - raise notice 'caught others?'; - when query_canceled then - raise notice 'nyeah nyeah, can''t stop me'; - end; - -- Abort transaction to abandon the statement_timeout setting. Otherwise, - -- the next top-level statement would be vulnerable to the timeout. - raise exception 'end of function'; -end$$ language plpgsql; -begin; -set statement_timeout to 2000; -select trap_timeout(); -ERROR: Internal subtransactions not supported in Postgres-XL -CONTEXT: PL/pgSQL function trap_timeout() line 4 during statement block entry -rollback; -- Test for pass-by-ref values being stored in proper context create function test_variable_storage() returns text as $$ declare x text; @@ -3109,7 +3094,7 @@ begin end$$ language plpgsql; select footest(); ERROR: query returned no rows -CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE +CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE statement create or replace function footest() returns void as $$ declare x record; begin @@ -3119,7 +3104,7 @@ begin end$$ language plpgsql; select footest(); ERROR: query returned more than one row -CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE +CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE statement drop function footest(); -- test printing parameters after failure due to STRICT set plpgsql.print_strict_params to true; @@ -3171,7 +3156,7 @@ end$$ language plpgsql; select footest(); ERROR: query returned no rows DETAIL: parameters: $1 = '0', $2 = 'foo' -CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE +CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE statement create or replace function footest() returns void as $$ declare x record; begin @@ -3182,7 +3167,7 @@ end$$ language plpgsql; select footest(); ERROR: query returned more than one row DETAIL: parameters: $1 = '1' -CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE +CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE statement create or replace function footest() returns void as $$ declare x record; begin @@ -3192,7 +3177,7 @@ begin end$$ language plpgsql; select footest(); ERROR: query returned more than one row -CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE +CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE statement create or replace function footest() returns void as $$ -- override the global #print_strict_params off @@ -4184,7 +4169,7 @@ end; $$ language plpgsql; select stacked_diagnostics_test(); ERROR: GET STACKED DIAGNOSTICS cannot be used outside an exception handler -CONTEXT: PL/pgSQL function stacked_diagnostics_test() line 6 at GET STACKED DIAGNOSTICS +CONTEXT: PL/pgSQL function stacked_diagnostics_test() line 6 at GET DIAGNOSTICS drop function zero_divide(); drop function stacked_diagnostics_test(); -- check cases where implicit SQLSTATE variable could be confused with @@ -4628,63 +4613,6 @@ ERROR: current transaction is aborted, commands ignored until end of transactio rollback; drop function error2(p_name_table text); drop function error1(text); --- Test for proper handling of cast-expression caching -create function sql_to_date(integer) returns date as $$ -select $1::text::date -$$ language sql immutable strict; -create cast (integer as date) with function sql_to_date(integer) as assignment; -create function cast_invoker(integer) returns date as $$ -begin - return $1; -end$$ language plpgsql; -select cast_invoker(20150717); - cast_invoker --------------- - 07-17-2015 -(1 row) - -select cast_invoker(20150718); -- second call crashed in pre-release 9.5 - cast_invoker --------------- - 07-18-2015 -(1 row) - -begin; -select cast_invoker(20150717); - cast_invoker --------------- - 07-17-2015 -(1 row) - -select cast_invoker(20150718); - cast_invoker --------------- - 07-18-2015 -(1 row) - -savepoint s1; -ERROR: SAVEPOINT is not yet supported. -select cast_invoker(20150718); -ERROR: current transaction is aborted, commands ignored until end of transaction block -select cast_invoker(-1); -- fails -ERROR: current transaction is aborted, commands ignored until end of transaction block -rollback to savepoint s1; -ERROR: no such savepoint -select cast_invoker(20150719); -ERROR: current transaction is aborted, commands ignored until end of transaction block -select cast_invoker(20150720); -ERROR: current transaction is aborted, commands ignored until end of transaction block -commit; -drop function cast_invoker(integer); -drop function sql_to_date(integer) cascade; -NOTICE: drop cascades to cast from integer to date --- Test handling of cast cache inside DO blocks --- (to check the original crash case, this must be a cast not previously --- used in this session) -begin; -do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$; -do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$; -end; -- Test for consistent reporting of error context create function fail() returns int language plpgsql as $$ begin diff --git a/src/test/regress/expected/prepared_xacts_2.out b/src/test/regress/expected/prepared_xacts_2.out index ce5a30c2eb..31c9501cf3 100644 --- a/src/test/regress/expected/prepared_xacts_2.out +++ b/src/test/regress/expected/prepared_xacts_2.out @@ -229,11 +229,10 @@ SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1; (1 row) -- pxtest3 should be locked because of the pending DROP -begin; set statement_timeout to 2000; SELECT * FROM pxtest3; ERROR: canceling statement due to statement timeout -rollback; +reset statement_timeout; -- Disconnect, we will continue testing in a different backend \c - -- There should still be two prepared transactions @@ -251,11 +250,10 @@ SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1; (1 row) -- pxtest3 should still be locked because of the pending DROP -begin; set statement_timeout to 2000; SELECT * FROM pxtest3; ERROR: canceling statement due to statement timeout -rollback; +reset statement_timeout; -- Commit table creation COMMIT PREPARED 'regress-one'; ERROR: prepared transaction with identifier "regress-one" does not exist diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index b1788dd4dc..7ac57e1f53 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2077,7 +2077,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem | JOIN pg_class c ON ((c.oid = s.starelid))) + | JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) + | LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) + - | WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid)))); + | WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text)); pg_tables | SELECT n.nspname AS schemaname, + | c.relname AS tablename, + | pg_get_userbyid(c.relowner) AS tableowner, + @@ -3930,13 +3930,13 @@ SELECT tablename, rulename, definition FROM pg_rules -- ensure explain works for on insert conflict rules explain (costs off) INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING *; - QUERY PLAN -------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Remote Subquery Scan on all (datanode_1) -> Insert on hat_data Conflict Resolution: UPDATE Conflict Arbiter Indexes: hat_data_unique_idx - Conflict Filter: ((excluded.hat_color <> 'forbidden'::bpchar) AND (hat_data.* <> excluded.*)) + Conflict Filter: (excluded.hat_color <> 'forbidden'::bpchar) -> Result (6 rows) @@ -3958,13 +3958,13 @@ EXPLAIN (nodes off, costs off) WITH data(hat_name, hat_color) AS ( INSERT INTO hats SELECT * FROM data RETURNING *; - QUERY PLAN -------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Remote Subquery Scan on all -> Insert on hat_data Conflict Resolution: UPDATE Conflict Arbiter Indexes: hat_data_unique_idx - Conflict Filter: ((excluded.hat_color <> 'forbidden'::bpchar) AND (hat_data.* <> excluded.*)) + Conflict Filter: (excluded.hat_color <> 'forbidden'::bpchar) CTE data -> Values Scan on "*VALUES*" -> Remote Subquery Scan on all diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out index cc2ebdf5a1..bb126edfdb 100644 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@ -1699,7 +1699,7 @@ ERROR: Postgres-XL does not support TRIGGER yet DETAIL: The feature is not currently supported CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b WITH CHECK OPTION; INSERT INTO rw_view1 VALUES (5,0); -- ok -ERROR: new row violates check option for view "rw_view1" +ERROR: new row violates WITH CHECK OPTION for "rw_view1" DETAIL: Failing row contains (5, 0). INSERT INTO rw_view1 VALUES (15, 20); -- should fail UPDATE rw_view1 SET a = 20, b = 30; -- should fail @@ -1734,7 +1734,7 @@ DETAIL: The feature is not currently supported CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a > 0 WITH LOCAL CHECK OPTION; INSERT INTO rw_view2 VALUES (-5); -- should fail -ERROR: new row violates check option for view "rw_view2" +ERROR: new row violates WITH CHECK OPTION for "rw_view2" DETAIL: Failing row contains (-5, null). INSERT INTO rw_view2 VALUES (5); -- ok INSERT INTO rw_view2 VALUES (50); -- ok, but not in view @@ -1749,7 +1749,7 @@ SELECT * FROM base_tbl; -- Check option won't cascade down to base view with INSTEAD OF triggers ALTER VIEW rw_view2 SET (check_option=cascaded); INSERT INTO rw_view2 VALUES (100); -- ok, but not in view (doesn't fail rw_view1's check) -ERROR: new row violates check option for view "rw_view1" +ERROR: new row violates WITH CHECK OPTION for "rw_view1" DETAIL: Failing row contains (100, null). UPDATE rw_view2 SET a = 200 WHERE a = 5; -- ok, but not in view (doesn't fail rw_view1's check) SELECT * FROM base_tbl; diff --git a/src/test/regress/output/largeobject_3.source b/src/test/regress/output/largeobject_3.source index 18e22769d2..c2bd3f6a4b 100644 --- a/src/test/regress/output/largeobject_3.source +++ b/src/test/regress/output/largeobject_3.source @@ -20,7 +20,7 @@ DO $$ END $$; ERROR: query string argument of EXECUTE is null -CONTEXT: PL/pgSQL function inline_code_block line 3 at EXECUTE +CONTEXT: PL/pgSQL function inline_code_block line 3 at EXECUTE statement SELECT rol.rolname FROM diff --git a/src/test/regress/output/misc_1.source b/src/test/regress/output/misc_1.source index 23ed7b3ea2..9df04295f1 100644 --- a/src/test/regress/output/misc_1.source +++ b/src/test/regress/output/misc_1.source @@ -450,353 +450,87 @@ SELECT class, aa, a FROM a_star* ORDER BY 1,2; -- -- versions -- --- --- postquel functions --- --- --- mike does post_hacking, --- joe and sally play basketball, and --- everyone else does nothing. --- -SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2; - name | name --------+------------- - joe | basketball - mike | posthacking - sally | basketball -(3 rows) - --- --- as above, but jeff also does post_hacking. --- -SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2; - name | name --------+------------- - jeff | posthacking - joe | basketball - mike | posthacking - sally | basketball -(4 rows) - --- --- the next two queries demonstrate how functions generate bogus duplicates. --- this is a "feature" .. --- -SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r - ORDER BY 1,2; - name | name --------------+--------------- - basketball | hightops - posthacking | advil - posthacking | peet's coffee - skywalking | guts -(4 rows) - -SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2; - name | name --------------+--------------- - basketball | hightops - basketball | hightops - posthacking | advil - posthacking | advil - posthacking | peet's coffee - posthacking | peet's coffee - skywalking | guts -(7 rows) - --- --- mike needs advil and peet's coffee, --- joe and sally need hightops, and --- everyone else is fine. --- -SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3; - name | name | name --------+-------------+--------------- - joe | basketball | hightops - mike | posthacking | advil - mike | posthacking | peet's coffee - sally | basketball | hightops -(4 rows) - --- --- as above, but jeff needs advil and peet's coffee as well. --- -SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3; - name | name | name --------+-------------+--------------- - jeff | posthacking | advil - jeff | posthacking | peet's coffee - joe | basketball | hightops - mike | posthacking | advil - mike | posthacking | peet's coffee - sally | basketball | hightops -(6 rows) - --- --- just like the last two, but make sure that the target list fixup and --- unflattening is being done correctly. --- -SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3; - name | name | name ----------------+-------+------------- - advil | mike | posthacking - hightops | joe | basketball - hightops | sally | basketball - peet's coffee | mike | posthacking -(4 rows) - -SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3; - name | name | name ----------------+-------+------------- - advil | jeff | posthacking - advil | mike | posthacking - hightops | joe | basketball - hightops | sally | basketball - peet's coffee | jeff | posthacking - peet's coffee | mike | posthacking -(6 rows) - -SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3; - name | name | name ----------------+-------------+------- - advil | posthacking | mike - hightops | basketball | joe - hightops | basketball | sally - peet's coffee | posthacking | mike -(4 rows) - -SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3; - name | name | name ----------------+-------------+------- - advil | posthacking | jeff - advil | posthacking | mike - hightops | basketball | joe - hightops | basketball | sally - peet's coffee | posthacking | jeff - peet's coffee | posthacking | mike -(6 rows) - -SELECT user_relns() AS user_relns - ORDER BY user_relns; - user_relns ---------------------- - a - a_star - abstime_tbl - aggtest - aggtype - array_index_op_test - array_op_test - arrtest - b - b_star - box_tbl - bprime - bt_f8_heap - bt_i4_heap - bt_name_heap - bt_txt_heap - c - c_star - char_tbl - check2_tbl - check_seq - check_tbl - circle_tbl - city - copy_tbl - d - d_star - date_tbl - default_seq - default_tbl - defaultexpr_tbl - dept - dupindexcols - e_star - emp - equipment_r - f_star - fast_emp4000 - float4_tbl - float8_tbl - foobar - func_index_heap - hash_f8_heap - hash_i4_heap - hash_name_heap - hash_txt_heap - hobbies_r - iexit - ihighway - inet_tbl - inhf - inhx - insert_seq - insert_tbl - int2_tbl - int4_tbl - int8_tbl - interval_tbl - iportaltest - kd_point_tbl - log_table - lseg_tbl - main_table - money_data - num_data - num_exp_add - num_exp_div - num_exp_ln - num_exp_log10 - num_exp_mul - num_exp_power_10_ln - num_exp_sqrt - num_exp_sub - num_input_test - num_result - onek - onek2 - path_tbl - person - point_tbl - polygon_tbl - quad_point_tbl - ramp - random_tbl - real_city - reltime_tbl - road - shighway - slow_emp4000 - street - stud_emp - student - subselect_tbl - suffix_text_tbl - tenk1 - tenk2 - test_range_excl - test_range_gist - test_tsvector - text_tbl - time_tbl - timestamp_tbl - timestamptz_tbl - timetz_tbl - tinterval_tbl - toyemp - varchar_tbl - xacttest -(108 rows) - -SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_2a(text 'skywalking')); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1; - name ---------------- - advil - guts - hightops - peet's coffee -(4 rows) - -SELECT hobbies_by_name('basketball'); - hobbies_by_name ------------------ - joe -(1 row) - -SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2; - name | overpaid ---------+---------- - bill | t - cim | f - jeff | f - linda | f - sam | t - sharon | t -(6 rows) - --- --- Try a few cases with SQL-spec row constructor expressions --- -SELECT * FROM equipment(ROW('skywalking', 'mer')); - name | hobby -------+------------ - guts | skywalking -(1 row) - -SELECT name(equipment(ROW('skywalking', 'mer'))); - name ------- - guts -(1 row) - -SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3; - name | person | name --------------+--------+--------------- - basketball | joe | hightops - basketball | sally | hightops - posthacking | jeff | advil - posthacking | jeff | peet's coffee - posthacking | mike | advil - posthacking | mike | peet's coffee - skywalking | | guts -(7 rows) - -SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3; - name | person | name --------------+--------+--------------- - basketball | joe | hightops - basketball | sally | hightops - posthacking | jeff | advil - posthacking | jeff | peet's coffee - posthacking | mike | advil - posthacking | mike | peet's coffee - skywalking | | guts -(7 rows) - +-- -- +-- -- postquel functions +-- -- +-- -- +-- -- mike does post_hacking, +-- -- joe and sally play basketball, and +-- -- everyone else does nothing. +-- -- +-- SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2; +-- +-- -- +-- -- as above, but jeff also does post_hacking. +-- -- +-- SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2; +-- +-- -- +-- -- the next two queries demonstrate how functions generate bogus duplicates. +-- -- this is a "feature" .. +-- -- +-- SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r +-- ORDER BY 1,2; +-- +-- SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2; +-- +-- -- +-- -- mike needs advil and peet's coffee, +-- -- joe and sally need hightops, and +-- -- everyone else is fine. +-- -- +-- SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3; +-- +-- -- +-- -- as above, but jeff needs advil and peet's coffee as well. +-- -- +-- SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3; +-- +-- -- +-- -- just like the last two, but make sure that the target list fixup and +-- -- unflattening is being done correctly. +-- -- +-- SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3; +-- +-- SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3; +-- +-- SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3; +-- +-- SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3; +-- +-- SELECT user_relns() AS user_relns +-- ORDER BY user_relns; +-- +-- SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))); +-- +-- SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer'))); +-- +-- SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer'))); +-- +-- SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer'))); +-- +-- SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer'))); +-- +-- SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer'))); +-- +-- SELECT name(equipment_named_ambiguous_2a(text 'skywalking')); +-- +-- SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1; +-- +-- SELECT hobbies_by_name('basketball'); +-- +-- SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2; +-- +-- -- +-- -- Try a few cases with SQL-spec row constructor expressions +-- -- +-- SELECT * FROM equipment(ROW('skywalking', 'mer')); +-- +-- SELECT name(equipment(ROW('skywalking', 'mer'))); +-- +-- SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3; +-- +-- SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3; -- -- check that old-style C functions work properly with TOASTed values -- diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 38ae7294d1..2e0e134b6f 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -100,7 +100,7 @@ test: rules # ---------- # Another group of parallel tests # ---------- -test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps json jsonb json_encoding indirect_toast equivclass +test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps json jsonb indirect_toast equivclass # ---------- # As XL uses advisory locks internally running this test separately. diff --git a/src/test/regress/sql/create_view.sql b/src/test/regress/sql/create_view.sql index 94094c423a..cc0ab6125d 100644 --- a/src/test/regress/sql/create_view.sql +++ b/src/test/regress/sql/create_view.sql @@ -469,6 +469,44 @@ alter table tt14t drop column f3; select pg_get_viewdef('tt14v', true); select * from tt14v; +-- check display of whole-row variables in some corner cases + +create type nestedcomposite as (x int8_tbl); +create view tt15v as select row(i)::nestedcomposite from int8_tbl i; +select * from tt15v; +select pg_get_viewdef('tt15v', true); +select row(i.*::int8_tbl)::nestedcomposite from int8_tbl i; + +create view tt16v as select * from int8_tbl i, lateral(values(i)) ss; +select * from tt16v; +select pg_get_viewdef('tt16v', true); +select * from int8_tbl i, lateral(values(i.*::int8_tbl)) ss; + +create view tt17v as select * from int8_tbl i where i in (values(i)); +select * from tt17v; +select pg_get_viewdef('tt17v', true); +select * from int8_tbl i where i.* in (values(i.*::int8_tbl)); + +-- check unique-ification of overlength names + +create view tt18v as + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy + union all + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz; +select pg_get_viewdef('tt18v', true); +explain (costs off) select * from tt18v; + +-- check display of ScalarArrayOp with a sub-select + +select 'foo'::text = any(array['abc','def','foo']::text[]); +select 'foo'::text = any((select array['abc','def','foo']::text[])); -- fail +select 'foo'::text = any((select array['abc','def','foo']::text[])::text[]); + +create view tt19v as +select 'foo'::text = any(array['abc','def','foo']::text[]) c1, + 'foo'::text = any((select array['abc','def','foo']::text[])::text[]) c2; +select pg_get_viewdef('tt19v', true); + -- clean up all the random objects we made above set client_min_messages = warning; DROP SCHEMA temp_view_test CASCADE; diff --git a/src/test/regress/sql/groupingsets.sql b/src/test/regress/sql/groupingsets.sql index 0bffb8531c..71cc0ec900 100644 --- a/src/test/regress/sql/groupingsets.sql +++ b/src/test/regress/sql/groupingsets.sql @@ -73,6 +73,35 @@ select grouping(a), a, array_agg(b), select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum from gstest2 group by rollup (a,b) order by rsum, a, b; +-- nesting with grouping sets +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(()))) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(((a, b))))) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets(grouping sets(rollup(c), grouping sets(cube(c)))) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets(a, grouping sets(a, cube(b))) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, (b)))) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, b))) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a), a)) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a, grouping sets(a), ((a)), a, grouping sets(a), (a)), a)) + order by 1 desc; +select sum(c) from gstest2 + group by grouping sets((a,(a,b)), grouping sets((a,(a,b)),a)) + order by 1 desc; + -- empty input: first is 0 rows, second 1, third 3 etc. select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a); select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()); @@ -154,6 +183,35 @@ select ten, sum(distinct four) from onek a group by grouping sets((ten,four),(ten)) having exists (select 1 from onek b where sum(distinct a.four) = b.four); +-- Tests around pushdown of HAVING clauses, partially testing against previous bugs +select a,count(*) from gstest2 group by rollup(a) order by a; +select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; +explain (costs off) + select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; + +select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c; +explain (costs off) + select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c; + +-- HAVING with GROUPING queries +select ten, grouping(ten) from onek +group by grouping sets(ten) having grouping(ten) >= 0 +order by 2,1; +select ten, grouping(ten) from onek +group by grouping sets(ten, four) having grouping(ten) > 0 +order by 2,1; +select ten, grouping(ten) from onek +group by rollup(ten) having grouping(ten) > 0 +order by 2,1; +select ten, grouping(ten) from onek +group by cube(ten) having grouping(ten) > 0 +order by 2,1; +select ten, grouping(ten) from onek +group by (ten) having grouping(ten) >= 0 +order by 2,1; + -- FILTER queries select ten, sum(distinct four) filter (where four::text ~ '123') from onek a group by rollup(ten); @@ -162,4 +220,8 @@ group by rollup(ten); select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by cube(four,ten)) s on true order by v.a,four,ten; select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by cube(two,four) order by two,four) s1) from (values (1),(2)) v(a); +-- Grouping on text columns +select sum(ten) from onek group by two, rollup(four::text) order by 1; +select sum(ten) from onek group by rollup(four::text), two order by 1; + -- end diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql index 7329bedee4..994a7e1646 100644 --- a/src/test/regress/sql/inherit.sql +++ b/src/test/regress/sql/inherit.sql @@ -473,6 +473,27 @@ reset enable_seqscan; drop table matest0 cascade; -- +-- Check that use of an index with an extraneous column doesn't produce +-- a plan with extraneous sorting +-- + +create table matest0 (a int, b int, c int, d int); +create table matest1 () inherits(matest0); +create index matest0i on matest0 (b, c); +create index matest1i on matest1 (b, c); + +set enable_nestloop = off; -- we want a plan with two MergeAppends + +explain (costs off) +select t1.* from matest0 t1, matest0 t2 +where t1.b = t2.b and t2.c = t2.d +order by t1.b limit 10; + +reset enable_nestloop; + +drop table matest0 cascade; + +-- -- Test merge-append for UNION ALL append relations -- diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index c6b42fa9d3..2db3b94962 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -976,3 +976,87 @@ DROP USER regressuser3; DROP USER regressuser4; DROP USER regressuser5; DROP USER regressuser6; + + +-- permissions with LOCK TABLE +CREATE USER locktable_user; +CREATE TABLE lock_table (a int); + +-- LOCK TABLE and SELECT permission +GRANT SELECT ON lock_table TO locktable_user; +SET SESSION AUTHORIZATION locktable_user; +BEGIN; +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail +ROLLBACK; +BEGIN; +LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass +COMMIT; +BEGIN; +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail +ROLLBACK; +\c +REVOKE SELECT ON lock_table FROM locktable_user; + +-- LOCK TABLE and INSERT permission +GRANT INSERT ON lock_table TO locktable_user; +SET SESSION AUTHORIZATION locktable_user; +BEGIN; +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass +COMMIT; +BEGIN; +LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail +ROLLBACK; +BEGIN; +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail +ROLLBACK; +\c +REVOKE INSERT ON lock_table FROM locktable_user; + +-- LOCK TABLE and UPDATE permission +GRANT UPDATE ON lock_table TO locktable_user; +SET SESSION AUTHORIZATION locktable_user; +BEGIN; +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass +COMMIT; +BEGIN; +LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail +ROLLBACK; +BEGIN; +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass +COMMIT; +\c +REVOKE UPDATE ON lock_table FROM locktable_user; + +-- LOCK TABLE and DELETE permission +GRANT DELETE ON lock_table TO locktable_user; +SET SESSION AUTHORIZATION locktable_user; +BEGIN; +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass +COMMIT; +BEGIN; +LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail +ROLLBACK; +BEGIN; +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass +COMMIT; +\c +REVOKE DELETE ON lock_table FROM locktable_user; + +-- LOCK TABLE and TRUNCATE permission +GRANT TRUNCATE ON lock_table TO locktable_user; +SET SESSION AUTHORIZATION locktable_user; +BEGIN; +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass +COMMIT; +BEGIN; +LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail +ROLLBACK; +BEGIN; +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass +COMMIT; +\c +REVOKE TRUNCATE ON lock_table FROM locktable_user; + +-- clean up +DROP TABLE lock_table; +DROP USER locktable_user; diff --git a/src/test/regress/sql/transactions.sql b/src/test/regress/sql/transactions.sql index d99fbf6500..6cdc986bb8 100644 --- a/src/test/regress/sql/transactions.sql +++ b/src/test/regress/sql/transactions.sql @@ -428,6 +428,38 @@ fetch from foo; abort; + +-- Test for proper cleanup after a failure in a cursor portal +-- that was created in an outer subtransaction +CREATE FUNCTION invert(x float8) RETURNS float8 LANGUAGE plpgsql AS +$$ begin return 1/x; end $$; + +CREATE FUNCTION create_temp_tab() RETURNS text +LANGUAGE plpgsql AS $$ +BEGIN + CREATE TEMP TABLE new_table (f1 float8); + -- case of interest is that we fail while holding an open + -- relcache reference to new_table + INSERT INTO new_table SELECT invert(0.0); + RETURN 'foo'; +END $$; + +BEGIN; +DECLARE ok CURSOR FOR SELECT * FROM int8_tbl; +DECLARE ctt CURSOR FOR SELECT create_temp_tab(); +FETCH ok; +SAVEPOINT s1; +FETCH ok; -- should work +FETCH ctt; -- error occurs here +ROLLBACK TO s1; +FETCH ok; -- should work +FETCH ctt; -- must be rejected +COMMIT; + +DROP FUNCTION create_temp_tab(); +DROP FUNCTION invert(x float8); + + -- Test for successful cleanup of an aborted transaction at session exit. -- THIS MUST BE THE LAST TEST IN THIS FILE. |