From bd416ef68f925997ee265b6353b634b208fd2b25 Mon Sep 17 00:00:00 2001 From: Hanefi Onaldi Date: Mon, 30 Sep 2019 14:53:41 +0300 Subject: [PATCH] Fix empty FROM clauses in PG12 --- .../planner/function_call_delegation.c | 29 ++++++++++++++++--- src/test/regress/expected/multi_mx_call.out | 5 ++-- src/test/regress/expected/multi_mx_call_0.out | 6 ++-- .../multi_unsupported_worker_operations.out | 6 ++-- src/test/regress/sql/multi_mx_call.sql | 3 +- .../multi_unsupported_worker_operations.sql | 3 ++ 6 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/backend/distributed/planner/function_call_delegation.c b/src/backend/distributed/planner/function_call_delegation.c index c33f9f79b..2cf2a6c74 100644 --- a/src/backend/distributed/planner/function_call_delegation.c +++ b/src/backend/distributed/planner/function_call_delegation.c @@ -156,24 +156,45 @@ TryToDelegateFunctionCall(Query *query, bool *hasExternParam) if (joinTree->fromlist != NIL) { - /* query has a FROM section */ #if PG_VERSION_NUM >= 120000 - /* in pg12 empty FROMs are represented with an RTE_RESULT */ + /* + * In pg12's planning phase empty FROMs are represented with an RTE_RESULT. + * When we arrive here, standard_planner has already been called which calls + * replace_empty_jointree() which replaces empty fromlist with a list of + * single RTE_RESULT RangleTableRef node. + */ if (list_length(joinTree->fromlist) == 1) { RangeTblRef *reference = linitial(joinTree->fromlist); - RangeTblEntry *rtentry = rt_fetch(reference->rtindex, query->rtable); - if (rtentry->rtekind != RTE_RESULT) + + if (IsA(reference, RangeTblRef)) { + RangeTblEntry *rtentry = rt_fetch(reference->rtindex, query->rtable); + if (rtentry->rtekind != RTE_RESULT) + { + /* e.g. SELECT f() FROM rel */ + return NULL; + } + } + else + { + /* + * e.g. IsA(reference, JoinExpr). This is explicit join expressions + * like INNER JOIN, NATURAL JOIN, ... + */ return NULL; } } else { + /* e.g. SELECT ... FROM rel1, rel2. */ + Assert(list_length(joinTree->fromlist) > 1); return NULL; } #else + + /* query has a FROM section */ return NULL; #endif } diff --git a/src/test/regress/expected/multi_mx_call.out b/src/test/regress/expected/multi_mx_call.out index 55d07c4a2..a45f0e67f 100644 --- a/src/test/regress/expected/multi_mx_call.out +++ b/src/test/regress/expected/multi_mx_call.out @@ -342,13 +342,12 @@ DETAIL: A distributed function is created. To make sure subsequent commands see (1 row) +\set VERBOSITY terse call multi_mx_call.mx_call_proc_raise(2); DEBUG: pushing down the procedure DEBUG: warning -DETAIL: WARNING from localhost:57638 ERROR: error -CONTEXT: while executing command on localhost:57638 -PL/pgSQL function multi_mx_call.mx_call_proc_raise(integer) line 4 at RAISE +\set VERBOSITY default -- Test that we don't propagate to non-metadata worker nodes select stop_metadata_sync_to_node('localhost', :worker_1_port); stop_metadata_sync_to_node diff --git a/src/test/regress/expected/multi_mx_call_0.out b/src/test/regress/expected/multi_mx_call_0.out index f16f2d551..106456139 100644 --- a/src/test/regress/expected/multi_mx_call_0.out +++ b/src/test/regress/expected/multi_mx_call_0.out @@ -263,10 +263,10 @@ select create_distributed_function('mx_call_proc_raise(int)', '$1', 'mx_call_dis ERROR: function "mx_call_proc_raise(int)" does not exist LINE 1: select create_distributed_function('mx_call_proc_raise(int)'... ^ +\set VERBOSITY terse call multi_mx_call.mx_call_proc_raise(2); -ERROR: syntax error at or near "call" -LINE 1: call multi_mx_call.mx_call_proc_raise(2); - ^ +ERROR: syntax error at or near "call" at character 1 +\set VERBOSITY default -- Test that we don't propagate to non-metadata worker nodes select stop_metadata_sync_to_node('localhost', :worker_1_port); stop_metadata_sync_to_node diff --git a/src/test/regress/expected/multi_unsupported_worker_operations.out b/src/test/regress/expected/multi_unsupported_worker_operations.out index 622cb026e..a1ff3db7b 100644 --- a/src/test/regress/expected/multi_unsupported_worker_operations.out +++ b/src/test/regress/expected/multi_unsupported_worker_operations.out @@ -265,11 +265,11 @@ SELECT worker_drop_distributed_table(logicalrelid::regclass::text) FROM pg_dist_ DELETE FROM pg_dist_node; \c - - - :worker_1_port -- DROP TABLE +-- terse verbosity because pg10 has slightly different output +\set VERBOSITY terse DROP TABLE mx_table; ERROR: operation is not allowed on this node -HINT: Connect to the coordinator and run it again. -CONTEXT: SQL statement "SELECT master_remove_distributed_table_metadata_from_workers(v_obj.objid, v_obj.schema_name, v_obj.object_name)" -PL/pgSQL function citus_drop_trigger() line 18 at PERFORM +\set VERBOSITY default SELECT count(*) FROM mx_table; count ------- diff --git a/src/test/regress/sql/multi_mx_call.sql b/src/test/regress/sql/multi_mx_call.sql index 53883b63e..1027c2e5d 100644 --- a/src/test/regress/sql/multi_mx_call.sql +++ b/src/test/regress/sql/multi_mx_call.sql @@ -143,8 +143,9 @@ BEGIN RAISE EXCEPTION 'error'; END;$$; select create_distributed_function('mx_call_proc_raise(int)', '$1', 'mx_call_dist_table_1'); +\set VERBOSITY terse call multi_mx_call.mx_call_proc_raise(2); - +\set VERBOSITY default -- Test that we don't propagate to non-metadata worker nodes select stop_metadata_sync_to_node('localhost', :worker_1_port); diff --git a/src/test/regress/sql/multi_unsupported_worker_operations.sql b/src/test/regress/sql/multi_unsupported_worker_operations.sql index d6f66aba4..10a86ae21 100644 --- a/src/test/regress/sql/multi_unsupported_worker_operations.sql +++ b/src/test/regress/sql/multi_unsupported_worker_operations.sql @@ -154,7 +154,10 @@ DELETE FROM pg_dist_node; \c - - - :worker_1_port -- DROP TABLE +-- terse verbosity because pg10 has slightly different output +\set VERBOSITY terse DROP TABLE mx_table; +\set VERBOSITY default SELECT count(*) FROM mx_table; -- master_drop_distributed_table_metadata