diff options
author | Pallavi Sontakke | 2015-08-25 08:13:31 +0000 |
---|---|---|
committer | Pallavi Sontakke | 2015-08-25 08:13:31 +0000 |
commit | 8a7b7af30cbc659c54941521095ef429550f192b (patch) | |
tree | d5c7ecf318a9b057f422c8da12ad83418cf98f20 | |
parent | 64fe8795534050a4db32db3f0e3c6f2bc612fc88 (diff) |
Tests related to user-defined-functions and not-supported features in Postgres-XL
-rwxr-xr-x[-rw-r--r--] | src/test/regress/expected/xl_alter_table.out | 8 | ||||
-rwxr-xr-x | src/test/regress/expected/xl_plan_pushdown.out | 36 | ||||
-rw-r--r-- | src/test/regress/expected/xl_plpgsql.out | 1048 | ||||
-rw-r--r-- | src/test/regress/serial_schedule | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | src/test/regress/sql/xl_alter_table.sql | 8 | ||||
-rwxr-xr-x | src/test/regress/sql/xl_plpgsql.sql | 545 |
6 files changed, 1620 insertions, 26 deletions
diff --git a/src/test/regress/expected/xl_alter_table.out b/src/test/regress/expected/xl_alter_table.out index c3dd967af7..c6285fae23 100644..100755 --- a/src/test/regress/expected/xl_alter_table.out +++ b/src/test/regress/expected/xl_alter_table.out @@ -74,8 +74,8 @@ ALTER TABLE xl_at2h ALTER COLUMN product_id DROP DEFAULT; ALTER TABLE xl_at2h RENAME COLUMN product_no TO product_number; ALTER TABLE xl_at2h RENAME COLUMN product_id TO product_identifier; ALTER TABLE xl_at2h RENAME TO xl_at3h; -ALTER TABLE xl_at3h DELETE NODE (datanode2); -ALTER TABLE xl_at3h ADD NODE (datanode2); +ALTER TABLE xl_at3h DELETE NODE (datanode_2); +ALTER TABLE xl_at3h ADD NODE (datanode_2); ALTER TABLE xl_at3h DISTRIBUTE BY REPLICATION; -- MODULO Distributed table: -- Distribution column cannot be dropped (BUG: It can be dropped now. Test Fails). @@ -98,8 +98,8 @@ ALTER TABLE xl_at2m ALTER COLUMN product_id DROP DEFAULT; ALTER TABLE xl_at2m RENAME COLUMN product_no TO product_number; ALTER TABLE xl_at2m RENAME COLUMN product_id TO product_identifier; ALTER TABLE xl_at2m RENAME TO xl_at3m; -ALTER TABLE xl_at3m DELETE NODE (datanode2); -ALTER TABLE xl_at3m ADD NODE (datanode2); +ALTER TABLE xl_at3m DELETE NODE (datanode_2); +ALTER TABLE xl_at3m ADD NODE (datanode_2); ALTER TABLE xl_at3m DROP COLUMN product_identifier;--fail - distribution column cannot be dropped. ERROR: Distribution column cannot be dropped ALTER TABLE xl_at3m DISTRIBUTE BY REPLICATION; diff --git a/src/test/regress/expected/xl_plan_pushdown.out b/src/test/regress/expected/xl_plan_pushdown.out index 51580b7ed5..720c631200 100755 --- a/src/test/regress/expected/xl_plan_pushdown.out +++ b/src/test/regress/expected/xl_plan_pushdown.out @@ -5,7 +5,7 @@ INSERT INTO xl_pp SELECT generate_series(1,100), 20; EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100; QUERY PLAN ---------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode2) (cost=0.00..35.50 rows=10 width=12) + Remote Subquery Scan on all (datanode_2) (cost=0.00..35.50 rows=10 width=12) Output: a, b -> Seq Scan on public.xl_pp (cost=0.00..35.50 rows=10 width=12) Output: a, b @@ -16,7 +16,7 @@ EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100; EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100::bigint; QUERY PLAN ------------------------------------------------------------------------------ - Remote Subquery Scan on all (datanode2) (cost=0.00..35.50 rows=10 width=12) + Remote Subquery Scan on all (datanode_2) (cost=0.00..35.50 rows=10 width=12) Output: a, b -> Seq Scan on public.xl_pp (cost=0.00..35.50 rows=10 width=12) Output: a, b @@ -31,7 +31,7 @@ EXPLAIN VERBOSE SELECT * FROM xl_pp WHERE a = 100::bigint; EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (200, 1) ; QUERY PLAN ---------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..0.01 rows=1 width=0) + Remote Subquery Scan on all (datanode_1) (cost=0.00..0.01 rows=1 width=0) -> Insert on public.xl_pp (cost=0.00..0.01 rows=1 width=0) -> Remote Subquery Scan on local node (cost=0.00..0.01 rows=1 width=0) Output: '200'::bigint, 1 @@ -43,7 +43,7 @@ EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (200, 1) ; EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (201::bigint, 1) ; QUERY PLAN ---------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..0.01 rows=1 width=0) + Remote Subquery Scan on all (datanode_1) (cost=0.00..0.01 rows=1 width=0) -> Insert on public.xl_pp (cost=0.00..0.01 rows=1 width=0) -> Remote Subquery Scan on local node (cost=0.00..0.01 rows=1 width=0) Output: '201'::bigint, 1 @@ -55,7 +55,7 @@ EXPLAIN VERBOSE INSERT INTO xl_pp (a, b) VALUES (201::bigint, 1) ; EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200; QUERY PLAN ---------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..35.50 rows=10 width=18) + Remote Subquery Scan on all (datanode_1) (cost=0.00..35.50 rows=10 width=18) -> Update on public.xl_pp (cost=0.00..35.50 rows=10 width=18) -> Seq Scan on public.xl_pp (cost=0.00..35.50 rows=10 width=18) Output: a, 2, a, xc_node_id, ctid @@ -65,7 +65,7 @@ EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200; EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200::bigint; QUERY PLAN ------------------------------------------------------------------------------ - Remote Subquery Scan on all (datanode1) (cost=0.00..35.50 rows=10 width=18) + Remote Subquery Scan on all (datanode_1) (cost=0.00..35.50 rows=10 width=18) -> Update on public.xl_pp (cost=0.00..35.50 rows=10 width=18) -> Seq Scan on public.xl_pp (cost=0.00..35.50 rows=10 width=18) Output: a, 2, a, xc_node_id, ctid @@ -75,7 +75,7 @@ EXPLAIN VERBOSE UPDATE xl_pp SET b=2 where a=200::bigint; EXPLAIN VERBOSE DELETE FROM xl_pp where a=200; QUERY PLAN ---------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..35.50 rows=10 width=18) + Remote Subquery Scan on all (datanode_1) (cost=0.00..35.50 rows=10 width=18) -> Delete on public.xl_pp (cost=0.00..35.50 rows=10 width=18) -> Seq Scan on public.xl_pp (cost=0.00..35.50 rows=10 width=18) Output: a, xc_node_id, ctid, a @@ -95,7 +95,7 @@ SELECT * from xl_pp where a=200::bigint; EXPLAIN VERBOSE DELETE FROM xl_pp where a=200; QUERY PLAN ---------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..35.50 rows=10 width=18) + Remote Subquery Scan on all (datanode_1) (cost=0.00..35.50 rows=10 width=18) -> Delete on public.xl_pp (cost=0.00..35.50 rows=10 width=18) -> Seq Scan on public.xl_pp (cost=0.00..35.50 rows=10 width=18) Output: a, xc_node_id, ctid, a @@ -105,7 +105,7 @@ EXPLAIN VERBOSE DELETE FROM xl_pp where a=200; EXPLAIN VERBOSE DELETE FROM xl_pp where a=200::bigint; QUERY PLAN ------------------------------------------------------------------------------ - Remote Subquery Scan on all (datanode1) (cost=0.00..35.50 rows=10 width=18) + Remote Subquery Scan on all (datanode_1) (cost=0.00..35.50 rows=10 width=18) -> Delete on public.xl_pp (cost=0.00..35.50 rows=10 width=18) -> Seq Scan on public.xl_pp (cost=0.00..35.50 rows=10 width=18) Output: a, xc_node_id, ctid, a @@ -118,7 +118,7 @@ INSERT INTO xl_ppm SELECT generate_series(1,100), 20; EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100; QUERY PLAN --------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..40.00 rows=12 width=6) + Remote Subquery Scan on all (datanode_1) (cost=0.00..40.00 rows=12 width=6) Output: a, b -> Seq Scan on public.xl_ppm (cost=0.00..40.00 rows=12 width=6) Output: a, b @@ -129,7 +129,7 @@ EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100; EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100::INT2; QUERY PLAN ----------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..40.00 rows=12 width=6) + Remote Subquery Scan on all (datanode_1) (cost=0.00..40.00 rows=12 width=6) Output: a, b -> Seq Scan on public.xl_ppm (cost=0.00..40.00 rows=12 width=6) Output: a, b @@ -144,7 +144,7 @@ EXPLAIN VERBOSE SELECT * FROM xl_ppm WHERE a = 100::INT2; EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (200, 1) ; QUERY PLAN ---------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..0.01 rows=1 width=0) + Remote Subquery Scan on all (datanode_1) (cost=0.00..0.01 rows=1 width=0) -> Insert on public.xl_ppm (cost=0.00..0.01 rows=1 width=0) -> Remote Subquery Scan on local node (cost=0.00..0.01 rows=1 width=0) Output: '200'::smallint, 1 @@ -156,7 +156,7 @@ EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (200, 1) ; EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (201::INT2, 1) ; QUERY PLAN ---------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode2) (cost=0.00..0.01 rows=1 width=0) + Remote Subquery Scan on all (datanode_2) (cost=0.00..0.01 rows=1 width=0) -> Insert on public.xl_ppm (cost=0.00..0.01 rows=1 width=0) -> Remote Subquery Scan on local node (cost=0.00..0.01 rows=1 width=0) Output: '201'::smallint, 1 @@ -168,7 +168,7 @@ EXPLAIN VERBOSE INSERT INTO xl_ppm (a, b) VALUES (201::INT2, 1) ; EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200; QUERY PLAN ---------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..40.00 rows=12 width=12) + Remote Subquery Scan on all (datanode_1) (cost=0.00..40.00 rows=12 width=12) -> Update on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) -> Seq Scan on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) Output: a, 2, a, xc_node_id, ctid @@ -178,7 +178,7 @@ EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200; EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200::INT2; QUERY PLAN ------------------------------------------------------------------------------ - Remote Subquery Scan on all (datanode1) (cost=0.00..40.00 rows=12 width=12) + Remote Subquery Scan on all (datanode_1) (cost=0.00..40.00 rows=12 width=12) -> Update on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) -> Seq Scan on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) Output: a, 2, a, xc_node_id, ctid @@ -188,7 +188,7 @@ EXPLAIN VERBOSE UPDATE xl_ppm SET b=2 where a=200::INT2; EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200; QUERY PLAN ---------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..40.00 rows=12 width=12) + Remote Subquery Scan on all (datanode_1) (cost=0.00..40.00 rows=12 width=12) -> Delete on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) -> Seq Scan on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) Output: a, xc_node_id, ctid, a @@ -208,7 +208,7 @@ SELECT * from xl_ppm where a=200::INT2; EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200; QUERY PLAN ---------------------------------------------------------------------------------------- - Remote Subquery Scan on all (datanode1) (cost=0.00..40.00 rows=12 width=12) + Remote Subquery Scan on all (datanode_1) (cost=0.00..40.00 rows=12 width=12) -> Delete on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) -> Seq Scan on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) Output: a, xc_node_id, ctid, a @@ -218,7 +218,7 @@ EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200; EXPLAIN VERBOSE DELETE FROM xl_ppm where a=200::INT2; QUERY PLAN ------------------------------------------------------------------------------ - Remote Subquery Scan on all (datanode1) (cost=0.00..40.00 rows=12 width=12) + Remote Subquery Scan on all (datanode_1) (cost=0.00..40.00 rows=12 width=12) -> Delete on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) -> Seq Scan on public.xl_ppm (cost=0.00..40.00 rows=12 width=12) Output: a, xc_node_id, ctid, a diff --git a/src/test/regress/expected/xl_plpgsql.out b/src/test/regress/expected/xl_plpgsql.out new file mode 100644 index 0000000000..b2776aa544 --- /dev/null +++ b/src/test/regress/expected/xl_plpgsql.out @@ -0,0 +1,1048 @@ +--User defined functions have several limitations +-- +-- PLPGSQL +-- Table xl_room default distributed by Hash(roomno) on all nodes. +create table xl_Room ( + roomno char(8), + comment text +); +create unique index xl_Room_rno on xl_Room using btree (roomno bpchar_ops); +-- Table xl_wslot default distributed by Hash(slotname) on all nodes. +create table xl_WSlot ( + slotname char(20), + roomno char(8), + slotlink char(20), + backlink char(20) +); +create unique index xl_WSlot_name on xl_WSlot using btree (slotname bpchar_ops); +--default distributed by HASH(slotname) +create table xl_PLine ( + slotname char(20), + phonenumber char(20), + comment text, + backlink char(20) +); +create unique index xl_PLine_name on xl_PLine using btree (slotname bpchar_ops); +-- ************************************************************ +-- * +-- * Trigger procedures and functions for the patchfield +-- * test of PL/pgSQL +-- * +-- ************************************************************ +-- ************************************************************ +-- * AFTER UPDATE on Room +-- * - If room no changes let wall slots follow +-- ************************************************************ +create function xl_room_au() returns trigger as ' +begin + if new.roomno != old.roomno then + update xl_WSlot set roomno = new.roomno where roomno = old.roomno; + end if; + return new; +end; +' language plpgsql; +--BEFORE/AFTER TRIGGERs are not supported in Postgres-XL - below would fail +create trigger tg_room_bu before update + on xl_Room for each row execute procedure xl_room_au(); +ERROR: Postgres-XL does not support TRIGGER yet +DETAIL: The feature is not currently supported +create trigger xl_room_au after update + on xl_Room for each row execute procedure xl_room_au(); +ERROR: Postgres-XL does not support TRIGGER yet +DETAIL: The feature is not currently supported +-- +-- Test error trapping +-- +--Internal subtransactions (exception clause within a function) +-- calling below function would fail. +create function xl_trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql; +select xl_trap_zero_divide(50); +ERROR: Internal subtransactions not supported in Postgres-XL +CONTEXT: PL/pgSQL function xl_trap_zero_divide(integer) line 5 during statement block entry +--SERIALIZABLE TRANSACTIONs are not supported. Isolation level SERIALIZABLE is converted to REPEATABLE READ internally silently. +-- ALTER OPERATOR FAMILY ... ADD/DROP +-- Should work. Textbook case of CREATE / ALTER ADD / ALTER DROP / DROP +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; +CREATE OPERATOR FAMILY alt_opf4 USING btree; +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD + -- int4 vs int2 + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2); +ALTER OPERATOR FAMILY alt_opf4 USING btree DROP + -- int4 vs int2 + OPERATOR 1 (int4, int2) , + OPERATOR 2 (int4, int2) , + OPERATOR 3 (int4, int2) , + OPERATOR 4 (int4, int2) , + OPERATOR 5 (int4, int2) , + FUNCTION 1 (int4, int2) ; +DROP OPERATOR FAMILY alt_opf4 USING btree; +ROLLBACK; +create function xl_nodename_from_id(integer) returns name as $$ +declare + n name; +BEGIN + select node_name into n from pgxc_node where node_id = $1; + RETURN n; +END;$$ language plpgsql; +--insert Plines +insert into xl_PLine values ('PL.001', '-0', 'Central call', 'PS.base.ta1'); +insert into xl_PLine values ('PL.002', '-101', '', 'PS.base.ta2'); +insert into xl_PLine values ('PL.003', '-102', '', 'PS.base.ta3'); +insert into xl_PLine values ('PL.004', '-103', '', 'PS.base.ta5'); +insert into xl_PLine values ('PL.005', '-104', '', 'PS.base.ta6'); +insert into xl_PLine values ('PL.006', '-106', '', 'PS.base.tb2'); +insert into xl_PLine values ('PL.007', '-108', '', 'PS.base.tb3'); +insert into xl_PLine values ('PL.008', '-109', '', 'PS.base.tb4'); +insert into xl_PLine values ('PL.009', '-121', '', 'PS.base.tb5'); +insert into xl_PLine values ('PL.010', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.011', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.012', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.013', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.014', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.015', '-134', '', 'PS.first.ta1'); +insert into xl_PLine values ('PL.016', '-137', '', 'PS.first.ta3'); +insert into xl_PLine values ('PL.017', '-139', '', 'PS.first.ta4'); +insert into xl_PLine values ('PL.018', '-362', '', 'PS.first.tb1'); +insert into xl_PLine values ('PL.019', '-363', '', 'PS.first.tb2'); +insert into xl_PLine values ('PL.020', '-364', '', 'PS.first.tb3'); +insert into xl_PLine values ('PL.021', '-365', '', 'PS.first.tb5'); +insert into xl_PLine values ('PL.022', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.023', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.024', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.025', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.026', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.027', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.028', '-501', 'Fax entrance', 'PS.base.ta2'); +insert into xl_PLine values ('PL.029', '-502', 'Fax first floor', 'PS.first.ta1'); +--INSENSITIVE/SCROLL/WITH HOLD cursors are not supported +-- if INSENSITIVE is not allowed then what is the default for Postgres-XL for cursor ? +-- May also check over here - FETCH and WHERE CURRENT OF conditions +-- WHERE CURRENT OF is not supported +--Many forms of FETCH are not supported such as those involving PRIOR, FIRST, LAST, ABSOLUTE, BACKWARD +--Basic test with data spannig on multiple nodes is working fine. +--scroll cursor would be insensitive to updates happening to the table +BEGIN; +declare xl_scroll_cursor SCROLL CURSOR for select * from xl_Pline order by slotname; +FETCH ALL FROM xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.001 | -0 | Central call | PS.base.ta1 + PL.002 | -101 | | PS.base.ta2 + PL.003 | -102 | | PS.base.ta3 + PL.004 | -103 | | PS.base.ta5 + PL.005 | -104 | | PS.base.ta6 + PL.006 | -106 | | PS.base.tb2 + PL.007 | -108 | | PS.base.tb3 + PL.008 | -109 | | PS.base.tb4 + PL.009 | -121 | | PS.base.tb5 + PL.010 | -122 | | PS.base.tb6 + PL.011 | -122 | | PS.base.tb6 + PL.012 | -122 | | PS.base.tb6 + PL.013 | -122 | | PS.base.tb6 + PL.014 | -122 | | PS.base.tb6 + PL.015 | -134 | | PS.first.ta1 + PL.016 | -137 | | PS.first.ta3 + PL.017 | -139 | | PS.first.ta4 + PL.018 | -362 | | PS.first.tb1 + PL.019 | -363 | | PS.first.tb2 + PL.020 | -364 | | PS.first.tb3 + PL.021 | -365 | | PS.first.tb5 + PL.022 | -367 | | PS.first.tb6 + PL.023 | -367 | | PS.first.tb6 + PL.024 | -367 | | PS.first.tb6 + PL.025 | -367 | | PS.first.tb6 + PL.026 | -367 | | PS.first.tb6 + PL.027 | -367 | | PS.first.tb6 + PL.028 | -501 | Fax entrance | PS.base.ta2 + PL.029 | -502 | Fax first floor | PS.first.ta1 +(29 rows) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+-----------------+---------------------- + datanode_1 | PL.001 | -0 | Central call | PS.base.ta1 + datanode_2 | PL.002 | -101 | | PS.base.ta2 + datanode_2 | PL.003 | -102 | | PS.base.ta3 + datanode_1 | PL.004 | -103 | | PS.base.ta5 + datanode_1 | PL.005 | -104 | | PS.base.ta6 + datanode_2 | PL.006 | -106 | | PS.base.tb2 + datanode_2 | PL.007 | -108 | | PS.base.tb3 + datanode_2 | PL.008 | -109 | | PS.base.tb4 + datanode_2 | PL.009 | -121 | | PS.base.tb5 + datanode_2 | PL.010 | -122 | | PS.base.tb6 + datanode_1 | PL.011 | -122 | | PS.base.tb6 + datanode_2 | PL.012 | -122 | | PS.base.tb6 + datanode_1 | PL.013 | -122 | | PS.base.tb6 + datanode_2 | PL.014 | -122 | | PS.base.tb6 + datanode_2 | PL.015 | -134 | | PS.first.ta1 + datanode_2 | PL.016 | -137 | | PS.first.ta3 + datanode_2 | PL.017 | -139 | | PS.first.ta4 + datanode_1 | PL.018 | -362 | | PS.first.tb1 + datanode_2 | PL.019 | -363 | | PS.first.tb2 + datanode_1 | PL.020 | -364 | | PS.first.tb3 + datanode_1 | PL.021 | -365 | | PS.first.tb5 + datanode_2 | PL.022 | -367 | | PS.first.tb6 + datanode_2 | PL.023 | -367 | | PS.first.tb6 + datanode_2 | PL.024 | -367 | | PS.first.tb6 + datanode_2 | PL.025 | -367 | | PS.first.tb6 + datanode_2 | PL.026 | -367 | | PS.first.tb6 + datanode_1 | PL.027 | -367 | | PS.first.tb6 + datanode_1 | PL.028 | -501 | Fax entrance | PS.base.ta2 + datanode_1 | PL.029 | -502 | Fax first floor | PS.first.ta1 +(29 rows) + +FETCH FIRST xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+--------------+---------------------- + PL.001 | -0 | Central call | PS.base.ta1 +(1 row) + +FETCH LAST xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.031', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.032', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.033', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.034', '-367', '', 'PS.first.tb6'); +FETCH LAST xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034') order by slotname; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+---------+---------------------- + datanode_1 | PL.030 | -367 | | PS.first.tb6 + datanode_1 | PL.031 | -367 | | PS.first.tb6 + datanode_1 | PL.032 | -367 | | PS.first.tb6 + datanode_2 | PL.033 | -367 | | PS.first.tb6 + datanode_2 | PL.034 | -367 | | PS.first.tb6 +(5 rows) + +delete from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034'); +FETCH LAST xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +delete from xl_Pline where slotname in ('PL.029'); +FETCH LAST xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +insert into xl_PLine values ('PL.029', '-367', '', 'PS.first.tb6'); +FETCH PRIOR xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+--------------+---------------------- + PL.028 | -501 | Fax entrance | PS.base.ta2 +(1 row) + +FETCH ABSOLUTE 5 xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.005 | -104 | | PS.base.ta6 +(1 row) + +FETCH BACKWARD 2 xl_scroll_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.004 | -103 | | PS.base.ta5 + PL.003 | -102 | | PS.base.ta3 +(2 rows) + +DELETE FROM xl_Pline WHERE CURRENT OF xl_scroll_cursor; +ERROR: WHERE CURRENT OF clause not yet supported +COMMIT; +--scroll cursor would be insensitive to updates happening to the table +BEGIN; +declare xl_scroll_cursor1 SCROLL CURSOR for select * from xl_Pline order by slotname desc; +FETCH ALL FROM xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 + PL.028 | -501 | Fax entrance | PS.base.ta2 + PL.027 | -367 | | PS.first.tb6 + PL.026 | -367 | | PS.first.tb6 + PL.025 | -367 | | PS.first.tb6 + PL.024 | -367 | | PS.first.tb6 + PL.023 | -367 | | PS.first.tb6 + PL.022 | -367 | | PS.first.tb6 + PL.021 | -365 | | PS.first.tb5 + PL.020 | -364 | | PS.first.tb3 + PL.019 | -363 | | PS.first.tb2 + PL.018 | -362 | | PS.first.tb1 + PL.017 | -139 | | PS.first.ta4 + PL.016 | -137 | | PS.first.ta3 + PL.015 | -134 | | PS.first.ta1 + PL.014 | -122 | | PS.base.tb6 + PL.013 | -122 | | PS.base.tb6 + PL.012 | -122 | | PS.base.tb6 + PL.011 | -122 | | PS.base.tb6 + PL.010 | -122 | | PS.base.tb6 + PL.009 | -121 | | PS.base.tb5 + PL.008 | -109 | | PS.base.tb4 + PL.007 | -108 | | PS.base.tb3 + PL.006 | -106 | | PS.base.tb2 + PL.005 | -104 | | PS.base.ta6 + PL.004 | -103 | | PS.base.ta5 + PL.003 | -102 | | PS.base.ta3 + PL.002 | -101 | | PS.base.ta2 + PL.001 | -0 | Central call | PS.base.ta1 +(29 rows) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname desc; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+-----------------+---------------------- + datanode_1 | PL.029 | -502 | Fax first floor | PS.first.ta1 + datanode_1 | PL.028 | -501 | Fax entrance | PS.base.ta2 + datanode_1 | PL.027 | -367 | | PS.first.tb6 + datanode_2 | PL.026 | -367 | | PS.first.tb6 + datanode_2 | PL.025 | -367 | | PS.first.tb6 + datanode_2 | PL.024 | -367 | | PS.first.tb6 + datanode_2 | PL.023 | -367 | | PS.first.tb6 + datanode_2 | PL.022 | -367 | | PS.first.tb6 + datanode_1 | PL.021 | -365 | | PS.first.tb5 + datanode_1 | PL.020 | -364 | | PS.first.tb3 + datanode_2 | PL.019 | -363 | | PS.first.tb2 + datanode_1 | PL.018 | -362 | | PS.first.tb1 + datanode_2 | PL.017 | -139 | | PS.first.ta4 + datanode_2 | PL.016 | -137 | | PS.first.ta3 + datanode_2 | PL.015 | -134 | | PS.first.ta1 + datanode_2 | PL.014 | -122 | | PS.base.tb6 + datanode_1 | PL.013 | -122 | | PS.base.tb6 + datanode_2 | PL.012 | -122 | | PS.base.tb6 + datanode_1 | PL.011 | -122 | | PS.base.tb6 + datanode_2 | PL.010 | -122 | | PS.base.tb6 + datanode_2 | PL.009 | -121 | | PS.base.tb5 + datanode_2 | PL.008 | -109 | | PS.base.tb4 + datanode_2 | PL.007 | -108 | | PS.base.tb3 + datanode_2 | PL.006 | -106 | | PS.base.tb2 + datanode_1 | PL.005 | -104 | | PS.base.ta6 + datanode_1 | PL.004 | -103 | | PS.base.ta5 + datanode_2 | PL.003 | -102 | | PS.base.ta3 + datanode_2 | PL.002 | -101 | | PS.base.ta2 + datanode_1 | PL.001 | -0 | Central call | PS.base.ta1 +(29 rows) + +FETCH FIRST xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.031', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.032', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.033', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.034', '-367', '', 'PS.first.tb6'); +FETCH FIRST xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034') order by slotname; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+---------+---------------------- + datanode_1 | PL.030 | -367 | | PS.first.tb6 + datanode_1 | PL.031 | -367 | | PS.first.tb6 + datanode_1 | PL.032 | -367 | | PS.first.tb6 + datanode_2 | PL.033 | -367 | | PS.first.tb6 + datanode_2 | PL.034 | -367 | | PS.first.tb6 +(5 rows) + +delete from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034'); +FETCH FIRST xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +delete from xl_Pline where slotname in ('PL.029'); +FETCH FIRST xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +FETCH LAST xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+--------------+---------------------- + PL.001 | -0 | Central call | PS.base.ta1 +(1 row) + +insert into xl_PLine values ('PL.029', '-367', '', 'PS.first.tb6'); +FETCH PRIOR xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.002 | -101 | | PS.base.ta2 +(1 row) + +FETCH ABSOLUTE 5 xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.025 | -367 | | PS.first.tb6 +(1 row) + +FETCH BACKWARD 2 xl_scroll_cursor1; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.026 | -367 | | PS.first.tb6 + PL.027 | -367 | | PS.first.tb6 +(2 rows) + +DELETE FROM xl_Pline WHERE CURRENT OF xl_scroll_cursor1; +ERROR: WHERE CURRENT OF clause not yet supported +COMMIT; +--insensitive cursor would be insensitive to updates happening to the table +BEGIN; +declare xl_ins_cursor INSENSITIVE CURSOR for select * from xl_Pline order by slotname desc; +FETCH FIRST xl_ins_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -502 | Fax first floor | PS.first.ta1 +(1 row) + +FETCH ABSOLUTE 5 xl_ins_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.025 | -367 | | PS.first.tb6 +(1 row) + +update xl_Pline set phonenumber='-503' where slotname = 'PL.029'; +insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); +FETCH FIRST xl_ins_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.030 | -367 | | PS.first.tb6 +(1 row) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline where slotname in ('PL.030', 'PL.029') order by slotname; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+-----------------+---------------------- + datanode_1 | PL.029 | -503 | Fax first floor | PS.first.ta1 + datanode_1 | PL.030 | -367 | | PS.first.tb6 +(2 rows) + +delete from xl_Pline where slotname in ('PL.030'); +FETCH FIRST xl_ins_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.029 | -503 | Fax first floor | PS.first.ta1 +(1 row) + +delete from xl_Pline where slotname in ('PL.029'); +FETCH FIRST xl_ins_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+--------------+---------------------- + PL.028 | -501 | Fax entrance | PS.base.ta2 +(1 row) + +insert into xl_PLine values ('PL.029', '-367', '', 'PS.first.tb6'); +FETCH ALL FROM xl_ins_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+--------------+---------------------- + PL.027 | -367 | | PS.first.tb6 + PL.026 | -367 | | PS.first.tb6 + PL.025 | -367 | | PS.first.tb6 + PL.024 | -367 | | PS.first.tb6 + PL.023 | -367 | | PS.first.tb6 + PL.022 | -367 | | PS.first.tb6 + PL.021 | -365 | | PS.first.tb5 + PL.020 | -364 | | PS.first.tb3 + PL.019 | -363 | | PS.first.tb2 + PL.018 | -362 | | PS.first.tb1 + PL.017 | -139 | | PS.first.ta4 + PL.016 | -137 | | PS.first.ta3 + PL.015 | -134 | | PS.first.ta1 + PL.014 | -122 | | PS.base.tb6 + PL.013 | -122 | | PS.base.tb6 + PL.012 | -122 | | PS.base.tb6 + PL.011 | -122 | | PS.base.tb6 + PL.010 | -122 | | PS.base.tb6 + PL.009 | -121 | | PS.base.tb5 + PL.008 | -109 | | PS.base.tb4 + PL.007 | -108 | | PS.base.tb3 + PL.006 | -106 | | PS.base.tb2 + PL.005 | -104 | | PS.base.ta6 + PL.004 | -103 | | PS.base.ta5 + PL.003 | -102 | | PS.base.ta3 + PL.002 | -101 | | PS.base.ta2 + PL.001 | -0 | Central call | PS.base.ta1 +(27 rows) + +DELETE FROM xl_Pline WHERE CURRENT OF xl_ins_cursor; +ERROR: WHERE CURRENT OF clause not yet supported +COMMIT; +--with hold cursor wold be available after the transaction that successfully committed it is gone +BEGIN; +declare xl_with_hold_cursor CURSOR WITH HOLD for select * from xl_Pline order by slotname; +FETCH FIRST xl_with_hold_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+--------------+---------------------- + PL.001 | -0 | Central call | PS.base.ta1 +(1 row) + +FETCH ABSOLUTE 5 xl_with_hold_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+---------+---------------------- + PL.005 | -104 | | PS.base.ta6 +(1 row) + +FETCH ALL FROM xl_with_hold_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+-----------------+---------------------- + PL.006 | -106 | | PS.base.tb2 + PL.007 | -108 | | PS.base.tb3 + PL.008 | -109 | | PS.base.tb4 + PL.009 | -121 | | PS.base.tb5 + PL.010 | -122 | | PS.base.tb6 + PL.011 | -122 | | PS.base.tb6 + PL.012 | -122 | | PS.base.tb6 + PL.013 | -122 | | PS.base.tb6 + PL.014 | -122 | | PS.base.tb6 + PL.015 | -134 | | PS.first.ta1 + PL.016 | -137 | | PS.first.ta3 + PL.017 | -139 | | PS.first.ta4 + PL.018 | -362 | | PS.first.tb1 + PL.019 | -363 | | PS.first.tb2 + PL.020 | -364 | | PS.first.tb3 + PL.021 | -365 | | PS.first.tb5 + PL.022 | -367 | | PS.first.tb6 + PL.023 | -367 | | PS.first.tb6 + PL.024 | -367 | | PS.first.tb6 + PL.025 | -367 | | PS.first.tb6 + PL.026 | -367 | | PS.first.tb6 + PL.027 | -367 | | PS.first.tb6 + PL.028 | -501 | Fax entrance | PS.base.ta2 + PL.029 | -502 | Fax first floor | PS.first.ta1 +(24 rows) + +COMMIT; +FETCH FIRST xl_with_hold_cursor; + slotname | phonenumber | comment | backlink +----------------------+----------------------+--------------+---------------------- + PL.001 | -0 | Central call | PS.base.ta1 +(1 row) + +--SAVEPOINTs are not supported +begin; + set constraints all deferred; + savepoint x; +ERROR: SAVEPOINT is not yet supported. + set constraints all immediate; -- fails +ERROR: current transaction is aborted, commands ignored until end of transaction block + rollback to x; +ERROR: no such savepoint +commit; -- still fails +--User defined functions have several limitations +--Basic insert, update, delete test on multiple datanodes using plpgsql function is passing. +create function xl_insert_Pline_test(int) returns boolean as $$ +BEGIN + IF $1 < 20 THEN + insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.031', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.032', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.033', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.034', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.035', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.036', '-367', '', 'PS.first.tb6'); + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;$$ language plpgsql; +select xl_insert_Pline_test(1); + xl_insert_pline_test +---------------------- + t +(1 row) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+-----------------+---------------------- + datanode_1 | PL.001 | -0 | Central call | PS.base.ta1 + datanode_2 | PL.002 | -101 | | PS.base.ta2 + datanode_2 | PL.003 | -102 | | PS.base.ta3 + datanode_1 | PL.004 | -103 | | PS.base.ta5 + datanode_1 | PL.005 | -104 | | PS.base.ta6 + datanode_2 | PL.006 | -106 | | PS.base.tb2 + datanode_2 | PL.007 | -108 | | PS.base.tb3 + datanode_2 | PL.008 | -109 | | PS.base.tb4 + datanode_2 | PL.009 | -121 | | PS.base.tb5 + datanode_2 | PL.010 | -122 | | PS.base.tb6 + datanode_1 | PL.011 | -122 | | PS.base.tb6 + datanode_2 | PL.012 | -122 | | PS.base.tb6 + datanode_1 | PL.013 | -122 | | PS.base.tb6 + datanode_2 | PL.014 | -122 | | PS.base.tb6 + datanode_2 | PL.015 | -134 | | PS.first.ta1 + datanode_2 | PL.016 | -137 | | PS.first.ta3 + datanode_2 | PL.017 | -139 | | PS.first.ta4 + datanode_1 | PL.018 | -362 | | PS.first.tb1 + datanode_2 | PL.019 | -363 | | PS.first.tb2 + datanode_1 | PL.020 | -364 | | PS.first.tb3 + datanode_1 | PL.021 | -365 | | PS.first.tb5 + datanode_2 | PL.022 | -367 | | PS.first.tb6 + datanode_2 | PL.023 | -367 | | PS.first.tb6 + datanode_2 | PL.024 | -367 | | PS.first.tb6 + datanode_2 | PL.025 | -367 | | PS.first.tb6 + datanode_2 | PL.026 | -367 | | PS.first.tb6 + datanode_1 | PL.027 | -367 | | PS.first.tb6 + datanode_1 | PL.028 | -501 | Fax entrance | PS.base.ta2 + datanode_1 | PL.029 | -502 | Fax first floor | PS.first.ta1 + datanode_1 | PL.030 | -367 | | PS.first.tb6 + datanode_1 | PL.031 | -367 | | PS.first.tb6 + datanode_1 | PL.032 | -367 | | PS.first.tb6 + datanode_2 | PL.033 | -367 | | PS.first.tb6 + datanode_2 | PL.034 | -367 | | PS.first.tb6 + datanode_1 | PL.035 | -367 | | PS.first.tb6 + datanode_1 | PL.036 | -367 | | PS.first.tb6 +(36 rows) + +create function xl_update_Pline_test(int) returns boolean as $$ +BEGIN + IF $1 < 20 THEN + update xl_Pline set phonenumber = '400' where slotname = 'PL.030'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.031'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.032'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.033'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.034'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.035'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.036'; + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;$$ language plpgsql; +select xl_update_Pline_test(1); + xl_update_pline_test +---------------------- + t +(1 row) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+-----------------+---------------------- + datanode_1 | PL.001 | -0 | Central call | PS.base.ta1 + datanode_2 | PL.002 | -101 | | PS.base.ta2 + datanode_2 | PL.003 | -102 | | PS.base.ta3 + datanode_1 | PL.004 | -103 | | PS.base.ta5 + datanode_1 | PL.005 | -104 | | PS.base.ta6 + datanode_2 | PL.006 | -106 | | PS.base.tb2 + datanode_2 | PL.007 | -108 | | PS.base.tb3 + datanode_2 | PL.008 | -109 | | PS.base.tb4 + datanode_2 | PL.009 | -121 | | PS.base.tb5 + datanode_2 | PL.010 | -122 | | PS.base.tb6 + datanode_1 | PL.011 | -122 | | PS.base.tb6 + datanode_2 | PL.012 | -122 | | PS.base.tb6 + datanode_1 | PL.013 | -122 | | PS.base.tb6 + datanode_2 | PL.014 | -122 | | PS.base.tb6 + datanode_2 | PL.015 | -134 | | PS.first.ta1 + datanode_2 | PL.016 | -137 | | PS.first.ta3 + datanode_2 | PL.017 | -139 | | PS.first.ta4 + datanode_1 | PL.018 | -362 | | PS.first.tb1 + datanode_2 | PL.019 | -363 | | PS.first.tb2 + datanode_1 | PL.020 | -364 | | PS.first.tb3 + datanode_1 | PL.021 | -365 | | PS.first.tb5 + datanode_2 | PL.022 | -367 | | PS.first.tb6 + datanode_2 | PL.023 | -367 | | PS.first.tb6 + datanode_2 | PL.024 | -367 | | PS.first.tb6 + datanode_2 | PL.025 | -367 | | PS.first.tb6 + datanode_2 | PL.026 | -367 | | PS.first.tb6 + datanode_1 | PL.027 | -367 | | PS.first.tb6 + datanode_1 | PL.028 | -501 | Fax entrance | PS.base.ta2 + datanode_1 | PL.029 | -502 | Fax first floor | PS.first.ta1 + datanode_1 | PL.030 | 400 | | PS.first.tb6 + datanode_1 | PL.031 | 400 | | PS.first.tb6 + datanode_1 | PL.032 | 400 | | PS.first.tb6 + datanode_2 | PL.033 | 400 | | PS.first.tb6 + datanode_2 | PL.034 | 400 | | PS.first.tb6 + datanode_1 | PL.035 | 400 | | PS.first.tb6 + datanode_1 | PL.036 | 400 | | PS.first.tb6 +(36 rows) + +create function xl_delete_Pline_test(int) returns boolean as $$ +BEGIN + IF $1 < 20 THEN + delete from xl_Pline where slotname = 'PL.030'; + delete from xl_Pline where slotname = 'PL.031'; + delete from xl_Pline where slotname = 'PL.032'; + delete from xl_Pline where slotname = 'PL.033'; + delete from xl_Pline where slotname = 'PL.034'; + delete from xl_Pline where slotname = 'PL.035'; + delete from xl_Pline where slotname = 'PL.036'; + + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;$$ language plpgsql; +select xl_delete_Pline_test(1); + xl_delete_pline_test +---------------------- + t +(1 row) + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; + xl_nodename_from_id | slotname | phonenumber | comment | backlink +---------------------+----------------------+----------------------+-----------------+---------------------- + datanode_1 | PL.001 | -0 | Central call | PS.base.ta1 + datanode_2 | PL.002 | -101 | | PS.base.ta2 + datanode_2 | PL.003 | -102 | | PS.base.ta3 + datanode_1 | PL.004 | -103 | | PS.base.ta5 + datanode_1 | PL.005 | -104 | | PS.base.ta6 + datanode_2 | PL.006 | -106 | | PS.base.tb2 + datanode_2 | PL.007 | -108 | | PS.base.tb3 + datanode_2 | PL.008 | -109 | | PS.base.tb4 + datanode_2 | PL.009 | -121 | | PS.base.tb5 + datanode_2 | PL.010 | -122 | | PS.base.tb6 + datanode_1 | PL.011 | -122 | | PS.base.tb6 + datanode_2 | PL.012 | -122 | | PS.base.tb6 + datanode_1 | PL.013 | -122 | | PS.base.tb6 + datanode_2 | PL.014 | -122 | | PS.base.tb6 + datanode_2 | PL.015 | -134 | | PS.first.ta1 + datanode_2 | PL.016 | -137 | | PS.first.ta3 + datanode_2 | PL.017 | -139 | | PS.first.ta4 + datanode_1 | PL.018 | -362 | | PS.first.tb1 + datanode_2 | PL.019 | -363 | | PS.first.tb2 + datanode_1 | PL.020 | -364 | | PS.first.tb3 + datanode_1 | PL.021 | -365 | | PS.first.tb5 + datanode_2 | PL.022 | -367 | | PS.first.tb6 + datanode_2 | PL.023 | -367 | | PS.first.tb6 + datanode_2 | PL.024 | -367 | | PS.first.tb6 + datanode_2 | PL.025 | -367 | | PS.first.tb6 + datanode_2 | PL.026 | -367 | | PS.first.tb6 + datanode_1 | PL.027 | -367 | | PS.first.tb6 + datanode_1 | PL.028 | -501 | Fax entrance | PS.base.ta2 + datanode_1 | PL.029 | -502 | Fax first floor | PS.first.ta1 +(29 rows) + +--Correlated UPDATE/DELETE is not supported. +-- distributed by default ==> xl_t by HASH(no), xl_t1 by HASH(no1) +CREATE TABLE xl_t("no" integer,"name" character varying); +CREATE TABLE xl_t1(no1 integer,name1 character varying); +create table xl_names("name" character varying, "name1" character varying); +INSERT INTO xl_t("no", "name")VALUES (1, 'A'); +INSERT INTO xl_t("no", "name")VALUES (2, 'B'); +INSERT INTO xl_t("no", "name")VALUES (3, 'C'); +INSERT INTO xl_t("no", "name")VALUES (4, 'D'); +INSERT INTO xl_t1("no1", "name1")VALUES (1, 'Z'); +INSERT INTO xl_t1("no1", "name1")VALUES (2, 'Y'); +INSERT INTO xl_t1("no1", "name1")VALUES (3, 'X'); +INSERT INTO xl_t1("no1", "name1")VALUES (4, 'W'); +INSERT INTO xl_names("name", "name1")VALUES ('A', 'A1'); +INSERT INTO xl_names("name", "name1")VALUES ('B', 'B1'); +INSERT INTO xl_names("name", "name1")VALUES ('C', 'C1'); +INSERT INTO xl_names("name", "name1")VALUES ('D', 'D1'); +INSERT INTO xl_names("name", "name1")VALUES ('W', 'W1'); +INSERT INTO xl_names("name", "name1")VALUES ('X', 'X1'); +INSERT INTO xl_names("name", "name1")VALUES ('Y', 'Y1'); +INSERT INTO xl_names("name", "name1")VALUES ('Z', 'Z1'); +select xl_nodename_from_id(xc_node_id), * from xl_t; + xl_nodename_from_id | no | name +---------------------+----+------ + datanode_1 | 1 | A + datanode_1 | 2 | B + datanode_2 | 3 | C + datanode_2 | 4 | D +(4 rows) + +select xl_nodename_from_id(xc_node_id), * from xl_t1; + xl_nodename_from_id | no1 | name1 +---------------------+-----+------- + datanode_1 | 1 | Z + datanode_1 | 2 | Y + datanode_2 | 3 | X + datanode_2 | 4 | W +(4 rows) + +select xl_nodename_from_id(xc_node_id), * from xl_names order by name; + xl_nodename_from_id | name | name1 +---------------------+------+------- + datanode_1 | A | A1 + datanode_2 | B | B1 + datanode_1 | C | C1 + datanode_1 | D | D1 + datanode_1 | W | W1 + datanode_1 | X | X1 + datanode_1 | Y | Y1 + datanode_2 | Z | Z1 +(8 rows) + +update xl_t set name = T1.name1 +from (select no1,name1 from xl_t1) T1 +where xl_t.no = T1.no1; +--correlated update fails +update xl_t1 set name1 = T1.name1 +from (select name,name1 from xl_names) T1 +where xl_t1.name1 = T1.name; +ERROR: could not plan this distributed update +DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. +select xl_nodename_from_id(xc_node_id), * from xl_t; + xl_nodename_from_id | no | name +---------------------+----+------ + datanode_1 | 1 | Z + datanode_1 | 2 | Y + datanode_2 | 3 | X + datanode_2 | 4 | W +(4 rows) + +select xl_nodename_from_id(xc_node_id), * from xl_t1; + xl_nodename_from_id | no1 | name1 +---------------------+-----+------- + datanode_1 | 1 | Z + datanode_1 | 2 | Y + datanode_2 | 3 | X + datanode_2 | 4 | W +(4 rows) + +--testing correlated delete: +delete from xl_t +where xl_t.no in (select no1 from xl_t1 where name1 in ('Z', 'X')) +; +--correlated delete fails +delete from xl_t1 +where xl_t1.name1 in (select name1 from xl_names where name in ('Z', 'X')) +; +ERROR: could not plan this distributed delete +DETAIL: correlated or complex DELETE is currently not supported in Postgres-XL. +select xl_nodename_from_id(xc_node_id), * from xl_t; + xl_nodename_from_id | no | name +---------------------+----+------ + datanode_1 | 2 | Y + datanode_2 | 4 | W +(2 rows) + +select xl_nodename_from_id(xc_node_id), * from xl_t1; + xl_nodename_from_id | no1 | name1 +---------------------+-----+------- + datanode_1 | 1 | Z + datanode_1 | 2 | Y + datanode_2 | 3 | X + datanode_2 | 4 | W +(4 rows) + +drop table xl_t; +drop table xl_t1; +drop table xl_names; +--EXCLUSION CONSTRAINTS are not supported +--The constraint is enforced when both rows map to the same datanode. But if they go into different datanodes, the constraint is not enforced +CREATE TABLE xl_circles ( + c circle, + EXCLUDE USING gist (c WITH &&) +); +CREATE TABLE xl_cons_hash (a int, c circle, EXCLUDE USING gist (c WITH &&)) DISTRIBUTE BY HASH(a); +CREATE TABLE xl_cons_modulo (a int, c circle, EXCLUDE USING gist (c WITH &&)) DISTRIBUTE BY MODULO(a); error +CREATE TABLE xl_cons_rr (c circle, EXCLUDE USING gist (c WITH &&)) DISTRIBUTE BY ROUNDROBIN; +ERROR: syntax error at or near "error" +LINE 1: error + ^ +CREATE TABLE xl_cons_hash2 (a int, b int, c circle, EXCLUDE USING btree (a WITH = , b WITH =)) DISTRIBUTE BY HASH(a); +CREATE TABLE xl_cons_modulo2 (a int, b int, c circle, EXCLUDE USING btree (a WITH =, b WITH =)) DISTRIBUTE BY MODULO(a); +-- xl_test1 is distributed by default on HASH(a) +CREATE TABLE xl_test1 (a int, b int); +INSERT INTO xl_test1 VALUES (1,2); +INSERT INTO xl_test1 VALUES (2,2); +INSERT INTO xl_test1 VALUES (3,2); +INSERT INTO xl_test1 VALUES (4,2); +INSERT INTO xl_test1 VALUES (5,2); +INSERT INTO xl_test1 VALUES (6,2); +INSERT INTO xl_test1 VALUES (7,2); +select xl_nodename_from_id(xc_node_id),* from xl_test1 order by a; + xl_nodename_from_id | a | b +---------------------+---+--- + datanode_1 | 1 | 2 + datanode_1 | 2 | 2 + datanode_2 | 3 | 2 + datanode_2 | 4 | 2 + datanode_1 | 5 | 2 + datanode_1 | 6 | 2 + datanode_2 | 7 | 2 +(7 rows) + +-- this is to see how hash of integers key distributes among data nodes. +-- xl_test is distributed by default on HASH(a) +CREATE TABLE xl_test (a int, b int, EXCLUDE USING btree (b WITH =)); +INSERT INTO xl_test VALUES (1,2); +INSERT INTO xl_test VALUES (2,2); +ERROR: conflicting key value violates exclusion constraint "xl_test_b_excl" +DETAIL: Key (b)=(2) conflicts with existing key (b)=(2). +INSERT INTO xl_test VALUES (3,2); +INSERT INTO xl_test VALUES (4,2); +ERROR: conflicting key value violates exclusion constraint "xl_test_b_excl" +DETAIL: Key (b)=(2) conflicts with existing key (b)=(2). +INSERT INTO xl_test VALUES (5,2); +ERROR: conflicting key value violates exclusion constraint "xl_test_b_excl" +DETAIL: Key (b)=(2) conflicts with existing key (b)=(2). +INSERT INTO xl_test VALUES (6,2); +ERROR: conflicting key value violates exclusion constraint "xl_test_b_excl" +DETAIL: Key (b)=(2) conflicts with existing key (b)=(2). +INSERT INTO xl_test VALUES (7,2); +ERROR: conflicting key value violates exclusion constraint "xl_test_b_excl" +DETAIL: Key (b)=(2) conflicts with existing key (b)=(2). +--the constraint is enforced when both rows map to the same datanode, e.g. when a=1, a=2 +--But if they go into different datanodes, the constraint is not enforced, e.g. when a=3 +drop table xl_circles; +drop table xl_cons_hash; +drop table xl_cons_modulo; +drop table xl_cons_rr; +ERROR: table "xl_cons_rr" does not exist +drop table xl_test; +drop table xl_test1; +drop table xl_Room; +drop table xl_WSlot; +drop table xl_PLine; +-- CREATE INDEX CONCURRENTLY is not supported +-- +-- Try some concurrent index builds +-- +-- Unfortunately this only tests about half the code paths because there are +-- no concurrent updates happening to the table at the same time. +CREATE TABLE xl_concur_heap (f1 text, f2 text); +-- empty table +CREATE INDEX CONCURRENTLY xl_concur_index1 ON xl_concur_heap(f2,f1); +ERROR: PGXC does not support concurrent INDEX yet +DETAIL: The feature is not currently supported +CREATE INDEX CONCURRENTLY IF NOT EXISTS xl_concur_index1 ON xl_concur_heap(f2,f1); +ERROR: PGXC does not support concurrent INDEX yet +DETAIL: The feature is not currently supported +INSERT INTO xl_concur_heap VALUES ('a','b'); +INSERT INTO xl_concur_heap VALUES ('b','b'); +drop index concurrently xl_concur_index1; +ERROR: index "xl_concur_index1" does not exist +drop table xl_concur_heap; +--Large objects are not supported +CREATE TABLE lotest_stash_values (loid oid, junk integer, fd integer); +-- lo_creat(mode integer) returns oid +-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times +-- returns the large object id +INSERT INTO lotest_stash_values (loid) VALUES( lo_creat(42) ); +ERROR: Postgres-XL does not yet support large objects +DETAIL: The feature is not currently supported +drop table lotest_stash_values; +--EVENT TRIGGERs are not supported +CREATE FUNCTION xl_event_trigger_for_drops() + RETURNS event_trigger LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE '% dropped object: % %.% %', + tg_tag, + obj.object_type, + obj.schema_name, + obj.object_name, + obj.object_identity; + END LOOP; +END +$$; +CREATE EVENT TRIGGER xl_event_trigger_for_drops + ON sql_drop + EXECUTE PROCEDURE xl_event_trigger_for_drops(); +ERROR: EVENT TRIGGER not yet supported in Postgres-XL +drop function xl_event_trigger_for_drops(); +drop EVENT TRIGGER xl_event_trigger_for_drops; +ERROR: event trigger "xl_event_trigger_for_drops" does not exist +--Recursive queries are not supported +WITH RECURSIVE t(n) AS ( + VALUES (1) + UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t; +ERROR: WITH RECURSIVE currently not supported on distributed tables. +--FDWs are not supported +CREATE FOREIGN DATA WRAPPER xl_foo; -- ERROR +ERROR: Postgres-XL does not support FOREIGN DATA WRAPPER yet +DETAIL: The feature is not currently supported +RESET ROLE; +CREATE FOREIGN DATA WRAPPER xl_foo VALIDATOR postgresql_fdw_validator; +ERROR: Postgres-XL does not support FOREIGN DATA WRAPPER yet +DETAIL: The feature is not currently supported +--LISTEN/NOTIFY is not supported. Looks like they are supported now. +--We would obviously have issues with LISTEN/NOTIFY if clients are connected to different coordinators. Need to test that manually as it is difficult via regression. +--Should work. Send a valid message via a valid channel name +--LISTEN notify_async1; +-- commenting LISTEN as PIDs shown here would never match in regression. +SELECT pg_notify('notify_async1','sample message1'); + pg_notify +----------- + +(1 row) + +SELECT pg_notify('notify_async1',''); + pg_notify +----------- + +(1 row) + +SELECT pg_notify('notify_async1',NULL); + pg_notify +----------- + +(1 row) + +-- Should fail. Send a valid message via an invalid channel name +SELECT pg_notify('','sample message1'); +ERROR: channel name cannot be empty +SELECT pg_notify(NULL,'sample message1'); +ERROR: channel name cannot be empty +SELECT pg_notify('notify_async_channel_name_too_long______________________________','sample_message1'); +ERROR: channel name too long +--Should work. Valid NOTIFY/LISTEN/UNLISTEN commands +NOTIFY notify_async2; +LISTEN notify_async2; +UNLISTEN notify_async2; +UNLISTEN *; +--LISTEN virtual; +NOTIFY virtual; +NOTIFY virtual, 'This is the payload'; +--LISTEN foo; +SELECT pg_notify('fo' || 'o', 'pay' || 'load'); + pg_notify +----------- + +(1 row) + +drop function xl_room_au(); +drop function xl_trap_zero_divide(int); +drop function xl_nodename_from_id(integer); +drop function xl_insert_Pline_test(int); +drop function xl_update_Pline_test(int); +drop function xl_delete_Pline_test(int); diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 33a6dddec9..949d5dbeeb 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -183,3 +183,4 @@ test: xl_alter_table test: xl_distribution_column_types_modulo test: xl_plan_pushdown test: xl_functions +test: xl_plpgsql diff --git a/src/test/regress/sql/xl_alter_table.sql b/src/test/regress/sql/xl_alter_table.sql index 4fc2948e90..c056227760 100644..100755 --- a/src/test/regress/sql/xl_alter_table.sql +++ b/src/test/regress/sql/xl_alter_table.sql @@ -124,9 +124,9 @@ ALTER TABLE xl_at2h RENAME COLUMN product_id TO product_identifier; ALTER TABLE xl_at2h RENAME TO xl_at3h; -ALTER TABLE xl_at3h DELETE NODE (datanode2); +ALTER TABLE xl_at3h DELETE NODE (datanode_2); -ALTER TABLE xl_at3h ADD NODE (datanode2); +ALTER TABLE xl_at3h ADD NODE (datanode_2); ALTER TABLE xl_at3h DISTRIBUTE BY REPLICATION; @@ -168,9 +168,9 @@ ALTER TABLE xl_at2m RENAME COLUMN product_id TO product_identifier; ALTER TABLE xl_at2m RENAME TO xl_at3m; -ALTER TABLE xl_at3m DELETE NODE (datanode2); +ALTER TABLE xl_at3m DELETE NODE (datanode_2); -ALTER TABLE xl_at3m ADD NODE (datanode2); +ALTER TABLE xl_at3m ADD NODE (datanode_2); ALTER TABLE xl_at3m DROP COLUMN product_identifier;--fail - distribution column cannot be dropped. diff --git a/src/test/regress/sql/xl_plpgsql.sql b/src/test/regress/sql/xl_plpgsql.sql new file mode 100755 index 0000000000..352354ea83 --- /dev/null +++ b/src/test/regress/sql/xl_plpgsql.sql @@ -0,0 +1,545 @@ + +--User defined functions have several limitations +-- +-- PLPGSQL + +-- Table xl_room default distributed by Hash(roomno) on all nodes. +create table xl_Room ( + roomno char(8), + comment text +); + +create unique index xl_Room_rno on xl_Room using btree (roomno bpchar_ops); + +-- Table xl_wslot default distributed by Hash(slotname) on all nodes. +create table xl_WSlot ( + slotname char(20), + roomno char(8), + slotlink char(20), + backlink char(20) +); + +create unique index xl_WSlot_name on xl_WSlot using btree (slotname bpchar_ops); + +--default distributed by HASH(slotname) +create table xl_PLine ( + slotname char(20), + phonenumber char(20), + comment text, + backlink char(20) +); + +create unique index xl_PLine_name on xl_PLine using btree (slotname bpchar_ops); + + +-- ************************************************************ +-- * +-- * Trigger procedures and functions for the patchfield +-- * test of PL/pgSQL +-- * +-- ************************************************************ + + +-- ************************************************************ +-- * AFTER UPDATE on Room +-- * - If room no changes let wall slots follow +-- ************************************************************ +create function xl_room_au() returns trigger as ' +begin + if new.roomno != old.roomno then + update xl_WSlot set roomno = new.roomno where roomno = old.roomno; + end if; + return new; +end; +' language plpgsql; + +--BEFORE/AFTER TRIGGERs are not supported in Postgres-XL - below would fail + +create trigger tg_room_bu before update + on xl_Room for each row execute procedure xl_room_au(); + +create trigger xl_room_au after update + on xl_Room for each row execute procedure xl_room_au(); + + +-- +-- Test error trapping +-- +--Internal subtransactions (exception clause within a function) +-- calling below function would fail. +create function xl_trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql; + +select xl_trap_zero_divide(50); + + +--SERIALIZABLE TRANSACTIONs are not supported. Isolation level SERIALIZABLE is converted to REPEATABLE READ internally silently. + +-- ALTER OPERATOR FAMILY ... ADD/DROP + +-- Should work. Textbook case of CREATE / ALTER ADD / ALTER DROP / DROP +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; +CREATE OPERATOR FAMILY alt_opf4 USING btree; +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD + -- int4 vs int2 + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf4 USING btree DROP + -- int4 vs int2 + OPERATOR 1 (int4, int2) , + OPERATOR 2 (int4, int2) , + OPERATOR 3 (int4, int2) , + OPERATOR 4 (int4, int2) , + OPERATOR 5 (int4, int2) , + FUNCTION 1 (int4, int2) ; +DROP OPERATOR FAMILY alt_opf4 USING btree; +ROLLBACK; + +create function xl_nodename_from_id(integer) returns name as $$ +declare + n name; +BEGIN + select node_name into n from pgxc_node where node_id = $1; + RETURN n; +END;$$ language plpgsql; + +--insert Plines +insert into xl_PLine values ('PL.001', '-0', 'Central call', 'PS.base.ta1'); +insert into xl_PLine values ('PL.002', '-101', '', 'PS.base.ta2'); +insert into xl_PLine values ('PL.003', '-102', '', 'PS.base.ta3'); +insert into xl_PLine values ('PL.004', '-103', '', 'PS.base.ta5'); +insert into xl_PLine values ('PL.005', '-104', '', 'PS.base.ta6'); +insert into xl_PLine values ('PL.006', '-106', '', 'PS.base.tb2'); +insert into xl_PLine values ('PL.007', '-108', '', 'PS.base.tb3'); +insert into xl_PLine values ('PL.008', '-109', '', 'PS.base.tb4'); +insert into xl_PLine values ('PL.009', '-121', '', 'PS.base.tb5'); +insert into xl_PLine values ('PL.010', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.011', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.012', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.013', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.014', '-122', '', 'PS.base.tb6'); +insert into xl_PLine values ('PL.015', '-134', '', 'PS.first.ta1'); +insert into xl_PLine values ('PL.016', '-137', '', 'PS.first.ta3'); +insert into xl_PLine values ('PL.017', '-139', '', 'PS.first.ta4'); +insert into xl_PLine values ('PL.018', '-362', '', 'PS.first.tb1'); +insert into xl_PLine values ('PL.019', '-363', '', 'PS.first.tb2'); +insert into xl_PLine values ('PL.020', '-364', '', 'PS.first.tb3'); +insert into xl_PLine values ('PL.021', '-365', '', 'PS.first.tb5'); +insert into xl_PLine values ('PL.022', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.023', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.024', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.025', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.026', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.027', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.028', '-501', 'Fax entrance', 'PS.base.ta2'); +insert into xl_PLine values ('PL.029', '-502', 'Fax first floor', 'PS.first.ta1'); + + +--INSENSITIVE/SCROLL/WITH HOLD cursors are not supported +-- if INSENSITIVE is not allowed then what is the default for Postgres-XL for cursor ? + +-- May also check over here - FETCH and WHERE CURRENT OF conditions +-- WHERE CURRENT OF is not supported +--Many forms of FETCH are not supported such as those involving PRIOR, FIRST, LAST, ABSOLUTE, BACKWARD +--Basic test with data spannig on multiple nodes is working fine. +--scroll cursor would be insensitive to updates happening to the table +BEGIN; + +declare xl_scroll_cursor SCROLL CURSOR for select * from xl_Pline order by slotname; + +FETCH ALL FROM xl_scroll_cursor; +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; +FETCH FIRST xl_scroll_cursor; +FETCH LAST xl_scroll_cursor; +insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.031', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.032', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.033', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.034', '-367', '', 'PS.first.tb6'); +FETCH LAST xl_scroll_cursor; +select xl_nodename_from_id(xc_node_id), * from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034') order by slotname; +delete from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034'); +FETCH LAST xl_scroll_cursor; +delete from xl_Pline where slotname in ('PL.029'); +FETCH LAST xl_scroll_cursor; +insert into xl_PLine values ('PL.029', '-367', '', 'PS.first.tb6'); +FETCH PRIOR xl_scroll_cursor; +FETCH ABSOLUTE 5 xl_scroll_cursor; +FETCH BACKWARD 2 xl_scroll_cursor; +DELETE FROM xl_Pline WHERE CURRENT OF xl_scroll_cursor; +COMMIT; + + +--scroll cursor would be insensitive to updates happening to the table +BEGIN; + +declare xl_scroll_cursor1 SCROLL CURSOR for select * from xl_Pline order by slotname desc; + +FETCH ALL FROM xl_scroll_cursor1; +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname desc; +FETCH FIRST xl_scroll_cursor1; +insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.031', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.032', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.033', '-367', '', 'PS.first.tb6'); +insert into xl_PLine values ('PL.034', '-367', '', 'PS.first.tb6'); +FETCH FIRST xl_scroll_cursor1; +select xl_nodename_from_id(xc_node_id), * from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034') order by slotname; +delete from xl_Pline where slotname in ('PL.030', 'PL.031', 'PL.032','PL.033', 'PL.034'); +FETCH FIRST xl_scroll_cursor1; +delete from xl_Pline where slotname in ('PL.029'); +FETCH FIRST xl_scroll_cursor1; +FETCH LAST xl_scroll_cursor1; +insert into xl_PLine values ('PL.029', '-367', '', 'PS.first.tb6'); +FETCH PRIOR xl_scroll_cursor1; +FETCH ABSOLUTE 5 xl_scroll_cursor1; +FETCH BACKWARD 2 xl_scroll_cursor1; +DELETE FROM xl_Pline WHERE CURRENT OF xl_scroll_cursor1; +COMMIT; + +--insensitive cursor would be insensitive to updates happening to the table +BEGIN; +declare xl_ins_cursor INSENSITIVE CURSOR for select * from xl_Pline order by slotname desc; + +FETCH FIRST xl_ins_cursor; +FETCH ABSOLUTE 5 xl_ins_cursor; +update xl_Pline set phonenumber='-503' where slotname = 'PL.029'; +insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); +FETCH FIRST xl_ins_cursor; +select xl_nodename_from_id(xc_node_id), * from xl_Pline where slotname in ('PL.030', 'PL.029') order by slotname; +delete from xl_Pline where slotname in ('PL.030'); +FETCH FIRST xl_ins_cursor; +delete from xl_Pline where slotname in ('PL.029'); +FETCH FIRST xl_ins_cursor; +insert into xl_PLine values ('PL.029', '-367', '', 'PS.first.tb6'); +FETCH ALL FROM xl_ins_cursor; +DELETE FROM xl_Pline WHERE CURRENT OF xl_ins_cursor; +COMMIT; + +--with hold cursor wold be available after the transaction that successfully committed it is gone +BEGIN; + +declare xl_with_hold_cursor CURSOR WITH HOLD for select * from xl_Pline order by slotname; + +FETCH FIRST xl_with_hold_cursor; +FETCH ABSOLUTE 5 xl_with_hold_cursor; +FETCH ALL FROM xl_with_hold_cursor; +COMMIT; +FETCH FIRST xl_with_hold_cursor; + +--SAVEPOINTs are not supported +begin; + set constraints all deferred; + savepoint x; + set constraints all immediate; -- fails + rollback to x; +commit; -- still fails + +--User defined functions have several limitations +--Basic insert, update, delete test on multiple datanodes using plpgsql function is passing. +create function xl_insert_Pline_test(int) returns boolean as $$ +BEGIN + IF $1 < 20 THEN + insert into xl_PLine values ('PL.030', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.031', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.032', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.033', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.034', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.035', '-367', '', 'PS.first.tb6'); + insert into xl_PLine values ('PL.036', '-367', '', 'PS.first.tb6'); + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;$$ language plpgsql; + +select xl_insert_Pline_test(1); + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; + + +create function xl_update_Pline_test(int) returns boolean as $$ +BEGIN + IF $1 < 20 THEN + update xl_Pline set phonenumber = '400' where slotname = 'PL.030'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.031'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.032'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.033'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.034'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.035'; + update xl_Pline set phonenumber = '400' where slotname = 'PL.036'; + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;$$ language plpgsql; + +select xl_update_Pline_test(1); + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; + +create function xl_delete_Pline_test(int) returns boolean as $$ +BEGIN + IF $1 < 20 THEN + delete from xl_Pline where slotname = 'PL.030'; + delete from xl_Pline where slotname = 'PL.031'; + delete from xl_Pline where slotname = 'PL.032'; + delete from xl_Pline where slotname = 'PL.033'; + delete from xl_Pline where slotname = 'PL.034'; + delete from xl_Pline where slotname = 'PL.035'; + delete from xl_Pline where slotname = 'PL.036'; + + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;$$ language plpgsql; + +select xl_delete_Pline_test(1); + +select xl_nodename_from_id(xc_node_id), * from xl_Pline order by slotname; + + +--Correlated UPDATE/DELETE is not supported. +-- distributed by default ==> xl_t by HASH(no), xl_t1 by HASH(no1) +CREATE TABLE xl_t("no" integer,"name" character varying); +CREATE TABLE xl_t1(no1 integer,name1 character varying); +create table xl_names("name" character varying, "name1" character varying); + +INSERT INTO xl_t("no", "name")VALUES (1, 'A'); +INSERT INTO xl_t("no", "name")VALUES (2, 'B'); +INSERT INTO xl_t("no", "name")VALUES (3, 'C'); +INSERT INTO xl_t("no", "name")VALUES (4, 'D'); + +INSERT INTO xl_t1("no1", "name1")VALUES (1, 'Z'); +INSERT INTO xl_t1("no1", "name1")VALUES (2, 'Y'); +INSERT INTO xl_t1("no1", "name1")VALUES (3, 'X'); +INSERT INTO xl_t1("no1", "name1")VALUES (4, 'W'); + +INSERT INTO xl_names("name", "name1")VALUES ('A', 'A1'); +INSERT INTO xl_names("name", "name1")VALUES ('B', 'B1'); +INSERT INTO xl_names("name", "name1")VALUES ('C', 'C1'); +INSERT INTO xl_names("name", "name1")VALUES ('D', 'D1'); +INSERT INTO xl_names("name", "name1")VALUES ('W', 'W1'); +INSERT INTO xl_names("name", "name1")VALUES ('X', 'X1'); +INSERT INTO xl_names("name", "name1")VALUES ('Y', 'Y1'); +INSERT INTO xl_names("name", "name1")VALUES ('Z', 'Z1'); + +select xl_nodename_from_id(xc_node_id), * from xl_t; + +select xl_nodename_from_id(xc_node_id), * from xl_t1; + +select xl_nodename_from_id(xc_node_id), * from xl_names order by name; + +update xl_t set name = T1.name1 +from (select no1,name1 from xl_t1) T1 +where xl_t.no = T1.no1; + +--correlated update fails +update xl_t1 set name1 = T1.name1 +from (select name,name1 from xl_names) T1 +where xl_t1.name1 = T1.name; + +select xl_nodename_from_id(xc_node_id), * from xl_t; +select xl_nodename_from_id(xc_node_id), * from xl_t1; + +--testing correlated delete: +delete from xl_t +where xl_t.no in (select no1 from xl_t1 where name1 in ('Z', 'X')) +; + +--correlated delete fails +delete from xl_t1 +where xl_t1.name1 in (select name1 from xl_names where name in ('Z', 'X')) +; + +select xl_nodename_from_id(xc_node_id), * from xl_t; + +select xl_nodename_from_id(xc_node_id), * from xl_t1; + +drop table xl_t; +drop table xl_t1; +drop table xl_names; + +--EXCLUSION CONSTRAINTS are not supported +--The constraint is enforced when both rows map to the same datanode. But if they go into different datanodes, the constraint is not enforced +CREATE TABLE xl_circles ( + c circle, + EXCLUDE USING gist (c WITH &&) +); + +CREATE TABLE xl_cons_hash (a int, c circle, EXCLUDE USING gist (c WITH &&)) DISTRIBUTE BY HASH(a); +CREATE TABLE xl_cons_modulo (a int, c circle, EXCLUDE USING gist (c WITH &&)) DISTRIBUTE BY MODULO(a); error +CREATE TABLE xl_cons_rr (c circle, EXCLUDE USING gist (c WITH &&)) DISTRIBUTE BY ROUNDROBIN; +CREATE TABLE xl_cons_hash2 (a int, b int, c circle, EXCLUDE USING btree (a WITH = , b WITH =)) DISTRIBUTE BY HASH(a); +CREATE TABLE xl_cons_modulo2 (a int, b int, c circle, EXCLUDE USING btree (a WITH =, b WITH =)) DISTRIBUTE BY MODULO(a); + +-- xl_test1 is distributed by default on HASH(a) +CREATE TABLE xl_test1 (a int, b int); +INSERT INTO xl_test1 VALUES (1,2); +INSERT INTO xl_test1 VALUES (2,2); +INSERT INTO xl_test1 VALUES (3,2); +INSERT INTO xl_test1 VALUES (4,2); +INSERT INTO xl_test1 VALUES (5,2); +INSERT INTO xl_test1 VALUES (6,2); +INSERT INTO xl_test1 VALUES (7,2); + +select xl_nodename_from_id(xc_node_id),* from xl_test1 order by a; +-- this is to see how hash of integers key distributes among data nodes. + +-- xl_test is distributed by default on HASH(a) +CREATE TABLE xl_test (a int, b int, EXCLUDE USING btree (b WITH =)); +INSERT INTO xl_test VALUES (1,2); +INSERT INTO xl_test VALUES (2,2); +INSERT INTO xl_test VALUES (3,2); +INSERT INTO xl_test VALUES (4,2); +INSERT INTO xl_test VALUES (5,2); +INSERT INTO xl_test VALUES (6,2); +INSERT INTO xl_test VALUES (7,2); + +--the constraint is enforced when both rows map to the same datanode, e.g. when a=1, a=2 +--But if they go into different datanodes, the constraint is not enforced, e.g. when a=3 + +drop table xl_circles; +drop table xl_cons_hash; +drop table xl_cons_modulo; +drop table xl_cons_rr; +drop table xl_test; +drop table xl_test1; + +drop table xl_Room; +drop table xl_WSlot; +drop table xl_PLine; + + +-- CREATE INDEX CONCURRENTLY is not supported +-- +-- Try some concurrent index builds +-- +-- Unfortunately this only tests about half the code paths because there are +-- no concurrent updates happening to the table at the same time. + +CREATE TABLE xl_concur_heap (f1 text, f2 text); +-- empty table +CREATE INDEX CONCURRENTLY xl_concur_index1 ON xl_concur_heap(f2,f1); +CREATE INDEX CONCURRENTLY IF NOT EXISTS xl_concur_index1 ON xl_concur_heap(f2,f1); +INSERT INTO xl_concur_heap VALUES ('a','b'); +INSERT INTO xl_concur_heap VALUES ('b','b'); + +drop index concurrently xl_concur_index1; +drop table xl_concur_heap; + + +--Large objects are not supported + +CREATE TABLE lotest_stash_values (loid oid, junk integer, fd integer); +-- lo_creat(mode integer) returns oid +-- The mode arg to lo_creat is unused, some vestigal holdover from ancient times +-- returns the large object id +INSERT INTO lotest_stash_values (loid) VALUES( lo_creat(42) ); + +drop table lotest_stash_values; + +--EVENT TRIGGERs are not supported +CREATE FUNCTION xl_event_trigger_for_drops() + RETURNS event_trigger LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE '% dropped object: % %.% %', + tg_tag, + obj.object_type, + obj.schema_name, + obj.object_name, + obj.object_identity; + END LOOP; +END +$$; +CREATE EVENT TRIGGER xl_event_trigger_for_drops + ON sql_drop + EXECUTE PROCEDURE xl_event_trigger_for_drops(); + +drop function xl_event_trigger_for_drops(); +drop EVENT TRIGGER xl_event_trigger_for_drops; + +--Recursive queries are not supported +WITH RECURSIVE t(n) AS ( + VALUES (1) + UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t; + +--FDWs are not supported + +CREATE FOREIGN DATA WRAPPER xl_foo; -- ERROR +RESET ROLE; +CREATE FOREIGN DATA WRAPPER xl_foo VALIDATOR postgresql_fdw_validator; + +--LISTEN/NOTIFY is not supported. Looks like they are supported now. +--We would obviously have issues with LISTEN/NOTIFY if clients are connected to different coordinators. Need to test that manually as it is difficult via regression. +--Should work. Send a valid message via a valid channel name +--LISTEN notify_async1; +-- commenting LISTEN as PIDs shown here would never match in regression. +SELECT pg_notify('notify_async1','sample message1'); +SELECT pg_notify('notify_async1',''); +SELECT pg_notify('notify_async1',NULL); + +-- Should fail. Send a valid message via an invalid channel name +SELECT pg_notify('','sample message1'); +SELECT pg_notify(NULL,'sample message1'); +SELECT pg_notify('notify_async_channel_name_too_long______________________________','sample_message1'); + +--Should work. Valid NOTIFY/LISTEN/UNLISTEN commands +NOTIFY notify_async2; +LISTEN notify_async2; +UNLISTEN notify_async2; +UNLISTEN *; + +--LISTEN virtual; +NOTIFY virtual; + +NOTIFY virtual, 'This is the payload'; + + +--LISTEN foo; +SELECT pg_notify('fo' || 'o', 'pay' || 'load'); + +drop function xl_room_au(); +drop function xl_trap_zero_divide(int); +drop function xl_nodename_from_id(integer); +drop function xl_insert_Pline_test(int); +drop function xl_update_Pline_test(int); +drop function xl_delete_Pline_test(int); + + + + |