mirror of https://github.com/citusdata/citus.git
904 lines
28 KiB
PL/PgSQL
904 lines
28 KiB
PL/PgSQL
--
|
|
-- multi subquery toplevel union queries aims to expand existing subquery pushdown
|
|
-- regression tests to cover more cases
|
|
-- 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.next_shard_id TO 1400000;
|
|
|
|
-- a very simple union query
|
|
SELECT user_id, counter
|
|
FROM (
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (1, 2)
|
|
UNION
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- can use different filters on partition columns
|
|
SELECT *
|
|
FROM (
|
|
SELECT user_id, max(value_2) FROM users_table WHERE user_id = 1 GROUP BY user_id
|
|
UNION ALL
|
|
SELECT user_id, max(value_2) FROM users_table WHERE user_id = 5 GROUP BY user_id
|
|
) user_id
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- a very simple union query with reference table
|
|
SELECT user_id, counter
|
|
FROM (
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (1, 2)
|
|
UNION
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_reference_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- the same query with union all
|
|
SELECT user_id, counter
|
|
FROM (
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (1, 2)
|
|
UNION ALL
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- the same query with union all and reference table
|
|
SELECT user_id, counter
|
|
FROM (
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (1, 2)
|
|
UNION ALL
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_reference_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- the same query with group by
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (1, 2)
|
|
UNION
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
GROUP BY 1
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- the same query with UNION ALL clause
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (1, 2)
|
|
UNION ALL
|
|
SELECT user_id, value_2 % 10 AS counter FROM events_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
GROUP BY 1
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- the same query target list entries shuffled
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT value_2 % 10 AS counter, user_id FROM events_table WHERE event_type IN (1, 2)
|
|
UNION
|
|
SELECT value_2 % 10 AS counter, user_id FROM events_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
GROUP BY 1
|
|
ORDER BY 2 DESC,1
|
|
LIMIT 5;
|
|
|
|
-- same query with GROUP BY
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, value_2 AS counter FROM events_table WHERE event_type IN (1, 2)
|
|
UNION
|
|
SELECT user_id, value_2 AS counter FROM events_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
GROUP BY
|
|
user_id
|
|
--HAVING sum(counter) > 900
|
|
ORDER BY 1,2 DESC LIMIT 5;
|
|
|
|
|
|
-- the same query target list entries shuffled but this time the subqueries target list
|
|
-- is shuffled
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT value_2 AS counter, user_id FROM events_table WHERE event_type IN (1, 2)
|
|
UNION
|
|
SELECT value_2 AS counter, user_id FROM events_table WHERE event_type IN (5, 6)
|
|
) user_id
|
|
GROUP BY
|
|
user_id
|
|
--HAVING sum(counter) > 900
|
|
ORDER BY 1,2 DESC LIMIT 5;
|
|
|
|
|
|
-- similar query this time more subqueries and target list contains a resjunk entry
|
|
SELECT sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 1 GROUP BY user_id HAVING sum(value_2) > 5
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 2 and value_1 < 3 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 3 and value_1 < 4 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 4 and value_1 < 5 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 5 and value_1 < 6 GROUP BY user_id HAVING sum(value_2) > 25
|
|
) user_id
|
|
GROUP BY user_id ORDER BY 1 DESC LIMIT 5;
|
|
|
|
-- similar query this time more subqueries with reference table and target list contains a resjunk entry
|
|
SELECT sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 1 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 2 and value_1 < 3 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_reference_table where value_1 < 3 and value_1 < 4 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 4 and value_1 < 5 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 5 and value_1 < 6 GROUP BY user_id HAVING sum(value_2) > 25
|
|
) user_id
|
|
GROUP BY user_id ORDER BY 1 DESC LIMIT 5;
|
|
|
|
-- similar query as above, with UNION ALL
|
|
SELECT sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 1 GROUP BY user_id HAVING sum(value_2) > 250
|
|
UNION ALL
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 2 and value_1 < 3 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION ALL
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 3 and value_1 < 4 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION ALL
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 4 and value_1 < 5 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION ALL
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 5 and value_1 < 6 GROUP BY user_id HAVING sum(value_2) > 25
|
|
) user_id
|
|
GROUP BY user_id ORDER BY 1 DESC LIMIT 5;
|
|
|
|
-- unions within unions
|
|
SELECT *
|
|
FROM (
|
|
( SELECT user_id,
|
|
sum(counter)
|
|
FROM
|
|
(SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
users_table
|
|
GROUP BY
|
|
user_id
|
|
UNION
|
|
SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
events_table
|
|
GROUP BY
|
|
user_id) user_id_1
|
|
GROUP BY
|
|
user_id)
|
|
UNION
|
|
(SELECT
|
|
user_id, sum(counter)
|
|
FROM
|
|
(SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
users_table
|
|
GROUP BY
|
|
user_id
|
|
UNION
|
|
SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
events_table
|
|
GROUP BY
|
|
user_id) user_id_2
|
|
GROUP BY
|
|
user_id)) AS ftop
|
|
ORDER BY 2 DESC, 1 DESC
|
|
LIMIT 5;
|
|
|
|
-- unions within unions with reference table
|
|
SELECT *
|
|
FROM (
|
|
( SELECT user_id,
|
|
sum(counter)
|
|
FROM
|
|
(SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
users_table
|
|
GROUP BY
|
|
user_id
|
|
UNION
|
|
SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
events_reference_table
|
|
GROUP BY
|
|
user_id) user_id_1
|
|
GROUP BY
|
|
user_id)
|
|
UNION
|
|
(SELECT
|
|
user_id, sum(counter)
|
|
FROM
|
|
(SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
users_table
|
|
GROUP BY
|
|
user_id
|
|
UNION
|
|
SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
events_table
|
|
GROUP BY
|
|
user_id) user_id_2
|
|
GROUP BY
|
|
user_id)) AS ftop
|
|
ORDER BY 2 DESC, 1 DESC
|
|
LIMIT 5;
|
|
|
|
-- top level unions are wrapped into top level aggregations
|
|
SELECT ("final_query"."event_types") as types, count(*) AS sumOfEventType
|
|
FROM
|
|
( SELECT *, random()
|
|
FROM
|
|
( SELECT "t"."user_id", "t"."time", unnest("t"."collected_events") AS "event_types"
|
|
FROM
|
|
( SELECT "t1"."user_id", min("t1"."time") AS "time", array_agg(("t1"."event") ORDER BY TIME ASC, event DESC) AS collected_events
|
|
FROM (
|
|
(SELECT *
|
|
FROM
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 0 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (1, 2)) events_subquery_1)
|
|
UNION
|
|
(SELECT *
|
|
FROM
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 1 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (2, 3) ) events_subquery_2)
|
|
UNION
|
|
(SELECT *
|
|
FROM
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 2 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (4, 5) ) events_subquery_3)
|
|
UNION
|
|
(SELECT *
|
|
FROM
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 3 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (6, 1)) events_subquery_4)) t1
|
|
GROUP BY "t1"."user_id") AS t) "q"
|
|
) as final_query
|
|
GROUP BY types
|
|
ORDER BY types;
|
|
|
|
-- exactly the same query
|
|
-- but wrapper unions are removed from the inner part of the query
|
|
SELECT ("final_query"."event_types") as types, count(*) AS sumOfEventType
|
|
FROM
|
|
(SELECT *, random()
|
|
FROM
|
|
(SELECT
|
|
"t"."user_id", "t"."time", unnest("t"."collected_events") AS "event_types"
|
|
FROM
|
|
(SELECT
|
|
"t1"."user_id", min("t1"."time") AS "time", array_agg(("t1"."event") ORDER BY TIME ASC, event DESC) AS collected_events
|
|
FROM(
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 0 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (1, 2))
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 1 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (2, 3) )
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 2 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (4, 5) )
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 3 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (6, 1))) t1
|
|
GROUP BY "t1"."user_id") AS t) "q"
|
|
) as final_query
|
|
GROUP BY types
|
|
ORDER BY types;
|
|
|
|
-- again excatly the same query with top level wrapper removed
|
|
SELECT ("q"."event_types") as types, count(*) AS sumOfEventType
|
|
FROM
|
|
( SELECT "t"."user_id", "t"."time", unnest("t"."collected_events") AS "event_types"
|
|
FROM
|
|
( SELECT "t1"."user_id", min("t1"."time") AS "time", array_agg(("t1"."event") ORDER BY TIME ASC, event DESC) AS collected_events
|
|
FROM (
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 0 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (1, 2))
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 1 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (2, 3) )
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 2 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (4, 5) )
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 3 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (6, 1))) t1
|
|
GROUP BY "t1"."user_id") AS t) "q"
|
|
GROUP BY types
|
|
ORDER BY types;
|
|
|
|
-- again same query but with only two top level empty queries (i.e., no group bys)
|
|
SELECT *
|
|
FROM
|
|
( SELECT *
|
|
FROM
|
|
( SELECT "t1"."user_id"
|
|
FROM (
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 0 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (1, 2))
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 1 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (2, 3) )
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 2 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (4, 5) )
|
|
UNION
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 3 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (6, 1))) t1
|
|
) AS t) "q"
|
|
ORDER BY 1
|
|
LIMIT 5;
|
|
|
|
-- a very similar query UNION ALL
|
|
SELECT ("q"."event_types") as types, count(*) AS sumOfEventType
|
|
FROM
|
|
( SELECT "t"."user_id", "t"."time", unnest("t"."collected_events") AS "event_types"
|
|
FROM
|
|
( SELECT "t1"."user_id", min("t1"."time") AS "time", array_agg(("t1"."event") ORDER BY TIME ASC, event DESC) AS collected_events
|
|
FROM (
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 0 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (1, 2))
|
|
UNION ALL
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 1 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (2, 3) )
|
|
UNION ALL
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 2 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (4, 5) )
|
|
UNION ALL
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 3 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (6, 1))) t1
|
|
GROUP BY "t1"."user_id") AS t) "q"
|
|
GROUP BY types
|
|
ORDER BY types;
|
|
|
|
-- some UNION ALL queries that are going to be pulled up
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
(
|
|
(SELECT user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT user_id FROM events_table)
|
|
) b;
|
|
|
|
-- some UNION ALL queries that are going to be pulled up with reference table
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
(
|
|
(SELECT user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT user_id FROM events_reference_table)
|
|
) b;
|
|
|
|
-- similar query without top level agg
|
|
SELECT
|
|
user_id
|
|
FROM
|
|
(
|
|
(SELECT user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT user_id FROM events_table)
|
|
) b
|
|
ORDER BY 1 DESC
|
|
LIMIT 5;
|
|
|
|
-- similar query with multiple target list entries
|
|
SELECT
|
|
user_id, value_3
|
|
FROM
|
|
(
|
|
(SELECT value_3, user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table)
|
|
) b
|
|
ORDER BY 1 DESC, 2 DESC
|
|
LIMIT 5;
|
|
|
|
-- similar query group by inside the subqueries
|
|
SELECT
|
|
user_id, value_3_sum
|
|
FROM
|
|
(
|
|
(SELECT sum(value_3) as value_3_sum, user_id FROM users_table GROUP BY user_id)
|
|
UNION ALL
|
|
(SELECT sum(value_3) as value_3_sum, user_id FROM users_table GROUP BY user_id)
|
|
) b
|
|
ORDER BY 2 DESC, 1 DESC
|
|
LIMIT 5;
|
|
|
|
-- similar query top level group by
|
|
SELECT
|
|
user_id, sum(value_3)
|
|
FROM
|
|
(
|
|
(SELECT value_3, user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table)
|
|
) b
|
|
GROUP BY 1
|
|
ORDER BY 2 DESC, 1 DESC
|
|
LIMIT 5;
|
|
|
|
-- a long set operation list
|
|
SELECT
|
|
user_id, value_3
|
|
FROM
|
|
(
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (1, 2))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (2, 3))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (3, 4))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (4, 5))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (5, 6))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (1, 6))
|
|
) b
|
|
ORDER BY 1 DESC, 2 DESC
|
|
LIMIT 5;
|
|
|
|
-- no partition key on the top
|
|
SELECT
|
|
max(value_3)
|
|
FROM
|
|
(
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (1, 2))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (2, 3))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (3, 4))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (4, 5))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (5, 6))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (1, 6))
|
|
) b
|
|
GROUP BY user_id
|
|
ORDER BY 1 DESC
|
|
LIMIT 5;
|
|
|
|
|
|
-- now lets also have some unsupported queries
|
|
|
|
-- group by is not on the partition key, supported through recursive planning
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM events_table GROUP BY user_id
|
|
UNION
|
|
SELECT value_1 as user_id, sum(value_2) AS counter FROM users_table GROUP BY value_1
|
|
) user_id
|
|
GROUP BY user_id
|
|
ORDER BY 1,2;
|
|
|
|
-- partition key is not selected, supported through recursive planning
|
|
SELECT sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 1 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 2 and value_1 < 3 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 3 and value_1 < 4 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table where value_1 < 4 and value_1 < 5 GROUP BY user_id HAVING sum(value_2) > 25
|
|
UNION
|
|
SELECT 2 * user_id, sum(value_2) AS counter FROM users_table where value_1 < 5 and value_1 < 6 GROUP BY user_id HAVING sum(value_2) > 25
|
|
) user_id
|
|
GROUP BY user_id ORDER BY 1 DESC LIMIT 5;
|
|
|
|
-- excepts within unions are supported through recursive planning
|
|
SELECT * FROM
|
|
(
|
|
(
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table GROUP BY user_id
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM events_table GROUP BY user_id
|
|
) user_id_1
|
|
GROUP BY user_id
|
|
)
|
|
UNION
|
|
(
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table GROUP BY user_id
|
|
EXCEPT
|
|
SELECT user_id, sum(value_2) AS counter FROM events_table GROUP BY user_id
|
|
) user_id_2
|
|
GROUP BY user_id)
|
|
) as ftop
|
|
ORDER BY 1,2;
|
|
|
|
-- non-equi join are not supported since there is no equivalence between the partition column
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table GROUP BY user_id
|
|
UNION
|
|
SELECT events_table.user_id, sum(events_table.value_2) AS counter FROM events_table, users_table WHERE users_table.user_id > events_table.user_id GROUP BY 1
|
|
) user_id
|
|
GROUP BY user_id;
|
|
|
|
-- non-equi join also not supported for UNION ALL
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table GROUP BY user_id
|
|
UNION ALL
|
|
SELECT events_table.user_id, sum(events_table.value_2) AS counter FROM events_table, users_table WHERE users_table.user_id > events_table.user_id GROUP BY 1
|
|
) user_id
|
|
GROUP BY user_id;
|
|
|
|
-- joins inside unions are supported -- slightly more comlex than the above
|
|
SELECT * FROM
|
|
(
|
|
(
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table GROUP BY user_id
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM events_table GROUP BY user_id
|
|
) user_id_1
|
|
GROUP BY user_id
|
|
)
|
|
UNION
|
|
(
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table GROUP BY user_id
|
|
UNION
|
|
SELECT events_table.user_id, sum(events_table.value_2) AS counter FROM events_table, users_table WHERE (events_table.user_id = users_table.user_id) GROUP BY events_table.user_id
|
|
) user_id_2
|
|
GROUP BY user_id)
|
|
) as ftop
|
|
ORDER BY 2, 1
|
|
LIMIT 10;
|
|
|
|
-- mix up the joins a bit
|
|
SELECT * FROM
|
|
(
|
|
(
|
|
SELECT sum(users_table.value_2), events_table.user_id
|
|
FROM users_table, events_table
|
|
WHERE users_table.user_id = events_Table.user_id
|
|
GROUP BY events_table.user_id
|
|
)
|
|
UNION
|
|
(
|
|
SELECT sum(users_table.value_2), user_id
|
|
FROM users_table LEFT JOIN events_table USING (user_id)
|
|
GROUP BY user_id
|
|
)
|
|
) ftop
|
|
ORDER BY 2, 1
|
|
LIMIT 10;
|
|
|
|
SELECT * FROM
|
|
(
|
|
(
|
|
SELECT value_2, user_id
|
|
FROM users_table
|
|
)
|
|
UNION
|
|
(
|
|
SELECT sum(users_table.value_2), user_id
|
|
FROM users_table RIGHT JOIN events_table USING (user_id)
|
|
GROUP BY user_id
|
|
)
|
|
) ftop
|
|
ORDER BY 2, 1
|
|
LIMIT 10;
|
|
|
|
-- UNION ALL with joins is supported
|
|
SELECT * FROM
|
|
(
|
|
(
|
|
SELECT sum(users_table.value_2), events_table.user_id
|
|
FROM users_table, events_table
|
|
WHERE users_table.user_id = events_Table.user_id
|
|
GROUP BY events_table.user_id
|
|
)
|
|
UNION ALL
|
|
(
|
|
SELECT sum(users_table.value_2), user_id
|
|
FROM users_table JOIN events_table USING (user_id)
|
|
GROUP BY user_id
|
|
)
|
|
) ftop
|
|
ORDER BY 2, 1
|
|
LIMIT 10;
|
|
|
|
-- offset inside the union
|
|
SELECT user_id, sum(counter)
|
|
FROM (
|
|
SELECT user_id, sum(value_2) AS counter FROM events_table GROUP BY user_id
|
|
UNION
|
|
SELECT user_id, sum(value_2) AS counter FROM users_table GROUP BY user_id ORDER BY user_id OFFSET 4
|
|
) user_id
|
|
GROUP BY user_id
|
|
ORDER BY 1,2;
|
|
|
|
-- lower level union does not return partition key with the other relations
|
|
SELECT *
|
|
FROM (
|
|
( SELECT user_id,
|
|
sum(counter)
|
|
FROM
|
|
(SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
users_table
|
|
GROUP BY
|
|
user_id
|
|
UNION
|
|
SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
events_table
|
|
GROUP BY
|
|
user_id) user_id_1
|
|
GROUP BY
|
|
user_id)
|
|
UNION
|
|
(SELECT
|
|
user_id, sum(counter)
|
|
FROM
|
|
(SELECT
|
|
sum(value_2) AS counter, user_id
|
|
FROM
|
|
users_table
|
|
GROUP BY
|
|
user_id
|
|
UNION
|
|
SELECT
|
|
user_id, sum(value_2) AS counter
|
|
FROM
|
|
events_table
|
|
GROUP BY
|
|
user_id) user_id_2
|
|
GROUP BY
|
|
user_id)) AS ftop
|
|
ORDER BY 1,2;
|
|
|
|
|
|
-- some UNION all queries that are going to be pulled up
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
(
|
|
(SELECT user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT 2 * user_id FROM events_table)
|
|
) b;
|
|
|
|
-- last query does not have partition key
|
|
SELECT
|
|
user_id, value_3
|
|
FROM
|
|
(
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (1, 2))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (2, 3))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (3, 4))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (4, 5))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (5, 6))
|
|
UNION ALL
|
|
(SELECT value_3, value_2 FROM events_table where event_type IN (1, 6))
|
|
) b
|
|
ORDER BY 1 DESC, 2 DESC
|
|
LIMIT 5;
|
|
|
|
-- we allow joins within unions
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
(
|
|
(SELECT user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT users_table.user_id FROM events_table, users_table WHERE events_table.user_id = users_table.user_id)
|
|
) b;
|
|
|
|
-- we support unions on subqueries without relations through recursive planning
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
(
|
|
(SELECT user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT 1)
|
|
) b;
|
|
|
|
-- we support pushing down subqueries without relations through recursive planning
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
(
|
|
(SELECT user_id FROM users_table)
|
|
UNION ALL
|
|
(SELECT (random() * 100)::int)
|
|
) b;
|
|
|
|
-- we support subqueries without relations within a union
|
|
SELECT
|
|
user_id, value_3
|
|
FROM
|
|
(
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (1, 2))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (2, 3))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (3, 4))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (4, 5))
|
|
UNION ALL
|
|
(SELECT value_3, user_id FROM events_table where event_type IN (5, 6))
|
|
UNION ALL
|
|
(SELECT 1, 2)
|
|
) b
|
|
ORDER BY 1 DESC, 2 DESC
|
|
LIMIT 5;
|
|
|
|
-- we support pushing down subqueries without relations through recursive planning
|
|
SELECT ("final_query"."event_types") as types, count(*) AS sumOfEventType
|
|
FROM
|
|
( SELECT *, random()
|
|
FROM
|
|
( SELECT "t"."user_id", "t"."time", unnest("t"."collected_events") AS "event_types"
|
|
FROM
|
|
( SELECT "t1"."user_id", min("t1"."time") AS "time", array_agg(("t1"."event") ORDER BY TIME ASC, event DESC) AS collected_events
|
|
FROM (
|
|
(SELECT *
|
|
FROM
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 0 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (1, 2)) events_subquery_1)
|
|
UNION
|
|
(SELECT *
|
|
FROM
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 1 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (2, 3) ) events_subquery_2)
|
|
UNION
|
|
(SELECT *
|
|
FROM
|
|
(SELECT
|
|
"events"."user_id", "events"."time", 2 AS event
|
|
FROM
|
|
events_table as "events"
|
|
WHERE
|
|
event_type IN (4, 5) ) events_subquery_3)
|
|
UNION
|
|
(SELECT *
|
|
FROM
|
|
(SELECT 1, now(), 3 AS event) events_subquery_4)) t1
|
|
GROUP BY "t1"."user_id") AS t) "q"
|
|
) as final_query
|
|
GROUP BY types
|
|
ORDER BY types;
|
|
|
|
-- Previously this produced a segfault from standard_planner introducing a subquery after we'd called AssignRTEIdentities
|
|
CREATE OR REPLACE FUNCTION users_udf()
|
|
RETURNS TABLE(user_id int)
|
|
AS $$SELECT user_id FROM users_reference_table;$$
|
|
LANGUAGE sql stable;
|
|
|
|
SELECT user_id FROM users_table
|
|
UNION SELECT u.user_id FROM users_table, users_udf() u;
|
|
|
|
DROP TABLE events_reference_table;
|
|
DROP TABLE users_reference_table;
|