--
-- 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_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;
 user_id | counter
---------------------------------------------------------------------
       2 |       5
       3 |       5
       4 |       5
       1 |       4
       2 |       4
(5 rows)

-- 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;
 user_id | max
---------------------------------------------------------------------
       5 |   5
       1 |   4
(2 rows)

-- 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;
 user_id | counter
---------------------------------------------------------------------
       2 |       5
       3 |       5
       4 |       5
       1 |       4
       2 |       4
(5 rows)

-- 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;
 user_id | counter
---------------------------------------------------------------------
       2 |       5
       2 |       5
       3 |       5
       3 |       5
       4 |       5
(5 rows)

-- 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;
 user_id | counter
---------------------------------------------------------------------
       2 |       5
       2 |       5
       3 |       5
       3 |       5
       4 |       5
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       2 |  15
       3 |  15
       4 |  15
       5 |  10
       1 |   7
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       2 |  32
       3 |  32
       4 |  23
       5 |  21
       1 |  15
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       2 |  15
       3 |  15
       4 |  15
       5 |  10
       1 |   7
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       1 |   7
       2 |  15
       3 |  15
       4 |  15
       5 |  10
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       1 |   7
       2 |  15
       3 |  15
       4 |  15
       5 |  10
(5 rows)

-- 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;
 sum
---------------------------------------------------------------------
 141
  94
  87
  76
(4 rows)

-- 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;
 sum
---------------------------------------------------------------------
 135
  87
  85
  69
(4 rows)

-- 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;
 sum
---------------------------------------------------------------------
 135
  87
  85
  69
(4 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       2 | 107
       3 | 101
       5 |  94
       4 |  91
       1 |  62
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       2 | 107
       3 | 101
       5 |  94
       4 |  91
       1 |  62
(5 rows)

-- 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;
 types | sumofeventtype
---------------------------------------------------------------------
     0 |             43
     1 |             42
     2 |             28
     3 |             25
(4 rows)

-- 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;
 types | sumofeventtype
---------------------------------------------------------------------
     0 |             43
     1 |             42
     2 |             28
     3 |             25
(4 rows)

-- 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;
 types | sumofeventtype
---------------------------------------------------------------------
     0 |             43
     1 |             42
     2 |             28
     3 |             25
(4 rows)

-- 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;
 user_id
---------------------------------------------------------------------
       1
       1
       1
       1
       1
(5 rows)

-- 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;
 types | sumofeventtype
---------------------------------------------------------------------
     0 |             43
     1 |             42
     2 |             28
     3 |             25
(4 rows)

-- 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;
 count
---------------------------------------------------------------------
   202
(1 row)

-- 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;
 count
---------------------------------------------------------------------
   202
(1 row)

-- 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;
 user_id
---------------------------------------------------------------------
       6
       6
       6
       6
       6
(5 rows)

-- 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;
 user_id | value_3
---------------------------------------------------------------------
       6 |       5
       6 |       5
       6 |       5
       6 |       5
       6 |       4
(5 rows)

-- 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;
 user_id | value_3_sum
---------------------------------------------------------------------
       4 |          65
       4 |          65
       5 |          64
       5 |          64
       2 |          54
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       2 | 119
       4 | 111
       3 | 100
       5 |  85
       1 |  53
(5 rows)

-- 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;
 user_id | value_3
---------------------------------------------------------------------
       6 |       5
       6 |       5
       6 |       3
       6 |       3
       6 |       3
(5 rows)

-- 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;
 max
---------------------------------------------------------------------
   5
   5
   5
   5
   4
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       0 |  31
       1 |  76
       2 |  99
       3 | 119
       4 |  94
       5 |  57
       6 |  22
(7 rows)

-- 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;
 sum
---------------------------------------------------------------------
  80
  76
  55
  50
  43
(5 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       1 |  20
       1 |  62
       2 |  50
       2 | 107
       3 |  55
       3 | 101
       4 |  50
       4 |  91
       5 |  63
       5 |  94
       6 |  21
       6 |  43
(12 rows)

-- 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;
ERROR:  complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator
-- 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;
ERROR:  complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator
-- 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;
 user_id | sum
---------------------------------------------------------------------
       6 |  43
       1 |  62
       4 |  91
       5 |  94
       3 | 101
       2 | 107
       6 | 241
       1 | 314
       3 | 837
       5 | 869
(10 rows)

-- 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;
 sum  | user_id
---------------------------------------------------------------------
  300 |       1
 1200 |       2
 1155 |       3
  850 |       4
  882 |       5
  210 |       6
(6 rows)

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;
 value_2 | user_id
---------------------------------------------------------------------
       0 |       1
       2 |       1
       3 |       1
       4 |       1
     300 |       1
       0 |       2
       1 |       2
       2 |       2
       3 |       2
       4 |       2
(10 rows)

-- 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;
 sum  | user_id
---------------------------------------------------------------------
  300 |       1
  300 |       1
 1200 |       2
 1200 |       2
 1155 |       3
 1155 |       3
  850 |       4
  850 |       4
  882 |       5
  882 |       5
(10 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       3 | 101
       4 |  91
       5 |  94
       6 |  43
(4 rows)

-- 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;
 user_id | sum
---------------------------------------------------------------------
       1 |  20
       1 |  62
       2 |  50
       2 | 107
       3 |  55
       3 | 101
       4 |  50
       4 |  91
       5 |  63
       5 |  94
       6 |  21
       6 |  43
      22 |   6
      31 |   5
      41 |   4
      42 |   1
      46 |   3
      57 |   2
(18 rows)

-- 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;
 count
---------------------------------------------------------------------
   202
(1 row)

-- 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;
 user_id | value_3
---------------------------------------------------------------------
       6 |       5
       6 |       5
       6 |       3
       6 |       3
       6 |       3
(5 rows)

-- 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;
 count
---------------------------------------------------------------------
  1850
(1 row)

-- we support unions on subqueries without relations through recursive planning
SELECT
  count(*)
FROM
(
  (SELECT user_id FROM users_table)
    UNION ALL
  (SELECT 1)
) b;
 count
---------------------------------------------------------------------
   102
(1 row)

-- 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;
 count
---------------------------------------------------------------------
   102
(1 row)

-- 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;
 user_id | value_3
---------------------------------------------------------------------
       6 |       5
       6 |       5
       6 |       3
       6 |       3
       6 |       3
(5 rows)

-- 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;
 types | sumofeventtype
---------------------------------------------------------------------
     0 |             43
     1 |             42
     2 |             28
     3 |              1
(4 rows)

-- 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;
ERROR:  cannot perform distributed planning on this query because parameterized queries for SQL functions referencing distributed tables are not supported
HINT:  Consider using PL/pgSQL functions instead.
