\SET VERBOSITY terse
invalid command \SET
SET citus.next_shard_id TO 1513000;
SET citus.shard_replication_factor TO 1;
CREATE SCHEMA mixed_relkind_tests;
SET search_path TO mixed_relkind_tests;
-- ensure that coordinator is added to pg_dist_node
SET client_min_messages TO ERROR;
SELECT 1 FROM master_add_node('localhost', :master_port, groupId => 0);
 ?column?
---------------------------------------------------------------------
        1
(1 row)

RESET client_min_messages;
-- make results consistent
-- create test tables
CREATE TABLE postgres_local_table (a int);
CREATE TABLE partitioned_postgres_local_table(a int) PARTITION BY RANGE(a);
CREATE TABLE partitioned_postgres_local_table_1 PARTITION OF partitioned_postgres_local_table FOR VALUES FROM (0) TO (3);
CREATE TABLE partitioned_postgres_local_table_2 PARTITION OF partitioned_postgres_local_table FOR VALUES FROM (3) TO (1000);
CREATE TABLE reference_table(a int);
SELECT create_reference_table('reference_table');
 create_reference_table
---------------------------------------------------------------------

(1 row)

CREATE VIEW view_on_ref AS SELECT * FROM reference_table;
CREATE TABLE citus_local_table(a int);
SELECT citus_add_local_table_to_metadata('citus_local_table');
 citus_add_local_table_to_metadata
---------------------------------------------------------------------

(1 row)

CREATE VIEW view_on_citus_local AS SELECT * FROM citus_local_table;
CREATE UNLOGGED TABLE unlogged_distributed_table(a int, b int);
SELECT create_distributed_table('unlogged_distributed_table', 'a');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

CREATE TABLE distributed_table(a int);
SELECT create_distributed_table('distributed_table', 'a');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

CREATE VIEW view_on_dist AS SELECT * FROM distributed_table;
CREATE MATERIALIZED VIEW mat_view_on_dist AS SELECT * FROM distributed_table;
CREATE TABLE partitioned_distributed_table(a int, b int) PARTITION BY RANGE(a);
CREATE TABLE partitioned_distributed_table_1 PARTITION OF partitioned_distributed_table FOR VALUES FROM (0) TO (3);
CREATE TABLE partitioned_distributed_table_2 PARTITION OF partitioned_distributed_table FOR VALUES FROM (3) TO (1000);
SELECT create_distributed_table('partitioned_distributed_table', 'a');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

CREATE VIEW view_on_part_dist AS SELECT * FROM partitioned_distributed_table;
CREATE MATERIALIZED VIEW mat_view_on_part_dist AS SELECT * FROM partitioned_distributed_table;
-- and insert some data
INSERT INTO postgres_local_table SELECT * FROM generate_series(0, 5);
INSERT INTO partitioned_postgres_local_table SELECT * FROM generate_series(0, 5);
INSERT INTO reference_table SELECT * FROM generate_series(0, 5);
INSERT INTO citus_local_table SELECT * FROM generate_series(0, 5);
INSERT INTO unlogged_distributed_table SELECT a,a+1 FROM generate_series(0, 5) AS a;
INSERT INTO distributed_table SELECT * FROM generate_series(0, 5);
INSERT INTO partitioned_distributed_table SELECT a,a+1 FROM generate_series(0, 5) AS a;
-- should work
SELECT * FROM partitioned_distributed_table UNION SELECT 1,1 ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(7 rows)

SELECT * FROM partitioned_distributed_table UNION SELECT 1, * FROM postgres_local_table ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 0
 1 | 1
 1 | 2
 1 | 3
 1 | 4
 1 | 5
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(11 rows)

SELECT * FROM partitioned_distributed_table UNION SELECT * FROM unlogged_distributed_table ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(6 rows)

SELECT *, 1 FROM postgres_local_table UNION SELECT * FROM unlogged_distributed_table ORDER BY 1,2;
 a | ?column?
---------------------------------------------------------------------
 0 |        1
 1 |        1
 1 |        2
 2 |        1
 2 |        3
 3 |        1
 3 |        4
 4 |        1
 4 |        5
 5 |        1
 5 |        6
(11 rows)

SELECT * FROM unlogged_distributed_table UNION SELECT 1,1 ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(7 rows)

