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.
|
-- 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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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_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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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