mirror of https://github.com/citusdata/citus.git
313 lines
9.6 KiB
Plaintext
313 lines
9.6 KiB
Plaintext
-- multi subquery pushdown misc aims to test subquery pushdown queries with
|
|
-- (i) Prepared statements
|
|
-- (ii) PL/PGSQL functions
|
|
-- (iii) SQL functions
|
|
-- the tables that are used depends to multi_insert_select_behavioral_analytics_create_table.sql
|
|
-- We don't need shard id sequence here, so commented out to prevent conflicts with concurrent tests
|
|
SET citus.enable_router_execution TO false;
|
|
PREPARE prepared_subquery_1 AS
|
|
SELECT
|
|
user_id,
|
|
user_lastseen,
|
|
array_length(event_array, 1)
|
|
FROM (
|
|
SELECT
|
|
user_id,
|
|
max(u.time) as user_lastseen,
|
|
array_agg(event_type ORDER BY u.time) AS event_array
|
|
FROM (
|
|
SELECT user_id, time
|
|
FROM users_table
|
|
WHERE
|
|
user_id >= 10 AND
|
|
user_id <= 70 AND
|
|
users_table.value_1 > 10 AND users_table.value_1 < 12
|
|
) u LEFT JOIN LATERAL (
|
|
SELECT event_type, time
|
|
FROM events_table
|
|
WHERE user_id = u.user_id AND
|
|
events_table.event_type > 10 AND events_table.event_type < 12
|
|
) t ON true
|
|
GROUP BY user_id
|
|
) AS shard_union
|
|
ORDER BY user_lastseen DESC, user_id;
|
|
EXECUTE prepared_subquery_1;
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
PREPARE prepared_subquery_2(int, int) AS
|
|
SELECT
|
|
user_id,
|
|
user_lastseen,
|
|
array_length(event_array, 1)
|
|
FROM (
|
|
SELECT
|
|
user_id,
|
|
max(u.time) as user_lastseen,
|
|
array_agg(event_type ORDER BY u.time) AS event_array
|
|
FROM (
|
|
SELECT user_id, time
|
|
FROM users_table
|
|
WHERE
|
|
user_id >= $1 AND
|
|
user_id <= $2 AND
|
|
users_table.value_1 > 10 AND users_table.value_1 < 12
|
|
) u LEFT JOIN LATERAL (
|
|
SELECT event_type, time
|
|
FROM events_table
|
|
WHERE user_id = u.user_id AND
|
|
events_table.event_type > 10 AND events_table.event_type < 12
|
|
) t ON true
|
|
GROUP BY user_id
|
|
) AS shard_union
|
|
ORDER BY user_lastseen DESC, user_id;
|
|
-- should be fine with more than five executions
|
|
EXECUTE prepared_subquery_2(10, 70);
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
EXECUTE prepared_subquery_2(10, 70);
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
EXECUTE prepared_subquery_2(10, 70);
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
EXECUTE prepared_subquery_2(10, 70);
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
EXECUTE prepared_subquery_2(10, 70);
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
EXECUTE prepared_subquery_2(10, 70);
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
EXECUTE prepared_subquery_2(10, 70);
|
|
user_id | user_lastseen | array_length
|
|
---------+---------------------------------+--------------
|
|
12 | Sun Jan 19 01:49:20.372688 2014 | 1
|
|
20 | Sat Jan 18 14:25:31.817903 2014 | 1
|
|
42 | Thu Jan 16 07:08:02.651966 2014 | 1
|
|
56 | Tue Jan 14 12:11:47.27375 2014 | 1
|
|
57 | Mon Jan 13 14:53:50.494836 2014 | 1
|
|
65 | Sun Jan 12 03:14:26.810597 2014 | 1
|
|
(6 rows)
|
|
|
|
-- prepared statements with subqueries in WHERE clause
|
|
PREPARE prepared_subquery_3(int, int, int, int, int, int) AS
|
|
SELECT user_id
|
|
FROM users_table
|
|
WHERE user_id IN (SELECT user_id FROM users_table WHERE value_1 >= $4 AND value_1 <= $3)
|
|
AND user_id IN (SELECT user_id FROM users_table WHERE value_1 >= $5 AND value_1 <= $6)
|
|
AND user_id IN (SELECT user_id FROM users_table WHERE value_1 >= $1 AND value_1 <= $2)
|
|
GROUP BY
|
|
user_id
|
|
ORDER BY
|
|
user_id DESC
|
|
LIMIT 5;
|
|
-- enough times (6+) to actually use prepared statements
|
|
EXECUTE prepared_subquery_3(50, 60, 20, 10, 30, 40);
|
|
user_id
|
|
---------
|
|
93
|
|
90
|
|
88
|
|
87
|
|
84
|
|
(5 rows)
|
|
|
|
EXECUTE prepared_subquery_3(50, 60, 20, 10, 30, 40);
|
|
user_id
|
|
---------
|
|
93
|
|
90
|
|
88
|
|
87
|
|
84
|
|
(5 rows)
|
|
|
|
EXECUTE prepared_subquery_3(50, 60, 20, 10, 30, 40);
|
|
user_id
|
|
---------
|
|
93
|
|
90
|
|
88
|
|
87
|
|
84
|
|
(5 rows)
|
|
|
|
EXECUTE prepared_subquery_3(50, 60, 20, 10, 30, 40);
|
|
user_id
|
|
---------
|
|
93
|
|
90
|
|
88
|
|
87
|
|
84
|
|
(5 rows)
|
|
|
|
EXECUTE prepared_subquery_3(50, 60, 20, 10, 30, 40);
|
|
user_id
|
|
---------
|
|
93
|
|
90
|
|
88
|
|
87
|
|
84
|
|
(5 rows)
|
|
|
|
EXECUTE prepared_subquery_3(50, 60, 20, 10, 30, 40);
|
|
user_id
|
|
---------
|
|
93
|
|
90
|
|
88
|
|
87
|
|
84
|
|
(5 rows)
|
|
|
|
CREATE FUNCTION plpgsql_subquery_test(int, int) RETURNS TABLE(count bigint) AS $$
|
|
DECLARE
|
|
BEGIN
|
|
RETURN QUERY
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
users_table
|
|
JOIN
|
|
(SELECT
|
|
ma.user_id, (GREATEST(coalesce(ma.value_4 / 250, 0.0) + GREATEST(1.0))) / 2 AS prob
|
|
FROM
|
|
users_table AS ma, events_table as short_list
|
|
WHERE
|
|
short_list.user_id = ma.user_id and ma.value_1 < $1 and short_list.event_type < 50
|
|
) temp
|
|
ON users_table.user_id = temp.user_id
|
|
WHERE
|
|
users_table.value_1 < $2;
|
|
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
-- enough times (6+) to actually use prepared statements
|
|
SELECT plpgsql_subquery_test(10, 20);
|
|
plpgsql_subquery_test
|
|
-----------------------
|
|
1500
|
|
(1 row)
|
|
|
|
SELECT plpgsql_subquery_test(10, 20);
|
|
plpgsql_subquery_test
|
|
-----------------------
|
|
1500
|
|
(1 row)
|
|
|
|
SELECT plpgsql_subquery_test(10, 20);
|
|
plpgsql_subquery_test
|
|
-----------------------
|
|
1500
|
|
(1 row)
|
|
|
|
SELECT plpgsql_subquery_test(10, 20);
|
|
plpgsql_subquery_test
|
|
-----------------------
|
|
1500
|
|
(1 row)
|
|
|
|
SELECT plpgsql_subquery_test(10, 20);
|
|
plpgsql_subquery_test
|
|
-----------------------
|
|
1500
|
|
(1 row)
|
|
|
|
SELECT plpgsql_subquery_test(10, 20);
|
|
plpgsql_subquery_test
|
|
-----------------------
|
|
1500
|
|
(1 row)
|
|
|
|
-- this should also work, but should return 0 given that int = NULL is always returns false
|
|
SELECT plpgsql_subquery_test(10, NULL);
|
|
plpgsql_subquery_test
|
|
-----------------------
|
|
0
|
|
(1 row)
|
|
|
|
CREATE FUNCTION sql_subquery_test(int, int) RETURNS bigint AS $$
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
users_table
|
|
JOIN
|
|
(SELECT
|
|
ma.user_id, (GREATEST(coalesce(ma.value_4 / 250, 0.0) + GREATEST(1.0))) / 2 AS prob
|
|
FROM
|
|
users_table AS ma, events_table as short_list
|
|
WHERE
|
|
short_list.user_id = ma.user_id and ma.value_1 < $1 and short_list.event_type < 50
|
|
) temp
|
|
ON users_table.user_id = temp.user_id
|
|
WHERE
|
|
users_table.value_1 < $2;
|
|
$$ LANGUAGE SQL;
|
|
-- should error out
|
|
SELECT sql_subquery_test(5,5);
|
|
ERROR: could not create distributed plan
|
|
DETAIL: Possibly this is caused by the use of parameters in SQL functions, which is not supported in Citus.
|
|
HINT: Consider using PL/pgSQL functions instead.
|
|
CONTEXT: SQL function "sql_subquery_test" statement 1
|
|
DROP FUNCTION plpgsql_subquery_test(int, int);
|
|
DROP FUNCTION sql_subquery_test(int, int);
|