SELECT 1 UNION SELECT * FROM citus_local_table ORDER BY 1;
 ?column?
---------------------------------------------------------------------
        0
        1
        2
        3
        4
        5
(6 rows)

SELECT * FROM view_on_part_dist UNION SELECT 1,1 ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(7 rows)

SELECT * FROM mat_view_on_part_dist UNION SELECT 1,1 ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 1 | 1
(1 row)

SELECT * FROM view_on_citus_local UNION SELECT 1 ORDER BY 1;
 a
---------------------------------------------------------------------
 0
 1
 2
 3
 4
 5
(6 rows)

SELECT * FROM view_on_dist UNION SELECT 1 ORDER BY 1;
 a
---------------------------------------------------------------------
 0
 1
 2
 3
 4
 5
(6 rows)

SELECT * FROM mat_view_on_dist UNION SELECT 1 ORDER BY 1;
 a
---------------------------------------------------------------------
 1
(1 row)

SET client_min_messages TO DEBUG1;
-- can push down the union in subquery
SELECT * FROM (SELECT * FROM partitioned_distributed_table UNION SELECT * FROM partitioned_distributed_table) AS foo ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(6 rows)

-- cannot push down the subquery, should evaluate subquery by creating a subplan
SELECT COUNT(*) FROM (SELECT b, random() FROM partitioned_distributed_table GROUP BY b) AS foo;
DEBUG:  generating subplan XXX_1 for subquery SELECT b, random() AS random FROM mixed_relkind_tests.partitioned_distributed_table GROUP BY b
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.b, intermediate_result.random FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(b integer, random double precision)) foo
 count
---------------------------------------------------------------------
     6
(1 row)

SELECT * FROM partitioned_distributed_table WHERE b IN (SELECT a FROM postgres_local_table) ORDER BY 1,2;
DEBUG:  generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.postgres_local_table
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT a, b FROM mixed_relkind_tests.partitioned_distributed_table WHERE (b OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer))) ORDER BY a, b
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
(5 rows)

-- can push down the subquery
SELECT * FROM partitioned_distributed_table WHERE a IN (SELECT a FROM distributed_table) ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(6 rows)

SELECT * FROM partitioned_distributed_table WHERE a IN (SELECT a FROM view_on_part_dist) ORDER BY 1,2;
 a | b
---------------------------------------------------------------------
 0 | 1
 1 | 2
 2 | 3
 3 | 4
 4 | 5
 5 | 6
(6 rows)

SELECT * FROM distributed_table WHERE a IN (SELECT a FROM view_on_part_dist) ORDER BY 1;
 a
---------------------------------------------------------------------
 0
 1
 2
 3
 4
 5
(6 rows)

SELECT * FROM view_on_dist WHERE a IN (SELECT a FROM view_on_part_dist) ORDER BY 1;
 a
---------------------------------------------------------------------
 0
 1
 2
 3
 4
 5
(6 rows)

SELECT * FROM view_on_citus_local WHERE a IN (SELECT a FROM reference_table) ORDER BY 1;
 a
---------------------------------------------------------------------
 0
 1
 2
 3
 4
 5
(6 rows)

SELECT COUNT(*) FROM (SELECT a, random() FROM partitioned_distributed_table GROUP BY a) AS foo;
 count
---------------------------------------------------------------------
     6
(1 row)

-- should add (a IS NOT NULL) filters similar to regular distributed tables
RESET client_min_messages;
SELECT public.explain_has_is_not_null(
$$
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_distributed_table SELECT * FROM partitioned_distributed_table;
$$);
 explain_has_is_not_null
---------------------------------------------------------------------
 t
(1 row)

SET client_min_messages TO DEBUG1;
SELECT COUNT(*) FROM partitioned_postgres_local_table JOIN distributed_table ON (true);
DEBUG:  Wrapping relation "partitioned_postgres_local_table" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT NULL::integer AS a FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) partitioned_postgres_local_table_1) partitioned_postgres_local_table JOIN mixed_relkind_tests.distributed_table ON (true))
 count
---------------------------------------------------------------------
    36
(1 row)

SELECT COUNT(*) FROM partitioned_postgres_local_table JOIN partitioned_distributed_table ON (true);
DEBUG:  Wrapping relation "partitioned_postgres_local_table" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT NULL::integer AS a FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) partitioned_postgres_local_table_1) partitioned_postgres_local_table JOIN mixed_relkind_tests.partitioned_distributed_table ON (true))
 count
