Commit 2cf8c7aa authored by Tom Lane's avatar Tom Lane

Clean up duplicate table and function names in regression tests.

Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.

The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm.  I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.

Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently.  I've made an
effort to make all such names more specific.

One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.

Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem.  The rest of this is just future-proofing.

Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
parent 1466bcfa
......@@ -9,40 +9,40 @@ CREATE USER regress_alter_table_user1;
--
-- add attribute
--
CREATE TABLE tmp (initial int4);
COMMENT ON TABLE tmp_wrong IS 'table comment';
ERROR: relation "tmp_wrong" does not exist
COMMENT ON TABLE tmp IS 'table comment';
COMMENT ON TABLE tmp IS NULL;
ALTER TABLE tmp ADD COLUMN xmin integer; -- fails
CREATE TABLE attmp (initial int4);
COMMENT ON TABLE attmp_wrong IS 'table comment';
ERROR: relation "attmp_wrong" does not exist
COMMENT ON TABLE attmp IS 'table comment';
COMMENT ON TABLE attmp IS NULL;
ALTER TABLE attmp ADD COLUMN xmin integer; -- fails
ERROR: column name "xmin" conflicts with a system column name
ALTER TABLE tmp ADD COLUMN a int4 default 3;
ALTER TABLE tmp ADD COLUMN b name;
ALTER TABLE tmp ADD COLUMN c text;
ALTER TABLE tmp ADD COLUMN d float8;
ALTER TABLE tmp ADD COLUMN e float4;
ALTER TABLE tmp ADD COLUMN f int2;
ALTER TABLE tmp ADD COLUMN g polygon;
ALTER TABLE tmp ADD COLUMN h abstime;
ALTER TABLE tmp ADD COLUMN i char;
ALTER TABLE tmp ADD COLUMN j abstime[];
ALTER TABLE tmp ADD COLUMN k int4;
ALTER TABLE tmp ADD COLUMN l tid;
ALTER TABLE tmp ADD COLUMN m xid;
ALTER TABLE tmp ADD COLUMN n oidvector;
--ALTER TABLE tmp ADD COLUMN o lock;
ALTER TABLE tmp ADD COLUMN p smgr;
ALTER TABLE tmp ADD COLUMN q point;
ALTER TABLE tmp ADD COLUMN r lseg;
ALTER TABLE tmp ADD COLUMN s path;
ALTER TABLE tmp ADD COLUMN t box;
ALTER TABLE tmp ADD COLUMN u tinterval;
ALTER TABLE tmp ADD COLUMN v timestamp;
ALTER TABLE tmp ADD COLUMN w interval;
ALTER TABLE tmp ADD COLUMN x float8[];
ALTER TABLE tmp ADD COLUMN y float4[];
ALTER TABLE tmp ADD COLUMN z int2[];
INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
ALTER TABLE attmp ADD COLUMN a int4 default 3;
ALTER TABLE attmp ADD COLUMN b name;
ALTER TABLE attmp ADD COLUMN c text;
ALTER TABLE attmp ADD COLUMN d float8;
ALTER TABLE attmp ADD COLUMN e float4;
ALTER TABLE attmp ADD COLUMN f int2;
ALTER TABLE attmp ADD COLUMN g polygon;
ALTER TABLE attmp ADD COLUMN h abstime;
ALTER TABLE attmp ADD COLUMN i char;
ALTER TABLE attmp ADD COLUMN j abstime[];
ALTER TABLE attmp ADD COLUMN k int4;
ALTER TABLE attmp ADD COLUMN l tid;
ALTER TABLE attmp ADD COLUMN m xid;
ALTER TABLE attmp ADD COLUMN n oidvector;
--ALTER TABLE attmp ADD COLUMN o lock;
ALTER TABLE attmp ADD COLUMN p smgr;
ALTER TABLE attmp ADD COLUMN q point;
ALTER TABLE attmp ADD COLUMN r lseg;
ALTER TABLE attmp ADD COLUMN s path;
ALTER TABLE attmp ADD COLUMN t box;
ALTER TABLE attmp ADD COLUMN u tinterval;
ALTER TABLE attmp ADD COLUMN v timestamp;
ALTER TABLE attmp ADD COLUMN w interval;
ALTER TABLE attmp ADD COLUMN x float8[];
ALTER TABLE attmp ADD COLUMN y float4[];
ALTER TABLE attmp ADD COLUMN z int2[];
INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
v, w, x, y, z)
VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}',
......@@ -50,44 +50,44 @@ INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
'1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)',
'(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]',
'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
SELECT * FROM tmp;
SELECT * FROM attmp;
initial | a | b | c | d | e | f | g | h | i | j | k | l | m | n | p | q | r | s | t | u | v | w | x | y | z
---------+---+------+------+-----+-----+---+-----------------------+------------------------------+---+------------------------------------------------------------------------------------------------+--------+-------+-----+-----------------+---------------+-----------+-----------------------+-----------------------------+---------------------+---------------------------------------------+--------------------------+------------------+-----------+-----------+-----------
| 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | Mon May 01 00:30:30 1995 PDT | c | {"Mon May 01 00:30:30 1995 PDT","Mon Aug 24 14:43:07 1992 PDT","Wed Dec 31 16:00:00 1969 PST"} | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | magnetic disk | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | ["Wed Dec 31 16:00:00 1969 PST" "infinity"] | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4}
(1 row)
DROP TABLE tmp;
DROP TABLE attmp;
-- the wolf bug - schema mods caused inconsistent row descriptors
CREATE TABLE tmp (
CREATE TABLE attmp (
initial int4
);
ALTER TABLE tmp ADD COLUMN a int4;
ALTER TABLE tmp ADD COLUMN b name;
ALTER TABLE tmp ADD COLUMN c text;
ALTER TABLE tmp ADD COLUMN d float8;
ALTER TABLE tmp ADD COLUMN e float4;
ALTER TABLE tmp ADD COLUMN f int2;
ALTER TABLE tmp ADD COLUMN g polygon;
ALTER TABLE tmp ADD COLUMN h abstime;
ALTER TABLE tmp ADD COLUMN i char;
ALTER TABLE tmp ADD COLUMN j abstime[];
ALTER TABLE tmp ADD COLUMN k int4;
ALTER TABLE tmp ADD COLUMN l tid;
ALTER TABLE tmp ADD COLUMN m xid;
ALTER TABLE tmp ADD COLUMN n oidvector;
--ALTER TABLE tmp ADD COLUMN o lock;
ALTER TABLE tmp ADD COLUMN p smgr;
ALTER TABLE tmp ADD COLUMN q point;
ALTER TABLE tmp ADD COLUMN r lseg;
ALTER TABLE tmp ADD COLUMN s path;
ALTER TABLE tmp ADD COLUMN t box;
ALTER TABLE tmp ADD COLUMN u tinterval;
ALTER TABLE tmp ADD COLUMN v timestamp;
ALTER TABLE tmp ADD COLUMN w interval;
ALTER TABLE tmp ADD COLUMN x float8[];
ALTER TABLE tmp ADD COLUMN y float4[];
ALTER TABLE tmp ADD COLUMN z int2[];
INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
ALTER TABLE attmp ADD COLUMN a int4;
ALTER TABLE attmp ADD COLUMN b name;
ALTER TABLE attmp ADD COLUMN c text;
ALTER TABLE attmp ADD COLUMN d float8;
ALTER TABLE attmp ADD COLUMN e float4;
ALTER TABLE attmp ADD COLUMN f int2;
ALTER TABLE attmp ADD COLUMN g polygon;
ALTER TABLE attmp ADD COLUMN h abstime;
ALTER TABLE attmp ADD COLUMN i char;
ALTER TABLE attmp ADD COLUMN j abstime[];
ALTER TABLE attmp ADD COLUMN k int4;
ALTER TABLE attmp ADD COLUMN l tid;
ALTER TABLE attmp ADD COLUMN m xid;
ALTER TABLE attmp ADD COLUMN n oidvector;
--ALTER TABLE attmp ADD COLUMN o lock;
ALTER TABLE attmp ADD COLUMN p smgr;
ALTER TABLE attmp ADD COLUMN q point;
ALTER TABLE attmp ADD COLUMN r lseg;
ALTER TABLE attmp ADD COLUMN s path;
ALTER TABLE attmp ADD COLUMN t box;
ALTER TABLE attmp ADD COLUMN u tinterval;
ALTER TABLE attmp ADD COLUMN v timestamp;
ALTER TABLE attmp ADD COLUMN w interval;
ALTER TABLE attmp ADD COLUMN x float8[];
ALTER TABLE attmp ADD COLUMN y float4[];
ALTER TABLE attmp ADD COLUMN z int2[];
INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
v, w, x, y, z)
VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}',
......@@ -95,137 +95,137 @@ INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
'1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)',
'(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]',
'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
SELECT * FROM tmp;
SELECT * FROM attmp;
initial | a | b | c | d | e | f | g | h | i | j | k | l | m | n | p | q | r | s | t | u | v | w | x | y | z
---------+---+------+------+-----+-----+---+-----------------------+------------------------------+---+------------------------------------------------------------------------------------------------+--------+-------+-----+-----------------+---------------+-----------+-----------------------+-----------------------------+---------------------+---------------------------------------------+--------------------------+------------------+-----------+-----------+-----------
| 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | Mon May 01 00:30:30 1995 PDT | c | {"Mon May 01 00:30:30 1995 PDT","Mon Aug 24 14:43:07 1992 PDT","Wed Dec 31 16:00:00 1969 PST"} | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | magnetic disk | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | ["Wed Dec 31 16:00:00 1969 PST" "infinity"] | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4}
(1 row)
CREATE INDEX tmp_idx ON tmp (a, (d + e), b);
ALTER INDEX tmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
CREATE INDEX attmp_idx ON attmp (a, (d + e), b);
ALTER INDEX attmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
ERROR: column number must be in range from 1 to 32767
LINE 1: ALTER INDEX tmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
^
ALTER INDEX tmp_idx ALTER COLUMN 1 SET STATISTICS 1000;
ERROR: cannot alter statistics on non-expression column "a" of index "tmp_idx"
LINE 1: ALTER INDEX attmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
^
ALTER INDEX attmp_idx ALTER COLUMN 1 SET STATISTICS 1000;
ERROR: cannot alter statistics on non-expression column "a" of index "attmp_idx"
HINT: Alter statistics on table column instead.
ALTER INDEX tmp_idx ALTER COLUMN 2 SET STATISTICS 1000;
\d+ tmp_idx
Index "public.tmp_idx"
ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000;
\d+ attmp_idx
Index "public.attmp_idx"
Column | Type | Definition | Storage | Stats target
--------+------------------+------------+---------+--------------
a | integer | a | plain |
expr | double precision | (d + e) | plain | 1000
b | cstring | b | plain |
btree, for table "public.tmp"
btree, for table "public.attmp"
ALTER INDEX tmp_idx ALTER COLUMN 3 SET STATISTICS 1000;
ERROR: cannot alter statistics on non-expression column "b" of index "tmp_idx"
ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000;
ERROR: cannot alter statistics on non-expression column "b" of index "attmp_idx"
HINT: Alter statistics on table column instead.
ALTER INDEX tmp_idx ALTER COLUMN 4 SET STATISTICS 1000;
ERROR: column number 4 of relation "tmp_idx" does not exist
ALTER INDEX tmp_idx ALTER COLUMN 2 SET STATISTICS -1;
DROP TABLE tmp;
ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000;
ERROR: column number 4 of relation "attmp_idx" does not exist
ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1;
DROP TABLE attmp;
--
-- rename - check on both non-temp and temp tables
--
CREATE TABLE tmp (regtable int);
CREATE TEMP TABLE tmp (tmptable int);
ALTER TABLE tmp RENAME TO tmp_new;
SELECT * FROM tmp;
CREATE TABLE attmp (regtable int);
CREATE TEMP TABLE attmp (attmptable int);
ALTER TABLE attmp RENAME TO attmp_new;
SELECT * FROM attmp;
regtable
----------
(0 rows)
SELECT * FROM tmp_new;
tmptable
----------
SELECT * FROM attmp_new;
attmptable
------------
(0 rows)
ALTER TABLE tmp RENAME TO tmp_new2;
SELECT * FROM tmp; -- should fail
ERROR: relation "tmp" does not exist
LINE 1: SELECT * FROM tmp;
ALTER TABLE attmp RENAME TO attmp_new2;
SELECT * FROM attmp; -- should fail
ERROR: relation "attmp" does not exist
LINE 1: SELECT * FROM attmp;
^
SELECT * FROM tmp_new;
tmptable
----------
SELECT * FROM attmp_new;
attmptable
------------
(0 rows)
SELECT * FROM tmp_new2;
SELECT * FROM attmp_new2;
regtable
----------
(0 rows)
DROP TABLE tmp_new;
DROP TABLE tmp_new2;
DROP TABLE attmp_new;
DROP TABLE attmp_new2;
--
-- check renaming to a table's array type's autogenerated name
-- (the array type's name should get out of the way)
--
CREATE TABLE tmp_array (id int);
CREATE TABLE tmp_array2 (id int);
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
typname
------------
_tmp_array
CREATE TABLE attmp_array (id int);
CREATE TABLE attmp_array2 (id int);
SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
typname
--------------
_attmp_array
(1 row)
SELECT typname FROM pg_type WHERE oid = 'tmp_array2[]'::regtype;
typname
-------------
_tmp_array2
SELECT typname FROM pg_type WHERE oid = 'attmp_array2[]'::regtype;
typname
---------------
_attmp_array2
(1 row)
ALTER TABLE tmp_array2 RENAME TO _tmp_array;
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
typname
-------------
__tmp_array
ALTER TABLE attmp_array2 RENAME TO _attmp_array;
SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
typname
---------------
__attmp_array
(1 row)
SELECT typname FROM pg_type WHERE oid = '_tmp_array[]'::regtype;
typname
--------------
___tmp_array
SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
typname
----------------
___attmp_array
(1 row)
DROP TABLE _tmp_array;
DROP TABLE tmp_array;
DROP TABLE _attmp_array;
DROP TABLE attmp_array;
-- renaming to table's own array type's name is an interesting corner case
CREATE TABLE tmp_array (id int);
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
typname
------------
_tmp_array
CREATE TABLE attmp_array (id int);
SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
typname
--------------
_attmp_array
(1 row)
ALTER TABLE tmp_array RENAME TO _tmp_array;
SELECT typname FROM pg_type WHERE oid = '_tmp_array[]'::regtype;
typname
-------------
__tmp_array
ALTER TABLE attmp_array RENAME TO _attmp_array;
SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
typname
---------------
__attmp_array
(1 row)
DROP TABLE _tmp_array;
DROP TABLE _attmp_array;
-- ALTER TABLE ... RENAME on non-table relations
-- renaming indexes (FIXME: this should probably test the index's functionality)
ALTER INDEX IF EXISTS __onek_unique1 RENAME TO tmp_onek_unique1;
ALTER INDEX IF EXISTS __onek_unique1 RENAME TO attmp_onek_unique1;
NOTICE: relation "__onek_unique1" does not exist, skipping
ALTER INDEX IF EXISTS __tmp_onek_unique1 RENAME TO onek_unique1;
NOTICE: relation "__tmp_onek_unique1" does not exist, skipping
ALTER INDEX onek_unique1 RENAME TO tmp_onek_unique1;
ALTER INDEX tmp_onek_unique1 RENAME TO onek_unique1;
ALTER INDEX IF EXISTS __attmp_onek_unique1 RENAME TO onek_unique1;
NOTICE: relation "__attmp_onek_unique1" does not exist, skipping
ALTER INDEX onek_unique1 RENAME TO attmp_onek_unique1;
ALTER INDEX attmp_onek_unique1 RENAME TO onek_unique1;
SET ROLE regress_alter_table_user1;
ALTER INDEX onek_unique1 RENAME TO fail; -- permission denied
ERROR: must be owner of index onek_unique1
RESET ROLE;
-- renaming views
CREATE VIEW tmp_view (unique1) AS SELECT unique1 FROM tenk1;
ALTER TABLE tmp_view RENAME TO tmp_view_new;
CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1;
ALTER TABLE attmp_view RENAME TO attmp_view_new;
SET ROLE regress_alter_table_user1;
ALTER VIEW tmp_view_new RENAME TO fail; -- permission denied
ERROR: must be owner of view tmp_view_new
ALTER VIEW attmp_view_new RENAME TO fail; -- permission denied
ERROR: must be owner of view attmp_view_new
RESET ROLE;
-- hack to ensure we get an indexscan here
set enable_seqscan to off;
......@@ -243,7 +243,7 @@ SELECT unique1 FROM tenk1 WHERE unique1 < 5;
reset enable_seqscan;
reset enable_bitmapscan;
DROP VIEW tmp_view_new;
DROP VIEW attmp_view_new;
-- toast-like relation name
alter table stud_emp rename to pg_toast_stud_emp;
alter table pg_toast_stud_emp rename to stud_emp;
......@@ -382,77 +382,77 @@ NOTICE: relation "constraint_not_exist" does not exist, skipping
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
NOTICE: relation "constraint_rename_test" does not exist, skipping
-- FOREIGN KEY CONSTRAINT adding TEST
CREATE TABLE tmp2 (a int primary key);
CREATE TABLE tmp3 (a int, b int);
CREATE TABLE tmp4 (a int, b int, unique(a,b));
CREATE TABLE tmp5 (a int, b int);
-- Insert rows into tmp2 (pktable)
INSERT INTO tmp2 values (1);
INSERT INTO tmp2 values (2);
INSERT INTO tmp2 values (3);
INSERT INTO tmp2 values (4);
-- Insert rows into tmp3
INSERT INTO tmp3 values (1,10);
INSERT INTO tmp3 values (1,20);
INSERT INTO tmp3 values (5,50);
CREATE TABLE attmp2 (a int primary key);
CREATE TABLE attmp3 (a int, b int);
CREATE TABLE attmp4 (a int, b int, unique(a,b));
CREATE TABLE attmp5 (a int, b int);
-- Insert rows into attmp2 (pktable)
INSERT INTO attmp2 values (1);
INSERT INTO attmp2 values (2);
INSERT INTO attmp2 values (3);
INSERT INTO attmp2 values (4);
-- Insert rows into attmp3
INSERT INTO attmp3 values (1,10);
INSERT INTO attmp3 values (1,20);
INSERT INTO attmp3 values (5,50);
-- Try (and fail) to add constraint due to invalid source columns
ALTER TABLE tmp3 add constraint tmpconstr foreign key(c) references tmp2 match full;
ALTER TABLE attmp3 add constraint attmpconstr foreign key(c) references attmp2 match full;
ERROR: column "c" referenced in foreign key constraint does not exist
-- Try (and fail) to add constraint due to invalid destination columns explicitly given
ALTER TABLE tmp3 add constraint tmpconstr foreign key(a) references tmp2(b) match full;
ALTER TABLE attmp3 add constraint attmpconstr foreign key(a) references attmp2(b) match full;
ERROR: column "b" referenced in foreign key constraint does not exist
-- Try (and fail) to add constraint due to invalid data
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
ERROR: insert or update on table "tmp3" violates foreign key constraint "tmpconstr"
DETAIL: Key (a)=(5) is not present in table "tmp2".
ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full;
ERROR: insert or update on table "attmp3" violates foreign key constraint "attmpconstr"
DETAIL: Key (a)=(5) is not present in table "attmp2".
-- Delete failing row
DELETE FROM tmp3 where a=5;
DELETE FROM attmp3 where a=5;
-- Try (and succeed)
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
ALTER TABLE tmp3 drop constraint tmpconstr;
INSERT INTO tmp3 values (5,50);
ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full;
ALTER TABLE attmp3 drop constraint attmpconstr;
INSERT INTO attmp3 values (5,50);
-- Try NOT VALID and then VALIDATE CONSTRAINT, but fails. Delete failure then re-validate
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full NOT VALID;
ALTER TABLE tmp3 validate constraint tmpconstr;
ERROR: insert or update on table "tmp3" violates foreign key constraint "tmpconstr"
DETAIL: Key (a)=(5) is not present in table "tmp2".
ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full NOT VALID;
ALTER TABLE attmp3 validate constraint attmpconstr;
ERROR: insert or update on table "attmp3" violates foreign key constraint "attmpconstr"
DETAIL: Key (a)=(5) is not present in table "attmp2".
-- Delete failing row
DELETE FROM tmp3 where a=5;
DELETE FROM attmp3 where a=5;
-- Try (and succeed) and repeat to show it works on already valid constraint
ALTER TABLE tmp3 validate constraint tmpconstr;
ALTER TABLE tmp3 validate constraint tmpconstr;
ALTER TABLE attmp3 validate constraint attmpconstr;
ALTER TABLE attmp3 validate constraint attmpconstr;
-- Try a non-verified CHECK constraint
ALTER TABLE tmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
ERROR: check constraint "b_greater_than_ten" is violated by some row
ALTER TABLE tmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
ERROR: check constraint "b_greater_than_ten" is violated by some row
DELETE FROM tmp3 WHERE NOT b > 10;
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
DELETE FROM attmp3 WHERE NOT b > 10;
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
-- Test inherited NOT VALID CHECK constraints
select * from tmp3;
select * from attmp3;
a | b
---+----
1 | 20
(1 row)
CREATE TABLE tmp6 () INHERITS (tmp3);
CREATE TABLE tmp7 () INHERITS (tmp3);
INSERT INTO tmp6 VALUES (6, 30), (7, 16);
ALTER TABLE tmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID;
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_le_20; -- fails
CREATE TABLE attmp6 () INHERITS (attmp3);
CREATE TABLE attmp7 () INHERITS (attmp3);
INSERT INTO attmp6 VALUES (6, 30), (7, 16);
ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID;
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; -- fails
ERROR: check constraint "b_le_20" is violated by some row
DELETE FROM tmp6 WHERE b > 20;
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_le_20; -- succeeds
DELETE FROM attmp6 WHERE b > 20;
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; -- succeeds
-- An already validated constraint must not be revalidated
CREATE FUNCTION boo(int) RETURNS int IMMUTABLE STRICT LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'boo: %', $1; RETURN $1; END; $$;
INSERT INTO tmp7 VALUES (8, 18);
ALTER TABLE tmp7 ADD CONSTRAINT identity CHECK (b = boo(b));
INSERT INTO attmp7 VALUES (8, 18);
ALTER TABLE attmp7 ADD CONSTRAINT identity CHECK (b = boo(b));
NOTICE: boo: 18
ALTER TABLE tmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID;
ALTER TABLE attmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID;
NOTICE: merging constraint "identity" with inherited definition
ALTER TABLE tmp3 VALIDATE CONSTRAINT identity;
ALTER TABLE attmp3 VALIDATE CONSTRAINT identity;
NOTICE: boo: 16
NOTICE: boo: 20
-- A NO INHERIT constraint should not be looked for in children during VALIDATE CONSTRAINT
......@@ -475,16 +475,16 @@ select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid':
-- cleanup
drop table parent_noinh_convalid, child_noinh_convalid;
-- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on
-- tmp4 is a,b
ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
ERROR: there is no unique constraint matching given keys for referenced table "tmp4"
DROP TABLE tmp7;
DROP TABLE tmp6;
DROP TABLE tmp5;
DROP TABLE tmp4;
DROP TABLE tmp3;
DROP TABLE tmp2;
-- Try (and fail) to create constraint from attmp5(a) to attmp4(a) - unique constraint on
-- attmp4 is a,b
ALTER TABLE attmp5 add constraint attmpconstr foreign key(a) references attmp4(a) match full;
ERROR: there is no unique constraint matching given keys for referenced table "attmp4"
DROP TABLE attmp7;
DROP TABLE attmp6;
DROP TABLE attmp5;
DROP TABLE attmp4;
DROP TABLE attmp3;
DROP TABLE attmp2;
-- NOT VALID with plan invalidation -- ensure we don't use a constraint for
-- exclusion until validated
set constraint_exclusion TO 'partition';
......@@ -1364,22 +1364,22 @@ create index "testing_idx" on atacc1("........pg.dropped.1........");
ERROR: column "........pg.dropped.1........" does not exist
-- test create as and select into
insert into atacc1 values (21, 22, 23);
create table test1 as select * from atacc1;
select * from test1;
create table attest1 as select * from atacc1;
select * from attest1;
b | c | d
----+----+----
21 | 22 | 23
(1 row)
drop table test1;
select * into test2 from atacc1;
select * from test2;
drop table attest1;
select * into attest2 from atacc1;
select * from attest2;
b | c | d
----+----+----
21 | 22 | 23
(1 row)
drop table test2;
drop table attest2;
-- try dropping all columns
alter table atacc1 drop c;
alter table atacc1 drop d;
......@@ -1460,38 +1460,38 @@ NOTICE: merging column "b" with inherited definition
drop table child;
drop table parent;
-- test copy in/out
create table test (a int4, b int4, c int4);
insert into test values (1,2,3);
alter table test drop a;
copy test to stdout;
create table attest (a int4, b int4, c int4);
insert into attest values (1,2,3);
alter table attest drop a;
copy attest to stdout;
2 3
copy test(a) to stdout;
ERROR: column "a" of relation "test" does not exist
copy test("........pg.dropped.1........") to stdout;
ERROR: column "........pg.dropped.1........" of relation "test" does not exist
copy test from stdin;
copy attest(a) to stdout;
ERROR: column "a" of relation "attest" does not exist
copy attest("........pg.dropped.1........") to stdout;
ERROR: column "........pg.dropped.1........" of relation "attest" does not exist
copy attest from stdin;
ERROR: extra data after last expected column
CONTEXT: COPY test, line 1: "10 11 12"
select * from test;
CONTEXT: COPY attest, line 1: "10 11 12"
select * from attest;
b | c
---+---
2 | 3
(1 row)
copy test from stdin;
select * from test;
copy attest from stdin;
select * from attest;
b | c
----+----
2 | 3
21 | 22
(2 rows)
copy test(a) from stdin;
ERROR: column "a" of relation "test" does not exist
copy test("........pg.dropped.1........") from stdin;
ERROR: column "........pg.dropped.1........" of relation "test" does not exist
copy test(b,c) from stdin;
select * from test;
copy attest(a) from stdin;
ERROR: column "a" of relation "attest" does not exist
copy attest("........pg.dropped.1........") from stdin;
ERROR: column "........pg.dropped.1........" of relation "attest" does not exist
copy attest(b,c) from stdin;
select * from attest;
b | c
----+----
2 | 3
......@@ -1499,7 +1499,7 @@ select * from test;
31 | 32
(3 rows)
drop table test;
drop table attest;
-- test inheritance
create table dropColumn (a int, b int, e int);
create table dropColumnChild (c int) inherits (dropColumn);
......@@ -3884,10 +3884,10 @@ alter table parted_validate_test add constraint parted_validate_test_chka check
alter table parted_validate_test validate constraint parted_validate_test_chka;
drop table parted_validate_test;
-- test alter column options
CREATE TABLE tmp(i integer);
INSERT INTO tmp VALUES (1);
ALTER TABLE tmp ALTER COLUMN i SET (n_distinct = 1, n_distinct_inherited = 2);
ALTER TABLE tmp ALTER COLUMN i RESET (n_distinct_inherited);
ANALYZE tmp;
DROP TABLE tmp;
CREATE TABLE attmp(i integer);
INSERT INTO attmp VALUES (1);
ALTER TABLE attmp ALTER COLUMN i SET (n_distinct = 1, n_distinct_inherited = 2);
ALTER TABLE attmp ALTER COLUMN i RESET (n_distinct_inherited);
ANALYZE attmp;
DROP TABLE attmp;
DROP USER regress_alter_table_user1;
......@@ -8,7 +8,7 @@ ERROR: random() is not a procedure
LINE 1: CALL random();
^
HINT: To call a function, use SELECT.
CREATE FUNCTION testfunc1(a int) RETURNS int LANGUAGE SQL AS $$ SELECT a $$;
CREATE FUNCTION cp_testfunc1(a int) RETURNS int LANGUAGE SQL AS $$ SELECT a $$;
CREATE TABLE cp_test (a int, b text);
CREATE PROCEDURE ptest1(x text)
LANGUAGE SQL
......@@ -118,14 +118,14 @@ LINE 1: ALTER PROCEDURE ptest1(text) STRICT;
^
ALTER FUNCTION ptest1(text) VOLATILE; -- error: not a function
ERROR: ptest1(text) is not a function
ALTER PROCEDURE testfunc1(int) VOLATILE; -- error: not a procedure
ERROR: testfunc1(integer) is not a procedure
ALTER PROCEDURE cp_testfunc1(int) VOLATILE; -- error: not a procedure
ERROR: cp_testfunc1(integer) is not a procedure
ALTER PROCEDURE nonexistent() VOLATILE;
ERROR: procedure nonexistent() does not exist
DROP FUNCTION ptest1(text); -- error: not a function
ERROR: ptest1(text) is not a function
DROP PROCEDURE testfunc1(int); -- error: not a procedure
ERROR: testfunc1(integer) is not a procedure
DROP PROCEDURE cp_testfunc1(int); -- error: not a procedure
ERROR: cp_testfunc1(integer) is not a procedure
DROP PROCEDURE nonexistent();
ERROR: procedure nonexistent() does not exist
-- privileges
......@@ -141,11 +141,11 @@ SET ROLE regress_cp_user1;
CALL ptest1('a'); -- ok
RESET ROLE;
-- ROUTINE syntax
ALTER ROUTINE testfunc1(int) RENAME TO testfunc1a;
ALTER ROUTINE testfunc1a RENAME TO testfunc1;
ALTER ROUTINE cp_testfunc1(int) RENAME TO cp_testfunc1a;
ALTER ROUTINE cp_testfunc1a RENAME TO cp_testfunc1;
ALTER ROUTINE ptest1(text) RENAME TO ptest1a;
ALTER ROUTINE ptest1a RENAME TO ptest1;
DROP ROUTINE testfunc1(int);
DROP ROUTINE cp_testfunc1(int);
-- cleanup
DROP PROCEDURE ptest1;
DROP PROCEDURE ptest2;
......
......@@ -1322,15 +1322,15 @@ DROP TRIGGER trigtest_after_stmt ON foreign_schema.foreign_table_1;
DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1;
DROP FUNCTION dummy_trigger();
-- Table inheritance
CREATE TABLE pt1 (
CREATE TABLE fd_pt1 (
c1 integer NOT NULL,
c2 text,
c3 date
);
CREATE FOREIGN TABLE ft2 () INHERITS (pt1)
CREATE FOREIGN TABLE ft2 () INHERITS (fd_pt1)
SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt1
Table "public.pt1"
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
......@@ -1347,11 +1347,11 @@ Child tables: ft2
c3 | date | | | | | plain | |
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
DROP FOREIGN TABLE ft2;
\d+ pt1
Table "public.pt1"
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
......@@ -1373,9 +1373,9 @@ CREATE FOREIGN TABLE ft2 (
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
ALTER FOREIGN TABLE ft2 INHERIT pt1;
\d+ pt1
Table "public.pt1"
ALTER FOREIGN TABLE ft2 INHERIT fd_pt1;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
......@@ -1392,7 +1392,7 @@ Child tables: ft2
c3 | date | | | | | plain | |
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
CREATE TABLE ct3() INHERITS(ft2);
CREATE FOREIGN TABLE ft3 (
......@@ -1413,7 +1413,7 @@ NOTICE: merging column "c3" with inherited definition
c3 | date | | | | | plain | |
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
Child tables: ct3,
ft3
......@@ -1437,13 +1437,13 @@ Server: s0
Inherits: ft2
-- add attributes recursively
ALTER TABLE pt1 ADD COLUMN c4 integer;
ALTER TABLE pt1 ADD COLUMN c5 integer DEFAULT 0;
ALTER TABLE pt1 ADD COLUMN c6 integer;
ALTER TABLE pt1 ADD COLUMN c7 integer NOT NULL;
ALTER TABLE pt1 ADD COLUMN c8 integer;
\d+ pt1
Table "public.pt1"
ALTER TABLE fd_pt1 ADD COLUMN c4 integer;
ALTER TABLE fd_pt1 ADD COLUMN c5 integer DEFAULT 0;
ALTER TABLE fd_pt1 ADD COLUMN c6 integer;
ALTER TABLE fd_pt1 ADD COLUMN c7 integer NOT NULL;
ALTER TABLE fd_pt1 ADD COLUMN c8 integer;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
......@@ -1470,7 +1470,7 @@ Child tables: ft2
c8 | integer | | | | | plain | |
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
Child tables: ct3,
ft3
......@@ -1504,20 +1504,20 @@ Server: s0
Inherits: ft2
-- alter attributes recursively
ALTER TABLE pt1 ALTER COLUMN c4 SET DEFAULT 0;
ALTER TABLE pt1 ALTER COLUMN c5 DROP DEFAULT;
ALTER TABLE pt1 ALTER COLUMN c6 SET NOT NULL;
ALTER TABLE pt1 ALTER COLUMN c7 DROP NOT NULL;
ALTER TABLE pt1 ALTER COLUMN c8 TYPE char(10) USING '0'; -- ERROR
ALTER TABLE fd_pt1 ALTER COLUMN c4 SET DEFAULT 0;
ALTER TABLE fd_pt1 ALTER COLUMN c5 DROP DEFAULT;
ALTER TABLE fd_pt1 ALTER COLUMN c6 SET NOT NULL;
ALTER TABLE fd_pt1 ALTER COLUMN c7 DROP NOT NULL;
ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) USING '0'; -- ERROR
ERROR: "ft2" is not a table
ALTER TABLE pt1 ALTER COLUMN c8 TYPE char(10);
ALTER TABLE pt1 ALTER COLUMN c8 SET DATA TYPE text;
ALTER TABLE pt1 ALTER COLUMN c1 SET STATISTICS 10000;
ALTER TABLE pt1 ALTER COLUMN c1 SET (n_distinct = 100);
ALTER TABLE pt1 ALTER COLUMN c8 SET STATISTICS -1;
ALTER TABLE pt1 ALTER COLUMN c8 SET STORAGE EXTERNAL;
\d+ pt1
Table "public.pt1"
ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10);
ALTER TABLE fd_pt1 ALTER COLUMN c8 SET DATA TYPE text;
ALTER TABLE fd_pt1 ALTER COLUMN c1 SET STATISTICS 10000;
ALTER TABLE fd_pt1 ALTER COLUMN c1 SET (n_distinct = 100);
ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STATISTICS -1;
ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STORAGE EXTERNAL;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
......@@ -1544,18 +1544,18 @@ Child tables: ft2
c8 | text | | | | | external | |
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
Child tables: ct3,
ft3
-- drop attributes recursively
ALTER TABLE pt1 DROP COLUMN c4;
ALTER TABLE pt1 DROP COLUMN c5;
ALTER TABLE pt1 DROP COLUMN c6;
ALTER TABLE pt1 DROP COLUMN c7;
ALTER TABLE pt1 DROP COLUMN c8;
\d+ pt1
Table "public.pt1"
ALTER TABLE fd_pt1 DROP COLUMN c4;
ALTER TABLE fd_pt1 DROP COLUMN c5;
ALTER TABLE fd_pt1 DROP COLUMN c6;
ALTER TABLE fd_pt1 DROP COLUMN c7;
ALTER TABLE fd_pt1 DROP COLUMN c8;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
......@@ -1572,35 +1572,35 @@ Child tables: ft2
c3 | date | | | | | plain | |
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
Child tables: ct3,
ft3
-- add constraints recursively
ALTER TABLE pt1 ADD CONSTRAINT pt1chk1 CHECK (c1 > 0) NO INHERIT;
ALTER TABLE pt1 ADD CONSTRAINT pt1chk2 CHECK (c2 <> '');
ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk1 CHECK (c1 > 0) NO INHERIT;
ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '');
-- connoinherit should be true for NO INHERIT constraint
SELECT relname, conname, contype, conislocal, coninhcount, connoinherit
FROM pg_class AS pc JOIN pg_constraint AS pgc ON (conrelid = pc.oid)
WHERE pc.relname = 'pt1'
WHERE pc.relname = 'fd_pt1'
ORDER BY 1,2;
relname | conname | contype | conislocal | coninhcount | connoinherit
---------+---------+---------+------------+-------------+--------------
pt1 | pt1chk1 | c | t | 0 | t
pt1 | pt1chk2 | c | t | 0 | f
relname | conname | contype | conislocal | coninhcount | connoinherit
---------+------------+---------+------------+-------------+--------------
fd_pt1 | fd_pt1chk1 | c | t | 0 | t
fd_pt1 | fd_pt1chk2 | c | t | 0 | f
(2 rows)
-- child does not inherit NO INHERIT constraints
\d+ pt1
Table "public.pt1"
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Check constraints:
"pt1chk1" CHECK (c1 > 0) NO INHERIT
"pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk1" CHECK (c1 > 0) NO INHERIT
"fd_pt1chk2" CHECK (c2 <> ''::text)
Child tables: ft2
\d+ ft2
......@@ -1611,10 +1611,10 @@ Child tables: ft2
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Check constraints:
"pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk2" CHECK (c2 <> ''::text)
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
Child tables: ct3,
ft3
......@@ -1630,21 +1630,21 @@ CREATE FOREIGN TABLE ft2 (
c3 date
) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
-- child must have parent's INHERIT constraints
ALTER FOREIGN TABLE ft2 INHERIT pt1; -- ERROR
ERROR: child table is missing constraint "pt1chk2"
ALTER FOREIGN TABLE ft2 ADD CONSTRAINT pt1chk2 CHECK (c2 <> '');
ALTER FOREIGN TABLE ft2 INHERIT pt1;
ALTER FOREIGN TABLE ft2 INHERIT fd_pt1; -- ERROR
ERROR: child table is missing constraint "fd_pt1chk2"
ALTER FOREIGN TABLE ft2 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '');
ALTER FOREIGN TABLE ft2 INHERIT fd_pt1;
-- child does not inherit NO INHERIT constraints
\d+ pt1
Table "public.pt1"
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Check constraints:
"pt1chk1" CHECK (c1 > 0) NO INHERIT
"pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk1" CHECK (c1 > 0) NO INHERIT
"fd_pt1chk2" CHECK (c2 <> ''::text)
Child tables: ft2
\d+ ft2
......@@ -1655,26 +1655,26 @@ Child tables: ft2
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Check constraints:
"pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk2" CHECK (c2 <> ''::text)
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
-- drop constraints recursively
ALTER TABLE pt1 DROP CONSTRAINT pt1chk1 CASCADE;
ALTER TABLE pt1 DROP CONSTRAINT pt1chk2 CASCADE;
ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk1 CASCADE;
ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk2 CASCADE;
-- NOT VALID case
INSERT INTO pt1 VALUES (1, 'pt1'::text, '1994-01-01'::date);
ALTER TABLE pt1 ADD CONSTRAINT pt1chk3 CHECK (c2 <> '') NOT VALID;
\d+ pt1
Table "public.pt1"
INSERT INTO fd_pt1 VALUES (1, 'fd_pt1'::text, '1994-01-01'::date);
ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk3 CHECK (c2 <> '') NOT VALID;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Check constraints:
"pt1chk3" CHECK (c2 <> ''::text) NOT VALID
"fd_pt1chk3" CHECK (c2 <> ''::text) NOT VALID
Child tables: ft2
\d+ ft2
......@@ -1685,23 +1685,23 @@ Child tables: ft2
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Check constraints:
"pt1chk2" CHECK (c2 <> ''::text)
"pt1chk3" CHECK (c2 <> ''::text) NOT VALID
"fd_pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk3" CHECK (c2 <> ''::text) NOT VALID
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
-- VALIDATE CONSTRAINT need do nothing on foreign tables
ALTER TABLE pt1 VALIDATE CONSTRAINT pt1chk3;
\d+ pt1
Table "public.pt1"
ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Check constraints:
"pt1chk3" CHECK (c2 <> ''::text)
"fd_pt1chk3" CHECK (c2 <> ''::text)
Child tables: ft2
\d+ ft2
......@@ -1712,23 +1712,23 @@ Child tables: ft2
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Check constraints:
"pt1chk2" CHECK (c2 <> ''::text)
"pt1chk3" CHECK (c2 <> ''::text)
"fd_pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk3" CHECK (c2 <> ''::text)
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
-- OID system column
ALTER TABLE pt1 SET WITH OIDS;
\d+ pt1
Table "public.pt1"
ALTER TABLE fd_pt1 SET WITH OIDS;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Check constraints:
"pt1chk3" CHECK (c2 <> ''::text)
"fd_pt1chk3" CHECK (c2 <> ''::text)
Child tables: ft2
Has OIDs: yes
......@@ -1740,25 +1740,25 @@ Has OIDs: yes
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Check constraints:
"pt1chk2" CHECK (c2 <> ''::text)
"pt1chk3" CHECK (c2 <> ''::text)
"fd_pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk3" CHECK (c2 <> ''::text)
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
Has OIDs: yes
ALTER TABLE ft2 SET WITHOUT OIDS; -- ERROR
ERROR: cannot drop inherited column "oid"
ALTER TABLE pt1 SET WITHOUT OIDS;
\d+ pt1
Table "public.pt1"
ALTER TABLE fd_pt1 SET WITHOUT OIDS;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | 10000 |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Check constraints:
"pt1chk3" CHECK (c2 <> ''::text)
"fd_pt1chk3" CHECK (c2 <> ''::text)
Child tables: ft2
\d+ ft2
......@@ -1769,20 +1769,20 @@ Child tables: ft2
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Check constraints:
"pt1chk2" CHECK (c2 <> ''::text)
"pt1chk3" CHECK (c2 <> ''::text)
"fd_pt1chk2" CHECK (c2 <> ''::text)
"fd_pt1chk3" CHECK (c2 <> ''::text)
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
-- changes name of an attribute recursively
ALTER TABLE pt1 RENAME COLUMN c1 TO f1;
ALTER TABLE pt1 RENAME COLUMN c2 TO f2;
ALTER TABLE pt1 RENAME COLUMN c3 TO f3;
ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1;
ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2;
ALTER TABLE fd_pt1 RENAME COLUMN c3 TO f3;
-- changes name of a constraint recursively
ALTER TABLE pt1 RENAME CONSTRAINT pt1chk3 TO f2_check;
\d+ pt1
Table "public.pt1"
ALTER TABLE fd_pt1 RENAME CONSTRAINT fd_pt1chk3 TO f2_check;
\d+ fd_pt1
Table "public.fd_pt1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
f1 | integer | | not null | | plain | 10000 |
......@@ -1801,17 +1801,17 @@ Child tables: ft2
f3 | date | | | | | plain | |
Check constraints:
"f2_check" CHECK (f2 <> ''::text)
"pt1chk2" CHECK (f2 <> ''::text)
"fd_pt1chk2" CHECK (f2 <> ''::text)
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
Inherits: pt1
Inherits: fd_pt1
-- TRUNCATE doesn't work on foreign tables, either directly or recursively
TRUNCATE ft2; -- ERROR
ERROR: "ft2" is not a table
TRUNCATE pt1; -- ERROR
TRUNCATE fd_pt1; -- ERROR
ERROR: "ft2" is not a table
DROP TABLE pt1 CASCADE;
DROP TABLE fd_pt1 CASCADE;
NOTICE: drop cascades to foreign table ft2
-- IMPORT FOREIGN SCHEMA
IMPORT FOREIGN SCHEMA s1 FROM SERVER s9 INTO public; -- ERROR
......@@ -1838,45 +1838,45 @@ HINT: Use DROP ... CASCADE to drop the dependent objects too.
DROP OWNED BY regress_test_role2 CASCADE;
NOTICE: drop cascades to user mapping for regress_test_role on server s5
-- Foreign partition DDL stuff
CREATE TABLE pt2 (
CREATE TABLE fd_pt2 (
c1 integer NOT NULL,
c2 text,
c3 date
) PARTITION BY LIST (c1);
CREATE FOREIGN TABLE pt2_1 PARTITION OF pt2 FOR VALUES IN (1)
CREATE FOREIGN TABLE fd_pt2_1 PARTITION OF fd_pt2 FOR VALUES IN (1)
SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt2
Table "public.pt2"
\d+ fd_pt2
Table "public.fd_pt2"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Partition key: LIST (c1)
Partitions: pt2_1 FOR VALUES IN (1)
Partitions: fd_pt2_1 FOR VALUES IN (1)
\d+ pt2_1
Foreign table "public.pt2_1"
\d+ fd_pt2_1
Foreign table "public.fd_pt2_1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
c1 | integer | | not null | | | plain | |
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Partition of: pt2 FOR VALUES IN (1)
Partition of: fd_pt2 FOR VALUES IN (1)
Partition constraint: ((c1 IS NOT NULL) AND (c1 = 1))
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
-- partition cannot have additional columns
DROP FOREIGN TABLE pt2_1;
CREATE FOREIGN TABLE pt2_1 (
DROP FOREIGN TABLE fd_pt2_1;
CREATE FOREIGN TABLE fd_pt2_1 (
c1 integer NOT NULL,
c2 text,
c3 date,
c4 char
) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt2_1
Foreign table "public.pt2_1"
\d+ fd_pt2_1
Foreign table "public.fd_pt2_1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+--------------+-----------+----------+---------+-------------+----------+--------------+-------------
c1 | integer | | not null | | | plain | |
......@@ -1886,12 +1886,12 @@ CREATE FOREIGN TABLE pt2_1 (
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1); -- ERROR
ERROR: table "pt2_1" contains column "c4" not found in parent "pt2"
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); -- ERROR
ERROR: table "fd_pt2_1" contains column "c4" not found in parent "fd_pt2"
DETAIL: The new partition may contain only the columns present in parent.
DROP FOREIGN TABLE pt2_1;
\d+ pt2
Table "public.pt2"
DROP FOREIGN TABLE fd_pt2_1;
\d+ fd_pt2
Table "public.fd_pt2"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
......@@ -1900,13 +1900,13 @@ DROP FOREIGN TABLE pt2_1;
Partition key: LIST (c1)
Number of partitions: 0
CREATE FOREIGN TABLE pt2_1 (
CREATE FOREIGN TABLE fd_pt2_1 (
c1 integer NOT NULL,
c2 text,
c3 date
) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt2_1
Foreign table "public.pt2_1"
\d+ fd_pt2_1
Foreign table "public.fd_pt2_1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
c1 | integer | | not null | | | plain | |
......@@ -1916,53 +1916,53 @@ Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
-- no attach partition validation occurs for foreign tables
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1);
\d+ pt2
Table "public.pt2"
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1);
\d+ fd_pt2
Table "public.fd_pt2"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Partition key: LIST (c1)
Partitions: pt2_1 FOR VALUES IN (1)
Partitions: fd_pt2_1 FOR VALUES IN (1)
\d+ pt2_1
Foreign table "public.pt2_1"
\d+ fd_pt2_1
Foreign table "public.fd_pt2_1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
c1 | integer | | not null | | | plain | |
c2 | text | | | | | extended | |
c3 | date | | | | | plain | |
Partition of: pt2 FOR VALUES IN (1)
Partition of: fd_pt2 FOR VALUES IN (1)
Partition constraint: ((c1 IS NOT NULL) AND (c1 = 1))
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
-- cannot add column to a partition
ALTER TABLE pt2_1 ADD c4 char;
ALTER TABLE fd_pt2_1 ADD c4 char;
ERROR: cannot add column to a partition
-- ok to have a partition's own constraints though
ALTER TABLE pt2_1 ALTER c3 SET NOT NULL;
ALTER TABLE pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> '');
\d+ pt2
Table "public.pt2"
ALTER TABLE fd_pt2_1 ALTER c3 SET NOT NULL;
ALTER TABLE fd_pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> '');
\d+ fd_pt2
Table "public.fd_pt2"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
c2 | text | | | | extended | |
c3 | date | | | | plain | |
Partition key: LIST (c1)
Partitions: pt2_1 FOR VALUES IN (1)
Partitions: fd_pt2_1 FOR VALUES IN (1)
\d+ pt2_1
Foreign table "public.pt2_1"
\d+ fd_pt2_1
Foreign table "public.fd_pt2_1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
c1 | integer | | not null | | | plain | |
c2 | text | | | | | extended | |
c3 | date | | not null | | | plain | |
Partition of: pt2 FOR VALUES IN (1)
Partition of: fd_pt2 FOR VALUES IN (1)
Partition constraint: ((c1 IS NOT NULL) AND (c1 = 1))
Check constraints:
"p21chk" CHECK (c2 <> ''::text)
......@@ -1970,13 +1970,13 @@ Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
-- cannot drop inherited NOT NULL constraint from a partition
ALTER TABLE pt2_1 ALTER c1 DROP NOT NULL;
ALTER TABLE fd_pt2_1 ALTER c1 DROP NOT NULL;
ERROR: column "c1" is marked NOT NULL in parent table
-- partition must have parent's constraints
ALTER TABLE pt2 DETACH PARTITION pt2_1;
ALTER TABLE pt2 ALTER c2 SET NOT NULL;
\d+ pt2
Table "public.pt2"
ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1;
ALTER TABLE fd_pt2 ALTER c2 SET NOT NULL;
\d+ fd_pt2
Table "public.fd_pt2"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
......@@ -1985,8 +1985,8 @@ ALTER TABLE pt2 ALTER c2 SET NOT NULL;
Partition key: LIST (c1)
Number of partitions: 0
\d+ pt2_1
Foreign table "public.pt2_1"
\d+ fd_pt2_1
Foreign table "public.fd_pt2_1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
c1 | integer | | not null | | | plain | |
......@@ -1997,14 +1997,14 @@ Check constraints:
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1); -- ERROR
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); -- ERROR
ERROR: column "c2" in child table must be marked NOT NULL
ALTER FOREIGN TABLE pt2_1 ALTER c2 SET NOT NULL;
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1);
ALTER TABLE pt2 DETACH PARTITION pt2_1;
ALTER TABLE pt2 ADD CONSTRAINT pt2chk1 CHECK (c1 > 0);
\d+ pt2
Table "public.pt2"
ALTER FOREIGN TABLE fd_pt2_1 ALTER c2 SET NOT NULL;
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1);
ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1;
ALTER TABLE fd_pt2 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0);
\d+ fd_pt2
Table "public.fd_pt2"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
c1 | integer | | not null | | plain | |
......@@ -2012,11 +2012,11 @@ ALTER TABLE pt2 ADD CONSTRAINT pt2chk1 CHECK (c1 > 0);
c3 | date | | | | plain | |
Partition key: LIST (c1)
Check constraints:
"pt2chk1" CHECK (c1 > 0)
"fd_pt2chk1" CHECK (c1 > 0)
Number of partitions: 0
\d+ pt2_1
Foreign table "public.pt2_1"
\d+ fd_pt2_1
Foreign table "public.fd_pt2_1"
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
c1 | integer | | not null | | | plain | |
......@@ -2027,17 +2027,17 @@ Check constraints:
Server: s0
FDW options: (delimiter ',', quote '"', "be quoted" 'value')
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1); -- ERROR
ERROR: child table is missing constraint "pt2chk1"
ALTER FOREIGN TABLE pt2_1 ADD CONSTRAINT pt2chk1 CHECK (c1 > 0);
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1);
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); -- ERROR
ERROR: child table is missing constraint "fd_pt2chk1"
ALTER FOREIGN TABLE fd_pt2_1 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0);
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1);
-- TRUNCATE doesn't work on foreign tables, either directly or recursively
TRUNCATE pt2_1; -- ERROR
ERROR: "pt2_1" is not a table
TRUNCATE pt2; -- ERROR
ERROR: "pt2_1" is not a table
DROP FOREIGN TABLE pt2_1;
DROP TABLE pt2;
TRUNCATE fd_pt2_1; -- ERROR
ERROR: "fd_pt2_1" is not a table
TRUNCATE fd_pt2; -- ERROR
ERROR: "fd_pt2_1" is not a table
DROP FOREIGN TABLE fd_pt2_1;
DROP TABLE fd_pt2;
-- Cleanup
DROP SCHEMA foreign_schema CASCADE;
DROP ROLE regress_test_role; -- ERROR
......
CREATE TABLE toasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text);
INSERT INTO toasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000));
INSERT INTO toasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000));
INSERT INTO toasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000));
INSERT INTO toasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000));
CREATE TABLE indtoasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text);
INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000));
INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000));
INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000));
INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000));
-- check whether indirect tuples works on the most basic level
SELECT descr, substring(make_tuple_indirect(toasttest)::text, 1, 200) FROM toasttest;
SELECT descr, substring(make_tuple_indirect(indtoasttest)::text, 1, 200) FROM indtoasttest;
descr | substring
-------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
two-compressed | (two-compressed,0,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
......@@ -14,7 +14,7 @@ SELECT descr, substring(make_tuple_indirect(toasttest)::text, 1, 200) FROM toast
(4 rows)
-- modification without changing varlenas
UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,1,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
......@@ -24,7 +24,7 @@ UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
(4 rows)
-- modification without modifying assigned value
UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,2,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
......@@ -34,7 +34,7 @@ UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text,
(4 rows)
-- modification modifying, but effectively not changing
UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,3,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
......@@ -43,7 +43,7 @@ UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::te
("one-toasted,one-null",3,,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123
(4 rows)
UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,4,-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
......@@ -52,7 +52,7 @@ UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toastte
("one-toasted,one-null",4,,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123
(4 rows)
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,4,-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
......@@ -62,8 +62,8 @@ SELECT substring(toasttest::text, 1, 200) FROM toasttest;
(4 rows)
-- check we didn't screw with main/toast tuple visibility
VACUUM FREEZE toasttest;
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
VACUUM FREEZE indtoasttest;
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,4,-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
......@@ -80,13 +80,13 @@ BEGIN
NEW := make_tuple_indirect(NEW);
RETURN NEW;
END$$;
CREATE TRIGGER toasttest_update_indirect
CREATE TRIGGER indtoasttest_update_indirect
BEFORE INSERT OR UPDATE
ON toasttest
ON indtoasttest
FOR EACH ROW
EXECUTE PROCEDURE update_using_indirect();
-- modification without changing varlenas
UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,5,-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
......@@ -96,7 +96,7 @@ UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
(4 rows)
-- modification without modifying assigned value
UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,6,-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
......@@ -106,7 +106,7 @@ UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text,
(4 rows)
-- modification modifying, but effectively not changing
UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,7,-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
......@@ -115,7 +115,7 @@ UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::te
("one-toasted,one-null",7,,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123
(4 rows)
UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200);
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,8,--123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
......@@ -124,8 +124,8 @@ UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toastte
("one-toasted,one-null",8,,12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123
(4 rows)
INSERT INTO toasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL);
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL);
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,8,--123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
......@@ -136,8 +136,8 @@ SELECT substring(toasttest::text, 1, 200) FROM toasttest;
(5 rows)
-- check we didn't screw with main/toast tuple visibility
VACUUM FREEZE toasttest;
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
VACUUM FREEZE indtoasttest;
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
substring
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(two-compressed,8,--123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
......@@ -147,5 +147,5 @@ SELECT substring(toasttest::text, 1, 200) FROM toasttest;
("one-toasted,one-null, via indirect",0,1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
(5 rows)
DROP TABLE toasttest;
DROP TABLE indtoasttest;
DROP FUNCTION update_using_indirect();
......@@ -5464,46 +5464,46 @@ HINT: There is an entry for table "xx1", but it cannot be referenced from this
-- test LATERAL reference propagation down a multi-level inheritance hierarchy
-- produced for a multi-level partitioned table hierarchy.
--
create table pt1 (a int, b int, c varchar) partition by range(a);
create table pt1p1 partition of pt1 for values from (0) to (100) partition by range(b);
create table pt1p2 partition of pt1 for values from (100) to (200);
create table pt1p1p1 partition of pt1p1 for values from (0) to (100);
insert into pt1 values (1, 1, 'x'), (101, 101, 'y');
create table ut1 (a int, b int, c varchar);
insert into ut1 values (101, 101, 'y'), (2, 2, 'z');
create table join_pt1 (a int, b int, c varchar) partition by range(a);
create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b);
create table join_pt1p2 partition of join_pt1 for values from (100) to (200);
create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100);
insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y');
create table join_ut1 (a int, b int, c varchar);
insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z');
explain (verbose, costs off)
select t1.b, ss.phv from ut1 t1 left join lateral
select t1.b, ss.phv from join_ut1 t1 left join lateral
(select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv
from pt1 t2 join ut1 t3 on t2.a = t3.b) ss
from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss
on t1.a = ss.t2a order by t1.a;
QUERY PLAN
-------------------------------------------------------------
QUERY PLAN
------------------------------------------------------------------
Sort
Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a
Sort Key: t1.a
-> Nested Loop Left Join
Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a
-> Seq Scan on public.ut1 t1
-> Seq Scan on public.join_ut1 t1
Output: t1.a, t1.b, t1.c
-> Hash Join
Output: t2.a, LEAST(t1.a, t2.a, t3.a)
Hash Cond: (t3.b = t2.a)
-> Seq Scan on public.ut1 t3
-> Seq Scan on public.join_ut1 t3
Output: t3.a, t3.b, t3.c
-> Hash
Output: t2.a
-> Append
-> Seq Scan on public.pt1p1p1 t2
-> Seq Scan on public.join_pt1p1p1 t2
Output: t2.a
Filter: (t1.a = t2.a)
-> Seq Scan on public.pt1p2 t2_1
-> Seq Scan on public.join_pt1p2 t2_1
Output: t2_1.a
Filter: (t1.a = t2_1.a)
(21 rows)
select t1.b, ss.phv from ut1 t1 left join lateral
select t1.b, ss.phv from join_ut1 t1 left join lateral
(select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv
from pt1 t2 join ut1 t3 on t2.a = t3.b) ss
from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss
on t1.a = ss.t2a order by t1.a;
b | phv
-----+-----
......@@ -5511,8 +5511,8 @@ select t1.b, ss.phv from ut1 t1 left join lateral
101 | 101
(2 rows)
drop table pt1;
drop table ut1;
drop table join_pt1;
drop table join_ut1;
--
-- test that foreign key join estimation performs sanely for outer joins
--
......@@ -6443,10 +6443,10 @@ $$);
rollback to settings;
-- Exercise rescans. We'll turn off parallel_leader_participation so
-- that we can check that instrumentation comes back correctly.
create table foo as select generate_series(1, 3) as id, 'xxxxx'::text as t;
alter table foo set (parallel_workers = 0);
create table bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t;
alter table bar set (parallel_workers = 2);
create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t;
alter table join_foo set (parallel_workers = 0);
create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t;
alter table join_bar set (parallel_workers = 2);
-- multi-batch with rescan, parallel-oblivious
savepoint settings;
set enable_parallel_hash = off;
......@@ -6459,27 +6459,27 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '64kB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
QUERY PLAN
--------------------------------------------------------------------------
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
QUERY PLAN
------------------------------------------------------------------------------------
Aggregate
-> Nested Loop Left Join
Join Filter: ((foo.id < (b1.id + 1)) AND (foo.id > (b1.id - 1)))
-> Seq Scan on foo
Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1)))
-> Seq Scan on join_foo
-> Gather
Workers Planned: 2
-> Hash Join
Hash Cond: (b1.id = b2.id)
-> Parallel Seq Scan on bar b1
-> Parallel Seq Scan on join_bar b1
-> Hash
-> Seq Scan on bar b2
-> Seq Scan on join_bar b2
(11 rows)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
count
-------
3
......@@ -6488,9 +6488,9 @@ select count(*) from foo
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
multibatch
------------
......@@ -6510,27 +6510,27 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '4MB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
QUERY PLAN
--------------------------------------------------------------------------
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
QUERY PLAN
------------------------------------------------------------------------------------
Aggregate
-> Nested Loop Left Join
Join Filter: ((foo.id < (b1.id + 1)) AND (foo.id > (b1.id - 1)))
-> Seq Scan on foo
Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1)))
-> Seq Scan on join_foo
-> Gather
Workers Planned: 2
-> Hash Join
Hash Cond: (b1.id = b2.id)
-> Parallel Seq Scan on bar b1
-> Parallel Seq Scan on join_bar b1
-> Hash
-> Seq Scan on bar b2
-> Seq Scan on join_bar b2
(11 rows)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
count
-------
3
......@@ -6539,9 +6539,9 @@ select count(*) from foo
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
multibatch
------------
......@@ -6561,27 +6561,27 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '64kB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
QUERY PLAN
--------------------------------------------------------------------------
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
QUERY PLAN
------------------------------------------------------------------------------------
Aggregate
-> Nested Loop Left Join
Join Filter: ((foo.id < (b1.id + 1)) AND (foo.id > (b1.id - 1)))
-> Seq Scan on foo
Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1)))
-> Seq Scan on join_foo
-> Gather
Workers Planned: 2
-> Parallel Hash Join
Hash Cond: (b1.id = b2.id)
-> Parallel Seq Scan on bar b1
-> Parallel Seq Scan on join_bar b1
-> Parallel Hash
-> Parallel Seq Scan on bar b2
-> Parallel Seq Scan on join_bar b2
(11 rows)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
count
-------
3
......@@ -6590,9 +6590,9 @@ select count(*) from foo
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
multibatch
------------
......@@ -6612,27 +6612,27 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '4MB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
QUERY PLAN
--------------------------------------------------------------------------
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
QUERY PLAN
------------------------------------------------------------------------------------
Aggregate
-> Nested Loop Left Join
Join Filter: ((foo.id < (b1.id + 1)) AND (foo.id > (b1.id - 1)))
-> Seq Scan on foo
Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1)))
-> Seq Scan on join_foo
-> Gather
Workers Planned: 2
-> Parallel Hash Join
Hash Cond: (b1.id = b2.id)
-> Parallel Seq Scan on bar b1
-> Parallel Seq Scan on join_bar b1
-> Parallel Hash
-> Parallel Seq Scan on bar b2
-> Parallel Seq Scan on join_bar b2
(11 rows)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
count
-------
3
......@@ -6641,9 +6641,9 @@ select count(*) from foo
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
multibatch
------------
......
......@@ -254,27 +254,27 @@ NOTICE: 3
-- Check that addition or removal of any partition is correctly dealt with by
-- default partition table when it is being used in prepared statement.
create table list_parted (a int) partition by list(a);
create table list_part_null partition of list_parted for values in (null);
create table list_part_1 partition of list_parted for values in (1);
create table list_part_def partition of list_parted default;
prepare pstmt_def_insert (int) as insert into list_part_def values($1);
create table pc_list_parted (a int) partition by list(a);
create table pc_list_part_null partition of pc_list_parted for values in (null);
create table pc_list_part_1 partition of pc_list_parted for values in (1);
create table pc_list_part_def partition of pc_list_parted default;
prepare pstmt_def_insert (int) as insert into pc_list_part_def values($1);
-- should fail
execute pstmt_def_insert(null);
ERROR: new row for relation "list_part_def" violates partition constraint
ERROR: new row for relation "pc_list_part_def" violates partition constraint
DETAIL: Failing row contains (null).
execute pstmt_def_insert(1);
ERROR: new row for relation "list_part_def" violates partition constraint
ERROR: new row for relation "pc_list_part_def" violates partition constraint
DETAIL: Failing row contains (1).
create table list_part_2 partition of list_parted for values in (2);
create table pc_list_part_2 partition of pc_list_parted for values in (2);
execute pstmt_def_insert(2);
ERROR: new row for relation "list_part_def" violates partition constraint
ERROR: new row for relation "pc_list_part_def" violates partition constraint
DETAIL: Failing row contains (2).
alter table list_parted detach partition list_part_null;
alter table pc_list_parted detach partition pc_list_part_null;
-- should be ok
execute pstmt_def_insert(null);
drop table list_part_1;
drop table pc_list_part_1;
-- should be ok
execute pstmt_def_insert(1);
drop table list_parted, list_part_null;
drop table pc_list_parted, pc_list_part_null;
deallocate pstmt_def_insert;
......@@ -1870,7 +1870,7 @@ create table perform_test (
a INT,
b INT
);
create function simple_func(int) returns boolean as '
create function perform_simple_func(int) returns boolean as '
BEGIN
IF $1 < 20 THEN
INSERT INTO perform_test VALUES ($1, $1 + 10);
......@@ -1885,13 +1885,13 @@ BEGIN
INSERT INTO perform_test VALUES (100, 100);
END IF;
PERFORM simple_func(5);
PERFORM perform_simple_func(5);
IF FOUND then
INSERT INTO perform_test VALUES (100, 100);
END IF;
PERFORM simple_func(50);
PERFORM perform_simple_func(50);
IF FOUND then
INSERT INTO perform_test VALUES (100, 100);
......@@ -2755,55 +2755,55 @@ select multi_datum_use(42);
--
create temp table foo (f1 int, f2 int);
insert into foo values (1,2), (3,4);
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
insert into foo values(5,6) returning * into x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
NOTICE: x.f1 = 5, x.f2 = 6
footest
---------
stricttest
------------
(1 row)
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail due to implicit strict
insert into foo values(7,8),(9,10) returning * into x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
CONTEXT: PL/pgSQL function footest() line 5 at SQL statement
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at SQL statement
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
execute 'insert into foo values(5,6) returning *' into x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
NOTICE: x.f1 = 5, x.f2 = 6
footest
---------
stricttest
------------
(1 row)
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- this should work since EXECUTE isn't as picky
execute 'insert into foo values(7,8),(9,10) returning *' into x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
NOTICE: x.f1 = 7, x.f2 = 8
footest
---------
stricttest
------------
(1 row)
......@@ -2818,78 +2818,78 @@ select * from foo;
9 | 10
(6 rows)
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
select * from foo where f1 = 3 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
NOTICE: x.f1 = 3, x.f2 = 4
footest
---------
stricttest
------------
(1 row)
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, no rows
select * from foo where f1 = 0 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned no rows
CONTEXT: PL/pgSQL function footest() line 5 at SQL statement
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at SQL statement
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, too many rows
select * from foo where f1 > 3 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
CONTEXT: PL/pgSQL function footest() line 5 at SQL statement
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at SQL statement
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
execute 'select * from foo where f1 = 3' into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
NOTICE: x.f1 = 3, x.f2 = 4
footest
---------
stricttest
------------
(1 row)
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, no rows
execute 'select * from foo where f1 = 0' into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned no rows
CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at EXECUTE
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, too many rows
execute 'select * from foo where f1 > 3' into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE
drop function footest();
CONTEXT: PL/pgSQL function stricttest() line 5 at EXECUTE
drop function stricttest();
-- test printing parameters after failure due to STRICT
set plpgsql.print_strict_params to true;
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare
x record;
p1 int := 2;
......@@ -2899,11 +2899,11 @@ begin
select * from foo where f1 = p1 and f1::text = p3 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned no rows
DETAIL: parameters: p1 = '2', p3 = 'foo'
CONTEXT: PL/pgSQL function footest() line 8 at SQL statement
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 8 at SQL statement
create or replace function stricttest() returns void as $$
declare
x record;
p1 int := 2;
......@@ -2913,53 +2913,53 @@ begin
select * from foo where f1 > p1 or f1::text = p3 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
DETAIL: parameters: p1 = '2', p3 = 'foo'
CONTEXT: PL/pgSQL function footest() line 8 at SQL statement
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 8 at SQL statement
create or replace function stricttest() returns void as $$
declare x record;
begin
-- too many rows, no params
select * from foo where f1 > 3 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
CONTEXT: PL/pgSQL function footest() line 5 at SQL statement
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at SQL statement
create or replace function stricttest() returns void as $$
declare x record;
begin
-- no rows
execute 'select * from foo where f1 = $1 or f1::text = $2' using 0, 'foo' into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned no rows
DETAIL: parameters: $1 = '0', $2 = 'foo'
CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at EXECUTE
create or replace function stricttest() returns void as $$
declare x record;
begin
-- too many rows
execute 'select * from foo where f1 > $1' using 1 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
DETAIL: parameters: $1 = '1'
CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at EXECUTE
create or replace function stricttest() returns void as $$
declare x record;
begin
-- too many rows, no parameters
execute 'select * from foo where f1 > 3' into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
CONTEXT: PL/pgSQL function footest() line 5 at EXECUTE
create or replace function footest() returns void as $$
CONTEXT: PL/pgSQL function stricttest() line 5 at EXECUTE
create or replace function stricttest() returns void as $$
-- override the global
#print_strict_params off
declare
......@@ -2971,11 +2971,11 @@ begin
select * from foo where f1 > p1 or f1::text = p3 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
CONTEXT: PL/pgSQL function footest() line 10 at SQL statement
CONTEXT: PL/pgSQL function stricttest() line 10 at SQL statement
reset plpgsql.print_strict_params;
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
-- override the global
#print_strict_params on
declare
......@@ -2987,10 +2987,10 @@ begin
select * from foo where f1 > p1 or f1::text = p3 into strict x;
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
ERROR: query returned more than one row
DETAIL: parameters: p1 = '2', p3 = 'foo'
CONTEXT: PL/pgSQL function footest() line 10 at SQL statement
CONTEXT: PL/pgSQL function stricttest() line 10 at SQL statement
-- test warnings and errors
set plpgsql.extra_warnings to 'all';
set plpgsql.extra_warnings to 'none';
......
......@@ -1303,31 +1303,31 @@ ERROR: cannot change name of input parameter "c"
HINT: Use DROP FUNCTION dfunc(character varying,numeric) first.
drop function dfunc(varchar, numeric);
--fail, named parameters are not unique
create function testfoo(a int, a int) returns int as $$ select 1;$$ language sql;
create function testpolym(a int, a int) returns int as $$ select 1;$$ language sql;
ERROR: parameter name "a" used more than once
create function testfoo(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
create function testpolym(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
ERROR: parameter name "a" used more than once
create function testfoo(out a int, inout a int) returns int as $$ select 1;$$ language sql;
create function testpolym(out a int, inout a int) returns int as $$ select 1;$$ language sql;
ERROR: parameter name "a" used more than once
create function testfoo(a int, inout a int) returns int as $$ select 1;$$ language sql;
create function testpolym(a int, inout a int) returns int as $$ select 1;$$ language sql;
ERROR: parameter name "a" used more than once
-- valid
create function testfoo(a int, out a int) returns int as $$ select $1;$$ language sql;
select testfoo(37);
testfoo
---------
37
create function testpolym(a int, out a int) returns int as $$ select $1;$$ language sql;
select testpolym(37);
testpolym
-----------
37
(1 row)
drop function testfoo(int);
create function testfoo(a int) returns table(a int) as $$ select $1;$$ language sql;
select * from testfoo(37);
drop function testpolym(int);
create function testpolym(a int) returns table(a int) as $$ select $1;$$ language sql;
select * from testpolym(37);
a
----
37
(1 row)
drop function testfoo(int);
drop function testpolym(int);
-- test polymorphic params and defaults
create function dfunc(a anyelement, b anyelement = null, flag bool = true)
returns anyelement as $$
......
......@@ -649,84 +649,84 @@ DETAIL: GRANT and REVOKE are not allowed on untrusted languages, because only s
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT USAGE ON LANGUAGE sql TO regress_priv_user2; -- fail
WARNING: no privileges were granted for "sql"
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE testagg1(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testproc1(int) AS 'select $1;' LANGUAGE sql;
REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int), testagg1(int) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int), testagg1(int) TO regress_priv_user2;
REVOKE ALL ON FUNCTION testproc1(int) FROM PUBLIC; -- fail, not a function
ERROR: testproc1(integer) is not a function
REVOKE ALL ON PROCEDURE testproc1(int) FROM PUBLIC;
GRANT EXECUTE ON PROCEDURE testproc1(int) TO regress_priv_user2;
GRANT USAGE ON FUNCTION testfunc1(int) TO regress_priv_user3; -- semantic error
CREATE FUNCTION priv_testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION priv_testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE priv_testagg1(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE priv_testproc1(int) AS 'select $1;' LANGUAGE sql;
REVOKE ALL ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) TO regress_priv_user2;
REVOKE ALL ON FUNCTION priv_testproc1(int) FROM PUBLIC; -- fail, not a function
ERROR: priv_testproc1(integer) is not a function
REVOKE ALL ON PROCEDURE priv_testproc1(int) FROM PUBLIC;
GRANT EXECUTE ON PROCEDURE priv_testproc1(int) TO regress_priv_user2;
GRANT USAGE ON FUNCTION priv_testfunc1(int) TO regress_priv_user3; -- semantic error
ERROR: invalid privilege type USAGE for function
GRANT USAGE ON FUNCTION testagg1(int) TO regress_priv_user3; -- semantic error
GRANT USAGE ON FUNCTION priv_testagg1(int) TO regress_priv_user3; -- semantic error
ERROR: invalid privilege type USAGE for function
GRANT USAGE ON PROCEDURE testproc1(int) TO regress_priv_user3; -- semantic error
GRANT USAGE ON PROCEDURE priv_testproc1(int) TO regress_priv_user3; -- semantic error
ERROR: invalid privilege type USAGE for procedure
GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regress_priv_user4;
ERROR: function testfunc_nosuch(integer) does not exist
GRANT ALL PRIVILEGES ON FUNCTION testagg1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON PROCEDURE testproc1(int) TO regress_priv_user4;
CREATE FUNCTION testfunc4(boolean) RETURNS text
GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc_nosuch(int) TO regress_priv_user4;
ERROR: function priv_testfunc_nosuch(integer) does not exist
GRANT ALL PRIVILEGES ON FUNCTION priv_testagg1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON PROCEDURE priv_testproc1(int) TO regress_priv_user4;
CREATE FUNCTION priv_testfunc4(boolean) RETURNS text
AS 'select col1 from atest2 where col2 = $1;'
LANGUAGE sql SECURITY DEFINER;
GRANT EXECUTE ON FUNCTION testfunc4(boolean) TO regress_priv_user3;
GRANT EXECUTE ON FUNCTION priv_testfunc4(boolean) TO regress_priv_user3;
SET SESSION AUTHORIZATION regress_priv_user2;
SELECT testfunc1(5), testfunc2(5); -- ok
testfunc1 | testfunc2
-----------+-----------
10 | 15
SELECT priv_testfunc1(5), priv_testfunc2(5); -- ok
priv_testfunc1 | priv_testfunc2
----------------+----------------
10 | 15
(1 row)
CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
CREATE FUNCTION priv_testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
ERROR: permission denied for language sql
SELECT testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
testagg1
----------
6
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
priv_testagg1
---------------
6
(1 row)
CALL testproc1(6); -- ok
CALL priv_testproc1(6); -- ok
SET SESSION AUTHORIZATION regress_priv_user3;
SELECT testfunc1(5); -- fail
ERROR: permission denied for function testfunc1
SELECT testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- fail
ERROR: permission denied for aggregate testagg1
CALL testproc1(6); -- fail
ERROR: permission denied for procedure testproc1
SELECT priv_testfunc1(5); -- fail
ERROR: permission denied for function priv_testfunc1
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- fail
ERROR: permission denied for aggregate priv_testagg1
CALL priv_testproc1(6); -- fail
ERROR: permission denied for procedure priv_testproc1
SELECT col1 FROM atest2 WHERE col2 = true; -- fail
ERROR: permission denied for table atest2
SELECT testfunc4(true); -- ok
testfunc4
-----------
SELECT priv_testfunc4(true); -- ok
priv_testfunc4
----------------
bar
(1 row)
SET SESSION AUTHORIZATION regress_priv_user4;
SELECT testfunc1(5); -- ok
testfunc1
-----------
10
SELECT priv_testfunc1(5); -- ok
priv_testfunc1
----------------
10
(1 row)
SELECT testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
testagg1
----------
6
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
priv_testagg1
---------------
6
(1 row)
CALL testproc1(6); -- ok
DROP FUNCTION testfunc1(int); -- fail
ERROR: must be owner of function testfunc1
DROP AGGREGATE testagg1(int); -- fail
ERROR: must be owner of aggregate testagg1
DROP PROCEDURE testproc1(int); -- fail
ERROR: must be owner of procedure testproc1
CALL priv_testproc1(6); -- ok
DROP FUNCTION priv_testfunc1(int); -- fail
ERROR: must be owner of function priv_testfunc1
DROP AGGREGATE priv_testagg1(int); -- fail
ERROR: must be owner of aggregate priv_testagg1
DROP PROCEDURE priv_testproc1(int); -- fail
ERROR: must be owner of procedure priv_testproc1
\c -
DROP FUNCTION testfunc1(int); -- ok
DROP FUNCTION priv_testfunc1(int); -- ok
-- restore to sanity
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
-- verify privilege checks on array-element coercions
......@@ -751,100 +751,100 @@ ROLLBACK;
-- privileges on types
-- switch to superuser
\c -
CREATE TYPE testtype1 AS (a int, b text);
REVOKE USAGE ON TYPE testtype1 FROM PUBLIC;
GRANT USAGE ON TYPE testtype1 TO regress_priv_user2;
GRANT USAGE ON TYPE _testtype1 TO regress_priv_user2; -- fail
CREATE TYPE priv_testtype1 AS (a int, b text);
REVOKE USAGE ON TYPE priv_testtype1 FROM PUBLIC;
GRANT USAGE ON TYPE priv_testtype1 TO regress_priv_user2;
GRANT USAGE ON TYPE _priv_testtype1 TO regress_priv_user2; -- fail
ERROR: cannot set privileges of array types
HINT: Set the privileges of the element type instead.
GRANT USAGE ON DOMAIN testtype1 TO regress_priv_user2; -- fail
ERROR: "testtype1" is not a domain
CREATE DOMAIN testdomain1 AS int;
REVOKE USAGE on DOMAIN testdomain1 FROM PUBLIC;
GRANT USAGE ON DOMAIN testdomain1 TO regress_priv_user2;
GRANT USAGE ON TYPE testdomain1 TO regress_priv_user2; -- ok
GRANT USAGE ON DOMAIN priv_testtype1 TO regress_priv_user2; -- fail
ERROR: "priv_testtype1" is not a domain
CREATE DOMAIN priv_testdomain1 AS int;
REVOKE USAGE on DOMAIN priv_testdomain1 FROM PUBLIC;
GRANT USAGE ON DOMAIN priv_testdomain1 TO regress_priv_user2;
GRANT USAGE ON TYPE priv_testdomain1 TO regress_priv_user2; -- ok
SET SESSION AUTHORIZATION regress_priv_user1;
-- commands that should fail
CREATE AGGREGATE testagg1a(testdomain1) (sfunc = int4_sum, stype = bigint);
ERROR: permission denied for type testdomain1
CREATE DOMAIN testdomain2a AS testdomain1;
ERROR: permission denied for type testdomain1
CREATE DOMAIN testdomain3a AS int;
CREATE FUNCTION castfunc(int) RETURNS testdomain3a AS $$ SELECT $1::testdomain3a $$ LANGUAGE SQL;
CREATE CAST (testdomain1 AS testdomain3a) WITH FUNCTION castfunc(int);
ERROR: permission denied for type testdomain1
CREATE AGGREGATE priv_testagg1a(priv_testdomain1) (sfunc = int4_sum, stype = bigint);
ERROR: permission denied for type priv_testdomain1
CREATE DOMAIN priv_testdomain2a AS priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
CREATE DOMAIN priv_testdomain3a AS int;
CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3a AS $$ SELECT $1::priv_testdomain3a $$ LANGUAGE SQL;
CREATE CAST (priv_testdomain1 AS priv_testdomain3a) WITH FUNCTION castfunc(int);
ERROR: permission denied for type priv_testdomain1
DROP FUNCTION castfunc(int) CASCADE;
DROP DOMAIN testdomain3a;
CREATE FUNCTION testfunc5a(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
ERROR: permission denied for type testdomain1
CREATE FUNCTION testfunc6a(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
ERROR: permission denied for type testdomain1
CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = testdomain1, RIGHTARG = testdomain1);
ERROR: permission denied for type testdomain1
CREATE TABLE test5a (a int, b testdomain1);
ERROR: permission denied for type testdomain1
CREATE TABLE test6a OF testtype1;
ERROR: permission denied for type testtype1
CREATE TABLE test10a (a int[], b testtype1[]);
ERROR: permission denied for type testtype1
DROP DOMAIN priv_testdomain3a;
CREATE FUNCTION priv_testfunc5a(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
ERROR: permission denied for type priv_testdomain1
CREATE FUNCTION priv_testfunc6a(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$;
ERROR: permission denied for type priv_testdomain1
CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = priv_testdomain1, RIGHTARG = priv_testdomain1);
ERROR: permission denied for type priv_testdomain1
CREATE TABLE test5a (a int, b priv_testdomain1);
ERROR: permission denied for type priv_testdomain1
CREATE TABLE test6a OF priv_testtype1;
ERROR: permission denied for type priv_testtype1
CREATE TABLE test10a (a int[], b priv_testtype1[]);
ERROR: permission denied for type priv_testtype1
CREATE TABLE test9a (a int, b int);
ALTER TABLE test9a ADD COLUMN c testdomain1;
ERROR: permission denied for type testdomain1
ALTER TABLE test9a ALTER COLUMN b TYPE testdomain1;
ERROR: permission denied for type testdomain1
CREATE TYPE test7a AS (a int, b testdomain1);
ERROR: permission denied for type testdomain1
ALTER TABLE test9a ADD COLUMN c priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
ALTER TABLE test9a ALTER COLUMN b TYPE priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
CREATE TYPE test7a AS (a int, b priv_testdomain1);
ERROR: permission denied for type priv_testdomain1
CREATE TYPE test8a AS (a int, b int);
ALTER TYPE test8a ADD ATTRIBUTE c testdomain1;
ERROR: permission denied for type testdomain1
ALTER TYPE test8a ALTER ATTRIBUTE b TYPE testdomain1;
ERROR: permission denied for type testdomain1
CREATE TABLE test11a AS (SELECT 1::testdomain1 AS a);
ERROR: permission denied for type testdomain1
REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
ERROR: permission denied for type testtype1
ALTER TYPE test8a ADD ATTRIBUTE c priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
ALTER TYPE test8a ALTER ATTRIBUTE b TYPE priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
CREATE TABLE test11a AS (SELECT 1::priv_testdomain1 AS a);
ERROR: permission denied for type priv_testdomain1
REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC;
ERROR: permission denied for type priv_testtype1
SET SESSION AUTHORIZATION regress_priv_user2;
-- commands that should succeed
CREATE AGGREGATE testagg1b(testdomain1) (sfunc = int4_sum, stype = bigint);
CREATE DOMAIN testdomain2b AS testdomain1;
CREATE DOMAIN testdomain3b AS int;
CREATE FUNCTION castfunc(int) RETURNS testdomain3b AS $$ SELECT $1::testdomain3b $$ LANGUAGE SQL;
CREATE CAST (testdomain1 AS testdomain3b) WITH FUNCTION castfunc(int);
CREATE AGGREGATE priv_testagg1b(priv_testdomain1) (sfunc = int4_sum, stype = bigint);
CREATE DOMAIN priv_testdomain2b AS priv_testdomain1;
CREATE DOMAIN priv_testdomain3b AS int;
CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3b AS $$ SELECT $1::priv_testdomain3b $$ LANGUAGE SQL;
CREATE CAST (priv_testdomain1 AS priv_testdomain3b) WITH FUNCTION castfunc(int);
WARNING: cast will be ignored because the source data type is a domain
CREATE FUNCTION testfunc5b(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
CREATE FUNCTION testfunc6b(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
CREATE OPERATOR !! (PROCEDURE = testfunc5b, RIGHTARG = testdomain1);
CREATE TABLE test5b (a int, b testdomain1);
CREATE TABLE test6b OF testtype1;
CREATE TABLE test10b (a int[], b testtype1[]);
CREATE FUNCTION priv_testfunc5b(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
CREATE FUNCTION priv_testfunc6b(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$;
CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1);
CREATE TABLE test5b (a int, b priv_testdomain1);
CREATE TABLE test6b OF priv_testtype1;
CREATE TABLE test10b (a int[], b priv_testtype1[]);
CREATE TABLE test9b (a int, b int);
ALTER TABLE test9b ADD COLUMN c testdomain1;
ALTER TABLE test9b ALTER COLUMN b TYPE testdomain1;
CREATE TYPE test7b AS (a int, b testdomain1);
ALTER TABLE test9b ADD COLUMN c priv_testdomain1;
ALTER TABLE test9b ALTER COLUMN b TYPE priv_testdomain1;
CREATE TYPE test7b AS (a int, b priv_testdomain1);
CREATE TYPE test8b AS (a int, b int);
ALTER TYPE test8b ADD ATTRIBUTE c testdomain1;
ALTER TYPE test8b ALTER ATTRIBUTE b TYPE testdomain1;
CREATE TABLE test11b AS (SELECT 1::testdomain1 AS a);
REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
WARNING: no privileges could be revoked for "testtype1"
ALTER TYPE test8b ADD ATTRIBUTE c priv_testdomain1;
ALTER TYPE test8b ALTER ATTRIBUTE b TYPE priv_testdomain1;
CREATE TABLE test11b AS (SELECT 1::priv_testdomain1 AS a);
REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC;
WARNING: no privileges could be revoked for "priv_testtype1"
\c -
DROP AGGREGATE testagg1b(testdomain1);
DROP DOMAIN testdomain2b;
DROP OPERATOR !! (NONE, testdomain1);
DROP FUNCTION testfunc5b(a testdomain1);
DROP FUNCTION testfunc6b(b int);
DROP AGGREGATE priv_testagg1b(priv_testdomain1);
DROP DOMAIN priv_testdomain2b;
DROP OPERATOR !! (NONE, priv_testdomain1);
DROP FUNCTION priv_testfunc5b(a priv_testdomain1);
DROP FUNCTION priv_testfunc6b(b int);
DROP TABLE test5b;
DROP TABLE test6b;
DROP TABLE test9b;
DROP TABLE test10b;
DROP TYPE test7b;
DROP TYPE test8b;
DROP CAST (testdomain1 AS testdomain3b);
DROP CAST (priv_testdomain1 AS priv_testdomain3b);
DROP FUNCTION castfunc(int) CASCADE;
DROP DOMAIN testdomain3b;
DROP DOMAIN priv_testdomain3b;
DROP TABLE test11b;
DROP TYPE testtype1; -- ok
DROP DOMAIN testdomain1; -- ok
DROP TYPE priv_testtype1; -- ok
DROP DOMAIN priv_testdomain1; -- ok
-- truncate
SET SESSION AUTHORIZATION regress_priv_user5;
TRUNCATE atest2; -- ok
......@@ -1620,23 +1620,23 @@ DROP FUNCTION testns.foo();
DROP AGGREGATE testns.agg1(int);
DROP PROCEDURE testns.bar();
ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE USAGE ON TYPES FROM public;
CREATE DOMAIN testns.testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.testdomain1', 'USAGE'); -- no
CREATE DOMAIN testns.priv_testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); -- no
has_type_privilege
--------------------
f
(1 row)
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public;
DROP DOMAIN testns.testdomain1;
CREATE DOMAIN testns.testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.testdomain1', 'USAGE'); -- yes
DROP DOMAIN testns.priv_testdomain1;
CREATE DOMAIN testns.priv_testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); -- yes
has_type_privilege
--------------------
t
(1 row)
DROP DOMAIN testns.testdomain1;
DROP DOMAIN testns.priv_testdomain1;
RESET ROLE;
SELECT count(*)
FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
......@@ -1696,67 +1696,67 @@ SELECT has_table_privilege('regress_priv_user1', 'testns.t2', 'SELECT'); -- fals
f
(1 row)
CREATE FUNCTION testns.testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE testns.testagg(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testns.testproc(int) AS 'select 3' LANGUAGE sql;
SELECT has_function_privilege('regress_priv_user1', 'testns.testfunc(int)', 'EXECUTE'); -- true by default
CREATE FUNCTION testns.priv_testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE testns.priv_testagg(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testns.priv_testproc(int) AS 'select 3' LANGUAGE sql;
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- true by default
has_function_privilege
------------------------
t
(1 row)
SELECT has_function_privilege('regress_priv_user1', 'testns.testagg(int)', 'EXECUTE'); -- true by default
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- true by default
has_function_privilege
------------------------
t
(1 row)
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- true by default
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- true by default
has_function_privilege
------------------------
t
(1 row)
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC;
SELECT has_function_privilege('regress_priv_user1', 'testns.testfunc(int)', 'EXECUTE'); -- false
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- false
has_function_privilege
------------------------
f
(1 row)
SELECT has_function_privilege('regress_priv_user1', 'testns.testagg(int)', 'EXECUTE'); -- false
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- false
has_function_privilege
------------------------
f
(1 row)
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- still true, not a function
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- still true, not a function
has_function_privilege
------------------------
t
(1 row)
REVOKE ALL ON ALL PROCEDURES IN SCHEMA testns FROM PUBLIC;
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- now false
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- now false
has_function_privilege
------------------------
f
(1 row)
GRANT ALL ON ALL ROUTINES IN SCHEMA testns TO PUBLIC;
SELECT has_function_privilege('regress_priv_user1', 'testns.testfunc(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- true
has_function_privilege
------------------------
t
(1 row)
SELECT has_function_privilege('regress_priv_user1', 'testns.testagg(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- true
has_function_privilege
------------------------
t
(1 row)
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- true
has_function_privilege
------------------------
t
......@@ -1847,10 +1847,10 @@ drop table dep_priv_test;
-- clean up
\c
drop sequence x_seq;
DROP AGGREGATE testagg1(int);
DROP FUNCTION testfunc2(int);
DROP FUNCTION testfunc4(boolean);
DROP PROCEDURE testproc1(int);
DROP AGGREGATE priv_testagg1(int);
DROP FUNCTION priv_testfunc2(int);
DROP FUNCTION priv_testfunc4(boolean);
DROP PROCEDURE priv_testproc1(int);
DROP VIEW atestv0;
DROP VIEW atestv1;
DROP VIEW atestv2;
......
CREATE TABLE foo2(fooid int, f2 int);
INSERT INTO foo2 VALUES(1, 11);
INSERT INTO foo2 VALUES(2, 22);
INSERT INTO foo2 VALUES(1, 111);
CREATE FUNCTION foot(int) returns setof foo2 as 'SELECT * FROM foo2 WHERE fooid = $1 ORDER BY f2;' LANGUAGE SQL;
CREATE TABLE rngfunc2(rngfuncid int, f2 int);
INSERT INTO rngfunc2 VALUES(1, 11);
INSERT INTO rngfunc2 VALUES(2, 22);
INSERT INTO rngfunc2 VALUES(1, 111);
CREATE FUNCTION rngfunct(int) returns setof rngfunc2 as 'SELECT * FROM rngfunc2 WHERE rngfuncid = $1 ORDER BY f2;' LANGUAGE SQL;
-- function with ORDINALITY
select * from foot(1) with ordinality as z(a,b,ord);
select * from rngfunct(1) with ordinality as z(a,b,ord);
a | b | ord
---+-----+-----
1 | 11 | 1
1 | 111 | 2
(2 rows)
select * from foot(1) with ordinality as z(a,b,ord) where b > 100; -- ordinal 2, not 1
select * from rngfunct(1) with ordinality as z(a,b,ord) where b > 100; -- ordinal 2, not 1
a | b | ord
---+-----+-----
1 | 111 | 2
(1 row)
-- ordinality vs. column names and types
select a,b,ord from foot(1) with ordinality as z(a,b,ord);
select a,b,ord from rngfunct(1) with ordinality as z(a,b,ord);
a | b | ord
---+-----+-----
1 | 11 | 1
......@@ -61,7 +61,7 @@ select row_to_json(s.*) from generate_series(11,14) with ordinality s;
(4 rows)
-- ordinality vs. views
create temporary view vw_ord as select * from (values (1)) v(n) join foot(1) with ordinality as z(a,b,ord) on (n=ord);
create temporary view vw_ord as select * from (values (1)) v(n) join rngfunct(1) with ordinality as z(a,b,ord) on (n=ord);
select * from vw_ord;
n | a | b | ord
---+---+----+-----
......@@ -69,26 +69,26 @@ select * from vw_ord;
(1 row)
select definition from pg_views where viewname='vw_ord';
definition
---------------------------------------------------------------------
SELECT v.n, +
z.a, +
z.b, +
z.ord +
FROM (( VALUES (1)) v(n) +
JOIN foot(1) WITH ORDINALITY z(a, b, ord) ON ((v.n = z.ord)));
definition
-------------------------------------------------------------------------
SELECT v.n, +
z.a, +
z.b, +
z.ord +
FROM (( VALUES (1)) v(n) +
JOIN rngfunct(1) WITH ORDINALITY z(a, b, ord) ON ((v.n = z.ord)));
(1 row)
drop view vw_ord;
-- multiple functions
select * from rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord);
select * from rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord);
a | b | c | d | ord
---+-----+---+----+-----
1 | 11 | 2 | 22 | 1
1 | 111 | | | 2
(2 rows)
create temporary view vw_ord as select * from (values (1)) v(n) join rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
create temporary view vw_ord as select * from (values (1)) v(n) join rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
select * from vw_ord;
n | a | b | c | d | ord
---+---+----+---+----+-----
......@@ -96,16 +96,16 @@ select * from vw_ord;
(1 row)
select definition from pg_views where viewname='vw_ord';
definition
-----------------------------------------------------------------------------------------------
SELECT v.n, +
z.a, +
z.b, +
z.c, +
z.d, +
z.ord +
FROM (( VALUES (1)) v(n) +
JOIN ROWS FROM(foot(1), foot(2)) WITH ORDINALITY z(a, b, c, d, ord) ON ((v.n = z.ord)));
definition
-------------------------------------------------------------------------------------------------------
SELECT v.n, +
z.a, +
z.b, +
z.c, +
z.d, +
z.ord +
FROM (( VALUES (1)) v(n) +
JOIN ROWS FROM(rngfunct(1), rngfunct(2)) WITH ORDINALITY z(a, b, c, d, ord) ON ((v.n = z.ord)));
(1 row)
drop view vw_ord;
......@@ -194,8 +194,8 @@ select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
-- ordinality and multiple functions vs. rewind and reverse scan
begin;
declare foo scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
fetch all from foo;
declare rf_cur scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
fetch all from rf_cur;
i | j | o
---+---+---
1 | 1 | 1
......@@ -205,7 +205,7 @@ fetch all from foo;
5 | | 5
(5 rows)
fetch backward all from foo;
fetch backward all from rf_cur;
i | j | o
---+---+---
5 | | 5
......@@ -215,7 +215,7 @@ fetch backward all from foo;
1 | 1 | 1
(5 rows)
fetch all from foo;
fetch all from rf_cur;
i | j | o
---+---+---
1 | 1 | 1
......@@ -225,59 +225,59 @@ fetch all from foo;
5 | | 5
(5 rows)
fetch next from foo;
fetch next from rf_cur;
i | j | o
---+---+---
(0 rows)
fetch next from foo;
fetch next from rf_cur;
i | j | o
---+---+---
(0 rows)
fetch prior from foo;
fetch prior from rf_cur;
i | j | o
---+---+---
5 | | 5
(1 row)
fetch absolute 1 from foo;
fetch absolute 1 from rf_cur;
i | j | o
---+---+---
1 | 1 | 1
(1 row)
fetch next from foo;
fetch next from rf_cur;
i | j | o
---+---+---
2 | 2 | 2
(1 row)
fetch next from foo;
fetch next from rf_cur;
i | j | o
---+---+---
3 | | 3
(1 row)
fetch next from foo;
fetch next from rf_cur;
i | j | o
---+---+---
4 | | 4
(1 row)
fetch prior from foo;
fetch prior from rf_cur;
i | j | o
---+---+---
3 | | 3
(1 row)
fetch prior from foo;
fetch prior from rf_cur;
i | j | o
---+---+---
2 | 2 | 2
(1 row)
fetch prior from foo;
fetch prior from rf_cur;
i | j | o
---+---+---
1 | 1 | 1
......@@ -285,357 +285,357 @@ fetch prior from foo;
commit;
-- function with implicit LATERAL
select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
fooid | f2 | fooid | f2
-------+-----+-------+-----
1 | 11 | 1 | 11
2 | 22 | 2 | 22
1 | 111 | 1 | 111
select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) z where rngfunc2.f2 = z.f2;
rngfuncid | f2 | rngfuncid | f2
-----------+-----+-----------+-----
1 | 11 | 1 | 11
2 | 22 | 2 | 22
1 | 111 | 1 | 111
(3 rows)
-- function with implicit LATERAL and explicit ORDINALITY
select * from foo2, foot(foo2.fooid) with ordinality as z(fooid,f2,ord) where foo2.f2 = z.f2;
fooid | f2 | fooid | f2 | ord
-------+-----+-------+-----+-----
1 | 11 | 1 | 11 | 1
2 | 22 | 2 | 22 | 1
1 | 111 | 1 | 111 | 2
select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) with ordinality as z(rngfuncid,f2,ord) where rngfunc2.f2 = z.f2;
rngfuncid | f2 | rngfuncid | f2 | ord
-----------+-----+-----------+-----+-----
1 | 11 | 1 | 11 | 1
2 | 22 | 2 | 22 | 1
1 | 111 | 1 | 111 | 2
(3 rows)
-- function in subselect
select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = foo2.fooid) ORDER BY 1,2;
fooid | f2
-------+-----
1 | 11
1 | 111
2 | 22
select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2;
rngfuncid | f2
-----------+-----
1 | 11
1 | 111
2 | 22
(3 rows)
-- function in subselect
select * from foo2 where f2 in (select f2 from foot(1) z where z.fooid = foo2.fooid) ORDER BY 1,2;
fooid | f2
-------+-----
1 | 11
1 | 111
select * from rngfunc2 where f2 in (select f2 from rngfunct(1) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2;
rngfuncid | f2
-----------+-----
1 | 11
1 | 111
(2 rows)
-- function in subselect
select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = 1) ORDER BY 1,2;
fooid | f2
-------+-----
1 | 11
1 | 111
select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = 1) ORDER BY 1,2;
rngfuncid | f2
-----------+-----
1 | 11
1 | 111
(2 rows)
-- nested functions
select foot.fooid, foot.f2 from foot(sin(pi()/2)::int) ORDER BY 1,2;
fooid | f2
-------+-----
1 | 11
1 | 111
select rngfunct.rngfuncid, rngfunct.f2 from rngfunct(sin(pi()/2)::int) ORDER BY 1,2;
rngfuncid | f2
-----------+-----
1 | 11
1 | 111
(2 rows)
CREATE TABLE foo (fooid int, foosubid int, fooname text, primary key(fooid,foosubid));
INSERT INTO foo VALUES(1,1,'Joe');
INSERT INTO foo VALUES(1,2,'Ed');
INSERT INTO foo VALUES(2,1,'Mary');
CREATE TABLE rngfunc (rngfuncid int, rngfuncsubid int, rngfuncname text, primary key(rngfuncid,rngfuncsubid));
INSERT INTO rngfunc VALUES(1,1,'Joe');
INSERT INTO rngfunc VALUES(1,2,'Ed');
INSERT INTO rngfunc VALUES(2,1,'Mary');
-- sql, proretset = f, prorettype = b
CREATE FUNCTION getfoo1(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL;
SELECT * FROM getfoo1(1) AS t1;
CREATE FUNCTION getrngfunc1(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc1(1) AS t1;
t1
----
1
(1 row)
SELECT * FROM getfoo1(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM getrngfunc1(1) WITH ORDINALITY AS t1(v,o);
v | o
---+---
1 | 1
(1 row)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo1(1);
SELECT * FROM vw_getfoo;
getfoo1
---------
1
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1);
SELECT * FROM vw_getrngfunc;
getrngfunc1
-------------
1
(1 row)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo1(1) WITH ORDINALITY as t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) WITH ORDINALITY as t1(v,o);
SELECT * FROM vw_getrngfunc;
v | o
---+---
1 | 1
(1 row)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = b
CREATE FUNCTION getfoo2(int) RETURNS setof int AS 'SELECT fooid FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo2(1) AS t1;
CREATE FUNCTION getrngfunc2(int) RETURNS setof int AS 'SELECT rngfuncid FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc2(1) AS t1;
t1
----
1
1
(2 rows)
SELECT * FROM getfoo2(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o);
v | o
---+---
1 | 1
1 | 2
(2 rows)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo2(1);
SELECT * FROM vw_getfoo;
getfoo2
---------
1
1
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1);
SELECT * FROM vw_getrngfunc;
getrngfunc2
-------------
1
1
(2 rows)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo2(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getrngfunc;
v | o
---+---
1 | 1
1 | 2
(2 rows)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = b
CREATE FUNCTION getfoo3(int) RETURNS setof text AS 'SELECT fooname FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo3(1) AS t1;
CREATE FUNCTION getrngfunc3(int) RETURNS setof text AS 'SELECT rngfuncname FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc3(1) AS t1;
t1
-----
Joe
Ed
(2 rows)
SELECT * FROM getfoo3(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o);
v | o
-----+---
Joe | 1
Ed | 2
(2 rows)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo3(1);
SELECT * FROM vw_getfoo;
getfoo3
---------
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1);
SELECT * FROM vw_getrngfunc;
getrngfunc3
-------------
Joe
Ed
(2 rows)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo3(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getrngfunc;
v | o
-----+---
Joe | 1
Ed | 2
(2 rows)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- sql, proretset = f, prorettype = c
CREATE FUNCTION getfoo4(int) RETURNS foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo4(1) AS t1;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
CREATE FUNCTION getrngfunc4(int) RETURNS rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc4(1) AS t1;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
(1 row)
SELECT * FROM getfoo4(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o);
a | b | c | o
---+---+-----+---
1 | 1 | Joe | 1
(1 row)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo4(1);
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1);
SELECT * FROM vw_getrngfunc;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
(1 row)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo4(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getrngfunc;
a | b | c | o
---+---+-----+---
1 | 1 | Joe | 1
(1 row)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = c
CREATE FUNCTION getfoo5(int) RETURNS setof foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo5(1) AS t1;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
1 | 2 | Ed
CREATE FUNCTION getrngfunc5(int) RETURNS setof rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc5(1) AS t1;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
1 | 2 | Ed
(2 rows)
SELECT * FROM getfoo5(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o);
a | b | c | o
---+---+-----+---
1 | 1 | Joe | 1
1 | 2 | Ed | 2
(2 rows)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo5(1);
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
1 | 2 | Ed
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1);
SELECT * FROM vw_getrngfunc;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
1 | 2 | Ed
(2 rows)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo5(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getrngfunc;
a | b | c | o
---+---+-----+---
1 | 1 | Joe | 1
1 | 2 | Ed | 2
(2 rows)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- sql, proretset = f, prorettype = record
CREATE FUNCTION getfoo6(int) RETURNS RECORD AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo6(1) AS t1(fooid int, foosubid int, fooname text);
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
CREATE FUNCTION getrngfunc6(int) RETURNS RECORD AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc6(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text);
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
(1 row)
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
fooid | foosubid | fooname | ordinality
-------+----------+---------+------------
1 | 1 | Joe | 1
SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY;
rngfuncid | rngfuncsubid | rngfuncname | ordinality
-----------+--------------+-------------+------------
1 | 1 | Joe | 1
(1 row)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo6(1) AS
(fooid int, foosubid int, fooname text);
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc6(1) AS
(rngfuncid int, rngfuncsubid int, rngfuncname text);
SELECT * FROM vw_getrngfunc;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
(1 row)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) )
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS
SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname | ordinality
-------+----------+---------+------------
1 | 1 | Joe | 1
SELECT * FROM vw_getrngfunc;
rngfuncid | rngfuncsubid | rngfuncname | ordinality
-----------+--------------+-------------+------------
1 | 1 | Joe | 1
(1 row)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = record
CREATE FUNCTION getfoo7(int) RETURNS setof record AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo7(1) AS t1(fooid int, foosubid int, fooname text);
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
1 | 2 | Ed
CREATE FUNCTION getrngfunc7(int) RETURNS setof record AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc7(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text);
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
1 | 2 | Ed
(2 rows)
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
fooid | foosubid | fooname | ordinality
-------+----------+---------+------------
1 | 1 | Joe | 1
1 | 2 | Ed | 2
SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY;
rngfuncid | rngfuncsubid | rngfuncname | ordinality
-----------+--------------+-------------+------------
1 | 1 | Joe | 1
1 | 2 | Ed | 2
(2 rows)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo7(1) AS
(fooid int, foosubid int, fooname text);
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
1 | 2 | Ed
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc7(1) AS
(rngfuncid int, rngfuncsubid int, rngfuncname text);
SELECT * FROM vw_getrngfunc;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
1 | 2 | Ed
(2 rows)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) )
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS
SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname | ordinality
-------+----------+---------+------------
1 | 1 | Joe | 1
1 | 2 | Ed | 2
SELECT * FROM vw_getrngfunc;
rngfuncid | rngfuncsubid | rngfuncname | ordinality
-----------+--------------+-------------+------------
1 | 1 | Joe | 1
1 | 2 | Ed | 2
(2 rows)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- plpgsql, proretset = f, prorettype = b
CREATE FUNCTION getfoo8(int) RETURNS int AS 'DECLARE fooint int; BEGIN SELECT fooid into fooint FROM foo WHERE fooid = $1; RETURN fooint; END;' LANGUAGE plpgsql;
SELECT * FROM getfoo8(1) AS t1;
CREATE FUNCTION getrngfunc8(int) RETURNS int AS 'DECLARE rngfuncint int; BEGIN SELECT rngfuncid into rngfuncint FROM rngfunc WHERE rngfuncid = $1; RETURN rngfuncint; END;' LANGUAGE plpgsql;
SELECT * FROM getrngfunc8(1) AS t1;
t1
----
1
(1 row)
SELECT * FROM getfoo8(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o);
v | o
---+---
1 | 1
(1 row)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo8(1);
SELECT * FROM vw_getfoo;
getfoo8
---------
1
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1);
SELECT * FROM vw_getrngfunc;
getrngfunc8
-------------
1
(1 row)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo8(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getrngfunc;
v | o
---+---
1 | 1
(1 row)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- plpgsql, proretset = f, prorettype = c
CREATE FUNCTION getfoo9(int) RETURNS foo AS 'DECLARE footup foo%ROWTYPE; BEGIN SELECT * into footup FROM foo WHERE fooid = $1; RETURN footup; END;' LANGUAGE plpgsql;
SELECT * FROM getfoo9(1) AS t1;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
CREATE FUNCTION getrngfunc9(int) RETURNS rngfunc AS 'DECLARE rngfunctup rngfunc%ROWTYPE; BEGIN SELECT * into rngfunctup FROM rngfunc WHERE rngfuncid = $1; RETURN rngfunctup; END;' LANGUAGE plpgsql;
SELECT * FROM getrngfunc9(1) AS t1;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
(1 row)
SELECT * FROM getfoo9(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o);
a | b | c | o
---+---+-----+---
1 | 1 | Joe | 1
(1 row)
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo9(1);
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname
-------+----------+---------
1 | 1 | Joe
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1);
SELECT * FROM vw_getrngfunc;
rngfuncid | rngfuncsubid | rngfuncname
-----------+--------------+-------------
1 | 1 | Joe
(1 row)
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo9(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getrngfunc;
a | b | c | o
---+---+-----+---
1 | 1 | Joe | 1
(1 row)
DROP VIEW vw_getfoo;
DROP VIEW vw_getrngfunc;
-- mix 'n match kinds, to exercise expandRTE and related logic
select * from rows from(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo8(1),getfoo9(1))
select * from rows from(getrngfunc1(1),getrngfunc2(1),getrngfunc3(1),getrngfunc4(1),getrngfunc5(1),
getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc8(1),getrngfunc9(1))
with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u);
a | b | c | d | e | f | g | h | i | j | k | l | m | o | p | q | r | s | t | u
---+---+-----+---+---+-----+---+---+-----+---+---+-----+---+---+-----+---+---+---+-----+---
......@@ -643,10 +643,10 @@ select * from rows from(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
| 1 | Ed | | | | 1 | 2 | Ed | | | | 1 | 2 | Ed | | | | | 2
(2 rows)
select * from rows from(getfoo9(1),getfoo8(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo5(1),getfoo4(1),getfoo3(1),getfoo2(1),getfoo1(1))
select * from rows from(getrngfunc9(1),getrngfunc8(1),
getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc5(1),getrngfunc4(1),getrngfunc3(1),getrngfunc2(1),getrngfunc1(1))
with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u);
a | b | c | d | e | f | g | h | i | j | k | l | m | o | p | q | r | s | t | u
---+---+-----+---+---+---+-----+---+---+-----+---+---+-----+---+---+-----+-----+---+---+---
......@@ -654,62 +654,62 @@ select * from rows from(getfoo9(1),getfoo8(1),
| | | | 1 | 2 | Ed | | | | 1 | 2 | Ed | | | | Ed | 1 | | 2
(2 rows)
create temporary view vw_foo as
select * from rows from(getfoo9(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo1(1))
create temporary view vw_rngfunc as
select * from rows from(getrngfunc9(1),
getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc1(1))
with ordinality as t1(a,b,c,d,e,f,g,n);
select * from vw_foo;
select * from vw_rngfunc;
a | b | c | d | e | f | g | n
---+---+-----+---+---+-----+---+---
1 | 1 | Joe | 1 | 1 | Joe | 1 | 1
| | | 1 | 2 | Ed | | 2
(2 rows)
select pg_get_viewdef('vw_foo');
pg_get_viewdef
------------------------------------------------------------------------------------------------------------------------------------------------------
SELECT t1.a, +
t1.b, +
t1.c, +
t1.d, +
t1.e, +
t1.f, +
t1.g, +
t1.n +
FROM ROWS FROM(getfoo9(1), getfoo7(1) AS (fooid integer, foosubid integer, fooname text), getfoo1(1)) WITH ORDINALITY t1(a, b, c, d, e, f, g, n);
(1 row)
drop view vw_foo;
DROP FUNCTION getfoo1(int);
DROP FUNCTION getfoo2(int);
DROP FUNCTION getfoo3(int);
DROP FUNCTION getfoo4(int);
DROP FUNCTION getfoo5(int);
DROP FUNCTION getfoo6(int);
DROP FUNCTION getfoo7(int);
DROP FUNCTION getfoo8(int);
DROP FUNCTION getfoo9(int);
DROP FUNCTION foot(int);
DROP TABLE foo2;
DROP TABLE foo;
select pg_get_viewdef('vw_rngfunc');
pg_get_viewdef
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SELECT t1.a, +
t1.b, +
t1.c, +
t1.d, +
t1.e, +
t1.f, +
t1.g, +
t1.n +
FROM ROWS FROM(getrngfunc9(1), getrngfunc7(1) AS (rngfuncid integer, rngfuncsubid integer, rngfuncname text), getrngfunc1(1)) WITH ORDINALITY t1(a, b, c, d, e, f, g, n);
(1 row)
drop view vw_rngfunc;
DROP FUNCTION getrngfunc1(int);
DROP FUNCTION getrngfunc2(int);
DROP FUNCTION getrngfunc3(int);
DROP FUNCTION getrngfunc4(int);
DROP FUNCTION getrngfunc5(int);
DROP FUNCTION getrngfunc6(int);
DROP FUNCTION getrngfunc7(int);
DROP FUNCTION getrngfunc8(int);
DROP FUNCTION getrngfunc9(int);
DROP FUNCTION rngfunct(int);
DROP TABLE rngfunc2;
DROP TABLE rngfunc;
-- Rescan tests --
CREATE TEMPORARY SEQUENCE foo_rescan_seq1;
CREATE TEMPORARY SEQUENCE foo_rescan_seq2;
CREATE TYPE foo_rescan_t AS (i integer, s bigint);
CREATE FUNCTION foo_sql(int,int) RETURNS setof foo_rescan_t AS 'SELECT i, nextval(''foo_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL;
CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq1;
CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq2;
CREATE TYPE rngfunc_rescan_t AS (i integer, s bigint);
CREATE FUNCTION rngfunc_sql(int,int) RETURNS setof rngfunc_rescan_t AS 'SELECT i, nextval(''rngfunc_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL;
-- plpgsql functions use materialize mode
CREATE FUNCTION foo_mat(int,int) RETURNS setof foo_rescan_t AS 'begin for i in $1..$2 loop return next (i, nextval(''foo_rescan_seq2'')); end loop; end;' LANGUAGE plpgsql;
CREATE FUNCTION rngfunc_mat(int,int) RETURNS setof rngfunc_rescan_t AS 'begin for i in $1..$2 loop return next (i, nextval(''rngfunc_rescan_seq2'')); end loop; end;' LANGUAGE plpgsql;
--invokes ExecReScanFunctionScan - all these cases should materialize the function only once
-- LEFT JOIN on a condition that the planner can't prove to be true is used to ensure the function
-- is on the inner path of a nestloop join
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_sql(11,13) ON (r+i)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) ON (r+i)<100;
r | i | s
---+----+---
1 | 11 | 1
......@@ -723,13 +723,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_sql(11,13) ON (r+i)<100;
3 | 13 | 3
(9 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_sql(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
r | i | s | o
---+----+---+---
1 | 11 | 1 | 1
......@@ -743,13 +743,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_sql(11,13) WITH ORDINALITY
3 | 13 | 3 | 3
(9 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) ON (r+i)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) ON (r+i)<100;
r | i | s
---+----+---
1 | 11 | 1
......@@ -763,13 +763,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) ON (r+i)<100;
3 | 13 | 3
(9 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
r | i | s | o
---+----+---+---
1 | 11 | 1 | 1
......@@ -783,13 +783,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) WITH ORDINALITY
3 | 13 | 3 | 3
(9 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( foo_sql(11,13), foo_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( rngfunc_sql(11,13), rngfunc_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
r | i1 | s1 | i2 | s2 | o
---+----+----+----+----+---
1 | 11 | 1 | 11 | 1 | 1
......@@ -860,13 +860,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) WITH O
(9 rows)
--invokes ExecReScanFunctionScan with chgParam != NULL (using implied LATERAL)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(10+r,13);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13);
r | i | s
---+----+---
1 | 11 | 1
......@@ -877,13 +877,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(10+r,13);
3 | 13 | 6
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(10+r,13) WITH ORDINALITY AS f(i,s,o);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13) WITH ORDINALITY AS f(i,s,o);
r | i | s | o
---+----+---+---
1 | 11 | 1 | 1
......@@ -894,13 +894,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(10+r,13) WITH ORDINALITY AS f(i
3 | 13 | 6 | 1
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(11,10+r);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r);
r | i | s
---+----+---
1 | 11 | 1
......@@ -911,13 +911,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(11,10+r);
3 | 13 | 6
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(11,10+r) WITH ORDINALITY AS f(i,s,o);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r) WITH ORDINALITY AS f(i,s,o);
r | i | s | o
---+----+---+---
1 | 11 | 1 | 1
......@@ -928,13 +928,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(11,10+r) WITH ORDINALITY AS f(i
3 | 13 | 6 | 3
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_sql(r1,r2);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2);
r1 | r2 | i | s
----+----+----+----
11 | 12 | 11 | 1
......@@ -949,13 +949,13 @@ SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_sql(r1,r2);
16 | 20 | 20 | 10
(10 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_sql(r1,r2) WITH ORDINALITY AS f(i,s,o);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2) WITH ORDINALITY AS f(i,s,o);
r1 | r2 | i | s | o
----+----+----+----+---
11 | 12 | 11 | 1 | 1
......@@ -970,13 +970,13 @@ SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_sql(r1,r2) WITH ORD
16 | 20 | 20 | 10 | 5
(10 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(10+r,13);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13);
r | i | s
---+----+---
1 | 11 | 1
......@@ -987,13 +987,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(10+r,13);
3 | 13 | 6
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(10+r,13) WITH ORDINALITY AS f(i,s,o);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13) WITH ORDINALITY AS f(i,s,o);
r | i | s | o
---+----+---+---
1 | 11 | 1 | 1
......@@ -1004,13 +1004,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(10+r,13) WITH ORDINALITY AS f(i
3 | 13 | 6 | 1
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(11,10+r);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r);
r | i | s
---+----+---
1 | 11 | 1
......@@ -1021,13 +1021,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(11,10+r);
3 | 13 | 6
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(11,10+r) WITH ORDINALITY AS f(i,s,o);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r) WITH ORDINALITY AS f(i,s,o);
r | i | s | o
---+----+---+---
1 | 11 | 1 | 1
......@@ -1038,13 +1038,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(11,10+r) WITH ORDINALITY AS f(i
3 | 13 | 6 | 3
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_mat(r1,r2);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2);
r1 | r2 | i | s
----+----+----+----
11 | 12 | 11 | 1
......@@ -1059,13 +1059,13 @@ SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_mat(r1,r2);
16 | 20 | 20 | 10
(10 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_mat(r1,r2) WITH ORDINALITY AS f(i,s,o);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2) WITH ORDINALITY AS f(i,s,o);
r1 | r2 | i | s | o
----+----+----+----+---
11 | 12 | 11 | 1 | 1
......@@ -1081,13 +1081,13 @@ SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_mat(r1,r2) WITH ORD
(10 rows)
-- selective rescan of multiple functions:
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(11,11), foo_mat(10+r,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(11,11), rngfunc_mat(10+r,13) );
r | i | s | i | s
---+----+---+----+---
1 | 11 | 1 | 11 | 1
......@@ -1098,13 +1098,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(11,11), foo_mat(10+r
3 | 11 | 1 | 13 | 6
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(11,11) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(11,11) );
r | i | s | i | s
---+----+---+----+---
1 | 11 | 1 | 11 | 1
......@@ -1115,13 +1115,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(11
3 | 13 | 6 | 11 | 1
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(10+r,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(10+r,13) );
r | i | s | i | s
---+----+---+----+---
1 | 11 | 1 | 11 | 1
......@@ -1132,13 +1132,13 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(10
3 | 13 | 6 | 13 | 6
(6 rows)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
setval | setval
--------+--------
1 | 1
(1 row)
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( foo_sql(10+r1,13), foo_mat(10+r2,13) );
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( rngfunc_sql(10+r1,13), rngfunc_mat(10+r2,13) );
r1 | r2 | i | s | i | s
----+----+----+----+----+---
1 | 1 | 11 | 1 | 11 | 1
......@@ -1391,53 +1391,53 @@ SELECT * FROM (VALUES (1),(2),(3)) v1(r1),
3 | 3 | 30 | 8
(45 rows)
DROP FUNCTION foo_sql(int,int);
DROP FUNCTION foo_mat(int,int);
DROP SEQUENCE foo_rescan_seq1;
DROP SEQUENCE foo_rescan_seq2;
DROP FUNCTION rngfunc_sql(int,int);
DROP FUNCTION rngfunc_mat(int,int);
DROP SEQUENCE rngfunc_rescan_seq1;
DROP SEQUENCE rngfunc_rescan_seq2;
--
-- Test cases involving OUT parameters
--
CREATE FUNCTION foo(in f1 int, out f2 int)
CREATE FUNCTION rngfunc(in f1 int, out f2 int)
AS 'select $1+1' LANGUAGE sql;
SELECT foo(42);
foo
-----
43
SELECT rngfunc(42);
rngfunc
---------
43
(1 row)
SELECT * FROM foo(42);
SELECT * FROM rngfunc(42);
f2
----
43
(1 row)
SELECT * FROM foo(42) AS p(x);
SELECT * FROM rngfunc(42) AS p(x);
x
----
43
(1 row)
-- explicit spec of return type is OK
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS int
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS int
AS 'select $1+1' LANGUAGE sql;
-- error, wrong result type
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS float
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS float
AS 'select $1+1' LANGUAGE sql;
ERROR: function result type must be integer because of OUT parameters
-- with multiple OUT params you must get a RECORD result
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text) RETURNS int
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) RETURNS int
AS 'select $1+1' LANGUAGE sql;
ERROR: function result type must be record because of OUT parameters
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text)
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text)
RETURNS record
AS 'select $1+1' LANGUAGE sql;
ERROR: cannot change return type of existing function
HINT: Use DROP FUNCTION foo(integer) first.
CREATE OR REPLACE FUNCTION foor(in f1 int, out f2 int, out text)
HINT: Use DROP FUNCTION rngfunc(integer) first.
CREATE OR REPLACE FUNCTION rngfuncr(in f1 int, out f2 int, out text)
AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql;
SELECT f1, foor(f1) FROM int4_tbl;
f1 | foor
SELECT f1, rngfuncr(f1) FROM int4_tbl;
f1 | rngfuncr
-------------+----------------------------
0 | (-1,0z)
123456 | (123455,123456z)
......@@ -1446,22 +1446,22 @@ SELECT f1, foor(f1) FROM int4_tbl;
-2147483647 | (-2147483648,-2147483647z)
(5 rows)
SELECT * FROM foor(42);
SELECT * FROM rngfuncr(42);
f2 | column2
----+---------
41 | 42z
(1 row)
SELECT * FROM foor(42) AS p(a,b);
SELECT * FROM rngfuncr(42) AS p(a,b);
a | b
----+-----
41 | 42z
(1 row)
CREATE OR REPLACE FUNCTION foob(in f1 int, inout f2 int, out text)
CREATE OR REPLACE FUNCTION rngfuncb(in f1 int, inout f2 int, out text)
AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql;
SELECT f1, foob(f1, f1/2) FROM int4_tbl;
f1 | foob
SELECT f1, rngfuncb(f1, f1/2) FROM int4_tbl;
f1 | rngfuncb
-------------+----------------------------
0 | (-1,0z)
123456 | (61727,123456z)
......@@ -1470,22 +1470,22 @@ SELECT f1, foob(f1, f1/2) FROM int4_tbl;
-2147483647 | (-1073741824,-2147483647z)
(5 rows)
SELECT * FROM foob(42, 99);
SELECT * FROM rngfuncb(42, 99);
f2 | column2
----+---------
98 | 42z
(1 row)
SELECT * FROM foob(42, 99) AS p(a,b);
SELECT * FROM rngfuncb(42, 99) AS p(a,b);
a | b
----+-----
98 | 42z
(1 row)
-- Can reference function with or without OUT params for DROP, etc
DROP FUNCTION foo(int);
DROP FUNCTION foor(in f2 int, out f1 int, out text);
DROP FUNCTION foob(in f1 int, inout f2 int);
DROP FUNCTION rngfunc(int);
DROP FUNCTION rngfuncr(in f2 int, out f1 int, out text);
DROP FUNCTION rngfuncb(in f1 int, inout f2 int);
--
-- For my next trick, polymorphic OUT parameters
--
......@@ -1535,10 +1535,10 @@ DETAIL: A function returning a polymorphic type must have at least one polymorp
--
-- table functions
--
CREATE OR REPLACE FUNCTION foo()
CREATE OR REPLACE FUNCTION rngfunc()
RETURNS TABLE(a int)
AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql;
SELECT * FROM foo();
SELECT * FROM rngfunc();
a
---
1
......@@ -1548,13 +1548,13 @@ SELECT * FROM foo();
5
(5 rows)
DROP FUNCTION foo();
CREATE OR REPLACE FUNCTION foo(int)
DROP FUNCTION rngfunc();
CREATE OR REPLACE FUNCTION rngfunc(int)
RETURNS TABLE(a int, b int)
AS $$ SELECT a, b
FROM generate_series(1,$1) a(a),
generate_series(1,$1) b(b) $$ LANGUAGE sql;
SELECT * FROM foo(3);
SELECT * FROM rngfunc(3);
a | b
---+---
1 | 1
......@@ -1568,18 +1568,18 @@ SELECT * FROM foo(3);
3 | 3
(9 rows)
DROP FUNCTION foo(int);
DROP FUNCTION rngfunc(int);
-- case that causes change of typmod knowledge during inlining
CREATE OR REPLACE FUNCTION foo()
CREATE OR REPLACE FUNCTION rngfunc()
RETURNS TABLE(a varchar(5))
AS $$ SELECT 'hello'::varchar(5) $$ LANGUAGE sql STABLE;
SELECT * FROM foo() GROUP BY 1;
SELECT * FROM rngfunc() GROUP BY 1;
a
-------
hello
(1 row)
DROP FUNCTION foo();
DROP FUNCTION rngfunc();
--
-- some tests on SQL functions with RETURNING
--
......@@ -1752,25 +1752,25 @@ select * from tt_log;
(2 rows)
-- test case for a whole-row-variable bug
create function foo1(n integer, out a text, out b text)
create function rngfunc1(n integer, out a text, out b text)
returns setof record
language sql
as $$ select 'foo ' || i, 'bar ' || i from generate_series(1,$1) i $$;
set work_mem='64kB';
select t.a, t, t.a from foo1(10000) t limit 1;
select t.a, t, t.a from rngfunc1(10000) t limit 1;
a | t | a
-------+-------------------+-------
foo 1 | ("foo 1","bar 1") | foo 1
(1 row)
reset work_mem;
select t.a, t, t.a from foo1(10000) t limit 1;
select t.a, t, t.a from rngfunc1(10000) t limit 1;
a | t | a
-------+-------------------+-------
foo 1 | ("foo 1","bar 1") | foo 1
(1 row)
drop function foo1(n integer);
drop function rngfunc1(n integer);
-- test use of SQL functions returning record
-- this is supported in some cases where the query doesn't specify
-- the actual record type ...
......@@ -1795,49 +1795,49 @@ select * from array_to_set(array['one', 'two']); -- fail
ERROR: a column definition list is required for functions returning "record"
LINE 1: select * from array_to_set(array['one', 'two']);
^
create temp table foo(f1 int8, f2 int8);
create function testfoo() returns record as $$
insert into foo values (1,2) returning *;
create temp table rngfunc(f1 int8, f2 int8);
create function testrngfunc() returns record as $$
insert into rngfunc values (1,2) returning *;
$$ language sql;
select testfoo();
testfoo
---------
select testrngfunc();
testrngfunc
-------------
(1,2)
(1 row)
select * from testfoo() as t(f1 int8,f2 int8);
select * from testrngfunc() as t(f1 int8,f2 int8);
f1 | f2
----+----
1 | 2
(1 row)
select * from testfoo(); -- fail
select * from testrngfunc(); -- fail
ERROR: a column definition list is required for functions returning "record"
LINE 1: select * from testfoo();
LINE 1: select * from testrngfunc();
^
drop function testfoo();
create function testfoo() returns setof record as $$
insert into foo values (1,2), (3,4) returning *;
drop function testrngfunc();
create function testrngfunc() returns setof record as $$
insert into rngfunc values (1,2), (3,4) returning *;
$$ language sql;
select testfoo();
testfoo
---------
select testrngfunc();
testrngfunc
-------------
(1,2)
(3,4)
(2 rows)
select * from testfoo() as t(f1 int8,f2 int8);
select * from testrngfunc() as t(f1 int8,f2 int8);
f1 | f2
----+----
1 | 2
3 | 4
(2 rows)
select * from testfoo(); -- fail
select * from testrngfunc(); -- fail
ERROR: a column definition list is required for functions returning "record"
LINE 1: select * from testfoo();
LINE 1: select * from testrngfunc();
^
drop function testfoo();
drop function testrngfunc();
--
-- Check some cases involving added/dropped columns in a rowtype result
--
......@@ -1931,44 +1931,44 @@ drop function get_first_user();
drop function get_users();
drop table users;
-- this won't get inlined because of type coercion, but it shouldn't fail
create or replace function foobar() returns setof text as
create or replace function rngfuncbar() returns setof text as
$$ select 'foo'::varchar union all select 'bar'::varchar ; $$
language sql stable;
select foobar();
foobar
--------
select rngfuncbar();
rngfuncbar
------------
foo
bar
(2 rows)
select * from foobar();
foobar
--------
select * from rngfuncbar();
rngfuncbar
------------
foo
bar
(2 rows)
drop function foobar();
drop function rngfuncbar();
-- check handling of a SQL function with multiple OUT params (bug #5777)
create or replace function foobar(out integer, out numeric) as
create or replace function rngfuncbar(out integer, out numeric) as
$$ select (1, 2.1) $$ language sql;
select * from foobar();
select * from rngfuncbar();
column1 | column2
---------+---------
1 | 2.1
(1 row)
create or replace function foobar(out integer, out numeric) as
create or replace function rngfuncbar(out integer, out numeric) as
$$ select (1, 2) $$ language sql;
select * from foobar(); -- fail
select * from rngfuncbar(); -- fail
ERROR: function return row and query-specified return row do not match
DETAIL: Returned type integer at ordinal position 2, but query expects numeric.
create or replace function foobar(out integer, out numeric) as
create or replace function rngfuncbar(out integer, out numeric) as
$$ select (1, 2.1, 3) $$ language sql;
select * from foobar(); -- fail
select * from rngfuncbar(); -- fail
ERROR: function return row and query-specified return row do not match
DETAIL: Returned row contains 3 attributes, but query expects 2.
drop function foobar();
drop function rngfuncbar();
-- check whole-row-Var handling in nested lateral functions (bug #11703)
create function extractq2(t int8_tbl) returns int8 as $$
select t.q2
......@@ -2044,22 +2044,22 @@ select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x);
(5 rows)
-- check handling of nulls in SRF results (bug #7808)
create type foo2 as (a integer, b text);
select *, row_to_json(u) from unnest(array[(1,'foo')::foo2, null::foo2]) u;
create type rngfunc2 as (a integer, b text);
select *, row_to_json(u) from unnest(array[(1,'foo')::rngfunc2, null::rngfunc2]) u;
a | b | row_to_json
---+-----+---------------------
1 | foo | {"a":1,"b":"foo"}
| | {"a":null,"b":null}
(2 rows)
select *, row_to_json(u) from unnest(array[null::foo2, null::foo2]) u;
select *, row_to_json(u) from unnest(array[null::rngfunc2, null::rngfunc2]) u;
a | b | row_to_json
---+---+---------------------
| | {"a":null,"b":null}
| | {"a":null,"b":null}
(2 rows)
select *, row_to_json(u) from unnest(array[null::foo2, (1,'foo')::foo2, null::foo2]) u;
select *, row_to_json(u) from unnest(array[null::rngfunc2, (1,'foo')::rngfunc2, null::rngfunc2]) u;
a | b | row_to_json
---+-----+---------------------
| | {"a":null,"b":null}
......@@ -2067,9 +2067,9 @@ select *, row_to_json(u) from unnest(array[null::foo2, (1,'foo')::foo2, null::fo
| | {"a":null,"b":null}
(3 rows)
select *, row_to_json(u) from unnest(array[]::foo2[]) u;
select *, row_to_json(u) from unnest(array[]::rngfunc2[]) u;
a | b | row_to_json
---+---+-------------
(0 rows)
drop type foo2;
drop type rngfunc2;
......@@ -1175,47 +1175,47 @@ SELECT count(*) FROM shoe;
--
-- Simple test of qualified ON INSERT ... this did not work in 7.0 ...
--
create table foo (f1 int);
create table foo2 (f1 int);
create rule foorule as on insert to foo where f1 < 100
create table rules_foo (f1 int);
create table rules_foo2 (f1 int);
create rule rules_foorule as on insert to rules_foo where f1 < 100
do instead nothing;
insert into foo values(1);
insert into foo values(1001);
select * from foo;
insert into rules_foo values(1);
insert into rules_foo values(1001);
select * from rules_foo;
f1
------
1001
(1 row)
drop rule foorule on foo;
drop rule rules_foorule on rules_foo;
-- this should fail because f1 is not exposed for unqualified reference:
create rule foorule as on insert to foo where f1 < 100
do instead insert into foo2 values (f1);
create rule rules_foorule as on insert to rules_foo where f1 < 100
do instead insert into rules_foo2 values (f1);
ERROR: column "f1" does not exist
LINE 2: do instead insert into foo2 values (f1);
^
LINE 2: do instead insert into rules_foo2 values (f1);
^
HINT: There is a column named "f1" in table "old", but it cannot be referenced from this part of the query.
-- this is the correct way:
create rule foorule as on insert to foo where f1 < 100
do instead insert into foo2 values (new.f1);
insert into foo values(2);
insert into foo values(100);
select * from foo;
create rule rules_foorule as on insert to rules_foo where f1 < 100
do instead insert into rules_foo2 values (new.f1);
insert into rules_foo values(2);
insert into rules_foo values(100);
select * from rules_foo;
f1
------
1001
100
(2 rows)
select * from foo2;
select * from rules_foo2;
f1
----
2
(1 row)
drop rule foorule on foo;
drop table foo;
drop table foo2;
drop rule rules_foorule on rules_foo;
drop table rules_foo;
drop table rules_foo2;
--
-- Test rules containing INSERT ... SELECT, which is a very ugly special
-- case as of 7.1. Example is based on bug report from Joel Burton.
......@@ -2535,50 +2535,50 @@ DETAIL: Key (id3a, id3b)=(1, 13) is not present in table "rule_and_refint_t1".
--
-- disallow dropping a view's rule (bug #5072)
--
create view fooview as select 'foo'::text;
drop rule "_RETURN" on fooview;
ERROR: cannot drop rule _RETURN on view fooview because view fooview requires it
HINT: You can drop view fooview instead.
drop view fooview;
create view rules_fooview as select 'rules_foo'::text;
drop rule "_RETURN" on rules_fooview;
ERROR: cannot drop rule _RETURN on view rules_fooview because view rules_fooview requires it
HINT: You can drop view rules_fooview instead.
drop view rules_fooview;
--
-- test conversion of table to view (needed to load some pg_dump files)
--
create table fooview (x int, y text);
select xmin, * from fooview;
create table rules_fooview (x int, y text);
select xmin, * from rules_fooview;
xmin | x | y
------+---+---
(0 rows)
create rule "_RETURN" as on select to fooview do instead
create rule "_RETURN" as on select to rules_fooview do instead
select 1 as x, 'aaa'::text as y;
select * from fooview;
select * from rules_fooview;
x | y
---+-----
1 | aaa
(1 row)
select xmin, * from fooview; -- fail, views don't have such a column
select xmin, * from rules_fooview; -- fail, views don't have such a column
ERROR: column "xmin" does not exist
LINE 1: select xmin, * from fooview;
LINE 1: select xmin, * from rules_fooview;
^
select reltoastrelid, relkind, relfrozenxid
from pg_class where oid = 'fooview'::regclass;
from pg_class where oid = 'rules_fooview'::regclass;
reltoastrelid | relkind | relfrozenxid
---------------+---------+--------------
0 | v | 0
(1 row)
drop view fooview;
drop view rules_fooview;
-- trying to convert a partitioned table to view is not allowed
create table fooview (x int, y text) partition by list (x);
create rule "_RETURN" as on select to fooview do instead
create table rules_fooview (x int, y text) partition by list (x);
create rule "_RETURN" as on select to rules_fooview do instead
select 1 as x, 'aaa'::text as y;
ERROR: cannot convert partitioned table "fooview" to a view
ERROR: cannot convert partitioned table "rules_fooview" to a view
-- nor can one convert a partition to view
create table fooview_part partition of fooview for values in (1);
create rule "_RETURN" as on select to fooview_part do instead
create table rules_fooview_part partition of rules_fooview for values in (1);
create rule "_RETURN" as on select to rules_fooview_part do instead
select 1 as x, 'aaa'::text as y;
ERROR: cannot convert partition "fooview_part" to a view
ERROR: cannot convert partition "rules_fooview_part" to a view
--
-- check for planner problems with complex inherited UPDATES
--
......@@ -3229,12 +3229,12 @@ SELECT pg_get_partkeydef(0);
(1 row)
-- test rename for a rule defined on a partitioned table
CREATE TABLE parted_table (a int) PARTITION BY LIST (a);
CREATE TABLE parted_table_1 PARTITION OF parted_table FOR VALUES IN (1);
CREATE RULE parted_table_insert AS ON INSERT to parted_table
DO INSTEAD INSERT INTO parted_table_1 VALUES (NEW.*);
ALTER RULE parted_table_insert ON parted_table RENAME TO parted_table_insert_redirect;
DROP TABLE parted_table;
CREATE TABLE rules_parted_table (a int) PARTITION BY LIST (a);
CREATE TABLE rules_parted_table_1 PARTITION OF rules_parted_table FOR VALUES IN (1);
CREATE RULE rules_parted_table_insert AS ON INSERT to rules_parted_table
DO INSTEAD INSERT INTO rules_parted_table_1 VALUES (NEW.*);
ALTER RULE rules_parted_table_insert ON rules_parted_table RENAME TO rules_parted_table_insert_redirect;
DROP TABLE rules_parted_table;
--
-- Test enabling/disabling
--
......
......@@ -2,15 +2,15 @@
-- SELECT_INTO
--
SELECT *
INTO TABLE tmp1
INTO TABLE sitmp1
FROM onek
WHERE onek.unique1 < 2;
DROP TABLE tmp1;
DROP TABLE sitmp1;
SELECT *
INTO TABLE tmp1
INTO TABLE sitmp1
FROM onek2
WHERE onek2.unique1 < 2;
DROP TABLE tmp1;
DROP TABLE sitmp1;
--
-- SELECT INTO and INSERT permission, if owner is not allowed to insert.
--
......
--
-- PARALLEL
--
create or replace function parallel_restricted(int) returns int as
create function sp_parallel_restricted(int) returns int as
$$begin return $1; end$$ language plpgsql parallel restricted;
-- Serializable isolation would disable parallel query, so explicitly use an
-- arbitrary other level.
......@@ -122,12 +122,12 @@ select round(avg(aa)), sum(aa) from a_star a4;
reset enable_parallel_append;
-- Parallel Append that runs serially
create or replace function foobar() returns setof text as
create function sp_test_func() returns setof text as
$$ select 'foo'::varchar union all select 'bar'::varchar $$
language sql stable;
select foobar() order by 1;
foobar
--------
select sp_test_func() order by 1;
sp_test_func
--------------
bar
foo
(2 rows)
......@@ -178,15 +178,15 @@ reset parallel_leader_participation;
-- test that parallel_restricted function doesn't run in worker
alter table tenk1 set (parallel_workers = 4);
explain (verbose, costs off)
select parallel_restricted(unique1) from tenk1
select sp_parallel_restricted(unique1) from tenk1
where stringu1 = 'GRAAAA' order by 1;
QUERY PLAN
---------------------------------------------------------
Sort
Output: (parallel_restricted(unique1))
Sort Key: (parallel_restricted(tenk1.unique1))
Output: (sp_parallel_restricted(unique1))
Sort Key: (sp_parallel_restricted(tenk1.unique1))
-> Gather
Output: parallel_restricted(unique1)
Output: sp_parallel_restricted(unique1)
Workers Planned: 4
-> Parallel Seq Scan on public.tenk1
Output: unique1
......@@ -231,12 +231,12 @@ explain (costs off)
-- test that parallel plan for aggregates is not selected when
-- target list contains parallel restricted clause.
explain (costs off)
select sum(parallel_restricted(unique1)) from tenk1
group by(parallel_restricted(unique1));
select sum(sp_parallel_restricted(unique1)) from tenk1
group by(sp_parallel_restricted(unique1));
QUERY PLAN
-------------------------------------------------------------------
HashAggregate
Group Key: parallel_restricted(unique1)
Group Key: sp_parallel_restricted(unique1)
-> Gather
Workers Planned: 4
-> Parallel Index Only Scan using tenk1_unique1 on tenk1
......@@ -609,21 +609,21 @@ select count(*) from tenk1 group by twenty;
(20 rows)
--test expressions in targetlist are pushed down for gather merge
create or replace function simple_func(var1 integer) returns integer
create function sp_simple_func(var1 integer) returns integer
as $$
begin
return var1 + 10;
end;
$$ language plpgsql PARALLEL SAFE;
explain (costs off, verbose)
select ten, simple_func(ten) from tenk1 where ten < 100 order by ten;
select ten, sp_simple_func(ten) from tenk1 where ten < 100 order by ten;
QUERY PLAN
-----------------------------------------------------
Gather Merge
Output: ten, (simple_func(ten))
Output: ten, (sp_simple_func(ten))
Workers Planned: 4
-> Result
Output: ten, simple_func(ten)
Output: ten, sp_simple_func(ten)
-> Sort
Output: ten
Sort Key: tenk1.ten
......@@ -632,7 +632,7 @@ explain (costs off, verbose)
Filter: (tenk1.ten < 100)
(11 rows)
drop function simple_func(integer);
drop function sp_simple_func(integer);
-- test gather merge with parallel leader participation disabled
set parallel_leader_participation = off;
explain (costs off)
......@@ -827,7 +827,7 @@ explain (costs off)
ROLLBACK TO SAVEPOINT settings;
-- exercise record typmod remapping between backends
CREATE OR REPLACE FUNCTION make_record(n int)
CREATE FUNCTION make_record(n int)
RETURNS RECORD LANGUAGE plpgsql PARALLEL SAFE AS
$$
BEGIN
......
......@@ -146,69 +146,69 @@ COMMIT;
-- Subtransactions, basic tests
-- create & drop tables
SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE;
CREATE TABLE foobar (a int);
CREATE TABLE trans_foobar (a int);
BEGIN;
CREATE TABLE foo (a int);
CREATE TABLE trans_foo (a int);
SAVEPOINT one;
DROP TABLE foo;
CREATE TABLE bar (a int);
DROP TABLE trans_foo;
CREATE TABLE trans_bar (a int);
ROLLBACK TO SAVEPOINT one;
RELEASE SAVEPOINT one;
SAVEPOINT two;
CREATE TABLE baz (a int);
CREATE TABLE trans_baz (a int);
RELEASE SAVEPOINT two;
drop TABLE foobar;
CREATE TABLE barbaz (a int);
drop TABLE trans_foobar;
CREATE TABLE trans_barbaz (a int);
COMMIT;
-- should exist: barbaz, baz, foo
SELECT * FROM foo; -- should be empty
-- should exist: trans_barbaz, trans_baz, trans_foo
SELECT * FROM trans_foo; -- should be empty
a
---
(0 rows)
SELECT * FROM bar; -- shouldn't exist
ERROR: relation "bar" does not exist
LINE 1: SELECT * FROM bar;
SELECT * FROM trans_bar; -- shouldn't exist
ERROR: relation "trans_bar" does not exist
LINE 1: SELECT * FROM trans_bar;
^
SELECT * FROM barbaz; -- should be empty
SELECT * FROM trans_barbaz; -- should be empty
a
---
(0 rows)
SELECT * FROM baz; -- should be empty
SELECT * FROM trans_baz; -- should be empty
a
---
(0 rows)
-- inserts
BEGIN;
INSERT INTO foo VALUES (1);
INSERT INTO trans_foo VALUES (1);
SAVEPOINT one;
INSERT into bar VALUES (1);
ERROR: relation "bar" does not exist
LINE 1: INSERT into bar VALUES (1);
INSERT into trans_bar VALUES (1);
ERROR: relation "trans_bar" does not exist
LINE 1: INSERT into trans_bar VALUES (1);
^
ROLLBACK TO one;
RELEASE SAVEPOINT one;
SAVEPOINT two;
INSERT into barbaz VALUES (1);
INSERT into trans_barbaz VALUES (1);
RELEASE two;
SAVEPOINT three;
SAVEPOINT four;
INSERT INTO foo VALUES (2);
INSERT INTO trans_foo VALUES (2);
RELEASE SAVEPOINT four;
ROLLBACK TO SAVEPOINT three;
RELEASE SAVEPOINT three;
INSERT INTO foo VALUES (3);
INSERT INTO trans_foo VALUES (3);
COMMIT;
SELECT * FROM foo; -- should have 1 and 3
SELECT * FROM trans_foo; -- should have 1 and 3
a
---
1
3
(2 rows)
SELECT * FROM barbaz; -- should have 1
SELECT * FROM trans_barbaz; -- should have 1
a
---
1
......@@ -217,9 +217,9 @@ SELECT * FROM barbaz; -- should have 1
-- test whole-tree commit
BEGIN;
SAVEPOINT one;
SELECT foo;
ERROR: column "foo" does not exist
LINE 1: SELECT foo;
SELECT trans_foo;
ERROR: column "trans_foo" does not exist
LINE 1: SELECT trans_foo;
^
ROLLBACK TO SAVEPOINT one;
RELEASE SAVEPOINT one;
......@@ -266,9 +266,9 @@ BEGIN;
INSERT INTO savepoints VALUES (4);
SAVEPOINT one;
INSERT INTO savepoints VALUES (5);
SELECT foo;
ERROR: column "foo" does not exist
LINE 1: SELECT foo;
SELECT trans_foo;
ERROR: column "trans_foo" does not exist
LINE 1: SELECT trans_foo;
^
COMMIT;
SELECT * FROM savepoints;
......@@ -549,9 +549,9 @@ DETAIL: Key (a)=(1) already exists.
ERROR: duplicate key value violates unique constraint "koju_a_key"
DETAIL: Key (a)=(1) already exists.
ROLLBACK;
DROP TABLE foo;
DROP TABLE baz;
DROP TABLE barbaz;
DROP TABLE trans_foo;
DROP TABLE trans_baz;
DROP TABLE trans_barbaz;
-- test case for problems with revalidating an open relation during abort
create function inverse(int) returns float8 as
$$
......
......@@ -23,8 +23,8 @@ CREATE VIEW rw_view15 AS SELECT a, upper(b) FROM base_tbl; -- Expression/functio
CREATE VIEW rw_view16 AS SELECT a, b, a AS aa FROM base_tbl; -- Repeated column may be part of an updatable view
CREATE VIEW ro_view17 AS SELECT * FROM ro_view1; -- Base relation not updatable
CREATE VIEW ro_view18 AS SELECT * FROM (VALUES(1)) AS tmp(a); -- VALUES in rangetable
CREATE SEQUENCE seq;
CREATE VIEW ro_view19 AS SELECT * FROM seq; -- View based on a sequence
CREATE SEQUENCE uv_seq;
CREATE VIEW ro_view19 AS SELECT * FROM uv_seq; -- View based on a sequence
CREATE VIEW ro_view20 AS SELECT a, b, generate_series(1, a) g FROM base_tbl; -- SRF in targetlist not supported
SELECT table_name, is_insertable_into
FROM information_schema.tables
......@@ -347,7 +347,7 @@ drop cascades to view ro_view20
drop cascades to view ro_view4
drop cascades to view rw_view14
DROP VIEW ro_view10, ro_view12, ro_view18;
DROP SEQUENCE seq CASCADE;
DROP SEQUENCE uv_seq CASCADE;
NOTICE: drop cascades to view ro_view19
-- simple updatable view
CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified');
......@@ -2368,66 +2368,66 @@ DETAIL: Failing row contains (-1, invalid).
DROP VIEW v1;
DROP TABLE t1;
-- check that an auto-updatable view on a partitioned table works correctly
create table pt (a int, b int, v varchar) partition by range (a, b);
create table pt1 (b int not null, v varchar, a int not null) partition by range (b);
create table pt11 (like pt1);
alter table pt11 drop a;
alter table pt11 add a int;
alter table pt11 drop a;
alter table pt11 add a int not null;
alter table pt1 attach partition pt11 for values from (2) to (5);
alter table pt attach partition pt1 for values from (1, 2) to (1, 10);
create view ptv as select * from pt;
create table uv_pt (a int, b int, v varchar) partition by range (a, b);
create table uv_pt1 (b int not null, v varchar, a int not null) partition by range (b);
create table uv_pt11 (like uv_pt1);
alter table uv_pt11 drop a;
alter table uv_pt11 add a int;
alter table uv_pt11 drop a;
alter table uv_pt11 add a int not null;
alter table uv_pt1 attach partition uv_pt11 for values from (2) to (5);
alter table uv_pt attach partition uv_pt1 for values from (1, 2) to (1, 10);
create view uv_ptv as select * from uv_pt;
select events & 4 != 0 AS upd,
events & 8 != 0 AS ins,
events & 16 != 0 AS del
from pg_catalog.pg_relation_is_updatable('pt'::regclass, false) t(events);
from pg_catalog.pg_relation_is_updatable('uv_pt'::regclass, false) t(events);
upd | ins | del
-----+-----+-----
t | t | t
(1 row)
select pg_catalog.pg_column_is_updatable('pt'::regclass, 1::smallint, false);
select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 1::smallint, false);
pg_column_is_updatable
------------------------
t
(1 row)
select pg_catalog.pg_column_is_updatable('pt'::regclass, 2::smallint, false);
select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 2::smallint, false);
pg_column_is_updatable
------------------------
t
(1 row)
select table_name, is_updatable, is_insertable_into
from information_schema.views where table_name = 'ptv';
from information_schema.views where table_name = 'uv_ptv';
table_name | is_updatable | is_insertable_into
------------+--------------+--------------------
ptv | YES | YES
uv_ptv | YES | YES
(1 row)
select table_name, column_name, is_updatable
from information_schema.columns where table_name = 'ptv' order by column_name;
from information_schema.columns where table_name = 'uv_ptv' order by column_name;
table_name | column_name | is_updatable
------------+-------------+--------------
ptv | a | YES
ptv | b | YES
ptv | v | YES
uv_ptv | a | YES
uv_ptv | b | YES
uv_ptv | v | YES
(3 rows)
insert into ptv values (1, 2);
select tableoid::regclass, * from pt;
insert into uv_ptv values (1, 2);
select tableoid::regclass, * from uv_pt;
tableoid | a | b | v
----------+---+---+---
pt11 | 1 | 2 |
uv_pt11 | 1 | 2 |
(1 row)
create view ptv_wco as select * from pt where a = 0 with check option;
insert into ptv_wco values (1, 2);
ERROR: new row violates check option for view "ptv_wco"
create view uv_ptv_wco as select * from uv_pt where a = 0 with check option;
insert into uv_ptv_wco values (1, 2);
ERROR: new row violates check option for view "uv_ptv_wco"
DETAIL: Failing row contains (1, 2, null).
drop view ptv, ptv_wco;
drop table pt, pt1, pt11;
drop view uv_ptv, uv_ptv_wco;
drop table uv_pt, uv_pt1, uv_pt11;
-- check that wholerow vars appearing in WITH CHECK OPTION constraint expressions
-- work fine with partitioned tables
create table wcowrtest (a int) partition by list (a);
......
......@@ -1819,12 +1819,12 @@ SELECT * FROM y;
(22 rows)
-- data-modifying WITH containing INSERT...ON CONFLICT DO UPDATE
CREATE TABLE z AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i;
ALTER TABLE z ADD UNIQUE (k);
CREATE TABLE withz AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i;
ALTER TABLE withz ADD UNIQUE (k);
WITH t AS (
INSERT INTO z SELECT i, 'insert'
INSERT INTO withz SELECT i, 'insert'
FROM generate_series(0, 16) i
ON CONFLICT (k) DO UPDATE SET v = z.v || ', now update'
ON CONFLICT (k) DO UPDATE SET v = withz.v || ', now update'
RETURNING *
)
SELECT * FROM t JOIN y ON t.k = y.a ORDER BY a, k;
......@@ -1836,8 +1836,8 @@ SELECT * FROM t JOIN y ON t.k = y.a ORDER BY a, k;
-- Test EXCLUDED.* reference within CTE
WITH aa AS (
INSERT INTO z VALUES(1, 5) ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v
WHERE z.k != EXCLUDED.k
INSERT INTO withz VALUES(1, 5) ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v
WHERE withz.k != EXCLUDED.k
RETURNING *
)
SELECT * FROM aa;
......@@ -1846,7 +1846,7 @@ SELECT * FROM aa;
(0 rows)
-- New query/snapshot demonstrates side-effects of previous query.
SELECT * FROM z ORDER BY k;
SELECT * FROM withz ORDER BY k;
k | v
----+------------------
0 | insert
......@@ -1873,19 +1873,19 @@ SELECT * FROM z ORDER BY k;
-- reference outside values
--
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, 'insert')
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = ' update' WHERE z.k = (SELECT a FROM aa);
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = ' update' WHERE withz.k = (SELECT a FROM aa);
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, 'insert')
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
WITH aa AS (SELECT 'a' a, 'b' b UNION ALL SELECT 'a' a, 'b' b)
INSERT INTO z VALUES(1, 'insert')
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 'a' LIMIT 1);
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, (SELECT b || ' insert' FROM aa WHERE a = 1 ))
INSERT INTO withz VALUES(1, (SELECT b || ' insert' FROM aa WHERE a = 1 ))
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
-- Update a row more than once, in different parts of a wCTE. That is
-- an allowed, presumably very rare, edge case, but since it was
......@@ -1893,17 +1893,17 @@ ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIM
WITH simpletup AS (
SELECT 2 k, 'Green' v),
upsert_cte AS (
INSERT INTO z VALUES(2, 'Blue') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM simpletup WHERE simpletup.k = z.k)
INSERT INTO withz VALUES(2, 'Blue') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM simpletup WHERE simpletup.k = withz.k)
RETURNING k, v)
INSERT INTO z VALUES(2, 'Red') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM upsert_cte WHERE upsert_cte.k = z.k)
INSERT INTO withz VALUES(2, 'Red') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM upsert_cte WHERE upsert_cte.k = withz.k)
RETURNING k, v;
k | v
---+---
(0 rows)
DROP TABLE z;
DROP TABLE withz;
-- check that run to completion happens in proper ordering
TRUNCATE TABLE y;
INSERT INTO y SELECT generate_series(1, 3);
......@@ -2280,7 +2280,7 @@ LINE 1: WITH test AS (SELECT 42) INSERT INTO test VALUES (1);
-- check response to attempt to modify table with same name as a CTE (perhaps
-- surprisingly it works, because CTEs don't hide tables from data-modifying
-- statements)
create table test (i int);
create temp table test (i int);
with test as (select 42) insert into test select * from test;
select * from test;
i
......
......@@ -13,66 +13,66 @@ CREATE USER regress_alter_table_user1;
-- add attribute
--
CREATE TABLE tmp (initial int4);
CREATE TABLE attmp (initial int4);
COMMENT ON TABLE tmp_wrong IS 'table comment';
COMMENT ON TABLE tmp IS 'table comment';
COMMENT ON TABLE tmp IS NULL;
COMMENT ON TABLE attmp_wrong IS 'table comment';
COMMENT ON TABLE attmp IS 'table comment';
COMMENT ON TABLE attmp IS NULL;
ALTER TABLE tmp ADD COLUMN xmin integer; -- fails
ALTER TABLE attmp ADD COLUMN xmin integer; -- fails
ALTER TABLE tmp ADD COLUMN a int4 default 3;
ALTER TABLE attmp ADD COLUMN a int4 default 3;
ALTER TABLE tmp ADD COLUMN b name;
ALTER TABLE attmp ADD COLUMN b name;
ALTER TABLE tmp ADD COLUMN c text;
ALTER TABLE attmp ADD COLUMN c text;
ALTER TABLE tmp ADD COLUMN d float8;
ALTER TABLE attmp ADD COLUMN d float8;
ALTER TABLE tmp ADD COLUMN e float4;
ALTER TABLE attmp ADD COLUMN e float4;
ALTER TABLE tmp ADD COLUMN f int2;
ALTER TABLE attmp ADD COLUMN f int2;
ALTER TABLE tmp ADD COLUMN g polygon;
ALTER TABLE attmp ADD COLUMN g polygon;
ALTER TABLE tmp ADD COLUMN h abstime;
ALTER TABLE attmp ADD COLUMN h abstime;
ALTER TABLE tmp ADD COLUMN i char;
ALTER TABLE attmp ADD COLUMN i char;
ALTER TABLE tmp ADD COLUMN j abstime[];
ALTER TABLE attmp ADD COLUMN j abstime[];
ALTER TABLE tmp ADD COLUMN k int4;
ALTER TABLE attmp ADD COLUMN k int4;
ALTER TABLE tmp ADD COLUMN l tid;
ALTER TABLE attmp ADD COLUMN l tid;
ALTER TABLE tmp ADD COLUMN m xid;
ALTER TABLE attmp ADD COLUMN m xid;
ALTER TABLE tmp ADD COLUMN n oidvector;
ALTER TABLE attmp ADD COLUMN n oidvector;
--ALTER TABLE tmp ADD COLUMN o lock;
ALTER TABLE tmp ADD COLUMN p smgr;
--ALTER TABLE attmp ADD COLUMN o lock;
ALTER TABLE attmp ADD COLUMN p smgr;
ALTER TABLE tmp ADD COLUMN q point;
ALTER TABLE attmp ADD COLUMN q point;
ALTER TABLE tmp ADD COLUMN r lseg;
ALTER TABLE attmp ADD COLUMN r lseg;
ALTER TABLE tmp ADD COLUMN s path;
ALTER TABLE attmp ADD COLUMN s path;
ALTER TABLE tmp ADD COLUMN t box;
ALTER TABLE attmp ADD COLUMN t box;
ALTER TABLE tmp ADD COLUMN u tinterval;
ALTER TABLE attmp ADD COLUMN u tinterval;
ALTER TABLE tmp ADD COLUMN v timestamp;
ALTER TABLE attmp ADD COLUMN v timestamp;
ALTER TABLE tmp ADD COLUMN w interval;
ALTER TABLE attmp ADD COLUMN w interval;
ALTER TABLE tmp ADD COLUMN x float8[];
ALTER TABLE attmp ADD COLUMN x float8[];
ALTER TABLE tmp ADD COLUMN y float4[];
ALTER TABLE attmp ADD COLUMN y float4[];
ALTER TABLE tmp ADD COLUMN z int2[];
ALTER TABLE attmp ADD COLUMN z int2[];
INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
v, w, x, y, z)
VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}',
......@@ -81,67 +81,67 @@ INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
'(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]',
'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
SELECT * FROM tmp;
SELECT * FROM attmp;
DROP TABLE tmp;
DROP TABLE attmp;
-- the wolf bug - schema mods caused inconsistent row descriptors
CREATE TABLE tmp (
CREATE TABLE attmp (
initial int4
);
ALTER TABLE tmp ADD COLUMN a int4;
ALTER TABLE attmp ADD COLUMN a int4;
ALTER TABLE tmp ADD COLUMN b name;
ALTER TABLE attmp ADD COLUMN b name;
ALTER TABLE tmp ADD COLUMN c text;
ALTER TABLE attmp ADD COLUMN c text;
ALTER TABLE tmp ADD COLUMN d float8;
ALTER TABLE attmp ADD COLUMN d float8;
ALTER TABLE tmp ADD COLUMN e float4;
ALTER TABLE attmp ADD COLUMN e float4;
ALTER TABLE tmp ADD COLUMN f int2;
ALTER TABLE attmp ADD COLUMN f int2;
ALTER TABLE tmp ADD COLUMN g polygon;
ALTER TABLE attmp ADD COLUMN g polygon;
ALTER TABLE tmp ADD COLUMN h abstime;
ALTER TABLE attmp ADD COLUMN h abstime;
ALTER TABLE tmp ADD COLUMN i char;
ALTER TABLE attmp ADD COLUMN i char;
ALTER TABLE tmp ADD COLUMN j abstime[];
ALTER TABLE attmp ADD COLUMN j abstime[];
ALTER TABLE tmp ADD COLUMN k int4;
ALTER TABLE attmp ADD COLUMN k int4;
ALTER TABLE tmp ADD COLUMN l tid;
ALTER TABLE attmp ADD COLUMN l tid;
ALTER TABLE tmp ADD COLUMN m xid;
ALTER TABLE attmp ADD COLUMN m xid;
ALTER TABLE tmp ADD COLUMN n oidvector;
ALTER TABLE attmp ADD COLUMN n oidvector;
--ALTER TABLE tmp ADD COLUMN o lock;
ALTER TABLE tmp ADD COLUMN p smgr;
--ALTER TABLE attmp ADD COLUMN o lock;
ALTER TABLE attmp ADD COLUMN p smgr;
ALTER TABLE tmp ADD COLUMN q point;
ALTER TABLE attmp ADD COLUMN q point;
ALTER TABLE tmp ADD COLUMN r lseg;
ALTER TABLE attmp ADD COLUMN r lseg;
ALTER TABLE tmp ADD COLUMN s path;
ALTER TABLE attmp ADD COLUMN s path;
ALTER TABLE tmp ADD COLUMN t box;
ALTER TABLE attmp ADD COLUMN t box;
ALTER TABLE tmp ADD COLUMN u tinterval;
ALTER TABLE attmp ADD COLUMN u tinterval;
ALTER TABLE tmp ADD COLUMN v timestamp;
ALTER TABLE attmp ADD COLUMN v timestamp;
ALTER TABLE tmp ADD COLUMN w interval;
ALTER TABLE attmp ADD COLUMN w interval;
ALTER TABLE tmp ADD COLUMN x float8[];
ALTER TABLE attmp ADD COLUMN x float8[];
ALTER TABLE tmp ADD COLUMN y float4[];
ALTER TABLE attmp ADD COLUMN y float4[];
ALTER TABLE tmp ADD COLUMN z int2[];
ALTER TABLE attmp ADD COLUMN z int2[];
INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
v, w, x, y, z)
VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}',
......@@ -150,86 +150,86 @@ INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
'(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]',
'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
SELECT * FROM tmp;
SELECT * FROM attmp;
CREATE INDEX tmp_idx ON tmp (a, (d + e), b);
CREATE INDEX attmp_idx ON attmp (a, (d + e), b);
ALTER INDEX tmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
ALTER INDEX attmp_idx ALTER COLUMN 0 SET STATISTICS 1000;
ALTER INDEX tmp_idx ALTER COLUMN 1 SET STATISTICS 1000;
ALTER INDEX attmp_idx ALTER COLUMN 1 SET STATISTICS 1000;
ALTER INDEX tmp_idx ALTER COLUMN 2 SET STATISTICS 1000;
ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000;
\d+ tmp_idx
\d+ attmp_idx
ALTER INDEX tmp_idx ALTER COLUMN 3 SET STATISTICS 1000;
ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000;
ALTER INDEX tmp_idx ALTER COLUMN 4 SET STATISTICS 1000;
ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000;
ALTER INDEX tmp_idx ALTER COLUMN 2 SET STATISTICS -1;
ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1;
DROP TABLE tmp;
DROP TABLE attmp;
--
-- rename - check on both non-temp and temp tables
--
CREATE TABLE tmp (regtable int);
CREATE TEMP TABLE tmp (tmptable int);
CREATE TABLE attmp (regtable int);
CREATE TEMP TABLE attmp (attmptable int);
ALTER TABLE tmp RENAME TO tmp_new;
ALTER TABLE attmp RENAME TO attmp_new;
SELECT * FROM tmp;
SELECT * FROM tmp_new;
SELECT * FROM attmp;
SELECT * FROM attmp_new;
ALTER TABLE tmp RENAME TO tmp_new2;
ALTER TABLE attmp RENAME TO attmp_new2;
SELECT * FROM tmp; -- should fail
SELECT * FROM tmp_new;
SELECT * FROM tmp_new2;
SELECT * FROM attmp; -- should fail
SELECT * FROM attmp_new;
SELECT * FROM attmp_new2;
DROP TABLE tmp_new;
DROP TABLE tmp_new2;
DROP TABLE attmp_new;
DROP TABLE attmp_new2;
--
-- check renaming to a table's array type's autogenerated name
-- (the array type's name should get out of the way)
--
CREATE TABLE tmp_array (id int);
CREATE TABLE tmp_array2 (id int);
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
SELECT typname FROM pg_type WHERE oid = 'tmp_array2[]'::regtype;
ALTER TABLE tmp_array2 RENAME TO _tmp_array;
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
SELECT typname FROM pg_type WHERE oid = '_tmp_array[]'::regtype;
DROP TABLE _tmp_array;
DROP TABLE tmp_array;
CREATE TABLE attmp_array (id int);
CREATE TABLE attmp_array2 (id int);
SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
SELECT typname FROM pg_type WHERE oid = 'attmp_array2[]'::regtype;
ALTER TABLE attmp_array2 RENAME TO _attmp_array;
SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
DROP TABLE _attmp_array;
DROP TABLE attmp_array;
-- renaming to table's own array type's name is an interesting corner case
CREATE TABLE tmp_array (id int);
SELECT typname FROM pg_type WHERE oid = 'tmp_array[]'::regtype;
ALTER TABLE tmp_array RENAME TO _tmp_array;
SELECT typname FROM pg_type WHERE oid = '_tmp_array[]'::regtype;
DROP TABLE _tmp_array;
CREATE TABLE attmp_array (id int);
SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype;
ALTER TABLE attmp_array RENAME TO _attmp_array;
SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype;
DROP TABLE _attmp_array;
-- ALTER TABLE ... RENAME on non-table relations
-- renaming indexes (FIXME: this should probably test the index's functionality)
ALTER INDEX IF EXISTS __onek_unique1 RENAME TO tmp_onek_unique1;
ALTER INDEX IF EXISTS __tmp_onek_unique1 RENAME TO onek_unique1;
ALTER INDEX IF EXISTS __onek_unique1 RENAME TO attmp_onek_unique1;
ALTER INDEX IF EXISTS __attmp_onek_unique1 RENAME TO onek_unique1;
ALTER INDEX onek_unique1 RENAME TO tmp_onek_unique1;
ALTER INDEX tmp_onek_unique1 RENAME TO onek_unique1;
ALTER INDEX onek_unique1 RENAME TO attmp_onek_unique1;
ALTER INDEX attmp_onek_unique1 RENAME TO onek_unique1;
SET ROLE regress_alter_table_user1;
ALTER INDEX onek_unique1 RENAME TO fail; -- permission denied
RESET ROLE;
-- renaming views
CREATE VIEW tmp_view (unique1) AS SELECT unique1 FROM tenk1;
ALTER TABLE tmp_view RENAME TO tmp_view_new;
CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1;
ALTER TABLE attmp_view RENAME TO attmp_view_new;
SET ROLE regress_alter_table_user1;
ALTER VIEW tmp_view_new RENAME TO fail; -- permission denied
ALTER VIEW attmp_view_new RENAME TO fail; -- permission denied
RESET ROLE;
-- hack to ensure we get an indexscan here
......@@ -240,7 +240,7 @@ SELECT unique1 FROM tenk1 WHERE unique1 < 5;
reset enable_seqscan;
reset enable_bitmapscan;
DROP VIEW tmp_view_new;
DROP VIEW attmp_view_new;
-- toast-like relation name
alter table stud_emp rename to pg_toast_stud_emp;
alter table pg_toast_stud_emp rename to stud_emp;
......@@ -288,79 +288,79 @@ ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
-- FOREIGN KEY CONSTRAINT adding TEST
CREATE TABLE tmp2 (a int primary key);
CREATE TABLE attmp2 (a int primary key);
CREATE TABLE tmp3 (a int, b int);
CREATE TABLE attmp3 (a int, b int);
CREATE TABLE tmp4 (a int, b int, unique(a,b));
CREATE TABLE attmp4 (a int, b int, unique(a,b));
CREATE TABLE tmp5 (a int, b int);
CREATE TABLE attmp5 (a int, b int);
-- Insert rows into tmp2 (pktable)
INSERT INTO tmp2 values (1);
INSERT INTO tmp2 values (2);
INSERT INTO tmp2 values (3);
INSERT INTO tmp2 values (4);
-- Insert rows into attmp2 (pktable)
INSERT INTO attmp2 values (1);
INSERT INTO attmp2 values (2);
INSERT INTO attmp2 values (3);
INSERT INTO attmp2 values (4);
-- Insert rows into tmp3
INSERT INTO tmp3 values (1,10);
INSERT INTO tmp3 values (1,20);
INSERT INTO tmp3 values (5,50);
-- Insert rows into attmp3
INSERT INTO attmp3 values (1,10);
INSERT INTO attmp3 values (1,20);
INSERT INTO attmp3 values (5,50);
-- Try (and fail) to add constraint due to invalid source columns
ALTER TABLE tmp3 add constraint tmpconstr foreign key(c) references tmp2 match full;
ALTER TABLE attmp3 add constraint attmpconstr foreign key(c) references attmp2 match full;
-- Try (and fail) to add constraint due to invalid destination columns explicitly given
ALTER TABLE tmp3 add constraint tmpconstr foreign key(a) references tmp2(b) match full;
ALTER TABLE attmp3 add constraint attmpconstr foreign key(a) references attmp2(b) match full;
-- Try (and fail) to add constraint due to invalid data
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full;
-- Delete failing row
DELETE FROM tmp3 where a=5;
DELETE FROM attmp3 where a=5;
-- Try (and succeed)
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
ALTER TABLE tmp3 drop constraint tmpconstr;
ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full;
ALTER TABLE attmp3 drop constraint attmpconstr;
INSERT INTO tmp3 values (5,50);
INSERT INTO attmp3 values (5,50);
-- Try NOT VALID and then VALIDATE CONSTRAINT, but fails. Delete failure then re-validate
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full NOT VALID;
ALTER TABLE tmp3 validate constraint tmpconstr;
ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full NOT VALID;
ALTER TABLE attmp3 validate constraint attmpconstr;
-- Delete failing row
DELETE FROM tmp3 where a=5;
DELETE FROM attmp3 where a=5;
-- Try (and succeed) and repeat to show it works on already valid constraint
ALTER TABLE tmp3 validate constraint tmpconstr;
ALTER TABLE tmp3 validate constraint tmpconstr;
ALTER TABLE attmp3 validate constraint attmpconstr;
ALTER TABLE attmp3 validate constraint attmpconstr;
-- Try a non-verified CHECK constraint
ALTER TABLE tmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
ALTER TABLE tmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
DELETE FROM tmp3 WHERE NOT b > 10;
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
DELETE FROM attmp3 WHERE NOT b > 10;
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
-- Test inherited NOT VALID CHECK constraints
select * from tmp3;
CREATE TABLE tmp6 () INHERITS (tmp3);
CREATE TABLE tmp7 () INHERITS (tmp3);
select * from attmp3;
CREATE TABLE attmp6 () INHERITS (attmp3);
CREATE TABLE attmp7 () INHERITS (attmp3);
INSERT INTO tmp6 VALUES (6, 30), (7, 16);
ALTER TABLE tmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID;
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_le_20; -- fails
DELETE FROM tmp6 WHERE b > 20;
ALTER TABLE tmp3 VALIDATE CONSTRAINT b_le_20; -- succeeds
INSERT INTO attmp6 VALUES (6, 30), (7, 16);
ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID;
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; -- fails
DELETE FROM attmp6 WHERE b > 20;
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; -- succeeds
-- An already validated constraint must not be revalidated
CREATE FUNCTION boo(int) RETURNS int IMMUTABLE STRICT LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'boo: %', $1; RETURN $1; END; $$;
INSERT INTO tmp7 VALUES (8, 18);
ALTER TABLE tmp7 ADD CONSTRAINT identity CHECK (b = boo(b));
ALTER TABLE tmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID;
ALTER TABLE tmp3 VALIDATE CONSTRAINT identity;
INSERT INTO attmp7 VALUES (8, 18);
ALTER TABLE attmp7 ADD CONSTRAINT identity CHECK (b = boo(b));
ALTER TABLE attmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID;
ALTER TABLE attmp3 VALIDATE CONSTRAINT identity;
-- A NO INHERIT constraint should not be looked for in children during VALIDATE CONSTRAINT
create table parent_noinh_convalid (a int);
......@@ -377,22 +377,22 @@ select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid':
-- cleanup
drop table parent_noinh_convalid, child_noinh_convalid;
-- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on
-- tmp4 is a,b
-- Try (and fail) to create constraint from attmp5(a) to attmp4(a) - unique constraint on
-- attmp4 is a,b
ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
ALTER TABLE attmp5 add constraint attmpconstr foreign key(a) references attmp4(a) match full;
DROP TABLE tmp7;
DROP TABLE attmp7;
DROP TABLE tmp6;
DROP TABLE attmp6;
DROP TABLE tmp5;
DROP TABLE attmp5;
DROP TABLE tmp4;
DROP TABLE attmp4;
DROP TABLE tmp3;
DROP TABLE attmp3;
DROP TABLE tmp2;
DROP TABLE attmp2;
-- NOT VALID with plan invalidation -- ensure we don't use a constraint for
-- exclusion until validated
......@@ -969,12 +969,12 @@ create index "testing_idx" on atacc1("........pg.dropped.1........");
-- test create as and select into
insert into atacc1 values (21, 22, 23);
create table test1 as select * from atacc1;
select * from test1;
drop table test1;
select * into test2 from atacc1;
select * from test2;
drop table test2;
create table attest1 as select * from atacc1;
select * from attest1;
drop table attest1;
select * into attest2 from atacc1;
select * from attest2;
drop table attest2;
-- try dropping all columns
alter table atacc1 drop c;
......@@ -1021,27 +1021,27 @@ drop table child;
drop table parent;
-- test copy in/out
create table test (a int4, b int4, c int4);
insert into test values (1,2,3);
alter table test drop a;
copy test to stdout;
copy test(a) to stdout;
copy test("........pg.dropped.1........") to stdout;
copy test from stdin;
create table attest (a int4, b int4, c int4);
insert into attest values (1,2,3);
alter table attest drop a;
copy attest to stdout;
copy attest(a) to stdout;
copy attest("........pg.dropped.1........") to stdout;
copy attest from stdin;
10 11 12
\.
select * from test;
copy test from stdin;
select * from attest;
copy attest from stdin;
21 22
\.
select * from test;
copy test(a) from stdin;
copy test("........pg.dropped.1........") from stdin;
copy test(b,c) from stdin;
select * from attest;
copy attest(a) from stdin;
copy attest("........pg.dropped.1........") from stdin;
copy attest(b,c) from stdin;
31 32
\.
select * from test;
drop table test;
select * from attest;
drop table attest;
-- test inheritance
......@@ -2557,11 +2557,11 @@ alter table parted_validate_test add constraint parted_validate_test_chka check
alter table parted_validate_test validate constraint parted_validate_test_chka;
drop table parted_validate_test;
-- test alter column options
CREATE TABLE tmp(i integer);
INSERT INTO tmp VALUES (1);
ALTER TABLE tmp ALTER COLUMN i SET (n_distinct = 1, n_distinct_inherited = 2);
ALTER TABLE tmp ALTER COLUMN i RESET (n_distinct_inherited);
ANALYZE tmp;
DROP TABLE tmp;
CREATE TABLE attmp(i integer);
INSERT INTO attmp VALUES (1);
ALTER TABLE attmp ALTER COLUMN i SET (n_distinct = 1, n_distinct_inherited = 2);
ALTER TABLE attmp ALTER COLUMN i RESET (n_distinct_inherited);
ANALYZE attmp;
DROP TABLE attmp;
DROP USER regress_alter_table_user1;
CALL nonexistent(); -- error
CALL random(); -- error
CREATE FUNCTION testfunc1(a int) RETURNS int LANGUAGE SQL AS $$ SELECT a $$;
CREATE FUNCTION cp_testfunc1(a int) RETURNS int LANGUAGE SQL AS $$ SELECT a $$;
CREATE TABLE cp_test (a int, b text);
......@@ -76,11 +76,11 @@ CREATE PROCEDURE ptestx(OUT a int) LANGUAGE SQL AS $$ INSERT INTO cp_test VALUES
ALTER PROCEDURE ptest1(text) STRICT;
ALTER FUNCTION ptest1(text) VOLATILE; -- error: not a function
ALTER PROCEDURE testfunc1(int) VOLATILE; -- error: not a procedure
ALTER PROCEDURE cp_testfunc1(int) VOLATILE; -- error: not a procedure
ALTER PROCEDURE nonexistent() VOLATILE;
DROP FUNCTION ptest1(text); -- error: not a function
DROP PROCEDURE testfunc1(int); -- error: not a procedure
DROP PROCEDURE cp_testfunc1(int); -- error: not a procedure
DROP PROCEDURE nonexistent();
......@@ -100,13 +100,13 @@ RESET ROLE;
-- ROUTINE syntax
ALTER ROUTINE testfunc1(int) RENAME TO testfunc1a;
ALTER ROUTINE testfunc1a RENAME TO testfunc1;
ALTER ROUTINE cp_testfunc1(int) RENAME TO cp_testfunc1a;
ALTER ROUTINE cp_testfunc1a RENAME TO cp_testfunc1;
ALTER ROUTINE ptest1(text) RENAME TO ptest1a;
ALTER ROUTINE ptest1a RENAME TO ptest1;
DROP ROUTINE testfunc1(int);
DROP ROUTINE cp_testfunc1(int);
-- cleanup
......
......@@ -579,25 +579,25 @@ DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1;
DROP FUNCTION dummy_trigger();
-- Table inheritance
CREATE TABLE pt1 (
CREATE TABLE fd_pt1 (
c1 integer NOT NULL,
c2 text,
c3 date
);
CREATE FOREIGN TABLE ft2 () INHERITS (pt1)
CREATE FOREIGN TABLE ft2 () INHERITS (fd_pt1)
SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt1
\d+ fd_pt1
\d+ ft2
DROP FOREIGN TABLE ft2;
\d+ pt1
\d+ fd_pt1
CREATE FOREIGN TABLE ft2 (
c1 integer NOT NULL,
c2 text,
c3 date
) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ ft2
ALTER FOREIGN TABLE ft2 INHERIT pt1;
\d+ pt1
ALTER FOREIGN TABLE ft2 INHERIT fd_pt1;
\d+ fd_pt1
\d+ ft2
CREATE TABLE ct3() INHERITS(ft2);
CREATE FOREIGN TABLE ft3 (
......@@ -611,50 +611,50 @@ CREATE FOREIGN TABLE ft3 (
\d+ ft3
-- add attributes recursively
ALTER TABLE pt1 ADD COLUMN c4 integer;
ALTER TABLE pt1 ADD COLUMN c5 integer DEFAULT 0;
ALTER TABLE pt1 ADD COLUMN c6 integer;
ALTER TABLE pt1 ADD COLUMN c7 integer NOT NULL;
ALTER TABLE pt1 ADD COLUMN c8 integer;
\d+ pt1
ALTER TABLE fd_pt1 ADD COLUMN c4 integer;
ALTER TABLE fd_pt1 ADD COLUMN c5 integer DEFAULT 0;
ALTER TABLE fd_pt1 ADD COLUMN c6 integer;
ALTER TABLE fd_pt1 ADD COLUMN c7 integer NOT NULL;
ALTER TABLE fd_pt1 ADD COLUMN c8 integer;
\d+ fd_pt1
\d+ ft2
\d+ ct3
\d+ ft3
-- alter attributes recursively
ALTER TABLE pt1 ALTER COLUMN c4 SET DEFAULT 0;
ALTER TABLE pt1 ALTER COLUMN c5 DROP DEFAULT;
ALTER TABLE pt1 ALTER COLUMN c6 SET NOT NULL;
ALTER TABLE pt1 ALTER COLUMN c7 DROP NOT NULL;
ALTER TABLE pt1 ALTER COLUMN c8 TYPE char(10) USING '0'; -- ERROR
ALTER TABLE pt1 ALTER COLUMN c8 TYPE char(10);
ALTER TABLE pt1 ALTER COLUMN c8 SET DATA TYPE text;
ALTER TABLE pt1 ALTER COLUMN c1 SET STATISTICS 10000;
ALTER TABLE pt1 ALTER COLUMN c1 SET (n_distinct = 100);
ALTER TABLE pt1 ALTER COLUMN c8 SET STATISTICS -1;
ALTER TABLE pt1 ALTER COLUMN c8 SET STORAGE EXTERNAL;
\d+ pt1
ALTER TABLE fd_pt1 ALTER COLUMN c4 SET DEFAULT 0;
ALTER TABLE fd_pt1 ALTER COLUMN c5 DROP DEFAULT;
ALTER TABLE fd_pt1 ALTER COLUMN c6 SET NOT NULL;
ALTER TABLE fd_pt1 ALTER COLUMN c7 DROP NOT NULL;
ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) USING '0'; -- ERROR
ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10);
ALTER TABLE fd_pt1 ALTER COLUMN c8 SET DATA TYPE text;
ALTER TABLE fd_pt1 ALTER COLUMN c1 SET STATISTICS 10000;
ALTER TABLE fd_pt1 ALTER COLUMN c1 SET (n_distinct = 100);
ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STATISTICS -1;
ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STORAGE EXTERNAL;
\d+ fd_pt1
\d+ ft2
-- drop attributes recursively
ALTER TABLE pt1 DROP COLUMN c4;
ALTER TABLE pt1 DROP COLUMN c5;
ALTER TABLE pt1 DROP COLUMN c6;
ALTER TABLE pt1 DROP COLUMN c7;
ALTER TABLE pt1 DROP COLUMN c8;
\d+ pt1
ALTER TABLE fd_pt1 DROP COLUMN c4;
ALTER TABLE fd_pt1 DROP COLUMN c5;
ALTER TABLE fd_pt1 DROP COLUMN c6;
ALTER TABLE fd_pt1 DROP COLUMN c7;
ALTER TABLE fd_pt1 DROP COLUMN c8;
\d+ fd_pt1
\d+ ft2
-- add constraints recursively
ALTER TABLE pt1 ADD CONSTRAINT pt1chk1 CHECK (c1 > 0) NO INHERIT;
ALTER TABLE pt1 ADD CONSTRAINT pt1chk2 CHECK (c2 <> '');
ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk1 CHECK (c1 > 0) NO INHERIT;
ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '');
-- connoinherit should be true for NO INHERIT constraint
SELECT relname, conname, contype, conislocal, coninhcount, connoinherit
FROM pg_class AS pc JOIN pg_constraint AS pgc ON (conrelid = pc.oid)
WHERE pc.relname = 'pt1'
WHERE pc.relname = 'fd_pt1'
ORDER BY 1,2;
-- child does not inherit NO INHERIT constraints
\d+ pt1
\d+ fd_pt1
\d+ ft2
\set VERBOSITY terse
DROP FOREIGN TABLE ft2; -- ERROR
......@@ -666,50 +666,50 @@ CREATE FOREIGN TABLE ft2 (
c3 date
) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
-- child must have parent's INHERIT constraints
ALTER FOREIGN TABLE ft2 INHERIT pt1; -- ERROR
ALTER FOREIGN TABLE ft2 ADD CONSTRAINT pt1chk2 CHECK (c2 <> '');
ALTER FOREIGN TABLE ft2 INHERIT pt1;
ALTER FOREIGN TABLE ft2 INHERIT fd_pt1; -- ERROR
ALTER FOREIGN TABLE ft2 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> '');
ALTER FOREIGN TABLE ft2 INHERIT fd_pt1;
-- child does not inherit NO INHERIT constraints
\d+ pt1
\d+ fd_pt1
\d+ ft2
-- drop constraints recursively
ALTER TABLE pt1 DROP CONSTRAINT pt1chk1 CASCADE;
ALTER TABLE pt1 DROP CONSTRAINT pt1chk2 CASCADE;
ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk1 CASCADE;
ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk2 CASCADE;
-- NOT VALID case
INSERT INTO pt1 VALUES (1, 'pt1'::text, '1994-01-01'::date);
ALTER TABLE pt1 ADD CONSTRAINT pt1chk3 CHECK (c2 <> '') NOT VALID;
\d+ pt1
INSERT INTO fd_pt1 VALUES (1, 'fd_pt1'::text, '1994-01-01'::date);
ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk3 CHECK (c2 <> '') NOT VALID;
\d+ fd_pt1
\d+ ft2
-- VALIDATE CONSTRAINT need do nothing on foreign tables
ALTER TABLE pt1 VALIDATE CONSTRAINT pt1chk3;
\d+ pt1
ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3;
\d+ fd_pt1
\d+ ft2
-- OID system column
ALTER TABLE pt1 SET WITH OIDS;
\d+ pt1
ALTER TABLE fd_pt1 SET WITH OIDS;
\d+ fd_pt1
\d+ ft2
ALTER TABLE ft2 SET WITHOUT OIDS; -- ERROR
ALTER TABLE pt1 SET WITHOUT OIDS;
\d+ pt1
ALTER TABLE fd_pt1 SET WITHOUT OIDS;
\d+ fd_pt1
\d+ ft2
-- changes name of an attribute recursively
ALTER TABLE pt1 RENAME COLUMN c1 TO f1;
ALTER TABLE pt1 RENAME COLUMN c2 TO f2;
ALTER TABLE pt1 RENAME COLUMN c3 TO f3;
ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1;
ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2;
ALTER TABLE fd_pt1 RENAME COLUMN c3 TO f3;
-- changes name of a constraint recursively
ALTER TABLE pt1 RENAME CONSTRAINT pt1chk3 TO f2_check;
\d+ pt1
ALTER TABLE fd_pt1 RENAME CONSTRAINT fd_pt1chk3 TO f2_check;
\d+ fd_pt1
\d+ ft2
-- TRUNCATE doesn't work on foreign tables, either directly or recursively
TRUNCATE ft2; -- ERROR
TRUNCATE pt1; -- ERROR
TRUNCATE fd_pt1; -- ERROR
DROP TABLE pt1 CASCADE;
DROP TABLE fd_pt1 CASCADE;
-- IMPORT FOREIGN SCHEMA
IMPORT FOREIGN SCHEMA s1 FROM SERVER s9 INTO public; -- ERROR
......@@ -729,75 +729,75 @@ DROP OWNED BY regress_test_role2;
DROP OWNED BY regress_test_role2 CASCADE;
-- Foreign partition DDL stuff
CREATE TABLE pt2 (
CREATE TABLE fd_pt2 (
c1 integer NOT NULL,
c2 text,
c3 date
) PARTITION BY LIST (c1);
CREATE FOREIGN TABLE pt2_1 PARTITION OF pt2 FOR VALUES IN (1)
CREATE FOREIGN TABLE fd_pt2_1 PARTITION OF fd_pt2 FOR VALUES IN (1)
SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt2
\d+ pt2_1
\d+ fd_pt2
\d+ fd_pt2_1
-- partition cannot have additional columns
DROP FOREIGN TABLE pt2_1;
CREATE FOREIGN TABLE pt2_1 (
DROP FOREIGN TABLE fd_pt2_1;
CREATE FOREIGN TABLE fd_pt2_1 (
c1 integer NOT NULL,
c2 text,
c3 date,
c4 char
) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt2_1
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1); -- ERROR
\d+ fd_pt2_1
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); -- ERROR
DROP FOREIGN TABLE pt2_1;
\d+ pt2
CREATE FOREIGN TABLE pt2_1 (
DROP FOREIGN TABLE fd_pt2_1;
\d+ fd_pt2
CREATE FOREIGN TABLE fd_pt2_1 (
c1 integer NOT NULL,
c2 text,
c3 date
) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value');
\d+ pt2_1
\d+ fd_pt2_1
-- no attach partition validation occurs for foreign tables
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1);
\d+ pt2
\d+ pt2_1
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1);
\d+ fd_pt2
\d+ fd_pt2_1
-- cannot add column to a partition
ALTER TABLE pt2_1 ADD c4 char;
ALTER TABLE fd_pt2_1 ADD c4 char;
-- ok to have a partition's own constraints though
ALTER TABLE pt2_1 ALTER c3 SET NOT NULL;
ALTER TABLE pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> '');
\d+ pt2
\d+ pt2_1
ALTER TABLE fd_pt2_1 ALTER c3 SET NOT NULL;
ALTER TABLE fd_pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> '');
\d+ fd_pt2
\d+ fd_pt2_1
-- cannot drop inherited NOT NULL constraint from a partition
ALTER TABLE pt2_1 ALTER c1 DROP NOT NULL;
ALTER TABLE fd_pt2_1 ALTER c1 DROP NOT NULL;
-- partition must have parent's constraints
ALTER TABLE pt2 DETACH PARTITION pt2_1;
ALTER TABLE pt2 ALTER c2 SET NOT NULL;
\d+ pt2
\d+ pt2_1
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1); -- ERROR
ALTER FOREIGN TABLE pt2_1 ALTER c2 SET NOT NULL;
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1);
ALTER TABLE pt2 DETACH PARTITION pt2_1;
ALTER TABLE pt2 ADD CONSTRAINT pt2chk1 CHECK (c1 > 0);
\d+ pt2
\d+ pt2_1
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1); -- ERROR
ALTER FOREIGN TABLE pt2_1 ADD CONSTRAINT pt2chk1 CHECK (c1 > 0);
ALTER TABLE pt2 ATTACH PARTITION pt2_1 FOR VALUES IN (1);
ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1;
ALTER TABLE fd_pt2 ALTER c2 SET NOT NULL;
\d+ fd_pt2
\d+ fd_pt2_1
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); -- ERROR
ALTER FOREIGN TABLE fd_pt2_1 ALTER c2 SET NOT NULL;
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1);
ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1;
ALTER TABLE fd_pt2 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0);
\d+ fd_pt2
\d+ fd_pt2_1
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); -- ERROR
ALTER FOREIGN TABLE fd_pt2_1 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0);
ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1);
-- TRUNCATE doesn't work on foreign tables, either directly or recursively
TRUNCATE pt2_1; -- ERROR
TRUNCATE pt2; -- ERROR
TRUNCATE fd_pt2_1; -- ERROR
TRUNCATE fd_pt2; -- ERROR
DROP FOREIGN TABLE pt2_1;
DROP TABLE pt2;
DROP FOREIGN TABLE fd_pt2_1;
DROP TABLE fd_pt2;
-- Cleanup
DROP SCHEMA foreign_schema CASCADE;
......
CREATE TABLE toasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text);
CREATE TABLE indtoasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text);
INSERT INTO toasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000));
INSERT INTO toasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000));
INSERT INTO toasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000));
INSERT INTO toasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000));
INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000));
INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000));
INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000));
INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000));
-- check whether indirect tuples works on the most basic level
SELECT descr, substring(make_tuple_indirect(toasttest)::text, 1, 200) FROM toasttest;
SELECT descr, substring(make_tuple_indirect(indtoasttest)::text, 1, 200) FROM indtoasttest;
-- modification without changing varlenas
UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200);
-- modification without modifying assigned value
UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200);
-- modification modifying, but effectively not changing
UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200);
UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200);
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
-- check we didn't screw with main/toast tuple visibility
VACUUM FREEZE toasttest;
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
VACUUM FREEZE indtoasttest;
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
-- now create a trigger that forces all Datums to be indirect ones
CREATE FUNCTION update_using_indirect()
......@@ -33,29 +33,29 @@ BEGIN
RETURN NEW;
END$$;
CREATE TRIGGER toasttest_update_indirect
CREATE TRIGGER indtoasttest_update_indirect
BEFORE INSERT OR UPDATE
ON toasttest
ON indtoasttest
FOR EACH ROW
EXECUTE PROCEDURE update_using_indirect();
-- modification without changing varlenas
UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200);
-- modification without modifying assigned value
UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200);
-- modification modifying, but effectively not changing
UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200);
UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toasttest::text, 1, 200);
UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200);
INSERT INTO toasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL);
INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL);
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
-- check we didn't screw with main/toast tuple visibility
VACUUM FREEZE toasttest;
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
VACUUM FREEZE indtoasttest;
SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest;
DROP TABLE toasttest;
DROP TABLE indtoasttest;
DROP FUNCTION update_using_indirect();
......@@ -1792,25 +1792,25 @@ delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss;
-- test LATERAL reference propagation down a multi-level inheritance hierarchy
-- produced for a multi-level partitioned table hierarchy.
--
create table pt1 (a int, b int, c varchar) partition by range(a);
create table pt1p1 partition of pt1 for values from (0) to (100) partition by range(b);
create table pt1p2 partition of pt1 for values from (100) to (200);
create table pt1p1p1 partition of pt1p1 for values from (0) to (100);
insert into pt1 values (1, 1, 'x'), (101, 101, 'y');
create table ut1 (a int, b int, c varchar);
insert into ut1 values (101, 101, 'y'), (2, 2, 'z');
create table join_pt1 (a int, b int, c varchar) partition by range(a);
create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b);
create table join_pt1p2 partition of join_pt1 for values from (100) to (200);
create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100);
insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y');
create table join_ut1 (a int, b int, c varchar);
insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z');
explain (verbose, costs off)
select t1.b, ss.phv from ut1 t1 left join lateral
select t1.b, ss.phv from join_ut1 t1 left join lateral
(select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv
from pt1 t2 join ut1 t3 on t2.a = t3.b) ss
from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss
on t1.a = ss.t2a order by t1.a;
select t1.b, ss.phv from ut1 t1 left join lateral
select t1.b, ss.phv from join_ut1 t1 left join lateral
(select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv
from pt1 t2 join ut1 t3 on t2.a = t3.b) ss
from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss
on t1.a = ss.t2a order by t1.a;
drop table pt1;
drop table ut1;
drop table join_pt1;
drop table join_ut1;
--
-- test that foreign key join estimation performs sanely for outer joins
--
......@@ -2281,10 +2281,10 @@ rollback to settings;
-- Exercise rescans. We'll turn off parallel_leader_participation so
-- that we can check that instrumentation comes back correctly.
create table foo as select generate_series(1, 3) as id, 'xxxxx'::text as t;
alter table foo set (parallel_workers = 0);
create table bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t;
alter table bar set (parallel_workers = 2);
create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t;
alter table join_foo set (parallel_workers = 0);
create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t;
alter table join_bar set (parallel_workers = 2);
-- multi-batch with rescan, parallel-oblivious
savepoint settings;
......@@ -2298,18 +2298,18 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '64kB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
rollback to settings;
......@@ -2325,18 +2325,18 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '4MB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
rollback to settings;
......@@ -2352,18 +2352,18 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '64kB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
rollback to settings;
......@@ -2379,18 +2379,18 @@ set enable_material = off;
set enable_mergejoin = off;
set work_mem = '4MB';
explain (costs off)
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
select final > 1 as multibatch
from hash_join_batches(
$$
select count(*) from foo
left join (select b1.id, b1.t from bar b1 join bar b2 using (id)) ss
on foo.id < ss.id + 1 and foo.id > ss.id - 1;
select count(*) from join_foo
left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss
on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1;
$$);
rollback to settings;
......
......@@ -159,21 +159,21 @@ select cachebug();
-- Check that addition or removal of any partition is correctly dealt with by
-- default partition table when it is being used in prepared statement.
create table list_parted (a int) partition by list(a);
create table list_part_null partition of list_parted for values in (null);
create table list_part_1 partition of list_parted for values in (1);
create table list_part_def partition of list_parted default;
prepare pstmt_def_insert (int) as insert into list_part_def values($1);
create table pc_list_parted (a int) partition by list(a);
create table pc_list_part_null partition of pc_list_parted for values in (null);
create table pc_list_part_1 partition of pc_list_parted for values in (1);
create table pc_list_part_def partition of pc_list_parted default;
prepare pstmt_def_insert (int) as insert into pc_list_part_def values($1);
-- should fail
execute pstmt_def_insert(null);
execute pstmt_def_insert(1);
create table list_part_2 partition of list_parted for values in (2);
create table pc_list_part_2 partition of pc_list_parted for values in (2);
execute pstmt_def_insert(2);
alter table list_parted detach partition list_part_null;
alter table pc_list_parted detach partition pc_list_part_null;
-- should be ok
execute pstmt_def_insert(null);
drop table list_part_1;
drop table pc_list_part_1;
-- should be ok
execute pstmt_def_insert(1);
drop table list_parted, list_part_null;
drop table pc_list_parted, pc_list_part_null;
deallocate pstmt_def_insert;
......@@ -1648,7 +1648,7 @@ create table perform_test (
b INT
);
create function simple_func(int) returns boolean as '
create function perform_simple_func(int) returns boolean as '
BEGIN
IF $1 < 20 THEN
INSERT INTO perform_test VALUES ($1, $1 + 10);
......@@ -1664,13 +1664,13 @@ BEGIN
INSERT INTO perform_test VALUES (100, 100);
END IF;
PERFORM simple_func(5);
PERFORM perform_simple_func(5);
IF FOUND then
INSERT INTO perform_test VALUES (100, 100);
END IF;
PERFORM simple_func(50);
PERFORM perform_simple_func(50);
IF FOUND then
INSERT INTO perform_test VALUES (100, 100);
......@@ -2332,7 +2332,7 @@ create temp table foo (f1 int, f2 int);
insert into foo values (1,2), (3,4);
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
......@@ -2340,9 +2340,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail due to implicit strict
......@@ -2350,9 +2350,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
......@@ -2360,9 +2360,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- this should work since EXECUTE isn't as picky
......@@ -2370,11 +2370,11 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
select * from foo;
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
......@@ -2382,9 +2382,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, no rows
......@@ -2392,9 +2392,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, too many rows
......@@ -2402,9 +2402,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should work
......@@ -2412,9 +2412,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, no rows
......@@ -2422,9 +2422,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- should fail, too many rows
......@@ -2432,15 +2432,15 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
drop function footest();
drop function stricttest();
-- test printing parameters after failure due to STRICT
set plpgsql.print_strict_params to true;
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare
x record;
p1 int := 2;
......@@ -2451,9 +2451,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare
x record;
p1 int := 2;
......@@ -2464,9 +2464,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- too many rows, no params
......@@ -2474,9 +2474,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- no rows
......@@ -2484,9 +2484,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- too many rows
......@@ -2494,9 +2494,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
declare x record;
begin
-- too many rows, no parameters
......@@ -2504,9 +2504,9 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
-- override the global
#print_strict_params off
declare
......@@ -2519,11 +2519,11 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
reset plpgsql.print_strict_params;
create or replace function footest() returns void as $$
create or replace function stricttest() returns void as $$
-- override the global
#print_strict_params on
declare
......@@ -2536,7 +2536,7 @@ begin
raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
end$$ language plpgsql;
select footest();
select stricttest();
-- test warnings and errors
set plpgsql.extra_warnings to 'all';
......
......@@ -734,18 +734,18 @@ $$ language sql;
drop function dfunc(varchar, numeric);
--fail, named parameters are not unique
create function testfoo(a int, a int) returns int as $$ select 1;$$ language sql;
create function testfoo(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
create function testfoo(out a int, inout a int) returns int as $$ select 1;$$ language sql;
create function testfoo(a int, inout a int) returns int as $$ select 1;$$ language sql;
create function testpolym(a int, a int) returns int as $$ select 1;$$ language sql;
create function testpolym(int, out a int, out a int) returns int as $$ select 1;$$ language sql;
create function testpolym(out a int, inout a int) returns int as $$ select 1;$$ language sql;
create function testpolym(a int, inout a int) returns int as $$ select 1;$$ language sql;
-- valid
create function testfoo(a int, out a int) returns int as $$ select $1;$$ language sql;
select testfoo(37);
drop function testfoo(int);
create function testfoo(a int) returns table(a int) as $$ select $1;$$ language sql;
select * from testfoo(37);
drop function testfoo(int);
create function testpolym(a int, out a int) returns int as $$ select $1;$$ language sql;
select testpolym(37);
drop function testpolym(int);
create function testpolym(a int) returns table(a int) as $$ select $1;$$ language sql;
select * from testpolym(37);
drop function testpolym(int);
-- test polymorphic params and defaults
create function dfunc(a anyelement, b anyelement = null, flag bool = true)
......
......@@ -440,54 +440,54 @@ GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT USAGE ON LANGUAGE sql TO regress_priv_user2; -- fail
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE testagg1(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testproc1(int) AS 'select $1;' LANGUAGE sql;
REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int), testagg1(int) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int), testagg1(int) TO regress_priv_user2;
REVOKE ALL ON FUNCTION testproc1(int) FROM PUBLIC; -- fail, not a function
REVOKE ALL ON PROCEDURE testproc1(int) FROM PUBLIC;
GRANT EXECUTE ON PROCEDURE testproc1(int) TO regress_priv_user2;
GRANT USAGE ON FUNCTION testfunc1(int) TO regress_priv_user3; -- semantic error
GRANT USAGE ON FUNCTION testagg1(int) TO regress_priv_user3; -- semantic error
GRANT USAGE ON PROCEDURE testproc1(int) TO regress_priv_user3; -- semantic error
GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON FUNCTION testfunc_nosuch(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON FUNCTION testagg1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON PROCEDURE testproc1(int) TO regress_priv_user4;
CREATE FUNCTION testfunc4(boolean) RETURNS text
CREATE FUNCTION priv_testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION priv_testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE priv_testagg1(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE priv_testproc1(int) AS 'select $1;' LANGUAGE sql;
REVOKE ALL ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) TO regress_priv_user2;
REVOKE ALL ON FUNCTION priv_testproc1(int) FROM PUBLIC; -- fail, not a function
REVOKE ALL ON PROCEDURE priv_testproc1(int) FROM PUBLIC;
GRANT EXECUTE ON PROCEDURE priv_testproc1(int) TO regress_priv_user2;
GRANT USAGE ON FUNCTION priv_testfunc1(int) TO regress_priv_user3; -- semantic error
GRANT USAGE ON FUNCTION priv_testagg1(int) TO regress_priv_user3; -- semantic error
GRANT USAGE ON PROCEDURE priv_testproc1(int) TO regress_priv_user3; -- semantic error
GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc_nosuch(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON FUNCTION priv_testagg1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON PROCEDURE priv_testproc1(int) TO regress_priv_user4;
CREATE FUNCTION priv_testfunc4(boolean) RETURNS text
AS 'select col1 from atest2 where col2 = $1;'
LANGUAGE sql SECURITY DEFINER;
GRANT EXECUTE ON FUNCTION testfunc4(boolean) TO regress_priv_user3;
GRANT EXECUTE ON FUNCTION priv_testfunc4(boolean) TO regress_priv_user3;
SET SESSION AUTHORIZATION regress_priv_user2;
SELECT testfunc1(5), testfunc2(5); -- ok
CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
SELECT testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
CALL testproc1(6); -- ok
SELECT priv_testfunc1(5), priv_testfunc2(5); -- ok
CREATE FUNCTION priv_testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
CALL priv_testproc1(6); -- ok
SET SESSION AUTHORIZATION regress_priv_user3;
SELECT testfunc1(5); -- fail
SELECT testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- fail
CALL testproc1(6); -- fail
SELECT priv_testfunc1(5); -- fail
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- fail
CALL priv_testproc1(6); -- fail
SELECT col1 FROM atest2 WHERE col2 = true; -- fail
SELECT testfunc4(true); -- ok
SELECT priv_testfunc4(true); -- ok
SET SESSION AUTHORIZATION regress_priv_user4;
SELECT testfunc1(5); -- ok
SELECT testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
CALL testproc1(6); -- ok
SELECT priv_testfunc1(5); -- ok
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
CALL priv_testproc1(6); -- ok
DROP FUNCTION testfunc1(int); -- fail
DROP AGGREGATE testagg1(int); -- fail
DROP PROCEDURE testproc1(int); -- fail
DROP FUNCTION priv_testfunc1(int); -- fail
DROP AGGREGATE priv_testagg1(int); -- fail
DROP PROCEDURE priv_testproc1(int); -- fail
\c -
DROP FUNCTION testfunc1(int); -- ok
DROP FUNCTION priv_testfunc1(int); -- ok
-- restore to sanity
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
......@@ -505,108 +505,108 @@ ROLLBACK;
-- switch to superuser
\c -
CREATE TYPE testtype1 AS (a int, b text);
REVOKE USAGE ON TYPE testtype1 FROM PUBLIC;
GRANT USAGE ON TYPE testtype1 TO regress_priv_user2;
GRANT USAGE ON TYPE _testtype1 TO regress_priv_user2; -- fail
GRANT USAGE ON DOMAIN testtype1 TO regress_priv_user2; -- fail
CREATE TYPE priv_testtype1 AS (a int, b text);
REVOKE USAGE ON TYPE priv_testtype1 FROM PUBLIC;
GRANT USAGE ON TYPE priv_testtype1 TO regress_priv_user2;
GRANT USAGE ON TYPE _priv_testtype1 TO regress_priv_user2; -- fail
GRANT USAGE ON DOMAIN priv_testtype1 TO regress_priv_user2; -- fail
CREATE DOMAIN testdomain1 AS int;
REVOKE USAGE on DOMAIN testdomain1 FROM PUBLIC;
GRANT USAGE ON DOMAIN testdomain1 TO regress_priv_user2;
GRANT USAGE ON TYPE testdomain1 TO regress_priv_user2; -- ok
CREATE DOMAIN priv_testdomain1 AS int;
REVOKE USAGE on DOMAIN priv_testdomain1 FROM PUBLIC;
GRANT USAGE ON DOMAIN priv_testdomain1 TO regress_priv_user2;
GRANT USAGE ON TYPE priv_testdomain1 TO regress_priv_user2; -- ok
SET SESSION AUTHORIZATION regress_priv_user1;
-- commands that should fail
CREATE AGGREGATE testagg1a(testdomain1) (sfunc = int4_sum, stype = bigint);
CREATE AGGREGATE priv_testagg1a(priv_testdomain1) (sfunc = int4_sum, stype = bigint);
CREATE DOMAIN testdomain2a AS testdomain1;
CREATE DOMAIN priv_testdomain2a AS priv_testdomain1;
CREATE DOMAIN testdomain3a AS int;
CREATE FUNCTION castfunc(int) RETURNS testdomain3a AS $$ SELECT $1::testdomain3a $$ LANGUAGE SQL;
CREATE CAST (testdomain1 AS testdomain3a) WITH FUNCTION castfunc(int);
CREATE DOMAIN priv_testdomain3a AS int;
CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3a AS $$ SELECT $1::priv_testdomain3a $$ LANGUAGE SQL;
CREATE CAST (priv_testdomain1 AS priv_testdomain3a) WITH FUNCTION castfunc(int);
DROP FUNCTION castfunc(int) CASCADE;
DROP DOMAIN testdomain3a;
DROP DOMAIN priv_testdomain3a;
CREATE FUNCTION testfunc5a(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
CREATE FUNCTION testfunc6a(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
CREATE FUNCTION priv_testfunc5a(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
CREATE FUNCTION priv_testfunc6a(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$;
CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = testdomain1, RIGHTARG = testdomain1);
CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = priv_testdomain1, RIGHTARG = priv_testdomain1);
CREATE TABLE test5a (a int, b testdomain1);
CREATE TABLE test6a OF testtype1;
CREATE TABLE test10a (a int[], b testtype1[]);
CREATE TABLE test5a (a int, b priv_testdomain1);
CREATE TABLE test6a OF priv_testtype1;
CREATE TABLE test10a (a int[], b priv_testtype1[]);
CREATE TABLE test9a (a int, b int);
ALTER TABLE test9a ADD COLUMN c testdomain1;
ALTER TABLE test9a ALTER COLUMN b TYPE testdomain1;
ALTER TABLE test9a ADD COLUMN c priv_testdomain1;
ALTER TABLE test9a ALTER COLUMN b TYPE priv_testdomain1;
CREATE TYPE test7a AS (a int, b testdomain1);
CREATE TYPE test7a AS (a int, b priv_testdomain1);
CREATE TYPE test8a AS (a int, b int);
ALTER TYPE test8a ADD ATTRIBUTE c testdomain1;
ALTER TYPE test8a ALTER ATTRIBUTE b TYPE testdomain1;
ALTER TYPE test8a ADD ATTRIBUTE c priv_testdomain1;
ALTER TYPE test8a ALTER ATTRIBUTE b TYPE priv_testdomain1;
CREATE TABLE test11a AS (SELECT 1::testdomain1 AS a);
CREATE TABLE test11a AS (SELECT 1::priv_testdomain1 AS a);
REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC;
SET SESSION AUTHORIZATION regress_priv_user2;
-- commands that should succeed
CREATE AGGREGATE testagg1b(testdomain1) (sfunc = int4_sum, stype = bigint);
CREATE AGGREGATE priv_testagg1b(priv_testdomain1) (sfunc = int4_sum, stype = bigint);
CREATE DOMAIN testdomain2b AS testdomain1;
CREATE DOMAIN priv_testdomain2b AS priv_testdomain1;
CREATE DOMAIN testdomain3b AS int;
CREATE FUNCTION castfunc(int) RETURNS testdomain3b AS $$ SELECT $1::testdomain3b $$ LANGUAGE SQL;
CREATE CAST (testdomain1 AS testdomain3b) WITH FUNCTION castfunc(int);
CREATE DOMAIN priv_testdomain3b AS int;
CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3b AS $$ SELECT $1::priv_testdomain3b $$ LANGUAGE SQL;
CREATE CAST (priv_testdomain1 AS priv_testdomain3b) WITH FUNCTION castfunc(int);
CREATE FUNCTION testfunc5b(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
CREATE FUNCTION testfunc6b(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$;
CREATE FUNCTION priv_testfunc5b(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
CREATE FUNCTION priv_testfunc6b(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$;
CREATE OPERATOR !! (PROCEDURE = testfunc5b, RIGHTARG = testdomain1);
CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1);
CREATE TABLE test5b (a int, b testdomain1);
CREATE TABLE test6b OF testtype1;
CREATE TABLE test10b (a int[], b testtype1[]);
CREATE TABLE test5b (a int, b priv_testdomain1);
CREATE TABLE test6b OF priv_testtype1;
CREATE TABLE test10b (a int[], b priv_testtype1[]);
CREATE TABLE test9b (a int, b int);
ALTER TABLE test9b ADD COLUMN c testdomain1;
ALTER TABLE test9b ALTER COLUMN b TYPE testdomain1;
ALTER TABLE test9b ADD COLUMN c priv_testdomain1;
ALTER TABLE test9b ALTER COLUMN b TYPE priv_testdomain1;
CREATE TYPE test7b AS (a int, b testdomain1);
CREATE TYPE test7b AS (a int, b priv_testdomain1);
CREATE TYPE test8b AS (a int, b int);
ALTER TYPE test8b ADD ATTRIBUTE c testdomain1;
ALTER TYPE test8b ALTER ATTRIBUTE b TYPE testdomain1;
ALTER TYPE test8b ADD ATTRIBUTE c priv_testdomain1;
ALTER TYPE test8b ALTER ATTRIBUTE b TYPE priv_testdomain1;
CREATE TABLE test11b AS (SELECT 1::testdomain1 AS a);
CREATE TABLE test11b AS (SELECT 1::priv_testdomain1 AS a);
REVOKE ALL ON TYPE testtype1 FROM PUBLIC;
REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC;
\c -
DROP AGGREGATE testagg1b(testdomain1);
DROP DOMAIN testdomain2b;
DROP OPERATOR !! (NONE, testdomain1);
DROP FUNCTION testfunc5b(a testdomain1);
DROP FUNCTION testfunc6b(b int);
DROP AGGREGATE priv_testagg1b(priv_testdomain1);
DROP DOMAIN priv_testdomain2b;
DROP OPERATOR !! (NONE, priv_testdomain1);
DROP FUNCTION priv_testfunc5b(a priv_testdomain1);
DROP FUNCTION priv_testfunc6b(b int);
DROP TABLE test5b;
DROP TABLE test6b;
DROP TABLE test9b;
DROP TABLE test10b;
DROP TYPE test7b;
DROP TYPE test8b;
DROP CAST (testdomain1 AS testdomain3b);
DROP CAST (priv_testdomain1 AS priv_testdomain3b);
DROP FUNCTION castfunc(int) CASCADE;
DROP DOMAIN testdomain3b;
DROP DOMAIN priv_testdomain3b;
DROP TABLE test11b;
DROP TYPE testtype1; -- ok
DROP DOMAIN testdomain1; -- ok
DROP TYPE priv_testtype1; -- ok
DROP DOMAIN priv_testdomain1; -- ok
-- truncate
......@@ -974,18 +974,18 @@ DROP PROCEDURE testns.bar();
ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE USAGE ON TYPES FROM public;
CREATE DOMAIN testns.testdomain1 AS int;
CREATE DOMAIN testns.priv_testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.testdomain1', 'USAGE'); -- no
SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); -- no
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public;
DROP DOMAIN testns.testdomain1;
CREATE DOMAIN testns.testdomain1 AS int;
DROP DOMAIN testns.priv_testdomain1;
CREATE DOMAIN testns.priv_testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.testdomain1', 'USAGE'); -- yes
SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); -- yes
DROP DOMAIN testns.testdomain1;
DROP DOMAIN testns.priv_testdomain1;
RESET ROLE;
......@@ -1023,29 +1023,29 @@ REVOKE ALL ON ALL TABLES IN SCHEMA testns FROM regress_priv_user1;
SELECT has_table_privilege('regress_priv_user1', 'testns.t1', 'SELECT'); -- false
SELECT has_table_privilege('regress_priv_user1', 'testns.t2', 'SELECT'); -- false
CREATE FUNCTION testns.testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE testns.testagg(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testns.testproc(int) AS 'select 3' LANGUAGE sql;
CREATE FUNCTION testns.priv_testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE testns.priv_testagg(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testns.priv_testproc(int) AS 'select 3' LANGUAGE sql;
SELECT has_function_privilege('regress_priv_user1', 'testns.testfunc(int)', 'EXECUTE'); -- true by default
SELECT has_function_privilege('regress_priv_user1', 'testns.testagg(int)', 'EXECUTE'); -- true by default
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- true by default
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- true by default
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- true by default
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- true by default
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC;
SELECT has_function_privilege('regress_priv_user1', 'testns.testfunc(int)', 'EXECUTE'); -- false
SELECT has_function_privilege('regress_priv_user1', 'testns.testagg(int)', 'EXECUTE'); -- false
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- still true, not a function
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- false
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- false
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- still true, not a function
REVOKE ALL ON ALL PROCEDURES IN SCHEMA testns FROM PUBLIC;
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- now false
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- now false
GRANT ALL ON ALL ROUTINES IN SCHEMA testns TO PUBLIC;
SELECT has_function_privilege('regress_priv_user1', 'testns.testfunc(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.testagg(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.testproc(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- true
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- true
\set VERBOSITY terse \\ -- suppress cascade details
DROP SCHEMA testns CASCADE;
......@@ -1109,10 +1109,10 @@ drop table dep_priv_test;
drop sequence x_seq;
DROP AGGREGATE testagg1(int);
DROP FUNCTION testfunc2(int);
DROP FUNCTION testfunc4(boolean);
DROP PROCEDURE testproc1(int);
DROP AGGREGATE priv_testagg1(int);
DROP FUNCTION priv_testfunc2(int);
DROP FUNCTION priv_testfunc4(boolean);
DROP PROCEDURE priv_testproc1(int);
DROP VIEW atestv0;
DROP VIEW atestv1;
......
CREATE TABLE foo2(fooid int, f2 int);
INSERT INTO foo2 VALUES(1, 11);
INSERT INTO foo2 VALUES(2, 22);
INSERT INTO foo2 VALUES(1, 111);
CREATE TABLE rngfunc2(rngfuncid int, f2 int);
INSERT INTO rngfunc2 VALUES(1, 11);
INSERT INTO rngfunc2 VALUES(2, 22);
INSERT INTO rngfunc2 VALUES(1, 111);
CREATE FUNCTION foot(int) returns setof foo2 as 'SELECT * FROM foo2 WHERE fooid = $1 ORDER BY f2;' LANGUAGE SQL;
CREATE FUNCTION rngfunct(int) returns setof rngfunc2 as 'SELECT * FROM rngfunc2 WHERE rngfuncid = $1 ORDER BY f2;' LANGUAGE SQL;
-- function with ORDINALITY
select * from foot(1) with ordinality as z(a,b,ord);
select * from foot(1) with ordinality as z(a,b,ord) where b > 100; -- ordinal 2, not 1
select * from rngfunct(1) with ordinality as z(a,b,ord);
select * from rngfunct(1) with ordinality as z(a,b,ord) where b > 100; -- ordinal 2, not 1
-- ordinality vs. column names and types
select a,b,ord from foot(1) with ordinality as z(a,b,ord);
select a,b,ord from rngfunct(1) with ordinality as z(a,b,ord);
select a,ord from unnest(array['a','b']) with ordinality as z(a,ord);
select * from unnest(array['a','b']) with ordinality as z(a,ord);
select a,ord from unnest(array[1.0::float8]) with ordinality as z(a,ord);
select * from unnest(array[1.0::float8]) with ordinality as z(a,ord);
select row_to_json(s.*) from generate_series(11,14) with ordinality s;
-- ordinality vs. views
create temporary view vw_ord as select * from (values (1)) v(n) join foot(1) with ordinality as z(a,b,ord) on (n=ord);
create temporary view vw_ord as select * from (values (1)) v(n) join rngfunct(1) with ordinality as z(a,b,ord) on (n=ord);
select * from vw_ord;
select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
-- multiple functions
select * from rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord);
create temporary view vw_ord as select * from (values (1)) v(n) join rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
select * from rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord);
create temporary view vw_ord as select * from (values (1)) v(n) join rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
select * from vw_ord;
select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
......@@ -48,209 +48,209 @@ drop view vw_ord;
-- ordinality and multiple functions vs. rewind and reverse scan
begin;
declare foo scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
fetch all from foo;
fetch backward all from foo;
fetch all from foo;
fetch next from foo;
fetch next from foo;
fetch prior from foo;
fetch absolute 1 from foo;
fetch next from foo;
fetch next from foo;
fetch next from foo;
fetch prior from foo;
fetch prior from foo;
fetch prior from foo;
declare rf_cur scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
fetch all from rf_cur;
fetch backward all from rf_cur;
fetch all from rf_cur;
fetch next from rf_cur;
fetch next from rf_cur;
fetch prior from rf_cur;
fetch absolute 1 from rf_cur;
fetch next from rf_cur;
fetch next from rf_cur;
fetch next from rf_cur;
fetch prior from rf_cur;
fetch prior from rf_cur;
fetch prior from rf_cur;
commit;
-- function with implicit LATERAL
select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) z where rngfunc2.f2 = z.f2;
-- function with implicit LATERAL and explicit ORDINALITY
select * from foo2, foot(foo2.fooid) with ordinality as z(fooid,f2,ord) where foo2.f2 = z.f2;
select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) with ordinality as z(rngfuncid,f2,ord) where rngfunc2.f2 = z.f2;
-- function in subselect
select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = foo2.fooid) ORDER BY 1,2;
select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2;
-- function in subselect
select * from foo2 where f2 in (select f2 from foot(1) z where z.fooid = foo2.fooid) ORDER BY 1,2;
select * from rngfunc2 where f2 in (select f2 from rngfunct(1) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2;
-- function in subselect
select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = 1) ORDER BY 1,2;
select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = 1) ORDER BY 1,2;
-- nested functions
select foot.fooid, foot.f2 from foot(sin(pi()/2)::int) ORDER BY 1,2;
select rngfunct.rngfuncid, rngfunct.f2 from rngfunct(sin(pi()/2)::int) ORDER BY 1,2;
CREATE TABLE foo (fooid int, foosubid int, fooname text, primary key(fooid,foosubid));
INSERT INTO foo VALUES(1,1,'Joe');
INSERT INTO foo VALUES(1,2,'Ed');
INSERT INTO foo VALUES(2,1,'Mary');
CREATE TABLE rngfunc (rngfuncid int, rngfuncsubid int, rngfuncname text, primary key(rngfuncid,rngfuncsubid));
INSERT INTO rngfunc VALUES(1,1,'Joe');
INSERT INTO rngfunc VALUES(1,2,'Ed');
INSERT INTO rngfunc VALUES(2,1,'Mary');
-- sql, proretset = f, prorettype = b
CREATE FUNCTION getfoo1(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL;
SELECT * FROM getfoo1(1) AS t1;
SELECT * FROM getfoo1(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo1(1);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo1(1) WITH ORDINALITY as t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE FUNCTION getrngfunc1(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc1(1) AS t1;
SELECT * FROM getrngfunc1(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) WITH ORDINALITY as t1(v,o);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = b
CREATE FUNCTION getfoo2(int) RETURNS setof int AS 'SELECT fooid FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo2(1) AS t1;
SELECT * FROM getfoo2(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo2(1);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo2(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE FUNCTION getrngfunc2(int) RETURNS setof int AS 'SELECT rngfuncid FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc2(1) AS t1;
SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = b
CREATE FUNCTION getfoo3(int) RETURNS setof text AS 'SELECT fooname FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo3(1) AS t1;
SELECT * FROM getfoo3(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo3(1);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo3(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE FUNCTION getrngfunc3(int) RETURNS setof text AS 'SELECT rngfuncname FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc3(1) AS t1;
SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- sql, proretset = f, prorettype = c
CREATE FUNCTION getfoo4(int) RETURNS foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo4(1) AS t1;
SELECT * FROM getfoo4(1) WITH ORDINALITY AS t1(a,b,c,o);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo4(1);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo4(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE FUNCTION getrngfunc4(int) RETURNS rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc4(1) AS t1;
SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o);
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = c
CREATE FUNCTION getfoo5(int) RETURNS setof foo AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo5(1) AS t1;
SELECT * FROM getfoo5(1) WITH ORDINALITY AS t1(a,b,c,o);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo5(1);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo5(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE FUNCTION getrngfunc5(int) RETURNS setof rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc5(1) AS t1;
SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o);
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- sql, proretset = f, prorettype = record
CREATE FUNCTION getfoo6(int) RETURNS RECORD AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo6(1) AS t1(fooid int, foosubid int, fooname text);
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo6(1) AS
(fooid int, foosubid int, fooname text);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) )
CREATE FUNCTION getrngfunc6(int) RETURNS RECORD AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc6(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text);
SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc6(1) AS
(rngfuncid int, rngfuncsubid int, rngfuncname text);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS
SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- sql, proretset = t, prorettype = record
CREATE FUNCTION getfoo7(int) RETURNS setof record AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo7(1) AS t1(fooid int, foosubid int, fooname text);
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo7(1) AS
(fooid int, foosubid int, fooname text);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) )
CREATE FUNCTION getrngfunc7(int) RETURNS setof record AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
SELECT * FROM getrngfunc7(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text);
SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc7(1) AS
(rngfuncid int, rngfuncsubid int, rngfuncname text);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS
SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- plpgsql, proretset = f, prorettype = b
CREATE FUNCTION getfoo8(int) RETURNS int AS 'DECLARE fooint int; BEGIN SELECT fooid into fooint FROM foo WHERE fooid = $1; RETURN fooint; END;' LANGUAGE plpgsql;
SELECT * FROM getfoo8(1) AS t1;
SELECT * FROM getfoo8(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo8(1);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo8(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE FUNCTION getrngfunc8(int) RETURNS int AS 'DECLARE rngfuncint int; BEGIN SELECT rngfuncid into rngfuncint FROM rngfunc WHERE rngfuncid = $1; RETURN rngfuncint; END;' LANGUAGE plpgsql;
SELECT * FROM getrngfunc8(1) AS t1;
SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o);
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- plpgsql, proretset = f, prorettype = c
CREATE FUNCTION getfoo9(int) RETURNS foo AS 'DECLARE footup foo%ROWTYPE; BEGIN SELECT * into footup FROM foo WHERE fooid = $1; RETURN footup; END;' LANGUAGE plpgsql;
SELECT * FROM getfoo9(1) AS t1;
SELECT * FROM getfoo9(1) WITH ORDINALITY AS t1(a,b,c,o);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo9(1);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo9(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE FUNCTION getrngfunc9(int) RETURNS rngfunc AS 'DECLARE rngfunctup rngfunc%ROWTYPE; BEGIN SELECT * into rngfunctup FROM rngfunc WHERE rngfuncid = $1; RETURN rngfunctup; END;' LANGUAGE plpgsql;
SELECT * FROM getrngfunc9(1) AS t1;
SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o);
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o);
SELECT * FROM vw_getrngfunc;
DROP VIEW vw_getrngfunc;
-- mix 'n match kinds, to exercise expandRTE and related logic
select * from rows from(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo8(1),getfoo9(1))
select * from rows from(getrngfunc1(1),getrngfunc2(1),getrngfunc3(1),getrngfunc4(1),getrngfunc5(1),
getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc8(1),getrngfunc9(1))
with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u);
select * from rows from(getfoo9(1),getfoo8(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo5(1),getfoo4(1),getfoo3(1),getfoo2(1),getfoo1(1))
select * from rows from(getrngfunc9(1),getrngfunc8(1),
getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc5(1),getrngfunc4(1),getrngfunc3(1),getrngfunc2(1),getrngfunc1(1))
with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u);
create temporary view vw_foo as
select * from rows from(getfoo9(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo1(1))
create temporary view vw_rngfunc as
select * from rows from(getrngfunc9(1),
getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text),
getrngfunc1(1))
with ordinality as t1(a,b,c,d,e,f,g,n);
select * from vw_foo;
select pg_get_viewdef('vw_foo');
drop view vw_foo;
DROP FUNCTION getfoo1(int);
DROP FUNCTION getfoo2(int);
DROP FUNCTION getfoo3(int);
DROP FUNCTION getfoo4(int);
DROP FUNCTION getfoo5(int);
DROP FUNCTION getfoo6(int);
DROP FUNCTION getfoo7(int);
DROP FUNCTION getfoo8(int);
DROP FUNCTION getfoo9(int);
DROP FUNCTION foot(int);
DROP TABLE foo2;
DROP TABLE foo;
select * from vw_rngfunc;
select pg_get_viewdef('vw_rngfunc');
drop view vw_rngfunc;
DROP FUNCTION getrngfunc1(int);
DROP FUNCTION getrngfunc2(int);
DROP FUNCTION getrngfunc3(int);
DROP FUNCTION getrngfunc4(int);
DROP FUNCTION getrngfunc5(int);
DROP FUNCTION getrngfunc6(int);
DROP FUNCTION getrngfunc7(int);
DROP FUNCTION getrngfunc8(int);
DROP FUNCTION getrngfunc9(int);
DROP FUNCTION rngfunct(int);
DROP TABLE rngfunc2;
DROP TABLE rngfunc;
-- Rescan tests --
CREATE TEMPORARY SEQUENCE foo_rescan_seq1;
CREATE TEMPORARY SEQUENCE foo_rescan_seq2;
CREATE TYPE foo_rescan_t AS (i integer, s bigint);
CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq1;
CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq2;
CREATE TYPE rngfunc_rescan_t AS (i integer, s bigint);
CREATE FUNCTION foo_sql(int,int) RETURNS setof foo_rescan_t AS 'SELECT i, nextval(''foo_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL;
CREATE FUNCTION rngfunc_sql(int,int) RETURNS setof rngfunc_rescan_t AS 'SELECT i, nextval(''rngfunc_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL;
-- plpgsql functions use materialize mode
CREATE FUNCTION foo_mat(int,int) RETURNS setof foo_rescan_t AS 'begin for i in $1..$2 loop return next (i, nextval(''foo_rescan_seq2'')); end loop; end;' LANGUAGE plpgsql;
CREATE FUNCTION rngfunc_mat(int,int) RETURNS setof rngfunc_rescan_t AS 'begin for i in $1..$2 loop return next (i, nextval(''rngfunc_rescan_seq2'')); end loop; end;' LANGUAGE plpgsql;
--invokes ExecReScanFunctionScan - all these cases should materialize the function only once
-- LEFT JOIN on a condition that the planner can't prove to be true is used to ensure the function
-- is on the inner path of a nestloop join
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_sql(11,13) ON (r+i)<100;
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_sql(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) ON (r+i)<100;
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) ON (r+i)<100;
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( foo_sql(11,13), foo_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) ON (r+i)<100;
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( rngfunc_sql(11,13), rngfunc_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) f(i) ON (r+i)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) WITH ORDINALITY AS f(i,o) ON (r+i)<100;
......@@ -260,43 +260,43 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) WITH O
--invokes ExecReScanFunctionScan with chgParam != NULL (using implied LATERAL)
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(10+r,13);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(10+r,13) WITH ORDINALITY AS f(i,s,o);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(11,10+r);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_sql(11,10+r) WITH ORDINALITY AS f(i,s,o);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_sql(r1,r2);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_sql(r1,r2) WITH ORDINALITY AS f(i,s,o);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(10+r,13);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(10+r,13) WITH ORDINALITY AS f(i,s,o);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(11,10+r);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), foo_mat(11,10+r) WITH ORDINALITY AS f(i,s,o);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_mat(r1,r2);
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_mat(r1,r2) WITH ORDINALITY AS f(i,s,o);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13) WITH ORDINALITY AS f(i,s,o);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r) WITH ORDINALITY AS f(i,s,o);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2) WITH ORDINALITY AS f(i,s,o);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13) WITH ORDINALITY AS f(i,s,o);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r) WITH ORDINALITY AS f(i,s,o);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2);
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2) WITH ORDINALITY AS f(i,s,o);
-- selective rescan of multiple functions:
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(11,11), foo_mat(10+r,13) );
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(11,11) );
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(10+r,13) );
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(11,11), rngfunc_mat(10+r,13) );
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(11,11) );
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(10+r,13) );
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( foo_sql(10+r1,13), foo_mat(10+r2,13) );
SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false);
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( rngfunc_sql(10+r1,13), rngfunc_mat(10+r2,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) f(i);
SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) WITH ORDINALITY AS f(i,o);
......@@ -319,50 +319,50 @@ SELECT * FROM (VALUES (1),(2),(3)) v1(r1),
LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2)
LEFT JOIN generate_series(r1,2+r2/5) f(i) ON ((r2+i)<100) OFFSET 0) s1;
DROP FUNCTION foo_sql(int,int);
DROP FUNCTION foo_mat(int,int);
DROP SEQUENCE foo_rescan_seq1;
DROP SEQUENCE foo_rescan_seq2;
DROP FUNCTION rngfunc_sql(int,int);
DROP FUNCTION rngfunc_mat(int,int);
DROP SEQUENCE rngfunc_rescan_seq1;
DROP SEQUENCE rngfunc_rescan_seq2;
--
-- Test cases involving OUT parameters
--
CREATE FUNCTION foo(in f1 int, out f2 int)
CREATE FUNCTION rngfunc(in f1 int, out f2 int)
AS 'select $1+1' LANGUAGE sql;
SELECT foo(42);
SELECT * FROM foo(42);
SELECT * FROM foo(42) AS p(x);
SELECT rngfunc(42);
SELECT * FROM rngfunc(42);
SELECT * FROM rngfunc(42) AS p(x);
-- explicit spec of return type is OK
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS int
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS int
AS 'select $1+1' LANGUAGE sql;
-- error, wrong result type
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int) RETURNS float
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS float
AS 'select $1+1' LANGUAGE sql;
-- with multiple OUT params you must get a RECORD result
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text) RETURNS int
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) RETURNS int
AS 'select $1+1' LANGUAGE sql;
CREATE OR REPLACE FUNCTION foo(in f1 int, out f2 int, out f3 text)
CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text)
RETURNS record
AS 'select $1+1' LANGUAGE sql;
CREATE OR REPLACE FUNCTION foor(in f1 int, out f2 int, out text)
CREATE OR REPLACE FUNCTION rngfuncr(in f1 int, out f2 int, out text)
AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql;
SELECT f1, foor(f1) FROM int4_tbl;
SELECT * FROM foor(42);
SELECT * FROM foor(42) AS p(a,b);
SELECT f1, rngfuncr(f1) FROM int4_tbl;
SELECT * FROM rngfuncr(42);
SELECT * FROM rngfuncr(42) AS p(a,b);
CREATE OR REPLACE FUNCTION foob(in f1 int, inout f2 int, out text)
CREATE OR REPLACE FUNCTION rngfuncb(in f1 int, inout f2 int, out text)
AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql;
SELECT f1, foob(f1, f1/2) FROM int4_tbl;
SELECT * FROM foob(42, 99);
SELECT * FROM foob(42, 99) AS p(a,b);
SELECT f1, rngfuncb(f1, f1/2) FROM int4_tbl;
SELECT * FROM rngfuncb(42, 99);
SELECT * FROM rngfuncb(42, 99) AS p(a,b);
-- Can reference function with or without OUT params for DROP, etc
DROP FUNCTION foo(int);
DROP FUNCTION foor(in f2 int, out f1 int, out text);
DROP FUNCTION foob(in f1 int, inout f2 int);
DROP FUNCTION rngfunc(int);
DROP FUNCTION rngfuncr(in f2 int, out f1 int, out text);
DROP FUNCTION rngfuncb(in f1 int, inout f2 int);
--
-- For my next trick, polymorphic OUT parameters
......@@ -396,26 +396,26 @@ AS 'select $1, array[$1,$1]' LANGUAGE sql;
-- table functions
--
CREATE OR REPLACE FUNCTION foo()
CREATE OR REPLACE FUNCTION rngfunc()
RETURNS TABLE(a int)
AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql;
SELECT * FROM foo();
DROP FUNCTION foo();
SELECT * FROM rngfunc();
DROP FUNCTION rngfunc();
CREATE OR REPLACE FUNCTION foo(int)
CREATE OR REPLACE FUNCTION rngfunc(int)
RETURNS TABLE(a int, b int)
AS $$ SELECT a, b
FROM generate_series(1,$1) a(a),
generate_series(1,$1) b(b) $$ LANGUAGE sql;
SELECT * FROM foo(3);
DROP FUNCTION foo(int);
SELECT * FROM rngfunc(3);
DROP FUNCTION rngfunc(int);
-- case that causes change of typmod knowledge during inlining
CREATE OR REPLACE FUNCTION foo()
CREATE OR REPLACE FUNCTION rngfunc()
RETURNS TABLE(a varchar(5))
AS $$ SELECT 'hello'::varchar(5) $$ LANGUAGE sql STABLE;
SELECT * FROM foo() GROUP BY 1;
DROP FUNCTION foo();
SELECT * FROM rngfunc() GROUP BY 1;
DROP FUNCTION rngfunc();
--
-- some tests on SQL functions with RETURNING
......@@ -477,17 +477,17 @@ select * from tt;
select * from tt_log;
-- test case for a whole-row-variable bug
create function foo1(n integer, out a text, out b text)
create function rngfunc1(n integer, out a text, out b text)
returns setof record
language sql
as $$ select 'foo ' || i, 'bar ' || i from generate_series(1,$1) i $$;
set work_mem='64kB';
select t.a, t, t.a from foo1(10000) t limit 1;
select t.a, t, t.a from rngfunc1(10000) t limit 1;
reset work_mem;
select t.a, t, t.a from foo1(10000) t limit 1;
select t.a, t, t.a from rngfunc1(10000) t limit 1;
drop function foo1(n integer);
drop function rngfunc1(n integer);
-- test use of SQL functions returning record
-- this is supported in some cases where the query doesn't specify
......@@ -501,27 +501,27 @@ select array_to_set(array['one', 'two']);
select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text);
select * from array_to_set(array['one', 'two']); -- fail
create temp table foo(f1 int8, f2 int8);
create temp table rngfunc(f1 int8, f2 int8);
create function testfoo() returns record as $$
insert into foo values (1,2) returning *;
create function testrngfunc() returns record as $$
insert into rngfunc values (1,2) returning *;
$$ language sql;
select testfoo();
select * from testfoo() as t(f1 int8,f2 int8);
select * from testfoo(); -- fail
select testrngfunc();
select * from testrngfunc() as t(f1 int8,f2 int8);
select * from testrngfunc(); -- fail
drop function testfoo();
drop function testrngfunc();
create function testfoo() returns setof record as $$
insert into foo values (1,2), (3,4) returning *;
create function testrngfunc() returns setof record as $$
insert into rngfunc values (1,2), (3,4) returning *;
$$ language sql;
select testfoo();
select * from testfoo() as t(f1 int8,f2 int8);
select * from testfoo(); -- fail
select testrngfunc();
select * from testrngfunc() as t(f1 int8,f2 int8);
select * from testrngfunc(); -- fail
drop function testfoo();
drop function testrngfunc();
--
-- Check some cases involving added/dropped columns in a rowtype result
......@@ -572,33 +572,33 @@ drop table users;
-- this won't get inlined because of type coercion, but it shouldn't fail
create or replace function foobar() returns setof text as
create or replace function rngfuncbar() returns setof text as
$$ select 'foo'::varchar union all select 'bar'::varchar ; $$
language sql stable;
select foobar();
select * from foobar();
select rngfuncbar();
select * from rngfuncbar();
drop function foobar();
drop function rngfuncbar();
-- check handling of a SQL function with multiple OUT params (bug #5777)
create or replace function foobar(out integer, out numeric) as
create or replace function rngfuncbar(out integer, out numeric) as
$$ select (1, 2.1) $$ language sql;
select * from foobar();
select * from rngfuncbar();
create or replace function foobar(out integer, out numeric) as
create or replace function rngfuncbar(out integer, out numeric) as
$$ select (1, 2) $$ language sql;
select * from foobar(); -- fail
select * from rngfuncbar(); -- fail
create or replace function foobar(out integer, out numeric) as
create or replace function rngfuncbar(out integer, out numeric) as
$$ select (1, 2.1, 3) $$ language sql;
select * from foobar(); -- fail
select * from rngfuncbar(); -- fail
drop function foobar();
drop function rngfuncbar();
-- check whole-row-Var handling in nested lateral functions (bug #11703)
......@@ -633,11 +633,11 @@ select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x);
-- check handling of nulls in SRF results (bug #7808)
create type foo2 as (a integer, b text);
create type rngfunc2 as (a integer, b text);
select *, row_to_json(u) from unnest(array[(1,'foo')::foo2, null::foo2]) u;
select *, row_to_json(u) from unnest(array[null::foo2, null::foo2]) u;
select *, row_to_json(u) from unnest(array[null::foo2, (1,'foo')::foo2, null::foo2]) u;
select *, row_to_json(u) from unnest(array[]::foo2[]) u;
select *, row_to_json(u) from unnest(array[(1,'foo')::rngfunc2, null::rngfunc2]) u;
select *, row_to_json(u) from unnest(array[null::rngfunc2, null::rngfunc2]) u;
select *, row_to_json(u) from unnest(array[null::rngfunc2, (1,'foo')::rngfunc2, null::rngfunc2]) u;
select *, row_to_json(u) from unnest(array[]::rngfunc2[]) u;
drop type foo2;
drop type rngfunc2;
......@@ -700,34 +700,34 @@ SELECT count(*) FROM shoe;
--
-- Simple test of qualified ON INSERT ... this did not work in 7.0 ...
--
create table foo (f1 int);
create table foo2 (f1 int);
create table rules_foo (f1 int);
create table rules_foo2 (f1 int);
create rule foorule as on insert to foo where f1 < 100
create rule rules_foorule as on insert to rules_foo where f1 < 100
do instead nothing;
insert into foo values(1);
insert into foo values(1001);
select * from foo;
insert into rules_foo values(1);
insert into rules_foo values(1001);
select * from rules_foo;
drop rule foorule on foo;
drop rule rules_foorule on rules_foo;
-- this should fail because f1 is not exposed for unqualified reference:
create rule foorule as on insert to foo where f1 < 100
do instead insert into foo2 values (f1);
create rule rules_foorule as on insert to rules_foo where f1 < 100
do instead insert into rules_foo2 values (f1);
-- this is the correct way:
create rule foorule as on insert to foo where f1 < 100
do instead insert into foo2 values (new.f1);
create rule rules_foorule as on insert to rules_foo where f1 < 100
do instead insert into rules_foo2 values (new.f1);
insert into foo values(2);
insert into foo values(100);
insert into rules_foo values(2);
insert into rules_foo values(100);
select * from foo;
select * from foo2;
select * from rules_foo;
select * from rules_foo2;
drop rule foorule on foo;
drop table foo;
drop table foo2;
drop rule rules_foorule on rules_foo;
drop table rules_foo;
drop table rules_foo2;
--
......@@ -876,36 +876,36 @@ insert into rule_and_refint_t3 values (1, 13, 11, 'row8');
-- disallow dropping a view's rule (bug #5072)
--
create view fooview as select 'foo'::text;
drop rule "_RETURN" on fooview;
drop view fooview;
create view rules_fooview as select 'rules_foo'::text;
drop rule "_RETURN" on rules_fooview;
drop view rules_fooview;
--
-- test conversion of table to view (needed to load some pg_dump files)
--
create table fooview (x int, y text);
select xmin, * from fooview;
create table rules_fooview (x int, y text);
select xmin, * from rules_fooview;
create rule "_RETURN" as on select to fooview do instead
create rule "_RETURN" as on select to rules_fooview do instead
select 1 as x, 'aaa'::text as y;
select * from fooview;
select xmin, * from fooview; -- fail, views don't have such a column
select * from rules_fooview;
select xmin, * from rules_fooview; -- fail, views don't have such a column
select reltoastrelid, relkind, relfrozenxid
from pg_class where oid = 'fooview'::regclass;
from pg_class where oid = 'rules_fooview'::regclass;
drop view fooview;
drop view rules_fooview;
-- trying to convert a partitioned table to view is not allowed
create table fooview (x int, y text) partition by list (x);
create rule "_RETURN" as on select to fooview do instead
create table rules_fooview (x int, y text) partition by list (x);
create rule "_RETURN" as on select to rules_fooview do instead
select 1 as x, 'aaa'::text as y;
-- nor can one convert a partition to view
create table fooview_part partition of fooview for values in (1);
create rule "_RETURN" as on select to fooview_part do instead
create table rules_fooview_part partition of rules_fooview for values in (1);
create rule "_RETURN" as on select to rules_fooview_part do instead
select 1 as x, 'aaa'::text as y;
--
......@@ -1171,12 +1171,12 @@ SELECT pg_get_function_arg_default('pg_class'::regclass, 0);
SELECT pg_get_partkeydef(0);
-- test rename for a rule defined on a partitioned table
CREATE TABLE parted_table (a int) PARTITION BY LIST (a);
CREATE TABLE parted_table_1 PARTITION OF parted_table FOR VALUES IN (1);
CREATE RULE parted_table_insert AS ON INSERT to parted_table
DO INSTEAD INSERT INTO parted_table_1 VALUES (NEW.*);
ALTER RULE parted_table_insert ON parted_table RENAME TO parted_table_insert_redirect;
DROP TABLE parted_table;
CREATE TABLE rules_parted_table (a int) PARTITION BY LIST (a);
CREATE TABLE rules_parted_table_1 PARTITION OF rules_parted_table FOR VALUES IN (1);
CREATE RULE rules_parted_table_insert AS ON INSERT to rules_parted_table
DO INSTEAD INSERT INTO rules_parted_table_1 VALUES (NEW.*);
ALTER RULE rules_parted_table_insert ON rules_parted_table RENAME TO rules_parted_table_insert_redirect;
DROP TABLE rules_parted_table;
--
-- Test enabling/disabling
......
......@@ -3,18 +3,18 @@
--
SELECT *
INTO TABLE tmp1
INTO TABLE sitmp1
FROM onek
WHERE onek.unique1 < 2;
DROP TABLE tmp1;
DROP TABLE sitmp1;
SELECT *
INTO TABLE tmp1
INTO TABLE sitmp1
FROM onek2
WHERE onek2.unique1 < 2;
DROP TABLE tmp1;
DROP TABLE sitmp1;
--
-- SELECT INTO and INSERT permission, if owner is not allowed to insert.
......
......@@ -2,7 +2,7 @@
-- PARALLEL
--
create or replace function parallel_restricted(int) returns int as
create function sp_parallel_restricted(int) returns int as
$$begin return $1; end$$ language plpgsql parallel restricted;
-- Serializable isolation would disable parallel query, so explicitly use an
......@@ -50,10 +50,10 @@ select round(avg(aa)), sum(aa) from a_star a4;
reset enable_parallel_append;
-- Parallel Append that runs serially
create or replace function foobar() returns setof text as
create function sp_test_func() returns setof text as
$$ select 'foo'::varchar union all select 'bar'::varchar $$
language sql stable;
select foobar() order by 1;
select sp_test_func() order by 1;
-- test with leader participation disabled
set parallel_leader_participation = off;
......@@ -74,7 +74,7 @@ reset parallel_leader_participation;
-- test that parallel_restricted function doesn't run in worker
alter table tenk1 set (parallel_workers = 4);
explain (verbose, costs off)
select parallel_restricted(unique1) from tenk1
select sp_parallel_restricted(unique1) from tenk1
where stringu1 = 'GRAAAA' order by 1;
-- test parallel plan when group by expression is in target list.
......@@ -88,8 +88,8 @@ explain (costs off)
-- test that parallel plan for aggregates is not selected when
-- target list contains parallel restricted clause.
explain (costs off)
select sum(parallel_restricted(unique1)) from tenk1
group by(parallel_restricted(unique1));
select sum(sp_parallel_restricted(unique1)) from tenk1
group by(sp_parallel_restricted(unique1));
-- test prepared statement
prepare tenk1_count(integer) As select count((unique1)) from tenk1 where hundred > $1;
......@@ -240,7 +240,7 @@ explain (costs off)
select count(*) from tenk1 group by twenty;
--test expressions in targetlist are pushed down for gather merge
create or replace function simple_func(var1 integer) returns integer
create function sp_simple_func(var1 integer) returns integer
as $$
begin
return var1 + 10;
......@@ -248,9 +248,9 @@ end;
$$ language plpgsql PARALLEL SAFE;
explain (costs off, verbose)
select ten, simple_func(ten) from tenk1 where ten < 100 order by ten;
select ten, sp_simple_func(ten) from tenk1 where ten < 100 order by ten;
drop function simple_func(integer);
drop function sp_simple_func(integer);
-- test gather merge with parallel leader participation disabled
set parallel_leader_participation = off;
......@@ -316,7 +316,7 @@ explain (costs off)
ROLLBACK TO SAVEPOINT settings;
-- exercise record typmod remapping between backends
CREATE OR REPLACE FUNCTION make_record(n int)
CREATE FUNCTION make_record(n int)
RETURNS RECORD LANGUAGE plpgsql PARALLEL SAFE AS
$$
BEGIN
......
......@@ -100,51 +100,51 @@ COMMIT;
-- Subtransactions, basic tests
-- create & drop tables
SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE;
CREATE TABLE foobar (a int);
CREATE TABLE trans_foobar (a int);
BEGIN;
CREATE TABLE foo (a int);
CREATE TABLE trans_foo (a int);
SAVEPOINT one;
DROP TABLE foo;
CREATE TABLE bar (a int);
DROP TABLE trans_foo;
CREATE TABLE trans_bar (a int);
ROLLBACK TO SAVEPOINT one;
RELEASE SAVEPOINT one;
SAVEPOINT two;
CREATE TABLE baz (a int);
CREATE TABLE trans_baz (a int);
RELEASE SAVEPOINT two;
drop TABLE foobar;
CREATE TABLE barbaz (a int);
drop TABLE trans_foobar;
CREATE TABLE trans_barbaz (a int);
COMMIT;
-- should exist: barbaz, baz, foo
SELECT * FROM foo; -- should be empty
SELECT * FROM bar; -- shouldn't exist
SELECT * FROM barbaz; -- should be empty
SELECT * FROM baz; -- should be empty
-- should exist: trans_barbaz, trans_baz, trans_foo
SELECT * FROM trans_foo; -- should be empty
SELECT * FROM trans_bar; -- shouldn't exist
SELECT * FROM trans_barbaz; -- should be empty
SELECT * FROM trans_baz; -- should be empty
-- inserts
BEGIN;
INSERT INTO foo VALUES (1);
INSERT INTO trans_foo VALUES (1);
SAVEPOINT one;
INSERT into bar VALUES (1);
INSERT into trans_bar VALUES (1);
ROLLBACK TO one;
RELEASE SAVEPOINT one;
SAVEPOINT two;
INSERT into barbaz VALUES (1);
INSERT into trans_barbaz VALUES (1);
RELEASE two;
SAVEPOINT three;
SAVEPOINT four;
INSERT INTO foo VALUES (2);
INSERT INTO trans_foo VALUES (2);
RELEASE SAVEPOINT four;
ROLLBACK TO SAVEPOINT three;
RELEASE SAVEPOINT three;
INSERT INTO foo VALUES (3);
INSERT INTO trans_foo VALUES (3);
COMMIT;
SELECT * FROM foo; -- should have 1 and 3
SELECT * FROM barbaz; -- should have 1
SELECT * FROM trans_foo; -- should have 1 and 3
SELECT * FROM trans_barbaz; -- should have 1
-- test whole-tree commit
BEGIN;
SAVEPOINT one;
SELECT foo;
SELECT trans_foo;
ROLLBACK TO SAVEPOINT one;
RELEASE SAVEPOINT one;
SAVEPOINT two;
......@@ -179,7 +179,7 @@ BEGIN;
INSERT INTO savepoints VALUES (4);
SAVEPOINT one;
INSERT INTO savepoints VALUES (5);
SELECT foo;
SELECT trans_foo;
COMMIT;
SELECT * FROM savepoints;
......@@ -329,9 +329,9 @@ BEGIN;
INSERT INTO koju VALUES (1);
ROLLBACK;
DROP TABLE foo;
DROP TABLE baz;
DROP TABLE barbaz;
DROP TABLE trans_foo;
DROP TABLE trans_baz;
DROP TABLE trans_barbaz;
-- test case for problems with revalidating an open relation during abort
......
......@@ -26,8 +26,8 @@ CREATE VIEW rw_view15 AS SELECT a, upper(b) FROM base_tbl; -- Expression/functio
CREATE VIEW rw_view16 AS SELECT a, b, a AS aa FROM base_tbl; -- Repeated column may be part of an updatable view
CREATE VIEW ro_view17 AS SELECT * FROM ro_view1; -- Base relation not updatable
CREATE VIEW ro_view18 AS SELECT * FROM (VALUES(1)) AS tmp(a); -- VALUES in rangetable
CREATE SEQUENCE seq;
CREATE VIEW ro_view19 AS SELECT * FROM seq; -- View based on a sequence
CREATE SEQUENCE uv_seq;
CREATE VIEW ro_view19 AS SELECT * FROM uv_seq; -- View based on a sequence
CREATE VIEW ro_view20 AS SELECT a, b, generate_series(1, a) g FROM base_tbl; -- SRF in targetlist not supported
SELECT table_name, is_insertable_into
......@@ -100,7 +100,7 @@ UPDATE ro_view20 SET b=upper(b);
DROP TABLE base_tbl CASCADE;
DROP VIEW ro_view10, ro_view12, ro_view18;
DROP SEQUENCE seq CASCADE;
DROP SEQUENCE uv_seq CASCADE;
-- simple updatable view
......@@ -1114,33 +1114,33 @@ DROP VIEW v1;
DROP TABLE t1;
-- check that an auto-updatable view on a partitioned table works correctly
create table pt (a int, b int, v varchar) partition by range (a, b);
create table pt1 (b int not null, v varchar, a int not null) partition by range (b);
create table pt11 (like pt1);
alter table pt11 drop a;
alter table pt11 add a int;
alter table pt11 drop a;
alter table pt11 add a int not null;
alter table pt1 attach partition pt11 for values from (2) to (5);
alter table pt attach partition pt1 for values from (1, 2) to (1, 10);
create view ptv as select * from pt;
create table uv_pt (a int, b int, v varchar) partition by range (a, b);
create table uv_pt1 (b int not null, v varchar, a int not null) partition by range (b);
create table uv_pt11 (like uv_pt1);
alter table uv_pt11 drop a;
alter table uv_pt11 add a int;
alter table uv_pt11 drop a;
alter table uv_pt11 add a int not null;
alter table uv_pt1 attach partition uv_pt11 for values from (2) to (5);
alter table uv_pt attach partition uv_pt1 for values from (1, 2) to (1, 10);
create view uv_ptv as select * from uv_pt;
select events & 4 != 0 AS upd,
events & 8 != 0 AS ins,
events & 16 != 0 AS del
from pg_catalog.pg_relation_is_updatable('pt'::regclass, false) t(events);
select pg_catalog.pg_column_is_updatable('pt'::regclass, 1::smallint, false);
select pg_catalog.pg_column_is_updatable('pt'::regclass, 2::smallint, false);
from pg_catalog.pg_relation_is_updatable('uv_pt'::regclass, false) t(events);
select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 1::smallint, false);
select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 2::smallint, false);
select table_name, is_updatable, is_insertable_into
from information_schema.views where table_name = 'ptv';
from information_schema.views where table_name = 'uv_ptv';
select table_name, column_name, is_updatable
from information_schema.columns where table_name = 'ptv' order by column_name;
insert into ptv values (1, 2);
select tableoid::regclass, * from pt;
create view ptv_wco as select * from pt where a = 0 with check option;
insert into ptv_wco values (1, 2);
drop view ptv, ptv_wco;
drop table pt, pt1, pt11;
from information_schema.columns where table_name = 'uv_ptv' order by column_name;
insert into uv_ptv values (1, 2);
select tableoid::regclass, * from uv_pt;
create view uv_ptv_wco as select * from uv_pt where a = 0 with check option;
insert into uv_ptv_wco values (1, 2);
drop view uv_ptv, uv_ptv_wco;
drop table uv_pt, uv_pt1, uv_pt11;
-- check that wholerow vars appearing in WITH CHECK OPTION constraint expressions
-- work fine with partitioned tables
......
......@@ -805,46 +805,46 @@ SELECT * FROM t LIMIT 10;
SELECT * FROM y;
-- data-modifying WITH containing INSERT...ON CONFLICT DO UPDATE
CREATE TABLE z AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i;
ALTER TABLE z ADD UNIQUE (k);
CREATE TABLE withz AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i;
ALTER TABLE withz ADD UNIQUE (k);
WITH t AS (
INSERT INTO z SELECT i, 'insert'
INSERT INTO withz SELECT i, 'insert'
FROM generate_series(0, 16) i
ON CONFLICT (k) DO UPDATE SET v = z.v || ', now update'
ON CONFLICT (k) DO UPDATE SET v = withz.v || ', now update'
RETURNING *
)
SELECT * FROM t JOIN y ON t.k = y.a ORDER BY a, k;
-- Test EXCLUDED.* reference within CTE
WITH aa AS (
INSERT INTO z VALUES(1, 5) ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v
WHERE z.k != EXCLUDED.k
INSERT INTO withz VALUES(1, 5) ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v
WHERE withz.k != EXCLUDED.k
RETURNING *
)
SELECT * FROM aa;
-- New query/snapshot demonstrates side-effects of previous query.
SELECT * FROM z ORDER BY k;
SELECT * FROM withz ORDER BY k;
--
-- Ensure subqueries within the update clause work, even if they
-- reference outside values
--
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, 'insert')
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = ' update' WHERE z.k = (SELECT a FROM aa);
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = ' update' WHERE withz.k = (SELECT a FROM aa);
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, 'insert')
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
WITH aa AS (SELECT 'a' a, 'b' b UNION ALL SELECT 'a' a, 'b' b)
INSERT INTO z VALUES(1, 'insert')
INSERT INTO withz VALUES(1, 'insert')
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 'a' LIMIT 1);
WITH aa AS (SELECT 1 a, 2 b)
INSERT INTO z VALUES(1, (SELECT b || ' insert' FROM aa WHERE a = 1 ))
INSERT INTO withz VALUES(1, (SELECT b || ' insert' FROM aa WHERE a = 1 ))
ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIMIT 1);
-- Update a row more than once, in different parts of a wCTE. That is
......@@ -853,14 +853,14 @@ ON CONFLICT (k) DO UPDATE SET v = (SELECT b || ' update' FROM aa WHERE a = 1 LIM
WITH simpletup AS (
SELECT 2 k, 'Green' v),
upsert_cte AS (
INSERT INTO z VALUES(2, 'Blue') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM simpletup WHERE simpletup.k = z.k)
INSERT INTO withz VALUES(2, 'Blue') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM simpletup WHERE simpletup.k = withz.k)
RETURNING k, v)
INSERT INTO z VALUES(2, 'Red') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM upsert_cte WHERE upsert_cte.k = z.k)
INSERT INTO withz VALUES(2, 'Red') ON CONFLICT (k) DO
UPDATE SET (k, v) = (SELECT k, v FROM upsert_cte WHERE upsert_cte.k = withz.k)
RETURNING k, v;
DROP TABLE z;
DROP TABLE withz;
-- check that run to completion happens in proper ordering
......@@ -1035,7 +1035,7 @@ WITH test AS (SELECT 42) INSERT INTO test VALUES (1);
-- check response to attempt to modify table with same name as a CTE (perhaps
-- surprisingly it works, because CTEs don't hide tables from data-modifying
-- statements)
create table test (i int);
create temp table test (i int);
with test as (select 42) insert into test select * from test;
select * from test;
drop table test;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment