diff --git a/src/backend/distributed/deparser/ruleutils_13.c b/src/backend/distributed/deparser/ruleutils_13.c index 5c1749c5f..d7e222d53 100644 --- a/src/backend/distributed/deparser/ruleutils_13.c +++ b/src/backend/distributed/deparser/ruleutils_13.c @@ -7306,7 +7306,8 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) /* Reconstruct the columndef list, which is also the aliases */ get_from_clause_coldeflist(rtfunc1, colinfo, context); } - else if (GetRangeTblKind(rte) != CITUS_RTE_SHARD) + else if (GetRangeTblKind(rte) != CITUS_RTE_SHARD || + (rte->alias != NULL && rte->alias->colnames != NIL)) { /* Else print column aliases as needed */ get_column_alias_list(colinfo, context); diff --git a/src/backend/distributed/deparser/ruleutils_14.c b/src/backend/distributed/deparser/ruleutils_14.c index bde8e1b23..9ae1f0a92 100644 --- a/src/backend/distributed/deparser/ruleutils_14.c +++ b/src/backend/distributed/deparser/ruleutils_14.c @@ -7809,7 +7809,8 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) /* Reconstruct the columndef list, which is also the aliases */ get_from_clause_coldeflist(rtfunc1, colinfo, context); } - else if (GetRangeTblKind(rte) != CITUS_RTE_SHARD) + else if (GetRangeTblKind(rte) != CITUS_RTE_SHARD || + (rte->alias != NULL && rte->alias->colnames != NIL)) { /* Else print column aliases as needed */ get_column_alias_list(colinfo, context); diff --git a/src/backend/distributed/deparser/ruleutils_15.c b/src/backend/distributed/deparser/ruleutils_15.c index 307ad4c6a..128442a69 100644 --- a/src/backend/distributed/deparser/ruleutils_15.c +++ b/src/backend/distributed/deparser/ruleutils_15.c @@ -7914,7 +7914,8 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) /* Reconstruct the columndef list, which is also the aliases */ get_from_clause_coldeflist(rtfunc1, colinfo, context); } - else if (GetRangeTblKind(rte) != CITUS_RTE_SHARD) + else if (GetRangeTblKind(rte) != CITUS_RTE_SHARD || + (rte->alias != NULL && rte->alias->colnames != NIL)) { /* Else print column aliases as needed */ get_column_alias_list(colinfo, context); diff --git a/src/test/regress/expected/local_table_join.out b/src/test/regress/expected/local_table_join.out index 99ab23efc..3c2f73393 100644 --- a/src/test/regress/expected/local_table_join.out +++ b/src/test/regress/expected/local_table_join.out @@ -646,15 +646,17 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c 1 (1 row) --- Known bug: #4269 SELECT count(*) FROM distributed_table_composite foo(a,b,c) JOIN postgres_table ON(foo.a > 1) WHERE foo.a IN (SELECT COUNT(*) FROM local_partitioned_table) AND (foo.a = 10 OR foo.b ='text'); DEBUG: generating subplan XXX_1 for subquery SELECT count(*) AS count FROM local_table_join.local_partitioned_table DEBUG: Wrapping relation "distributed_table_composite" "foo" to a subquery DEBUG: generating subplan XXX_2 for subquery SELECT a AS key, b AS value FROM local_table_join.distributed_table_composite foo(a, b, c) WHERE ((a OPERATOR(pg_catalog.>) 1) AND ((a OPERATOR(pg_catalog.=) 10) OR (b OPERATOR(pg_catalog.=) 'text'::text))) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT foo_1.a AS key, foo_1.b AS value, NULL::jsonb AS value_2 FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) foo_1(a, b)) foo(a, b, c) JOIN local_table_join.postgres_table ON ((foo.a OPERATOR(pg_catalog.>) 1))) WHERE ((foo.a OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result.count FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(count bigint))) AND ((foo.a OPERATOR(pg_catalog.=) 10) OR (foo.b OPERATOR(pg_catalog.=) 'text'::text))) -ERROR: column "a" does not exist -CONTEXT: while executing command on localhost:xxxxx + count +--------------------------------------------------------------------- + 0 +(1 row) + -- a unique index on key so dist table should be recursively planned SELECT count(*) FROM postgres_table JOIN distributed_table_pkey USING(key); DEBUG: Wrapping relation "postgres_table" to a subquery diff --git a/src/test/regress/expected/multi_alias.out b/src/test/regress/expected/multi_alias.out new file mode 100644 index 000000000..6d729dc30 --- /dev/null +++ b/src/test/regress/expected/multi_alias.out @@ -0,0 +1,176 @@ +-- +-- MULTI_ALIAS +-- +-- Here we test using various types of aliases for a distributed table +-- Test file is created when fixing #4269 column alias bug +-- +CREATE SCHEMA alias; +SET search_path TO alias; +SET citus.shard_count TO 1; +SET citus.shard_replication_factor TO 1; +SET citus.next_shard_id TO 90630800; +CREATE TABLE alias_test(a int, b int); +SELECT create_distributed_table('alias_test', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO alias_test VALUES (0, 0), (1, 1); +SET citus.log_remote_commands TO on; +SELECT * FROM alias_test; +NOTICE: issuing SELECT a, b FROM alias.alias_test_90630800 alias_test +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b +--------------------------------------------------------------------- + 0 | 0 + 1 | 1 +(2 rows) + +SELECT * FROM alias_test AS alias_test; +NOTICE: issuing SELECT a, b FROM alias.alias_test_90630800 alias_test +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b +--------------------------------------------------------------------- + 0 | 0 + 1 | 1 +(2 rows) + +SELECT * FROM alias_test AS another_name; +NOTICE: issuing SELECT a, b FROM alias.alias_test_90630800 another_name +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b +--------------------------------------------------------------------- + 0 | 0 + 1 | 1 +(2 rows) + +SELECT * FROM alias_test AS alias_test(col1, col2); +NOTICE: issuing SELECT col1, col2 FROM alias.alias_test_90630800 alias_test(col1, col2) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + col1 | col2 +--------------------------------------------------------------------- + 0 | 0 + 1 | 1 +(2 rows) + +SELECT * FROM alias_test AS another_name(col1, col2); +NOTICE: issuing SELECT col1, col2 FROM alias.alias_test_90630800 another_name(col1, col2) +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + col1 | col2 +--------------------------------------------------------------------- + 0 | 0 + 1 | 1 +(2 rows) + +RESET citus.log_remote_commands; +-- test everything on https://github.com/citusdata/citus/issues/4269 +CREATE TABLE test (x int, y int, z int); +INSERT INTO test VALUES (0, 1, 2), (3, 4, 5), (6, 7, 8); +-- on PG works fine +SELECT * FROM test AS t1 (a, b, c) ORDER BY 1; + a | b | c +--------------------------------------------------------------------- + 0 | 1 | 2 + 3 | 4 | 5 + 6 | 7 | 8 +(3 rows) + +SELECT * FROM test AS t1 (a, b, c) WHERE a = 6 ORDER BY 2; + a | b | c +--------------------------------------------------------------------- + 6 | 7 | 8 +(1 row) + +CREATE TABLE test_2 (x int, y int); +INSERT INTO test_2 VALUES (0, 10), (3, 30); +-- on PG works fine +SELECT * + FROM test t1 (a, b, c) JOIN test_2 t2 (a, d) USING (a) + ORDER BY a, d; + a | b | c | d +--------------------------------------------------------------------- + 0 | 1 | 2 | 10 + 3 | 4 | 5 | 30 +(2 rows) + +-- same queries on Citus now also work! +SELECT create_distributed_table('test', 'x'); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$alias.test$$) + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('test_2', 'x'); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$alias.test_2$$) + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SET citus.log_remote_commands TO on; +SELECT * FROM test AS t1 (a, b, c) ORDER BY 1; +NOTICE: issuing SELECT a, b, c FROM alias.test_90630801 t1(a, b, c) ORDER BY a +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b | c +--------------------------------------------------------------------- + 0 | 1 | 2 + 3 | 4 | 5 + 6 | 7 | 8 +(3 rows) + +SELECT * + FROM test t1 (a, b, c) JOIN test_2 t2 (a, d) USING (a) + ORDER BY a, d; +NOTICE: issuing SELECT t1.a, t1.b, t1.c, t2.d FROM (alias.test_90630801 t1(a, b, c) JOIN alias.test_2_90630802 t2(a, d) USING (a)) ORDER BY t1.a, t2.d +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b | c | d +--------------------------------------------------------------------- + 0 | 1 | 2 | 10 + 3 | 4 | 5 | 30 +(2 rows) + +SELECT * FROM test AS t1 (a, b, c) WHERE a = 6 ORDER BY 2; +NOTICE: issuing SELECT a, b, c FROM alias.test_90630801 t1(a, b, c) WHERE (a OPERATOR(pg_catalog.=) 6) ORDER BY b +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b | c +--------------------------------------------------------------------- + 6 | 7 | 8 +(1 row) + +SET citus.enable_fast_path_router_planner TO off; +SELECT * FROM test AS t1 (a, b, c) WHERE a = 6 ORDER BY 2; +NOTICE: issuing SELECT a, b, c FROM alias.test_90630801 t1(a, b, c) WHERE (a OPERATOR(pg_catalog.=) 6) ORDER BY b +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b | c +--------------------------------------------------------------------- + 6 | 7 | 8 +(1 row) + +RESET citus.enable_fast_path_router_planner; +-- outer JOINs go through pushdown planner +SELECT * + FROM test t1 (a, b, c) LEFT JOIN test_2 t2 (a, d) USING (a) + ORDER BY a, d; +NOTICE: issuing SELECT t1.a, t1.b, t1.c, t2.d FROM (alias.test_90630801 t1(a, b, c) LEFT JOIN alias.test_2_90630802 t2(a, d) USING (a)) ORDER BY t1.a, t2.d +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx + a | b | c | d +--------------------------------------------------------------------- + 0 | 1 | 2 | 10 + 3 | 4 | 5 | 30 + 6 | 7 | 8 | +(3 rows) + +RESET citus.log_remote_commands; +DROP SCHEMA alias CASCADE; +NOTICE: drop cascades to 3 other objects +DETAIL: drop cascades to table alias_test +drop cascades to table test +drop cascades to table test_2 diff --git a/src/test/regress/multi_1_schedule b/src/test/regress/multi_1_schedule index c0bc4f1da..2d77023dd 100644 --- a/src/test/regress/multi_1_schedule +++ b/src/test/regress/multi_1_schedule @@ -35,6 +35,7 @@ test: distributed_triggers test: multi_test_catalog_views test: multi_table_ddl +test: multi_alias test: multi_sequence_default test: grant_on_sequence_propagation test: multi_name_lengths diff --git a/src/test/regress/sql/local_table_join.sql b/src/test/regress/sql/local_table_join.sql index d6f305d41..96b51ff69 100644 --- a/src/test/regress/sql/local_table_join.sql +++ b/src/test/regress/sql/local_table_join.sql @@ -173,7 +173,6 @@ SELECT count(*) FROM distributed_table_composite JOIN postgres_table USING(key) WHERE (distributed_table_composite.key > 10 AND distributed_table_composite.key = 20) OR (distributed_table_composite.value = 'text' AND distributed_table_composite.value = 'text'); --- Known bug: #4269 SELECT count(*) FROM distributed_table_composite foo(a,b,c) JOIN postgres_table ON(foo.a > 1) WHERE foo.a IN (SELECT COUNT(*) FROM local_partitioned_table) AND (foo.a = 10 OR foo.b ='text'); diff --git a/src/test/regress/sql/multi_alias.sql b/src/test/regress/sql/multi_alias.sql new file mode 100644 index 000000000..809c7c88e --- /dev/null +++ b/src/test/regress/sql/multi_alias.sql @@ -0,0 +1,66 @@ +-- +-- MULTI_ALIAS +-- +-- Here we test using various types of aliases for a distributed table +-- Test file is created when fixing #4269 column alias bug +-- +CREATE SCHEMA alias; +SET search_path TO alias; +SET citus.shard_count TO 1; +SET citus.shard_replication_factor TO 1; +SET citus.next_shard_id TO 90630800; + +CREATE TABLE alias_test(a int, b int); +SELECT create_distributed_table('alias_test', 'a'); +INSERT INTO alias_test VALUES (0, 0), (1, 1); + +SET citus.log_remote_commands TO on; + +SELECT * FROM alias_test; +SELECT * FROM alias_test AS alias_test; +SELECT * FROM alias_test AS another_name; +SELECT * FROM alias_test AS alias_test(col1, col2); +SELECT * FROM alias_test AS another_name(col1, col2); + +RESET citus.log_remote_commands; + +-- test everything on https://github.com/citusdata/citus/issues/4269 +CREATE TABLE test (x int, y int, z int); +INSERT INTO test VALUES (0, 1, 2), (3, 4, 5), (6, 7, 8); + +-- on PG works fine +SELECT * FROM test AS t1 (a, b, c) ORDER BY 1; +SELECT * FROM test AS t1 (a, b, c) WHERE a = 6 ORDER BY 2; + +CREATE TABLE test_2 (x int, y int); +INSERT INTO test_2 VALUES (0, 10), (3, 30); + +-- on PG works fine +SELECT * + FROM test t1 (a, b, c) JOIN test_2 t2 (a, d) USING (a) + ORDER BY a, d; + +-- same queries on Citus now also work! +SELECT create_distributed_table('test', 'x'); +SELECT create_distributed_table('test_2', 'x'); +SET citus.log_remote_commands TO on; + +SELECT * FROM test AS t1 (a, b, c) ORDER BY 1; + +SELECT * + FROM test t1 (a, b, c) JOIN test_2 t2 (a, d) USING (a) + ORDER BY a, d; + +SELECT * FROM test AS t1 (a, b, c) WHERE a = 6 ORDER BY 2; + +SET citus.enable_fast_path_router_planner TO off; +SELECT * FROM test AS t1 (a, b, c) WHERE a = 6 ORDER BY 2; +RESET citus.enable_fast_path_router_planner; + +-- outer JOINs go through pushdown planner +SELECT * + FROM test t1 (a, b, c) LEFT JOIN test_2 t2 (a, d) USING (a) + ORDER BY a, d; + +RESET citus.log_remote_commands; +DROP SCHEMA alias CASCADE;