---------------------------------------------------------------------
    36
(1 row)

SELECT COUNT(*) FROM distributed_table JOIN partitioned_postgres_local_table ON (true);
DEBUG:  Wrapping relation "partitioned_postgres_local_table" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (mixed_relkind_tests.distributed_table JOIN (SELECT NULL::integer AS a FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) partitioned_postgres_local_table_1) partitioned_postgres_local_table ON (true))
 count
---------------------------------------------------------------------
    36
(1 row)

INSERT INTO partitioned_distributed_table SELECT foo.* FROM partitioned_distributed_table AS foo JOIN citus_local_table ON (true);
DEBUG:  distributed INSERT ... SELECT cannot select from distributed tables and local tables at the same time
DEBUG:  Wrapping relation "citus_local_table" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM mixed_relkind_tests.citus_local_table WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT foo.a, foo.b FROM (mixed_relkind_tests.partitioned_distributed_table foo JOIN (SELECT NULL::integer AS a FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) citus_local_table_1) citus_local_table ON (true))
DEBUG:  performing repartitioned INSERT ... SELECT
INSERT INTO partitioned_distributed_table SELECT foo.* FROM distributed_table AS foo JOIN citus_local_table ON (true);
DEBUG:  distributed INSERT ... SELECT cannot select from distributed tables and local tables at the same time
DEBUG:  Wrapping relation "citus_local_table" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM mixed_relkind_tests.citus_local_table WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT foo.a FROM (mixed_relkind_tests.distributed_table foo JOIN (SELECT NULL::integer AS a FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) citus_local_table_1) citus_local_table ON (true))
DEBUG:  performing repartitioned INSERT ... SELECT
INSERT INTO distributed_table SELECT foo.a FROM partitioned_distributed_table AS foo JOIN citus_local_table ON (true);
DEBUG:  distributed INSERT ... SELECT cannot select from distributed tables and local tables at the same time
DEBUG:  Wrapping relation "citus_local_table" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM mixed_relkind_tests.citus_local_table WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT foo.a FROM (mixed_relkind_tests.partitioned_distributed_table foo JOIN (SELECT NULL::integer AS a FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) citus_local_table_1) citus_local_table ON (true))
DEBUG:  performing repartitioned INSERT ... SELECT
SELECT COUNT(*) FROM reference_table LEFT JOIN partitioned_distributed_table ON true;
DEBUG:  recursively planning right side of the left join since the outer side is a recurring rel
DEBUG:  recursively planning distributed relation "partitioned_distributed_table" since it is part of a distributed join node that is outer joined with a recurring rel
DEBUG:  Wrapping relation "partitioned_distributed_table" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT NULL::integer AS "dummy-1" FROM mixed_relkind_tests.partitioned_distributed_table WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (mixed_relkind_tests.reference_table LEFT JOIN (SELECT NULL::integer AS a, NULL::integer AS b FROM (SELECT intermediate_result."dummy-1" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("dummy-1" integer)) partitioned_distributed_table_1) partitioned_distributed_table ON (true))
 count
---------------------------------------------------------------------
   468
(1 row)

-- non-colocated subquery should work
SELECT COUNT(*) FROM
  (SELECT *, random() FROM partitioned_distributed_table) AS foo,
  (SELECT *, random() FROM partitioned_distributed_table) AS bar
WHERE foo.a = bar.b;
DEBUG:  generating subplan XXX_1 for subquery SELECT a, b, random() AS random FROM mixed_relkind_tests.partitioned_distributed_table
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT partitioned_distributed_table.a, partitioned_distributed_table.b, random() AS random FROM mixed_relkind_tests.partitioned_distributed_table) foo, (SELECT intermediate_result.a, intermediate_result.b, intermediate_result.random FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer, random double precision)) bar WHERE (foo.a OPERATOR(pg_catalog.=) bar.b)
 count
---------------------------------------------------------------------
   455
(1 row)

