Merge pull request #820 from citusdata/parameterized_queries_regression_tests

Add regression tests for parameterized queries
pull/864/head
Metin Döşlü 2016-10-18 14:08:59 +03:00 committed by GitHub
commit a317683046
7 changed files with 2058 additions and 270 deletions

View File

@ -6,47 +6,7 @@
-- use prepared statements internally. -- use prepared statements internally.
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 780000; ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 780000;
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 780000; ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 780000;
CREATE FUNCTION sql_test_no_1() RETURNS bigint AS ' CREATE FUNCTION plpgsql_test_1() RETURNS TABLE(count bigint) AS $$
SELECT
count(*)
FROM
orders;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_2() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_3() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer
WHERE
o_custkey = c_custkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_4() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer, lineitem
WHERE
o_custkey = c_custkey AND
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE OR REPLACE FUNCTION sql_test_no_6(integer) RETURNS bigint AS $$
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey AND
l_suppkey > $1;
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT;
CREATE OR REPLACE FUNCTION plpgsql_test_1() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -57,7 +17,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_2() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_2() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -70,7 +30,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_3() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_3() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -83,7 +43,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_4() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_4() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -96,7 +56,7 @@ BEGIN
o_orderkey = l_orderkey; o_orderkey = l_orderkey;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_5() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_5() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -108,7 +68,7 @@ BEGIN
l_partkey = c_nationkey; l_partkey = c_nationkey;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_6(int) RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_6(int) RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -121,7 +81,7 @@ BEGIN
l_suppkey > $1; l_suppkey > $1;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_7(text, text) RETURNS TABLE(supp_natadsion text, cusasdt_nation text, l_yeasdar int, sasdaum double precision) AS $$ CREATE FUNCTION plpgsql_test_7(text, text) RETURNS TABLE(supp_natadsion text, cusasdt_nation text, l_yeasdar int, sasdaum double precision) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -177,31 +137,6 @@ END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
SET citus.task_executor_type TO 'task-tracker'; SET citus.task_executor_type TO 'task-tracker';
SET client_min_messages TO INFO; SET client_min_messages TO INFO;
-- now, run plain SQL functions
SELECT sql_test_no_1();
sql_test_no_1
---------------
2984
(1 row)
SELECT sql_test_no_2();
sql_test_no_2
---------------
11998
(1 row)
SELECT sql_test_no_3();
sql_test_no_3
---------------
1955
(1 row)
SELECT sql_test_no_4();
sql_test_no_4
---------------
7804
(1 row)
-- now, run PL/pgsql functions -- now, run PL/pgsql functions
SELECT plpgsql_test_1(); SELECT plpgsql_test_1();
plpgsql_test_1 plpgsql_test_1
@ -316,23 +251,6 @@ SELECT plpgsql_test_2();
-- run the tests which do not require re-partition -- run the tests which do not require re-partition
-- with real-time executor -- with real-time executor
SET citus.task_executor_type TO 'real-time'; SET citus.task_executor_type TO 'real-time';
-- now, run plain SQL functions
SELECT sql_test_no_1();
sql_test_no_1
---------------
2984
(1 row)
SELECT sql_test_no_2();
sql_test_no_2
---------------
11998
(1 row)
-- plain SQL functions with parameters cannot be executed
-- FIXME: temporarily disabled, bad error message - waiting for proper parametrized query
-- FIXME: support
-- SELECT sql_test_no_6(155);
-- now, run PL/pgsql functions -- now, run PL/pgsql functions
SELECT plpgsql_test_1(); SELECT plpgsql_test_1();
plpgsql_test_1 plpgsql_test_1
@ -351,25 +269,25 @@ SELECT plpgsql_test_2();
-- SELECT plpgsql_test_6(155); -- SELECT plpgsql_test_6(155);
-- SELECT plpgsql_test_6(1555); -- SELECT plpgsql_test_6(1555);
-- test router executor parameterized PL/pgsql functions -- test router executor parameterized PL/pgsql functions
CREATE TABLE temp_table ( CREATE TABLE plpgsql_table (
key int, key int,
value int value int
); );
SELECT master_create_distributed_table('temp_table','key','hash'); SELECT master_create_distributed_table('plpgsql_table','key','hash');
master_create_distributed_table master_create_distributed_table
--------------------------------- ---------------------------------
(1 row) (1 row)
SELECT master_create_worker_shards('temp_table',4,1); SELECT master_create_worker_shards('plpgsql_table',4,1);
master_create_worker_shards master_create_worker_shards
----------------------------- -----------------------------
(1 row) (1 row)
CREATE OR REPLACE FUNCTION no_parameter_insert() RETURNS void as $$ CREATE FUNCTION no_parameter_insert() RETURNS void as $$
BEGIN BEGIN
INSERT INTO temp_table (key) VALUES (0); INSERT INTO plpgsql_table (key) VALUES (0);
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage -- execute 6 times to trigger prepared statement usage
@ -409,9 +327,10 @@ SELECT no_parameter_insert();
(1 row) (1 row)
CREATE OR REPLACE FUNCTION single_parameter_insert(key_arg int) RETURNS void as $$ CREATE FUNCTION single_parameter_insert(key_arg int)
RETURNS void as $$
BEGIN BEGIN
INSERT INTO temp_table (key) VALUES (key_arg); INSERT INTO plpgsql_table (key) VALUES (key_arg);
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage -- execute 6 times to trigger prepared statement usage
@ -447,11 +366,12 @@ SELECT single_parameter_insert(5);
SELECT single_parameter_insert(6); SELECT single_parameter_insert(6);
ERROR: values given for the partition column must be constants or constant expressions ERROR: values given for the partition column must be constants or constant expressions
CONTEXT: SQL statement "INSERT INTO temp_table (key) VALUES (key_arg)" CONTEXT: SQL statement "INSERT INTO plpgsql_table (key) VALUES (key_arg)"
PL/pgSQL function single_parameter_insert(integer) line 3 at SQL statement PL/pgSQL function single_parameter_insert(integer) line 3 at SQL statement
CREATE OR REPLACE FUNCTION double_parameter_insert(key_arg int, value_arg int) RETURNS void as $$ CREATE FUNCTION double_parameter_insert(key_arg int, value_arg int)
RETURNS void as $$
BEGIN BEGIN
INSERT INTO temp_table (key, value) VALUES (key_arg, value_arg); INSERT INTO plpgsql_table (key, value) VALUES (key_arg, value_arg);
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage -- execute 6 times to trigger prepared statement usage
@ -487,12 +407,61 @@ SELECT double_parameter_insert(5, 50);
SELECT double_parameter_insert(6, 60); SELECT double_parameter_insert(6, 60);
ERROR: values given for the partition column must be constants or constant expressions ERROR: values given for the partition column must be constants or constant expressions
CONTEXT: SQL statement "INSERT INTO temp_table (key, value) VALUES (key_arg, value_arg)" CONTEXT: SQL statement "INSERT INTO plpgsql_table (key, value) VALUES (key_arg, value_arg)"
PL/pgSQL function double_parameter_insert(integer,integer) line 3 at SQL statement PL/pgSQL function double_parameter_insert(integer,integer) line 3 at SQL statement
CREATE FUNCTION non_partition_parameter_insert(value_arg int)
RETURNS void as $$
BEGIN
INSERT INTO plpgsql_table (key, value) VALUES (0, value_arg);
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_insert(10);
non_partition_parameter_insert
--------------------------------
(1 row)
SELECT non_partition_parameter_insert(20);
non_partition_parameter_insert
--------------------------------
(1 row)
SELECT non_partition_parameter_insert(30);
non_partition_parameter_insert
--------------------------------
(1 row)
SELECT non_partition_parameter_insert(40);
non_partition_parameter_insert
--------------------------------
(1 row)
SELECT non_partition_parameter_insert(50);
non_partition_parameter_insert
--------------------------------
(1 row)
SELECT non_partition_parameter_insert(60);
non_partition_parameter_insert
--------------------------------
(1 row)
-- check inserted values -- check inserted values
SELECT * FROM temp_table ORDER BY key, value; SELECT * FROM plpgsql_table ORDER BY key, value;
key | value key | value
-----+------- -----+-------
0 | 10
0 | 20
0 | 30
0 | 40
0 | 50
0 | 60
0 | 0 |
0 | 0 |
0 | 0 |
@ -509,119 +478,570 @@ SELECT * FROM temp_table ORDER BY key, value;
4 | 4 |
5 | 50 5 | 50
5 | 5 |
(16 rows) (22 rows)
-- check router executor select -- check router executor select
CREATE OR REPLACE FUNCTION partition_column_select(key_arg int) RETURNS TABLE(key int, value int) AS $$ CREATE FUNCTION router_partition_column_select(key_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
SELECT SELECT
temp_table.key, plpgsql_table.key,
temp_table.value plpgsql_table.value
FROM FROM
temp_table plpgsql_table
WHERE WHERE
temp_table.key = key_arg plpgsql_table.key = key_arg
ORDER BY ORDER BY
key, key,
value; value;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
SELECT partition_column_select(1); SELECT router_partition_column_select(1);
partition_column_select router_partition_column_select
------------------------- --------------------------------
(1,10) (1,10)
(1,) (1,)
(2 rows) (2 rows)
SELECT partition_column_select(2); SELECT router_partition_column_select(2);
partition_column_select router_partition_column_select
------------------------- --------------------------------
(2,20) (2,20)
(2,) (2,)
(2 rows) (2 rows)
SELECT partition_column_select(3); SELECT router_partition_column_select(3);
partition_column_select router_partition_column_select
------------------------- --------------------------------
(3,30) (3,30)
(3,) (3,)
(2 rows) (2 rows)
SELECT partition_column_select(4); SELECT router_partition_column_select(4);
partition_column_select router_partition_column_select
------------------------- --------------------------------
(4,40) (4,40)
(4,) (4,)
(2 rows) (2 rows)
SELECT partition_column_select(5); SELECT router_partition_column_select(5);
partition_column_select router_partition_column_select
------------------------- --------------------------------
(5,50) (5,50)
(5,) (5,)
(2 rows) (2 rows)
-- 6th execution is failing. We don't want to run the failing test because of -- FIXME: 6th execution is failing. We don't want to run the failing test
-- changing output. After implementing this feature, uncomment this. -- because of changing output. After implementing this feature, uncomment this.
-- SELECT partition_column_select(6); -- SELECT router_partition_column_select(6);
-- check real-time executor CREATE FUNCTION router_non_partition_column_select(value_arg int)
CREATE OR REPLACE FUNCTION non_partition_column_select(value_arg int) RETURNS TABLE(key int, value int) AS $$ RETURNS TABLE(key int, value int) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
SELECT SELECT
temp_table.key, plpgsql_table.key,
temp_table.value plpgsql_table.value
FROM FROM
temp_table plpgsql_table
WHERE WHERE
temp_table.value = value_arg plpgsql_table.key = 0 AND
plpgsql_table.value = value_arg
ORDER BY ORDER BY
key, key,
value; value;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
SELECT non_partition_column_select(10); SELECT router_non_partition_column_select(10);
non_partition_column_select router_non_partition_column_select
----------------------------- ------------------------------------
(0,10)
(1 row)
SELECT router_non_partition_column_select(20);
router_non_partition_column_select
------------------------------------
(0,20)
(1 row)
SELECT router_non_partition_column_select(30);
router_non_partition_column_select
------------------------------------
(0,30)
(1 row)
SELECT router_non_partition_column_select(40);
router_non_partition_column_select
------------------------------------
(0,40)
(1 row)
SELECT router_non_partition_column_select(50);
router_non_partition_column_select
------------------------------------
(0,50)
(1 row)
SELECT router_non_partition_column_select(60);
router_non_partition_column_select
------------------------------------
(0,60)
(1 row)
-- check real-time executor
CREATE FUNCTION real_time_non_partition_column_select(value_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.value = value_arg
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT real_time_non_partition_column_select(10);
real_time_non_partition_column_select
---------------------------------------
(0,10)
(1,10) (1,10)
(1 row) (2 rows)
SELECT non_partition_column_select(20); SELECT real_time_non_partition_column_select(20);
non_partition_column_select real_time_non_partition_column_select
----------------------------- ---------------------------------------
(0,20)
(2,20) (2,20)
(1 row) (2 rows)
SELECT non_partition_column_select(30); SELECT real_time_non_partition_column_select(30);
non_partition_column_select real_time_non_partition_column_select
----------------------------- ---------------------------------------
(0,30)
(3,30) (3,30)
(1 row) (2 rows)
SELECT non_partition_column_select(40); SELECT real_time_non_partition_column_select(40);
non_partition_column_select real_time_non_partition_column_select
----------------------------- ---------------------------------------
(0,40)
(4,40) (4,40)
(1 row) (2 rows)
SELECT non_partition_column_select(50); SELECT real_time_non_partition_column_select(50);
non_partition_column_select real_time_non_partition_column_select
----------------------------- ---------------------------------------
(0,50)
(5,50) (5,50)
(2 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- SELECT real_time_non_partition_column_select(60);
CREATE FUNCTION real_time_partition_column_select(key_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.key = key_arg OR
plpgsql_table.value = 10
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT real_time_partition_column_select(1);
real_time_partition_column_select
-----------------------------------
(0,10)
(1,10)
(1,)
(3 rows)
SELECT real_time_partition_column_select(2);
real_time_partition_column_select
-----------------------------------
(0,10)
(1,10)
(2,20)
(2,)
(4 rows)
SELECT real_time_partition_column_select(3);
real_time_partition_column_select
-----------------------------------
(0,10)
(1,10)
(3,30)
(3,)
(4 rows)
SELECT real_time_partition_column_select(4);
real_time_partition_column_select
-----------------------------------
(0,10)
(1,10)
(4,40)
(4,)
(4 rows)
SELECT real_time_partition_column_select(5);
real_time_partition_column_select
-----------------------------------
(0,10)
(1,10)
(5,50)
(5,)
(4 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- SELECT real_time_partition_column_select(6);
-- check task-tracker executor
SET citus.task_executor_type TO 'task-tracker';
CREATE FUNCTION task_tracker_non_partition_column_select(value_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.value = value_arg
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT task_tracker_non_partition_column_select(10);
task_tracker_non_partition_column_select
------------------------------------------
(0,10)
(1,10)
(2 rows)
SELECT task_tracker_non_partition_column_select(20);
task_tracker_non_partition_column_select
------------------------------------------
(0,20)
(2,20)
(2 rows)
SELECT task_tracker_non_partition_column_select(30);
task_tracker_non_partition_column_select
------------------------------------------
(0,30)
(3,30)
(2 rows)
SELECT task_tracker_non_partition_column_select(40);
task_tracker_non_partition_column_select
------------------------------------------
(0,40)
(4,40)
(2 rows)
SELECT task_tracker_non_partition_column_select(50);
task_tracker_non_partition_column_select
------------------------------------------
(0,50)
(5,50)
(2 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- SELECT real_time_non_partition_column_select(60);
CREATE FUNCTION task_tracker_partition_column_select(key_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.key = key_arg OR
plpgsql_table.value = 10
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT task_tracker_partition_column_select(1);
task_tracker_partition_column_select
--------------------------------------
(0,10)
(1,10)
(1,)
(3 rows)
SELECT task_tracker_partition_column_select(2);
task_tracker_partition_column_select
--------------------------------------
(0,10)
(1,10)
(2,20)
(2,)
(4 rows)
SELECT task_tracker_partition_column_select(3);
task_tracker_partition_column_select
--------------------------------------
(0,10)
(1,10)
(3,30)
(3,)
(4 rows)
SELECT task_tracker_partition_column_select(4);
task_tracker_partition_column_select
--------------------------------------
(0,10)
(1,10)
(4,40)
(4,)
(4 rows)
SELECT task_tracker_partition_column_select(5);
task_tracker_partition_column_select
--------------------------------------
(0,10)
(1,10)
(5,50)
(5,)
(4 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- SELECT task_tracker_partition_column_select(6);
SET citus.task_executor_type TO 'real-time';
-- check updates
CREATE FUNCTION partition_parameter_update(int, int) RETURNS void as $$
BEGIN
UPDATE plpgsql_table SET value = $2 WHERE key = $1;
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT partition_parameter_update(1, 11);
partition_parameter_update
----------------------------
(1 row) (1 row)
-- 6th execution is failing. We don't want to run the failing test because of SELECT partition_parameter_update(2, 21);
-- changing output. After implementing this feature, uncomment this. partition_parameter_update
-- SELECT partition_column_select(6); ----------------------------
(1 row)
SELECT partition_parameter_update(3, 31);
partition_parameter_update
----------------------------
(1 row)
SELECT partition_parameter_update(4, 41);
partition_parameter_update
----------------------------
(1 row)
SELECT partition_parameter_update(5, 51);
partition_parameter_update
----------------------------
(1 row)
-- This fails with an unexpected error message
SELECT partition_parameter_update(5, 52);
ERROR: distributed modifications must target exactly one shard
CONTEXT: SQL statement "UPDATE plpgsql_table SET value = $2 WHERE key = $1"
PL/pgSQL function partition_parameter_update(integer,integer) line 3 at SQL statement
CREATE FUNCTION non_partition_parameter_update(int, int) RETURNS void as $$
BEGIN
UPDATE plpgsql_table SET value = $2 WHERE key = 0 AND value = $1;
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_update(10, 12);
non_partition_parameter_update
--------------------------------
(1 row)
SELECT non_partition_parameter_update(20, 22);
non_partition_parameter_update
--------------------------------
(1 row)
SELECT non_partition_parameter_update(30, 32);
non_partition_parameter_update
--------------------------------
(1 row)
SELECT non_partition_parameter_update(40, 42);
non_partition_parameter_update
--------------------------------
(1 row)
SELECT non_partition_parameter_update(50, 52);
non_partition_parameter_update
--------------------------------
(1 row)
SELECT non_partition_parameter_update(60, 62);
non_partition_parameter_update
--------------------------------
(1 row)
-- check table after updates
SELECT * FROM plpgsql_table ORDER BY key, value;
key | value
-----+-------
0 | 12
0 | 22
0 | 32
0 | 42
0 | 52
0 | 62
0 |
0 |
0 |
0 |
0 |
0 |
1 | 11
1 | 11
2 | 21
2 | 21
3 | 31
3 | 31
4 | 41
4 | 41
5 | 51
5 | 51
(22 rows)
-- check deletes
CREATE FUNCTION partition_parameter_delete(int, int) RETURNS void as $$
BEGIN
DELETE FROM plpgsql_table WHERE key = $1 AND value = $2;
END;
$$ LANGUAGE plpgsql;
SELECT partition_parameter_delete(1, 11);
partition_parameter_delete
----------------------------
(1 row)
SELECT partition_parameter_delete(2, 21);
partition_parameter_delete
----------------------------
(1 row)
SELECT partition_parameter_delete(3, 31);
partition_parameter_delete
----------------------------
(1 row)
SELECT partition_parameter_delete(4, 41);
partition_parameter_delete
----------------------------
(1 row)
SELECT partition_parameter_delete(5, 51);
partition_parameter_delete
----------------------------
(1 row)
-- This fails with an unexpected error message
SELECT partition_parameter_delete(0, 10);
ERROR: distributed modifications must target exactly one shard
CONTEXT: SQL statement "DELETE FROM plpgsql_table WHERE key = $1 AND value = $2"
PL/pgSQL function partition_parameter_delete(integer,integer) line 3 at SQL statement
CREATE FUNCTION non_partition_parameter_delete(int) RETURNS void as $$
BEGIN
DELETE FROM plpgsql_table WHERE key = 0 AND value = $1;
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_delete(12);
non_partition_parameter_delete
--------------------------------
(1 row)
SELECT non_partition_parameter_delete(22);
non_partition_parameter_delete
--------------------------------
(1 row)
SELECT non_partition_parameter_delete(32);
non_partition_parameter_delete
--------------------------------
(1 row)
SELECT non_partition_parameter_delete(42);
non_partition_parameter_delete
--------------------------------
(1 row)
SELECT non_partition_parameter_delete(52);
non_partition_parameter_delete
--------------------------------
(1 row)
SELECT non_partition_parameter_delete(62);
non_partition_parameter_delete
--------------------------------
(1 row)
-- check table after deletes
SELECT * FROM plpgsql_table ORDER BY key, value;
key | value
-----+-------
0 |
0 |
0 |
0 |
0 |
0 |
(6 rows)
-- clean-up functions -- clean-up functions
DROP FUNCTION sql_test_no_1();
DROP FUNCTION sql_test_no_2();
DROP FUNCTION sql_test_no_3();
DROP FUNCTION sql_test_no_4();
DROP FUNCTION sql_test_no_6(int);
DROP FUNCTION plpgsql_test_1(); DROP FUNCTION plpgsql_test_1();
DROP FUNCTION plpgsql_test_2(); DROP FUNCTION plpgsql_test_2();
DROP FUNCTION plpgsql_test_3(); DROP FUNCTION plpgsql_test_3();
@ -632,5 +1052,14 @@ DROP FUNCTION plpgsql_test_7(text, text);
DROP FUNCTION no_parameter_insert(); DROP FUNCTION no_parameter_insert();
DROP FUNCTION single_parameter_insert(int); DROP FUNCTION single_parameter_insert(int);
DROP FUNCTION double_parameter_insert(int, int); DROP FUNCTION double_parameter_insert(int, int);
DROP FUNCTION partition_column_select(int); DROP FUNCTION non_partition_parameter_insert(int);
DROP FUNCTION non_partition_column_select(int); DROP FUNCTION router_partition_column_select(int);
DROP FUNCTION router_non_partition_column_select(int);
DROP FUNCTION real_time_non_partition_column_select(int);
DROP FUNCTION real_time_partition_column_select(int);
DROP FUNCTION task_tracker_non_partition_column_select(int);
DROP FUNCTION task_tracker_partition_column_select(int);
DROP FUNCTION partition_parameter_update(int, int);
DROP FUNCTION non_partition_parameter_update(int, int);
DROP FUNCTION partition_parameter_delete(int, int);
DROP FUNCTION non_partition_parameter_delete(int);

View File

@ -338,5 +338,487 @@ EXECUTE prepared_partition_column_insert(6);
ERROR: values given for the partition column must be constants or constant expressions ERROR: values given for the partition column must be constants or constant expressions
DROP TYPE test_composite_type CASCADE; DROP TYPE test_composite_type CASCADE;
NOTICE: drop cascades to table router_executor_table column stats NOTICE: drop cascades to table router_executor_table column stats
-- test router executor with prepare statements
CREATE TABLE prepare_table (
key int,
value int
);
SELECT master_create_distributed_table('prepare_table','key','hash');
master_create_distributed_table
---------------------------------
(1 row)
SELECT master_create_worker_shards('prepare_table',4,1);
master_create_worker_shards
-----------------------------
(1 row)
PREPARE prepared_no_parameter_insert AS
INSERT INTO prepare_table (key) VALUES (0);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
PREPARE prepared_single_parameter_insert(int) AS
INSERT INTO prepare_table (key) VALUES ($1);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_single_parameter_insert(1);
EXECUTE prepared_single_parameter_insert(2);
EXECUTE prepared_single_parameter_insert(3);
EXECUTE prepared_single_parameter_insert(4);
EXECUTE prepared_single_parameter_insert(5);
EXECUTE prepared_single_parameter_insert(6);
ERROR: values given for the partition column must be constants or constant expressions
PREPARE prepared_double_parameter_insert(int, int) AS
INSERT INTO prepare_table (key, value) VALUES ($1, $2);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_double_parameter_insert(1, 10);
EXECUTE prepared_double_parameter_insert(2, 20);
EXECUTE prepared_double_parameter_insert(3, 30);
EXECUTE prepared_double_parameter_insert(4, 40);
EXECUTE prepared_double_parameter_insert(5, 50);
EXECUTE prepared_double_parameter_insert(6, 60);
ERROR: values given for the partition column must be constants or constant expressions
PREPARE prepared_non_partition_parameter_insert(int) AS
INSERT INTO prepare_table (key, value) VALUES (0, $1);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_non_partition_parameter_insert(10);
EXECUTE prepared_non_partition_parameter_insert(20);
EXECUTE prepared_non_partition_parameter_insert(30);
EXECUTE prepared_non_partition_parameter_insert(40);
EXECUTE prepared_non_partition_parameter_insert(50);
EXECUTE prepared_non_partition_parameter_insert(60);
-- check inserted values
SELECT * FROM prepare_table ORDER BY key, value;
key | value
-----+-------
0 | 10
0 | 20
0 | 30
0 | 40
0 | 50
0 | 60
0 |
0 |
0 |
0 |
0 |
0 |
1 | 10
1 |
2 | 20
2 |
3 | 30
3 |
4 | 40
4 |
5 | 50
5 |
(22 rows)
-- check router executor select
PREPARE prepared_router_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = $1
ORDER BY
key,
value;
EXECUTE prepared_router_partition_column_select(1);
key | value
-----+-------
1 | 10
1 |
(2 rows)
EXECUTE prepared_router_partition_column_select(2);
key | value
-----+-------
2 | 20
2 |
(2 rows)
EXECUTE prepared_router_partition_column_select(3);
key | value
-----+-------
3 | 30
3 |
(2 rows)
EXECUTE prepared_router_partition_column_select(4);
key | value
-----+-------
4 | 40
4 |
(2 rows)
EXECUTE prepared_router_partition_column_select(5);
key | value
-----+-------
5 | 50
5 |
(2 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_router_partition_column_select(6);
PREPARE prepared_router_non_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = 0 AND
prepare_table.value = $1
ORDER BY
key,
value;
EXECUTE prepared_router_non_partition_column_select(10);
key | value
-----+-------
0 | 10
(1 row)
EXECUTE prepared_router_non_partition_column_select(20);
key | value
-----+-------
0 | 20
(1 row)
EXECUTE prepared_router_non_partition_column_select(30);
key | value
-----+-------
0 | 30
(1 row)
EXECUTE prepared_router_non_partition_column_select(40);
key | value
-----+-------
0 | 40
(1 row)
EXECUTE prepared_router_non_partition_column_select(50);
key | value
-----+-------
0 | 50
(1 row)
EXECUTE prepared_router_non_partition_column_select(60);
key | value
-----+-------
0 | 60
(1 row)
-- check real-time executor
PREPARE prepared_real_time_non_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.value = $1
ORDER BY
key,
value;
EXECUTE prepared_real_time_non_partition_column_select(10);
key | value
-----+-------
0 | 10
1 | 10
(2 rows)
EXECUTE prepared_real_time_non_partition_column_select(20);
key | value
-----+-------
0 | 20
2 | 20
(2 rows)
EXECUTE prepared_real_time_non_partition_column_select(30);
key | value
-----+-------
0 | 30
3 | 30
(2 rows)
EXECUTE prepared_real_time_non_partition_column_select(40);
key | value
-----+-------
0 | 40
4 | 40
(2 rows)
EXECUTE prepared_real_time_non_partition_column_select(50);
key | value
-----+-------
0 | 50
5 | 50
(2 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_real_time_non_partition_column_select(60);
PREPARE prepared_real_time_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = $1 OR
prepare_table.value = 10
ORDER BY
key,
value;
EXECUTE prepared_real_time_partition_column_select(1);
key | value
-----+-------
0 | 10
1 | 10
1 |
(3 rows)
EXECUTE prepared_real_time_partition_column_select(2);
key | value
-----+-------
0 | 10
1 | 10
2 | 20
2 |
(4 rows)
EXECUTE prepared_real_time_partition_column_select(3);
key | value
-----+-------
0 | 10
1 | 10
3 | 30
3 |
(4 rows)
EXECUTE prepared_real_time_partition_column_select(4);
key | value
-----+-------
0 | 10
1 | 10
4 | 40
4 |
(4 rows)
EXECUTE prepared_real_time_partition_column_select(5);
key | value
-----+-------
0 | 10
1 | 10
5 | 50
5 |
(4 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_real_time_partition_column_select(6);
-- check task-tracker executor
SET citus.task_executor_type TO 'task-tracker';
PREPARE prepared_task_tracker_non_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.value = $1
ORDER BY
key,
value;
EXECUTE prepared_task_tracker_non_partition_column_select(10);
key | value
-----+-------
0 | 10
1 | 10
(2 rows)
EXECUTE prepared_task_tracker_non_partition_column_select(20);
key | value
-----+-------
0 | 20
2 | 20
(2 rows)
EXECUTE prepared_task_tracker_non_partition_column_select(30);
key | value
-----+-------
0 | 30
3 | 30
(2 rows)
EXECUTE prepared_task_tracker_non_partition_column_select(40);
key | value
-----+-------
0 | 40
4 | 40
(2 rows)
EXECUTE prepared_task_tracker_non_partition_column_select(50);
key | value
-----+-------
0 | 50
5 | 50
(2 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_task_tracker_non_partition_column_select(60);
PREPARE prepared_task_tracker_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = $1 OR
prepare_table.value = 10
ORDER BY
key,
value;
EXECUTE prepared_task_tracker_partition_column_select(1);
key | value
-----+-------
0 | 10
1 | 10
1 |
(3 rows)
EXECUTE prepared_task_tracker_partition_column_select(2);
key | value
-----+-------
0 | 10
1 | 10
2 | 20
2 |
(4 rows)
EXECUTE prepared_task_tracker_partition_column_select(3);
key | value
-----+-------
0 | 10
1 | 10
3 | 30
3 |
(4 rows)
EXECUTE prepared_task_tracker_partition_column_select(4);
key | value
-----+-------
0 | 10
1 | 10
4 | 40
4 |
(4 rows)
EXECUTE prepared_task_tracker_partition_column_select(5);
key | value
-----+-------
0 | 10
1 | 10
5 | 50
5 |
(4 rows)
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_task_tracker_partition_column_select(6);
SET citus.task_executor_type TO 'real-time';
-- check updates
PREPARE prepared_partition_parameter_update(int, int) AS
UPDATE prepare_table SET value = $2 WHERE key = $1;
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_partition_parameter_update(1, 11);
EXECUTE prepared_partition_parameter_update(2, 21);
EXECUTE prepared_partition_parameter_update(3, 31);
EXECUTE prepared_partition_parameter_update(4, 41);
EXECUTE prepared_partition_parameter_update(5, 51);
-- This fails with an unexpected error message
EXECUTE prepared_partition_parameter_update(5, 52);
ERROR: distributed modifications must target exactly one shard
PREPARE prepared_non_partition_parameter_update(int, int) AS
UPDATE prepare_table SET value = $2 WHERE key = 0 AND value = $1;
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_non_partition_parameter_update(10, 12);
EXECUTE prepared_non_partition_parameter_update(20, 22);
EXECUTE prepared_non_partition_parameter_update(30, 32);
EXECUTE prepared_non_partition_parameter_update(40, 42);
EXECUTE prepared_non_partition_parameter_update(50, 52);
EXECUTE prepared_non_partition_parameter_update(60, 62);
-- check after updates
SELECT * FROM prepare_table ORDER BY key, value;
key | value
-----+-------
0 | 12
0 | 22
0 | 32
0 | 42
0 | 52
0 | 62
0 |
0 |
0 |
0 |
0 |
0 |
1 | 11
1 | 11
2 | 21
2 | 21
3 | 31
3 | 31
4 | 41
4 | 41
5 | 51
5 | 51
(22 rows)
-- check deletes
PREPARE prepared_partition_parameter_delete(int, int) AS
DELETE FROM prepare_table WHERE key = $1 AND value = $2;
EXECUTE prepared_partition_parameter_delete(1, 11);
EXECUTE prepared_partition_parameter_delete(2, 21);
EXECUTE prepared_partition_parameter_delete(3, 31);
EXECUTE prepared_partition_parameter_delete(4, 41);
EXECUTE prepared_partition_parameter_delete(5, 51);
-- This fails with an unexpected error message
EXECUTE prepared_partition_parameter_delete(0, 10);
ERROR: distributed modifications must target exactly one shard
PREPARE prepared_non_partition_parameter_delete(int) AS
DELETE FROM prepare_table WHERE key = 0 AND value = $1;
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_non_partition_parameter_delete(12);
EXECUTE prepared_non_partition_parameter_delete(22);
EXECUTE prepared_non_partition_parameter_delete(32);
EXECUTE prepared_non_partition_parameter_delete(42);
EXECUTE prepared_non_partition_parameter_delete(52);
EXECUTE prepared_non_partition_parameter_delete(62);
-- check after deletes
SELECT * FROM prepare_table ORDER BY key, value;
key | value
-----+-------
0 |
0 |
0 |
0 |
0 |
0 |
(6 rows)
-- clean-up prepared statements -- clean-up prepared statements
DEALLOCATE ALL; DEALLOCATE ALL;

View File

@ -0,0 +1,330 @@
--
-- MULTI_SQL_FUNCTION
--
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
CREATE FUNCTION sql_test_no_1() RETURNS bigint AS '
SELECT
count(*)
FROM
orders;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_2() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_3() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer
WHERE
o_custkey = c_custkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_4() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer, lineitem
WHERE
o_custkey = c_custkey AND
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_6(integer) RETURNS bigint AS $$
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey AND
l_suppkey > $1;
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT;
SET citus.task_executor_type TO 'task-tracker';
SET client_min_messages TO INFO;
-- now, run plain SQL functions
SELECT sql_test_no_1();
sql_test_no_1
---------------
2984
(1 row)
SELECT sql_test_no_2();
sql_test_no_2
---------------
11998
(1 row)
SELECT sql_test_no_3();
sql_test_no_3
---------------
1955
(1 row)
SELECT sql_test_no_4();
sql_test_no_4
---------------
7804
(1 row)
-- run the tests which do not require re-partition
-- with real-time executor
SET citus.task_executor_type TO 'real-time';
-- now, run plain SQL functions
SELECT sql_test_no_1();
sql_test_no_1
---------------
2984
(1 row)
SELECT sql_test_no_2();
sql_test_no_2
---------------
11998
(1 row)
-- plain SQL functions with parameters cannot be executed
-- FIXME: temporarily disabled, bad error message - waiting for proper
-- parametrized query support
-- SELECT sql_test_no_6(155);
-- test router executor parameterized sql functions
CREATE TABLE temp_table (
key int,
value int
);
SELECT master_create_distributed_table('temp_table','key','hash');
master_create_distributed_table
---------------------------------
(1 row)
SELECT master_create_worker_shards('temp_table',4,1);
master_create_worker_shards
-----------------------------
(1 row)
CREATE FUNCTION no_parameter_insert_sql() RETURNS void AS $$
INSERT INTO temp_table (key) VALUES (0);
$$ LANGUAGE SQL;
-- execute 6 times
SELECT no_parameter_insert_sql();
no_parameter_insert_sql
-------------------------
(1 row)
SELECT no_parameter_insert_sql();
no_parameter_insert_sql
-------------------------
(1 row)
SELECT no_parameter_insert_sql();
no_parameter_insert_sql
-------------------------
(1 row)
SELECT no_parameter_insert_sql();
no_parameter_insert_sql
-------------------------
(1 row)
SELECT no_parameter_insert_sql();
no_parameter_insert_sql
-------------------------
(1 row)
SELECT no_parameter_insert_sql();
no_parameter_insert_sql
-------------------------
(1 row)
CREATE FUNCTION non_partition_parameter_insert_sql(int) RETURNS void AS $$
INSERT INTO temp_table (key, value) VALUES (0, $1);
$$ LANGUAGE SQL;
-- execute 6 times
SELECT non_partition_parameter_insert_sql(10);
non_partition_parameter_insert_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_insert_sql(20);
non_partition_parameter_insert_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_insert_sql(30);
non_partition_parameter_insert_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_insert_sql(40);
non_partition_parameter_insert_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_insert_sql(50);
non_partition_parameter_insert_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_insert_sql(60);
non_partition_parameter_insert_sql
------------------------------------
(1 row)
-- check inserted values
SELECT * FROM temp_table ORDER BY key, value;
key | value
-----+-------
0 | 10
0 | 20
0 | 30
0 | 40
0 | 50
0 | 60
0 |
0 |
0 |
0 |
0 |
0 |
(12 rows)
-- check updates
CREATE FUNCTION non_partition_parameter_update_sql(int, int) RETURNS void AS $$
UPDATE temp_table SET value = $2 WHERE key = 0 AND value = $1;
$$ LANGUAGE SQL;
-- execute 6 times
SELECT non_partition_parameter_update_sql(10, 12);
non_partition_parameter_update_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_update_sql(20, 22);
non_partition_parameter_update_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_update_sql(30, 32);
non_partition_parameter_update_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_update_sql(40, 42);
non_partition_parameter_update_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_update_sql(50, 52);
non_partition_parameter_update_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_update_sql(60, 62);
non_partition_parameter_update_sql
------------------------------------
(1 row)
-- check after updates
SELECT * FROM temp_table ORDER BY key, value;
key | value
-----+-------
0 | 12
0 | 22
0 | 32
0 | 42
0 | 52
0 | 62
0 |
0 |
0 |
0 |
0 |
0 |
(12 rows)
-- check deletes
CREATE FUNCTION non_partition_parameter_delete_sql(int) RETURNS void AS $$
DELETE FROM prepare_table WHERE key = 0 AND value = $1;
$$ LANGUAGE SQL;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_delete_sql(12);
non_partition_parameter_delete_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_delete_sql(22);
non_partition_parameter_delete_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_delete_sql(32);
non_partition_parameter_delete_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_delete_sql(42);
non_partition_parameter_delete_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_delete_sql(52);
non_partition_parameter_delete_sql
------------------------------------
(1 row)
SELECT non_partition_parameter_delete_sql(62);
non_partition_parameter_delete_sql
------------------------------------
(1 row)
-- check after deletes
SELECT * FROM prepare_table ORDER BY key, value;
key | value
-----+-------
0 |
0 |
0 |
0 |
0 |
0 |
(6 rows)
DROP TABLE temp_table;
-- clean-up functions
DROP FUNCTION sql_test_no_1();
DROP FUNCTION sql_test_no_2();
DROP FUNCTION sql_test_no_3();
DROP FUNCTION sql_test_no_4();
DROP FUNCTION sql_test_no_6(int);
DROP FUNCTION no_parameter_insert_sql();
DROP FUNCTION non_partition_parameter_insert_sql(int);
DROP FUNCTION non_partition_parameter_update_sql(int, int);
DROP FUNCTION non_partition_parameter_delete_sql(int);

View File

@ -49,6 +49,7 @@ test: multi_utility_statements
test: multi_dropped_column_aliases test: multi_dropped_column_aliases
test: multi_binary_master_copy_format test: multi_binary_master_copy_format
test: multi_prepare_sql multi_prepare_plsql test: multi_prepare_sql multi_prepare_plsql
test: multi_sql_function
# ---------- # ----------
# Parallel TPC-H tests to check our distributed execution behavior # Parallel TPC-H tests to check our distributed execution behavior

View File

@ -11,52 +11,7 @@ ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 780000;
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 780000; ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 780000;
CREATE FUNCTION sql_test_no_1() RETURNS bigint AS ' CREATE FUNCTION plpgsql_test_1() RETURNS TABLE(count bigint) AS $$
SELECT
count(*)
FROM
orders;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_2() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_3() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer
WHERE
o_custkey = c_custkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_4() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer, lineitem
WHERE
o_custkey = c_custkey AND
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE OR REPLACE FUNCTION sql_test_no_6(integer) RETURNS bigint AS $$
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey AND
l_suppkey > $1;
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT;
CREATE OR REPLACE FUNCTION plpgsql_test_1() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -68,7 +23,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_2() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_2() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -82,7 +37,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_3() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_3() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -96,7 +51,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_4() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_4() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -110,7 +65,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_5() RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_5() RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -123,7 +78,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_6(int) RETURNS TABLE(count bigint) AS $$ CREATE FUNCTION plpgsql_test_6(int) RETURNS TABLE(count bigint) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -137,7 +92,7 @@ BEGIN
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION plpgsql_test_7(text, text) RETURNS TABLE(supp_natadsion text, cusasdt_nation text, l_yeasdar int, sasdaum double precision) AS $$ CREATE FUNCTION plpgsql_test_7(text, text) RETURNS TABLE(supp_natadsion text, cusasdt_nation text, l_yeasdar int, sasdaum double precision) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
@ -195,12 +150,6 @@ $$ LANGUAGE plpgsql;
SET citus.task_executor_type TO 'task-tracker'; SET citus.task_executor_type TO 'task-tracker';
SET client_min_messages TO INFO; SET client_min_messages TO INFO;
-- now, run plain SQL functions
SELECT sql_test_no_1();
SELECT sql_test_no_2();
SELECT sql_test_no_3();
SELECT sql_test_no_4();
-- now, run PL/pgsql functions -- now, run PL/pgsql functions
SELECT plpgsql_test_1(); SELECT plpgsql_test_1();
SELECT plpgsql_test_2(); SELECT plpgsql_test_2();
@ -229,15 +178,6 @@ SELECT plpgsql_test_2();
-- with real-time executor -- with real-time executor
SET citus.task_executor_type TO 'real-time'; SET citus.task_executor_type TO 'real-time';
-- now, run plain SQL functions
SELECT sql_test_no_1();
SELECT sql_test_no_2();
-- plain SQL functions with parameters cannot be executed
-- FIXME: temporarily disabled, bad error message - waiting for proper parametrized query
-- FIXME: support
-- SELECT sql_test_no_6(155);
-- now, run PL/pgsql functions -- now, run PL/pgsql functions
SELECT plpgsql_test_1(); SELECT plpgsql_test_1();
SELECT plpgsql_test_2(); SELECT plpgsql_test_2();
@ -248,16 +188,16 @@ SELECT plpgsql_test_2();
-- SELECT plpgsql_test_6(1555); -- SELECT plpgsql_test_6(1555);
-- test router executor parameterized PL/pgsql functions -- test router executor parameterized PL/pgsql functions
CREATE TABLE temp_table ( CREATE TABLE plpgsql_table (
key int, key int,
value int value int
); );
SELECT master_create_distributed_table('temp_table','key','hash'); SELECT master_create_distributed_table('plpgsql_table','key','hash');
SELECT master_create_worker_shards('temp_table',4,1); SELECT master_create_worker_shards('plpgsql_table',4,1);
CREATE OR REPLACE FUNCTION no_parameter_insert() RETURNS void as $$ CREATE FUNCTION no_parameter_insert() RETURNS void as $$
BEGIN BEGIN
INSERT INTO temp_table (key) VALUES (0); INSERT INTO plpgsql_table (key) VALUES (0);
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
@ -269,9 +209,10 @@ SELECT no_parameter_insert();
SELECT no_parameter_insert(); SELECT no_parameter_insert();
SELECT no_parameter_insert(); SELECT no_parameter_insert();
CREATE OR REPLACE FUNCTION single_parameter_insert(key_arg int) RETURNS void as $$ CREATE FUNCTION single_parameter_insert(key_arg int)
RETURNS void as $$
BEGIN BEGIN
INSERT INTO temp_table (key) VALUES (key_arg); INSERT INTO plpgsql_table (key) VALUES (key_arg);
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
@ -283,9 +224,10 @@ SELECT single_parameter_insert(4);
SELECT single_parameter_insert(5); SELECT single_parameter_insert(5);
SELECT single_parameter_insert(6); SELECT single_parameter_insert(6);
CREATE OR REPLACE FUNCTION double_parameter_insert(key_arg int, value_arg int) RETURNS void as $$ CREATE FUNCTION double_parameter_insert(key_arg int, value_arg int)
RETURNS void as $$
BEGIN BEGIN
INSERT INTO temp_table (key, value) VALUES (key_arg, value_arg); INSERT INTO plpgsql_table (key, value) VALUES (key_arg, value_arg);
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
@ -297,71 +239,265 @@ SELECT double_parameter_insert(4, 40);
SELECT double_parameter_insert(5, 50); SELECT double_parameter_insert(5, 50);
SELECT double_parameter_insert(6, 60); SELECT double_parameter_insert(6, 60);
CREATE FUNCTION non_partition_parameter_insert(value_arg int)
RETURNS void as $$
BEGIN
INSERT INTO plpgsql_table (key, value) VALUES (0, value_arg);
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_insert(10);
SELECT non_partition_parameter_insert(20);
SELECT non_partition_parameter_insert(30);
SELECT non_partition_parameter_insert(40);
SELECT non_partition_parameter_insert(50);
SELECT non_partition_parameter_insert(60);
-- check inserted values -- check inserted values
SELECT * FROM temp_table ORDER BY key, value; SELECT * FROM plpgsql_table ORDER BY key, value;
-- check router executor select -- check router executor select
CREATE OR REPLACE FUNCTION partition_column_select(key_arg int) RETURNS TABLE(key int, value int) AS $$ CREATE FUNCTION router_partition_column_select(key_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
SELECT SELECT
temp_table.key, plpgsql_table.key,
temp_table.value plpgsql_table.value
FROM FROM
temp_table plpgsql_table
WHERE WHERE
temp_table.key = key_arg plpgsql_table.key = key_arg
ORDER BY ORDER BY
key, key,
value; value;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
SELECT partition_column_select(1); SELECT router_partition_column_select(1);
SELECT partition_column_select(2); SELECT router_partition_column_select(2);
SELECT partition_column_select(3); SELECT router_partition_column_select(3);
SELECT partition_column_select(4); SELECT router_partition_column_select(4);
SELECT partition_column_select(5); SELECT router_partition_column_select(5);
-- 6th execution is failing. We don't want to run the failing test because of -- FIXME: 6th execution is failing. We don't want to run the failing test
-- changing output. After implementing this feature, uncomment this. -- because of changing output. After implementing this feature, uncomment this.
-- SELECT partition_column_select(6); -- SELECT router_partition_column_select(6);
CREATE FUNCTION router_non_partition_column_select(value_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.key = 0 AND
plpgsql_table.value = value_arg
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT router_non_partition_column_select(10);
SELECT router_non_partition_column_select(20);
SELECT router_non_partition_column_select(30);
SELECT router_non_partition_column_select(40);
SELECT router_non_partition_column_select(50);
SELECT router_non_partition_column_select(60);
-- check real-time executor -- check real-time executor
CREATE OR REPLACE FUNCTION non_partition_column_select(value_arg int) RETURNS TABLE(key int, value int) AS $$ CREATE FUNCTION real_time_non_partition_column_select(value_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE DECLARE
BEGIN BEGIN
RETURN QUERY RETURN QUERY
SELECT SELECT
temp_table.key, plpgsql_table.key,
temp_table.value plpgsql_table.value
FROM FROM
temp_table plpgsql_table
WHERE WHERE
temp_table.value = value_arg plpgsql_table.value = value_arg
ORDER BY ORDER BY
key, key,
value; value;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
SELECT non_partition_column_select(10); SELECT real_time_non_partition_column_select(10);
SELECT non_partition_column_select(20); SELECT real_time_non_partition_column_select(20);
SELECT non_partition_column_select(30); SELECT real_time_non_partition_column_select(30);
SELECT non_partition_column_select(40); SELECT real_time_non_partition_column_select(40);
SELECT non_partition_column_select(50); SELECT real_time_non_partition_column_select(50);
-- 6th execution is failing. We don't want to run the failing test because of -- FIXME: 6th execution is failing. We don't want to run the failing test
-- changing output. After implementing this feature, uncomment this. -- because of changing output. After implementing this feature, uncomment this.
-- SELECT partition_column_select(6); -- SELECT real_time_non_partition_column_select(60);
CREATE FUNCTION real_time_partition_column_select(key_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.key = key_arg OR
plpgsql_table.value = 10
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT real_time_partition_column_select(1);
SELECT real_time_partition_column_select(2);
SELECT real_time_partition_column_select(3);
SELECT real_time_partition_column_select(4);
SELECT real_time_partition_column_select(5);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- SELECT real_time_partition_column_select(6);
-- check task-tracker executor
SET citus.task_executor_type TO 'task-tracker';
CREATE FUNCTION task_tracker_non_partition_column_select(value_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.value = value_arg
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT task_tracker_non_partition_column_select(10);
SELECT task_tracker_non_partition_column_select(20);
SELECT task_tracker_non_partition_column_select(30);
SELECT task_tracker_non_partition_column_select(40);
SELECT task_tracker_non_partition_column_select(50);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- SELECT real_time_non_partition_column_select(60);
CREATE FUNCTION task_tracker_partition_column_select(key_arg int)
RETURNS TABLE(key int, value int) AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT
plpgsql_table.key,
plpgsql_table.value
FROM
plpgsql_table
WHERE
plpgsql_table.key = key_arg OR
plpgsql_table.value = 10
ORDER BY
key,
value;
END;
$$ LANGUAGE plpgsql;
SELECT task_tracker_partition_column_select(1);
SELECT task_tracker_partition_column_select(2);
SELECT task_tracker_partition_column_select(3);
SELECT task_tracker_partition_column_select(4);
SELECT task_tracker_partition_column_select(5);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- SELECT task_tracker_partition_column_select(6);
SET citus.task_executor_type TO 'real-time';
-- check updates
CREATE FUNCTION partition_parameter_update(int, int) RETURNS void as $$
BEGIN
UPDATE plpgsql_table SET value = $2 WHERE key = $1;
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT partition_parameter_update(1, 11);
SELECT partition_parameter_update(2, 21);
SELECT partition_parameter_update(3, 31);
SELECT partition_parameter_update(4, 41);
SELECT partition_parameter_update(5, 51);
-- This fails with an unexpected error message
SELECT partition_parameter_update(5, 52);
CREATE FUNCTION non_partition_parameter_update(int, int) RETURNS void as $$
BEGIN
UPDATE plpgsql_table SET value = $2 WHERE key = 0 AND value = $1;
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_update(10, 12);
SELECT non_partition_parameter_update(20, 22);
SELECT non_partition_parameter_update(30, 32);
SELECT non_partition_parameter_update(40, 42);
SELECT non_partition_parameter_update(50, 52);
SELECT non_partition_parameter_update(60, 62);
-- check table after updates
SELECT * FROM plpgsql_table ORDER BY key, value;
-- check deletes
CREATE FUNCTION partition_parameter_delete(int, int) RETURNS void as $$
BEGIN
DELETE FROM plpgsql_table WHERE key = $1 AND value = $2;
END;
$$ LANGUAGE plpgsql;
SELECT partition_parameter_delete(1, 11);
SELECT partition_parameter_delete(2, 21);
SELECT partition_parameter_delete(3, 31);
SELECT partition_parameter_delete(4, 41);
SELECT partition_parameter_delete(5, 51);
-- This fails with an unexpected error message
SELECT partition_parameter_delete(0, 10);
CREATE FUNCTION non_partition_parameter_delete(int) RETURNS void as $$
BEGIN
DELETE FROM plpgsql_table WHERE key = 0 AND value = $1;
END;
$$ LANGUAGE plpgsql;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_delete(12);
SELECT non_partition_parameter_delete(22);
SELECT non_partition_parameter_delete(32);
SELECT non_partition_parameter_delete(42);
SELECT non_partition_parameter_delete(52);
SELECT non_partition_parameter_delete(62);
-- check table after deletes
SELECT * FROM plpgsql_table ORDER BY key, value;
-- clean-up functions -- clean-up functions
DROP FUNCTION sql_test_no_1();
DROP FUNCTION sql_test_no_2();
DROP FUNCTION sql_test_no_3();
DROP FUNCTION sql_test_no_4();
DROP FUNCTION sql_test_no_6(int);
DROP FUNCTION plpgsql_test_1(); DROP FUNCTION plpgsql_test_1();
DROP FUNCTION plpgsql_test_2(); DROP FUNCTION plpgsql_test_2();
DROP FUNCTION plpgsql_test_3(); DROP FUNCTION plpgsql_test_3();
@ -372,5 +508,14 @@ DROP FUNCTION plpgsql_test_7(text, text);
DROP FUNCTION no_parameter_insert(); DROP FUNCTION no_parameter_insert();
DROP FUNCTION single_parameter_insert(int); DROP FUNCTION single_parameter_insert(int);
DROP FUNCTION double_parameter_insert(int, int); DROP FUNCTION double_parameter_insert(int, int);
DROP FUNCTION partition_column_select(int); DROP FUNCTION non_partition_parameter_insert(int);
DROP FUNCTION non_partition_column_select(int); DROP FUNCTION router_partition_column_select(int);
DROP FUNCTION router_non_partition_column_select(int);
DROP FUNCTION real_time_non_partition_column_select(int);
DROP FUNCTION real_time_partition_column_select(int);
DROP FUNCTION task_tracker_non_partition_column_select(int);
DROP FUNCTION task_tracker_partition_column_select(int);
DROP FUNCTION partition_parameter_update(int, int);
DROP FUNCTION non_partition_parameter_update(int, int);
DROP FUNCTION partition_parameter_delete(int, int);
DROP FUNCTION non_partition_parameter_delete(int);

View File

@ -209,5 +209,252 @@ EXECUTE prepared_partition_column_insert(6);
DROP TYPE test_composite_type CASCADE; DROP TYPE test_composite_type CASCADE;
-- test router executor with prepare statements
CREATE TABLE prepare_table (
key int,
value int
);
SELECT master_create_distributed_table('prepare_table','key','hash');
SELECT master_create_worker_shards('prepare_table',4,1);
PREPARE prepared_no_parameter_insert AS
INSERT INTO prepare_table (key) VALUES (0);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
EXECUTE prepared_no_parameter_insert;
PREPARE prepared_single_parameter_insert(int) AS
INSERT INTO prepare_table (key) VALUES ($1);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_single_parameter_insert(1);
EXECUTE prepared_single_parameter_insert(2);
EXECUTE prepared_single_parameter_insert(3);
EXECUTE prepared_single_parameter_insert(4);
EXECUTE prepared_single_parameter_insert(5);
EXECUTE prepared_single_parameter_insert(6);
PREPARE prepared_double_parameter_insert(int, int) AS
INSERT INTO prepare_table (key, value) VALUES ($1, $2);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_double_parameter_insert(1, 10);
EXECUTE prepared_double_parameter_insert(2, 20);
EXECUTE prepared_double_parameter_insert(3, 30);
EXECUTE prepared_double_parameter_insert(4, 40);
EXECUTE prepared_double_parameter_insert(5, 50);
EXECUTE prepared_double_parameter_insert(6, 60);
PREPARE prepared_non_partition_parameter_insert(int) AS
INSERT INTO prepare_table (key, value) VALUES (0, $1);
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_non_partition_parameter_insert(10);
EXECUTE prepared_non_partition_parameter_insert(20);
EXECUTE prepared_non_partition_parameter_insert(30);
EXECUTE prepared_non_partition_parameter_insert(40);
EXECUTE prepared_non_partition_parameter_insert(50);
EXECUTE prepared_non_partition_parameter_insert(60);
-- check inserted values
SELECT * FROM prepare_table ORDER BY key, value;
-- check router executor select
PREPARE prepared_router_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = $1
ORDER BY
key,
value;
EXECUTE prepared_router_partition_column_select(1);
EXECUTE prepared_router_partition_column_select(2);
EXECUTE prepared_router_partition_column_select(3);
EXECUTE prepared_router_partition_column_select(4);
EXECUTE prepared_router_partition_column_select(5);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_router_partition_column_select(6);
PREPARE prepared_router_non_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = 0 AND
prepare_table.value = $1
ORDER BY
key,
value;
EXECUTE prepared_router_non_partition_column_select(10);
EXECUTE prepared_router_non_partition_column_select(20);
EXECUTE prepared_router_non_partition_column_select(30);
EXECUTE prepared_router_non_partition_column_select(40);
EXECUTE prepared_router_non_partition_column_select(50);
EXECUTE prepared_router_non_partition_column_select(60);
-- check real-time executor
PREPARE prepared_real_time_non_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.value = $1
ORDER BY
key,
value;
EXECUTE prepared_real_time_non_partition_column_select(10);
EXECUTE prepared_real_time_non_partition_column_select(20);
EXECUTE prepared_real_time_non_partition_column_select(30);
EXECUTE prepared_real_time_non_partition_column_select(40);
EXECUTE prepared_real_time_non_partition_column_select(50);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_real_time_non_partition_column_select(60);
PREPARE prepared_real_time_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = $1 OR
prepare_table.value = 10
ORDER BY
key,
value;
EXECUTE prepared_real_time_partition_column_select(1);
EXECUTE prepared_real_time_partition_column_select(2);
EXECUTE prepared_real_time_partition_column_select(3);
EXECUTE prepared_real_time_partition_column_select(4);
EXECUTE prepared_real_time_partition_column_select(5);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_real_time_partition_column_select(6);
-- check task-tracker executor
SET citus.task_executor_type TO 'task-tracker';
PREPARE prepared_task_tracker_non_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.value = $1
ORDER BY
key,
value;
EXECUTE prepared_task_tracker_non_partition_column_select(10);
EXECUTE prepared_task_tracker_non_partition_column_select(20);
EXECUTE prepared_task_tracker_non_partition_column_select(30);
EXECUTE prepared_task_tracker_non_partition_column_select(40);
EXECUTE prepared_task_tracker_non_partition_column_select(50);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_task_tracker_non_partition_column_select(60);
PREPARE prepared_task_tracker_partition_column_select(int) AS
SELECT
prepare_table.key,
prepare_table.value
FROM
prepare_table
WHERE
prepare_table.key = $1 OR
prepare_table.value = 10
ORDER BY
key,
value;
EXECUTE prepared_task_tracker_partition_column_select(1);
EXECUTE prepared_task_tracker_partition_column_select(2);
EXECUTE prepared_task_tracker_partition_column_select(3);
EXECUTE prepared_task_tracker_partition_column_select(4);
EXECUTE prepared_task_tracker_partition_column_select(5);
-- FIXME: 6th execution is failing. We don't want to run the failing test
-- because of changing output. After implementing this feature, uncomment this.
-- EXECUTE prepared_task_tracker_partition_column_select(6);
SET citus.task_executor_type TO 'real-time';
-- check updates
PREPARE prepared_partition_parameter_update(int, int) AS
UPDATE prepare_table SET value = $2 WHERE key = $1;
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_partition_parameter_update(1, 11);
EXECUTE prepared_partition_parameter_update(2, 21);
EXECUTE prepared_partition_parameter_update(3, 31);
EXECUTE prepared_partition_parameter_update(4, 41);
EXECUTE prepared_partition_parameter_update(5, 51);
-- This fails with an unexpected error message
EXECUTE prepared_partition_parameter_update(5, 52);
PREPARE prepared_non_partition_parameter_update(int, int) AS
UPDATE prepare_table SET value = $2 WHERE key = 0 AND value = $1;
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_non_partition_parameter_update(10, 12);
EXECUTE prepared_non_partition_parameter_update(20, 22);
EXECUTE prepared_non_partition_parameter_update(30, 32);
EXECUTE prepared_non_partition_parameter_update(40, 42);
EXECUTE prepared_non_partition_parameter_update(50, 52);
EXECUTE prepared_non_partition_parameter_update(60, 62);
-- check after updates
SELECT * FROM prepare_table ORDER BY key, value;
-- check deletes
PREPARE prepared_partition_parameter_delete(int, int) AS
DELETE FROM prepare_table WHERE key = $1 AND value = $2;
EXECUTE prepared_partition_parameter_delete(1, 11);
EXECUTE prepared_partition_parameter_delete(2, 21);
EXECUTE prepared_partition_parameter_delete(3, 31);
EXECUTE prepared_partition_parameter_delete(4, 41);
EXECUTE prepared_partition_parameter_delete(5, 51);
-- This fails with an unexpected error message
EXECUTE prepared_partition_parameter_delete(0, 10);
PREPARE prepared_non_partition_parameter_delete(int) AS
DELETE FROM prepare_table WHERE key = 0 AND value = $1;
-- execute 6 times to trigger prepared statement usage
EXECUTE prepared_non_partition_parameter_delete(12);
EXECUTE prepared_non_partition_parameter_delete(22);
EXECUTE prepared_non_partition_parameter_delete(32);
EXECUTE prepared_non_partition_parameter_delete(42);
EXECUTE prepared_non_partition_parameter_delete(52);
EXECUTE prepared_non_partition_parameter_delete(62);
-- check after deletes
SELECT * FROM prepare_table ORDER BY key, value;
-- clean-up prepared statements -- clean-up prepared statements
DEALLOCATE ALL; DEALLOCATE ALL;

View File

@ -0,0 +1,154 @@
--
-- MULTI_SQL_FUNCTION
--
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 1230000;
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 1230000;
CREATE FUNCTION sql_test_no_1() RETURNS bigint AS '
SELECT
count(*)
FROM
orders;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_2() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_3() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer
WHERE
o_custkey = c_custkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_4() RETURNS bigint AS '
SELECT
count(*)
FROM
orders, customer, lineitem
WHERE
o_custkey = c_custkey AND
o_orderkey = l_orderkey;
' LANGUAGE SQL;
CREATE FUNCTION sql_test_no_6(integer) RETURNS bigint AS $$
SELECT
count(*)
FROM
orders, lineitem
WHERE
o_orderkey = l_orderkey AND
l_suppkey > $1;
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT;
SET citus.task_executor_type TO 'task-tracker';
SET client_min_messages TO INFO;
-- now, run plain SQL functions
SELECT sql_test_no_1();
SELECT sql_test_no_2();
SELECT sql_test_no_3();
SELECT sql_test_no_4();
-- run the tests which do not require re-partition
-- with real-time executor
SET citus.task_executor_type TO 'real-time';
-- now, run plain SQL functions
SELECT sql_test_no_1();
SELECT sql_test_no_2();
-- plain SQL functions with parameters cannot be executed
-- FIXME: temporarily disabled, bad error message - waiting for proper
-- parametrized query support
-- SELECT sql_test_no_6(155);
-- test router executor parameterized sql functions
CREATE TABLE temp_table (
key int,
value int
);
SELECT master_create_distributed_table('temp_table','key','hash');
SELECT master_create_worker_shards('temp_table',4,1);
CREATE FUNCTION no_parameter_insert_sql() RETURNS void AS $$
INSERT INTO temp_table (key) VALUES (0);
$$ LANGUAGE SQL;
-- execute 6 times
SELECT no_parameter_insert_sql();
SELECT no_parameter_insert_sql();
SELECT no_parameter_insert_sql();
SELECT no_parameter_insert_sql();
SELECT no_parameter_insert_sql();
SELECT no_parameter_insert_sql();
CREATE FUNCTION non_partition_parameter_insert_sql(int) RETURNS void AS $$
INSERT INTO temp_table (key, value) VALUES (0, $1);
$$ LANGUAGE SQL;
-- execute 6 times
SELECT non_partition_parameter_insert_sql(10);
SELECT non_partition_parameter_insert_sql(20);
SELECT non_partition_parameter_insert_sql(30);
SELECT non_partition_parameter_insert_sql(40);
SELECT non_partition_parameter_insert_sql(50);
SELECT non_partition_parameter_insert_sql(60);
-- check inserted values
SELECT * FROM temp_table ORDER BY key, value;
-- check updates
CREATE FUNCTION non_partition_parameter_update_sql(int, int) RETURNS void AS $$
UPDATE temp_table SET value = $2 WHERE key = 0 AND value = $1;
$$ LANGUAGE SQL;
-- execute 6 times
SELECT non_partition_parameter_update_sql(10, 12);
SELECT non_partition_parameter_update_sql(20, 22);
SELECT non_partition_parameter_update_sql(30, 32);
SELECT non_partition_parameter_update_sql(40, 42);
SELECT non_partition_parameter_update_sql(50, 52);
SELECT non_partition_parameter_update_sql(60, 62);
-- check after updates
SELECT * FROM temp_table ORDER BY key, value;
-- check deletes
CREATE FUNCTION non_partition_parameter_delete_sql(int) RETURNS void AS $$
DELETE FROM prepare_table WHERE key = 0 AND value = $1;
$$ LANGUAGE SQL;
-- execute 6 times to trigger prepared statement usage
SELECT non_partition_parameter_delete_sql(12);
SELECT non_partition_parameter_delete_sql(22);
SELECT non_partition_parameter_delete_sql(32);
SELECT non_partition_parameter_delete_sql(42);
SELECT non_partition_parameter_delete_sql(52);
SELECT non_partition_parameter_delete_sql(62);
-- check after deletes
SELECT * FROM prepare_table ORDER BY key, value;
DROP TABLE temp_table;
-- clean-up functions
DROP FUNCTION sql_test_no_1();
DROP FUNCTION sql_test_no_2();
DROP FUNCTION sql_test_no_3();
DROP FUNCTION sql_test_no_4();
DROP FUNCTION sql_test_no_6(int);
DROP FUNCTION no_parameter_insert_sql();
DROP FUNCTION non_partition_parameter_insert_sql(int);
DROP FUNCTION non_partition_parameter_update_sql(int, int);
DROP FUNCTION non_partition_parameter_delete_sql(int);