mirror of https://github.com/citusdata/citus.git
Merge pull request #820 from citusdata/parameterized_queries_regression_tests
Add regression tests for parameterized queriespull/864/head
commit
a317683046
|
@ -6,47 +6,7 @@
|
|||
-- use prepared statements internally.
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 780000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 780000;
|
||||
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 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 $$
|
||||
CREATE FUNCTION plpgsql_test_1() RETURNS TABLE(count bigint) AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -57,7 +17,7 @@ BEGIN
|
|||
|
||||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -70,7 +30,7 @@ BEGIN
|
|||
|
||||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -83,7 +43,7 @@ BEGIN
|
|||
|
||||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -96,7 +56,7 @@ BEGIN
|
|||
o_orderkey = l_orderkey;
|
||||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -108,7 +68,7 @@ BEGIN
|
|||
l_partkey = c_nationkey;
|
||||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -121,7 +81,7 @@ BEGIN
|
|||
l_suppkey > $1;
|
||||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -177,31 +137,6 @@ END;
|
|||
$$ LANGUAGE plpgsql;
|
||||
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)
|
||||
|
||||
-- now, run PL/pgsql functions
|
||||
SELECT plpgsql_test_1();
|
||||
plpgsql_test_1
|
||||
|
@ -316,23 +251,6 @@ SELECT plpgsql_test_2();
|
|||
-- 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
|
||||
-- FIXME: support
|
||||
-- SELECT sql_test_no_6(155);
|
||||
-- now, run PL/pgsql functions
|
||||
SELECT plpgsql_test_1();
|
||||
plpgsql_test_1
|
||||
|
@ -351,25 +269,25 @@ SELECT plpgsql_test_2();
|
|||
-- SELECT plpgsql_test_6(155);
|
||||
-- SELECT plpgsql_test_6(1555);
|
||||
-- test router executor parameterized PL/pgsql functions
|
||||
CREATE TABLE temp_table (
|
||||
CREATE TABLE plpgsql_table (
|
||||
key 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
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('temp_table',4,1);
|
||||
SELECT master_create_worker_shards('plpgsql_table',4,1);
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE OR REPLACE FUNCTION no_parameter_insert() RETURNS void as $$
|
||||
CREATE FUNCTION no_parameter_insert() RETURNS void as $$
|
||||
BEGIN
|
||||
INSERT INTO temp_table (key) VALUES (0);
|
||||
INSERT INTO plpgsql_table (key) VALUES (0);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
-- execute 6 times to trigger prepared statement usage
|
||||
|
@ -409,9 +327,10 @@ SELECT no_parameter_insert();
|
|||
|
||||
(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
|
||||
INSERT INTO temp_table (key) VALUES (key_arg);
|
||||
INSERT INTO plpgsql_table (key) VALUES (key_arg);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
-- execute 6 times to trigger prepared statement usage
|
||||
|
@ -447,11 +366,12 @@ SELECT single_parameter_insert(5);
|
|||
|
||||
SELECT single_parameter_insert(6);
|
||||
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
|
||||
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
|
||||
INSERT INTO temp_table (key, value) VALUES (key_arg, value_arg);
|
||||
INSERT INTO plpgsql_table (key, value) VALUES (key_arg, value_arg);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
-- execute 6 times to trigger prepared statement usage
|
||||
|
@ -487,12 +407,61 @@ SELECT double_parameter_insert(5, 50);
|
|||
|
||||
SELECT double_parameter_insert(6, 60);
|
||||
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
|
||||
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
|
||||
SELECT * FROM temp_table ORDER BY key, value;
|
||||
SELECT * FROM plpgsql_table ORDER BY key, value;
|
||||
key | value
|
||||
-----+-------
|
||||
0 | 10
|
||||
0 | 20
|
||||
0 | 30
|
||||
0 | 40
|
||||
0 | 50
|
||||
0 | 60
|
||||
0 |
|
||||
0 |
|
||||
0 |
|
||||
|
@ -509,119 +478,570 @@ SELECT * FROM temp_table ORDER BY key, value;
|
|||
4 |
|
||||
5 | 50
|
||||
5 |
|
||||
(16 rows)
|
||||
(22 rows)
|
||||
|
||||
-- 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
temp_table.key,
|
||||
temp_table.value
|
||||
plpgsql_table.key,
|
||||
plpgsql_table.value
|
||||
FROM
|
||||
temp_table
|
||||
plpgsql_table
|
||||
WHERE
|
||||
temp_table.key = key_arg
|
||||
plpgsql_table.key = key_arg
|
||||
ORDER BY
|
||||
key,
|
||||
value;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
SELECT partition_column_select(1);
|
||||
partition_column_select
|
||||
-------------------------
|
||||
SELECT router_partition_column_select(1);
|
||||
router_partition_column_select
|
||||
--------------------------------
|
||||
(1,10)
|
||||
(1,)
|
||||
(2 rows)
|
||||
|
||||
SELECT partition_column_select(2);
|
||||
partition_column_select
|
||||
-------------------------
|
||||
SELECT router_partition_column_select(2);
|
||||
router_partition_column_select
|
||||
--------------------------------
|
||||
(2,20)
|
||||
(2,)
|
||||
(2 rows)
|
||||
|
||||
SELECT partition_column_select(3);
|
||||
partition_column_select
|
||||
-------------------------
|
||||
SELECT router_partition_column_select(3);
|
||||
router_partition_column_select
|
||||
--------------------------------
|
||||
(3,30)
|
||||
(3,)
|
||||
(2 rows)
|
||||
|
||||
SELECT partition_column_select(4);
|
||||
partition_column_select
|
||||
-------------------------
|
||||
SELECT router_partition_column_select(4);
|
||||
router_partition_column_select
|
||||
--------------------------------
|
||||
(4,40)
|
||||
(4,)
|
||||
(2 rows)
|
||||
|
||||
SELECT partition_column_select(5);
|
||||
partition_column_select
|
||||
-------------------------
|
||||
SELECT router_partition_column_select(5);
|
||||
router_partition_column_select
|
||||
--------------------------------
|
||||
(5,50)
|
||||
(5,)
|
||||
(2 rows)
|
||||
|
||||
-- 6th execution is failing. We don't want to run the failing test because of
|
||||
-- changing output. After implementing this feature, uncomment this.
|
||||
-- SELECT partition_column_select(6);
|
||||
-- check real-time executor
|
||||
CREATE OR REPLACE FUNCTION non_partition_column_select(value_arg int) RETURNS TABLE(key int, value int) AS $$
|
||||
-- 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 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
|
||||
temp_table.key,
|
||||
temp_table.value
|
||||
plpgsql_table.key,
|
||||
plpgsql_table.value
|
||||
FROM
|
||||
temp_table
|
||||
plpgsql_table
|
||||
WHERE
|
||||
temp_table.value = value_arg
|
||||
plpgsql_table.key = 0 AND
|
||||
plpgsql_table.value = value_arg
|
||||
ORDER BY
|
||||
key,
|
||||
value;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
SELECT non_partition_column_select(10);
|
||||
non_partition_column_select
|
||||
-----------------------------
|
||||
SELECT router_non_partition_column_select(10);
|
||||
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 row)
|
||||
(2 rows)
|
||||
|
||||
SELECT non_partition_column_select(20);
|
||||
non_partition_column_select
|
||||
-----------------------------
|
||||
SELECT real_time_non_partition_column_select(20);
|
||||
real_time_non_partition_column_select
|
||||
---------------------------------------
|
||||
(0,20)
|
||||
(2,20)
|
||||
(1 row)
|
||||
(2 rows)
|
||||
|
||||
SELECT non_partition_column_select(30);
|
||||
non_partition_column_select
|
||||
-----------------------------
|
||||
SELECT real_time_non_partition_column_select(30);
|
||||
real_time_non_partition_column_select
|
||||
---------------------------------------
|
||||
(0,30)
|
||||
(3,30)
|
||||
(1 row)
|
||||
(2 rows)
|
||||
|
||||
SELECT non_partition_column_select(40);
|
||||
non_partition_column_select
|
||||
-----------------------------
|
||||
SELECT real_time_non_partition_column_select(40);
|
||||
real_time_non_partition_column_select
|
||||
---------------------------------------
|
||||
(0,40)
|
||||
(4,40)
|
||||
(1 row)
|
||||
(2 rows)
|
||||
|
||||
SELECT non_partition_column_select(50);
|
||||
non_partition_column_select
|
||||
-----------------------------
|
||||
SELECT real_time_non_partition_column_select(50);
|
||||
real_time_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 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)
|
||||
|
||||
-- 6th execution is failing. We don't want to run the failing test because of
|
||||
-- changing output. After implementing this feature, uncomment this.
|
||||
-- SELECT partition_column_select(6);
|
||||
SELECT partition_parameter_update(2, 21);
|
||||
partition_parameter_update
|
||||
----------------------------
|
||||
|
||||
(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
|
||||
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_2();
|
||||
DROP FUNCTION plpgsql_test_3();
|
||||
|
@ -632,5 +1052,14 @@ DROP FUNCTION plpgsql_test_7(text, text);
|
|||
DROP FUNCTION no_parameter_insert();
|
||||
DROP FUNCTION single_parameter_insert(int);
|
||||
DROP FUNCTION double_parameter_insert(int, int);
|
||||
DROP FUNCTION partition_column_select(int);
|
||||
DROP FUNCTION non_partition_column_select(int);
|
||||
DROP FUNCTION non_partition_parameter_insert(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);
|
||||
|
|
|
@ -338,5 +338,487 @@ EXECUTE prepared_partition_column_insert(6);
|
|||
ERROR: values given for the partition column must be constants or constant expressions
|
||||
DROP TYPE test_composite_type CASCADE;
|
||||
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
|
||||
DEALLOCATE ALL;
|
||||
|
|
|
@ -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);
|
|
@ -49,6 +49,7 @@ test: multi_utility_statements
|
|||
test: multi_dropped_column_aliases
|
||||
test: multi_binary_master_copy_format
|
||||
test: multi_prepare_sql multi_prepare_plsql
|
||||
test: multi_sql_function
|
||||
|
||||
# ----------
|
||||
# Parallel TPC-H tests to check our distributed execution behavior
|
||||
|
|
|
@ -11,52 +11,7 @@ ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 780000;
|
|||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 780000;
|
||||
|
||||
|
||||
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 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 $$
|
||||
CREATE FUNCTION plpgsql_test_1() RETURNS TABLE(count bigint) AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -68,7 +23,7 @@ BEGIN
|
|||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -82,7 +37,7 @@ BEGIN
|
|||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -96,7 +51,7 @@ BEGIN
|
|||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -110,7 +65,7 @@ BEGIN
|
|||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -123,7 +78,7 @@ BEGIN
|
|||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -137,7 +92,7 @@ BEGIN
|
|||
END;
|
||||
$$ 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
@ -195,12 +150,6 @@ $$ LANGUAGE plpgsql;
|
|||
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();
|
||||
|
||||
-- now, run PL/pgsql functions
|
||||
SELECT plpgsql_test_1();
|
||||
SELECT plpgsql_test_2();
|
||||
|
@ -229,15 +178,6 @@ SELECT plpgsql_test_2();
|
|||
-- 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
|
||||
-- FIXME: support
|
||||
-- SELECT sql_test_no_6(155);
|
||||
|
||||
-- now, run PL/pgsql functions
|
||||
SELECT plpgsql_test_1();
|
||||
SELECT plpgsql_test_2();
|
||||
|
@ -248,16 +188,16 @@ SELECT plpgsql_test_2();
|
|||
-- SELECT plpgsql_test_6(1555);
|
||||
|
||||
-- test router executor parameterized PL/pgsql functions
|
||||
CREATE TABLE temp_table (
|
||||
CREATE TABLE plpgsql_table (
|
||||
key int,
|
||||
value int
|
||||
);
|
||||
SELECT master_create_distributed_table('temp_table','key','hash');
|
||||
SELECT master_create_worker_shards('temp_table',4,1);
|
||||
SELECT master_create_distributed_table('plpgsql_table','key','hash');
|
||||
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
|
||||
INSERT INTO temp_table (key) VALUES (0);
|
||||
INSERT INTO plpgsql_table (key) VALUES (0);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
@ -269,9 +209,10 @@ 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
|
||||
INSERT INTO temp_table (key) VALUES (key_arg);
|
||||
INSERT INTO plpgsql_table (key) VALUES (key_arg);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
@ -283,9 +224,10 @@ SELECT single_parameter_insert(4);
|
|||
SELECT single_parameter_insert(5);
|
||||
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
|
||||
INSERT INTO temp_table (key, value) VALUES (key_arg, value_arg);
|
||||
INSERT INTO plpgsql_table (key, value) VALUES (key_arg, value_arg);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
@ -297,71 +239,265 @@ SELECT double_parameter_insert(4, 40);
|
|||
SELECT double_parameter_insert(5, 50);
|
||||
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
|
||||
SELECT * FROM temp_table ORDER BY key, value;
|
||||
SELECT * FROM plpgsql_table ORDER BY key, value;
|
||||
|
||||
-- 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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
temp_table.key,
|
||||
temp_table.value
|
||||
plpgsql_table.key,
|
||||
plpgsql_table.value
|
||||
FROM
|
||||
temp_table
|
||||
plpgsql_table
|
||||
WHERE
|
||||
temp_table.key = key_arg
|
||||
plpgsql_table.key = key_arg
|
||||
ORDER BY
|
||||
key,
|
||||
value;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT partition_column_select(1);
|
||||
SELECT partition_column_select(2);
|
||||
SELECT partition_column_select(3);
|
||||
SELECT partition_column_select(4);
|
||||
SELECT partition_column_select(5);
|
||||
SELECT router_partition_column_select(1);
|
||||
SELECT router_partition_column_select(2);
|
||||
SELECT router_partition_column_select(3);
|
||||
SELECT router_partition_column_select(4);
|
||||
SELECT router_partition_column_select(5);
|
||||
|
||||
-- 6th execution is failing. We don't want to run the failing test because of
|
||||
-- changing output. After implementing this feature, uncomment this.
|
||||
-- SELECT partition_column_select(6);
|
||||
-- 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 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
|
||||
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
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
temp_table.key,
|
||||
temp_table.value
|
||||
plpgsql_table.key,
|
||||
plpgsql_table.value
|
||||
FROM
|
||||
temp_table
|
||||
plpgsql_table
|
||||
WHERE
|
||||
temp_table.value = value_arg
|
||||
plpgsql_table.value = value_arg
|
||||
ORDER BY
|
||||
key,
|
||||
value;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT non_partition_column_select(10);
|
||||
SELECT non_partition_column_select(20);
|
||||
SELECT non_partition_column_select(30);
|
||||
SELECT non_partition_column_select(40);
|
||||
SELECT non_partition_column_select(50);
|
||||
SELECT real_time_non_partition_column_select(10);
|
||||
SELECT real_time_non_partition_column_select(20);
|
||||
SELECT real_time_non_partition_column_select(30);
|
||||
SELECT real_time_non_partition_column_select(40);
|
||||
SELECT real_time_non_partition_column_select(50);
|
||||
|
||||
-- 6th execution is failing. We don't want to run the failing test because of
|
||||
-- changing output. After implementing this feature, uncomment this.
|
||||
-- SELECT partition_column_select(6);
|
||||
-- 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);
|
||||
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
|
||||
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_2();
|
||||
DROP FUNCTION plpgsql_test_3();
|
||||
|
@ -372,5 +508,14 @@ DROP FUNCTION plpgsql_test_7(text, text);
|
|||
DROP FUNCTION no_parameter_insert();
|
||||
DROP FUNCTION single_parameter_insert(int);
|
||||
DROP FUNCTION double_parameter_insert(int, int);
|
||||
DROP FUNCTION partition_column_select(int);
|
||||
DROP FUNCTION non_partition_column_select(int);
|
||||
DROP FUNCTION non_partition_parameter_insert(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);
|
||||
|
|
|
@ -209,5 +209,252 @@ EXECUTE prepared_partition_column_insert(6);
|
|||
|
||||
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
|
||||
DEALLOCATE ALL;
|
||||
|
|
|
@ -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);
|
Loading…
Reference in New Issue