UPDATE partitioned_distributed_table SET b = foo.a FROM citus_local_table AS foo;
DEBUG:  Wrapping relation "citus_local_table" "foo" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET b = foo.a FROM (SELECT foo_1.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo_1) foo
UPDATE partitioned_distributed_table SET b = foo.a FROM postgres_local_table AS foo;
DEBUG:  Wrapping relation "postgres_local_table" "foo" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET b = foo.a FROM (SELECT foo_1.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo_1) foo
UPDATE partitioned_distributed_table SET a = foo.a FROM postgres_local_table AS foo WHERE foo.a = partitioned_distributed_table.a;
DEBUG:  Wrapping relation "postgres_local_table" "foo" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET a = foo.a FROM (SELECT foo_1.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo_1) foo WHERE (foo.a OPERATOR(pg_catalog.=) partitioned_distributed_table.a)
UPDATE partitioned_distributed_table SET a = foo.a FROM citus_local_table AS foo WHERE foo.a = partitioned_distributed_table.a;
DEBUG:  Wrapping relation "citus_local_table" "foo" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET a = foo.a FROM (SELECT foo_1.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo_1) foo WHERE (foo.a OPERATOR(pg_catalog.=) partitioned_distributed_table.a)
-- should fail
UPDATE partitioned_distributed_table SET a = foo.a FROM mat_view_on_part_dist AS foo WHERE foo.a = partitioned_distributed_table.a;
DEBUG:  Wrapping relation "mat_view_on_part_dist" "foo" to a subquery
DEBUG:  generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.mat_view_on_part_dist foo WHERE true
DEBUG:  Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET a = foo.a FROM (SELECT foo_1.a, NULL::integer AS b FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo_1) foo WHERE (foo.a OPERATOR(pg_catalog.=) partitioned_distributed_table.a)
UPDATE partitioned_distributed_table SET a = foo.a FROM partitioned_distributed_table AS foo WHERE foo.a < partitioned_distributed_table.a;
ERROR:  complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
UPDATE partitioned_distributed_table SET a = foo.a FROM distributed_table AS foo WHERE foo.a < partitioned_distributed_table.a;
ERROR:  complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- should work
UPDATE partitioned_distributed_table SET a = foo.a FROM partitioned_distributed_table AS foo WHERE foo.a = partitioned_distributed_table.a;
UPDATE partitioned_distributed_table SET a = foo.a FROM view_on_part_dist AS foo WHERE foo.a = partitioned_distributed_table.a;
UPDATE partitioned_distributed_table SET a = foo.a FROM view_on_dist AS foo WHERE foo.a = partitioned_distributed_table.a;
UPDATE partitioned_distributed_table SET a = foo.a FROM view_on_ref AS foo WHERE foo.a = partitioned_distributed_table.a;
-- JOINs on the distribution key
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN partitioned_distributed_table p2 USING (a);
 count
---------------------------------------------------------------------
  1014
(1 row)

SELECT COUNT(*) FROM unlogged_distributed_table u1 JOIN partitioned_distributed_table p2 USING (a);
 count
---------------------------------------------------------------------
    78
(1 row)

SELECT COUNT(*) FROM partitioned_distributed_table p1 LEFT JOIN partitioned_distributed_table p2 USING (a);
 count
---------------------------------------------------------------------
  1014
(1 row)

-- lateral JOIN
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN LATERAL (SELECT * FROM partitioned_distributed_table p2 WHERE p1.a = p2.a) AS foo ON (true);
 count
---------------------------------------------------------------------
  1014
(1 row)

-- router query
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN partitioned_distributed_table p2 USING (a) WHERE a = 1;
 count
---------------------------------------------------------------------
   169
(1 row)

-- repartition query
SET citus.enable_repartition_joins TO ON;
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN partitioned_distributed_table p2 USING (b) WHERE b = 1;
 count
---------------------------------------------------------------------
     0
(1 row)

SELECT COUNT(*) FROM unlogged_distributed_table u1 JOIN partitioned_distributed_table p2 USING (b) WHERE b = 1;
 count
---------------------------------------------------------------------
     0
(1 row)

RESET citus.enable_repartition_joins;
-- joins with cte's
WITH cte_1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table)
  SELECT COUNT(*) FROM cte_1;
DEBUG:  generating subplan XXX_1 for CTE cte_1: SELECT a, b FROM mixed_relkind_tests.partitioned_distributed_table
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) cte_1
 count
---------------------------------------------------------------------
    78
(1 row)

WITH cte_1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table)
  SELECT COUNT(*) FROM cte_1 JOIN partitioned_distributed_table USING (a);
DEBUG:  generating subplan XXX_1 for CTE cte_1: SELECT a, b FROM mixed_relkind_tests.partitioned_distributed_table
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) cte_1 JOIN mixed_relkind_tests.partitioned_distributed_table USING (a))
 count
---------------------------------------------------------------------
  1014
(1 row)

WITH cte_1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table)
  SELECT COUNT(*) FROM cte_1 JOIN partitioned_distributed_table USING (b);
DEBUG:  generating subplan XXX_1 for CTE cte_1: SELECT a, b FROM mixed_relkind_tests.partitioned_distributed_table
DEBUG:  Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) cte_1 JOIN mixed_relkind_tests.partitioned_distributed_table USING (b))
 count
---------------------------------------------------------------------
  6084
(1 row)

-- multi shard colocated update
UPDATE partitioned_distributed_table dt
SET b = sub1.a + sub2.a
FROM (SELECT * FROM partitioned_distributed_table WHERE b = 1) AS sub1,
     (SELECT * FROM partitioned_distributed_table WHERE b = 2) AS sub2
WHERE sub1.a = sub2.a AND sub1.a = dt.a AND dt.a > 1;
UPDATE unlogged_distributed_table dt
SET b = sub1.a + sub2.a
FROM (SELECT * FROM unlogged_distributed_table WHERE b = 1) AS sub1,
     (SELECT * FROM unlogged_distributed_table WHERE b = 2) AS sub2
WHERE sub1.a = sub2.a AND sub1.a = dt.a AND dt.a > 1;
-- multi shard non-colocated update
WITH cte1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table WHERE b = 1),
     cte2 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table WHERE b = 2)
UPDATE partitioned_distributed_table dt SET b = cte1.a + cte2.a
FROM cte1, cte2 WHERE cte1.a != cte2.a AND cte1.a = dt.a AND dt.a > 1;
DEBUG:  generating subplan XXX_1 for CTE cte1: SELECT a, b FROM mixed_relkind_tests.partitioned_distributed_table WHERE (b OPERATOR(pg_catalog.=) 1)
DEBUG:  generating subplan XXX_2 for CTE cte2: SELECT a, b FROM mixed_relkind_tests.partitioned_distributed_table WHERE (b OPERATOR(pg_catalog.=) 2)
DEBUG:  Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table dt SET b = (cte1.a OPERATOR(pg_catalog.+) cte2.a) FROM (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) cte1, (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) cte2 WHERE ((cte1.a OPERATOR(pg_catalog.<>) cte2.a) AND (cte1.a OPERATOR(pg_catalog.=) dt.a) AND (dt.a OPERATOR(pg_catalog.>) 1))
-- router update with CTE
UPDATE partitioned_distributed_table dt
SET b = sub1.a + sub2.a
FROM (SELECT * FROM partitioned_distributed_table WHERE b = 1) AS sub1,
     (SELECT * FROM partitioned_distributed_table WHERE b = 2) AS sub2
WHERE sub1.a = sub2.a AND sub1.a = dt.a AND dt.a = 1;
-- INSERT .. SELECT via coordinator
RESET client_min_messages;
SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_distributed_table SELECT * FROM partitioned_distributed_table ORDER BY 1,2 LIMIT 5;
$Q$);
                   coordinator_plan
---------------------------------------------------------------------
 Custom Scan (Citus INSERT ... SELECT)
   INSERT/SELECT method: pull to coordinator
   ->  Limit
         ->  Sort
               Sort Key: remote_scan.a, remote_scan.b
               ->  Custom Scan (Citus Adaptive)
                     Task Count: 4
(7 rows)

SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
INSERT INTO unlogged_distributed_table SELECT * FROM partitioned_distributed_table ORDER BY 1,2 LIMIT 5;
$Q$);
                   coordinator_plan
---------------------------------------------------------------------
 Custom Scan (Citus INSERT ... SELECT)
   INSERT/SELECT method: pull to coordinator
   ->  Limit
         ->  Sort
               Sort Key: remote_scan.a, remote_scan.b
               ->  Custom Scan (Citus Adaptive)
                     Task Count: 4
(7 rows)

SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_distributed_table SELECT * FROM distributed_table ORDER BY 1 LIMIT 5;
$Q$);
                coordinator_plan
---------------------------------------------------------------------
 Custom Scan (Citus INSERT ... SELECT)
   INSERT/SELECT method: pull to coordinator
   ->  Limit
         ->  Sort
               Sort Key: remote_scan.a
               ->  Custom Scan (Citus Adaptive)
                     Task Count: 4
(7 rows)

-- INSERT .. SELECT via repartition
SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_distributed_table SELECT a + 1 FROM partitioned_distributed_table;
$Q$);
           coordinator_plan
---------------------------------------------------------------------
 Custom Scan (Citus INSERT ... SELECT)
   INSERT/SELECT method: repartition
   ->  Custom Scan (Citus Adaptive)
         Task Count: 4
(4 rows)

SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
INSERT INTO unlogged_distributed_table SELECT a + 1 FROM partitioned_distributed_table;
$Q$);
           coordinator_plan
---------------------------------------------------------------------
 Custom Scan (Citus INSERT ... SELECT)
   INSERT/SELECT method: repartition
   ->  Custom Scan (Citus Adaptive)
         Task Count: 4
(4 rows)

SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_distributed_table SELECT a + 1 FROM distributed_table;
$Q$);
           coordinator_plan
---------------------------------------------------------------------
 Custom Scan (Citus INSERT ... SELECT)
   INSERT/SELECT method: repartition
   ->  Custom Scan (Citus Adaptive)
         Task Count: 4
(4 rows)

SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
INSERT INTO partitioned_distributed_table SELECT a + 1 FROM unlogged_distributed_table;
$Q$);
           coordinator_plan
---------------------------------------------------------------------
 Custom Scan (Citus INSERT ... SELECT)
   INSERT/SELECT method: repartition
   ->  Custom Scan (Citus Adaptive)
         Task Count: 4
(4 rows)

SET client_min_messages TO DEBUG1;
-- some aggregate queries
SELECT sum(a) FROM partitioned_distributed_table;
 sum
---------------------------------------------------------------------
 195
(1 row)

SELECT ceil(regr_syy(a, b)) FROM partitioned_distributed_table;
 ceil
---------------------------------------------------------------------
  228
(1 row)

SELECT ceil(regr_syy(a, b)) FROM unlogged_distributed_table;
 ceil
---------------------------------------------------------------------
   18
(1 row)

-- pushdown WINDOW
SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
SELECT a, COUNT(*) OVER (PARTITION BY a) FROM partitioned_distributed_table ORDER BY 1,2;
$Q$);
               coordinator_plan
---------------------------------------------------------------------
 Sort
   Sort Key: remote_scan.a, remote_scan.count
   ->  Custom Scan (Citus Adaptive)
         Task Count: 4
(4 rows)

-- pull to coordinator WINDOW
SELECT public.coordinator_plan($Q$
EXPLAIN (COSTS OFF)
SELECT a, COUNT(*) OVER (PARTITION BY a+1) FROM partitioned_distributed_table ORDER BY 1,2;
$Q$);
                  coordinator_plan
---------------------------------------------------------------------
 Sort
   Sort Key: remote_scan.a, (count(*) OVER (?))
   ->  WindowAgg
         ->  Sort
               Sort Key: remote_scan.worker_column_2
               ->  Custom Scan (Citus Adaptive)
                     Task Count: 4
(7 rows)

-- FOR UPDATE
SELECT * FROM partitioned_distributed_table WHERE a = 1 ORDER BY 1,2 FOR UPDATE;
 a | b
---------------------------------------------------------------------
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
 1 | 0
(13 rows)

SELECT * FROM unlogged_distributed_table WHERE a = 1 ORDER BY 1,2 FOR UPDATE;
 a | b
---------------------------------------------------------------------
 1 | 2
(1 row)

VACUUM partitioned_distributed_table;
TRUNCATE partitioned_distributed_table;
SET client_min_messages TO ERROR;
-- drop column followed by SELECT in transaction block
BEGIN;
  ALTER TABLE partitioned_distributed_table DROP COLUMN b CASCADE;
  SELECT * FROM partitioned_distributed_table;
 a
---------------------------------------------------------------------
(0 rows)

COMMIT;
-- cleanup at exit
DROP SCHEMA mixed_relkind_tests CASCADE;
