diff --git a/src/backend/distributed/planner/function_call_delegation.c b/src/backend/distributed/planner/function_call_delegation.c index 716c5357c..9ea275035 100644 --- a/src/backend/distributed/planner/function_call_delegation.c +++ b/src/backend/distributed/planner/function_call_delegation.c @@ -313,16 +313,6 @@ TryToDelegateFunctionCall(DistributedPlanningContext *planContext) return NULL; } - if (fromFuncExpr && !IsMultiStatementTransaction()) - { - /* - * For now, let's not push the function from the FROM clause unless it's in a - * multistatement transaction with the forceDelegation flag ON. - */ - ereport(DEBUG2, (errmsg("function from the FROM clause is not pushed"))); - return NULL; - } - /* dissuade the planner from trying a generic plan with parameters */ (void) expression_tree_walker((Node *) funcExpr->args, contain_param_walker, &walkerParamContext); diff --git a/src/test/regress/expected/forcedelegation_functions.out b/src/test/regress/expected/forcedelegation_functions.out index ad3b6cb8e..abfcaced8 100644 --- a/src/test/regress/expected/forcedelegation_functions.out +++ b/src/test/regress/expected/forcedelegation_functions.out @@ -1162,18 +1162,11 @@ SELECT * FROM forcepushdown_schema.test_subquery ORDER BY 1; (5 rows) -- Query with targetList greater than 1 --- Function from FROM clause is not delegated outside of a BEGIN (for now) +-- Function from FROM clause is delegated outside of a BEGIN SELECT 1,2,3 FROM select_data(100); -DEBUG: generating subplan XXX_1 for subquery SELECT data FROM forcepushdown_schema.test_subquery WHERE (data OPERATOR(pg_catalog.=) 100) -CONTEXT: SQL statement "SELECT result FROM forcepushdown_schema.test_subquery WHERE data = - (SELECT data FROM forcepushdown_schema.test_subquery WHERE data = a)" -PL/pgSQL function select_data(integer) line XX at SQL statement -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT result FROM forcepushdown_schema.test_subquery WHERE (data OPERATOR(pg_catalog.=) (SELECT intermediate_result.data FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(data integer))) -CONTEXT: SQL statement "SELECT result FROM forcepushdown_schema.test_subquery WHERE data = - (SELECT data FROM forcepushdown_schema.test_subquery WHERE data = a)" -PL/pgSQL function select_data(integer) line XX at SQL statement +DEBUG: pushing down the function call NOTICE: Result: -1 -CONTEXT: PL/pgSQL function select_data(integer) line XX at RAISE +DETAIL: from localhost:xxxxx ?column? | ?column? | ?column? --------------------------------------------------------------------- 1 | 2 | 3 diff --git a/src/test/regress/expected/multi_mx_function_call_delegation.out b/src/test/regress/expected/multi_mx_function_call_delegation.out index d48f001bf..8192ee35c 100644 --- a/src/test/regress/expected/multi_mx_function_call_delegation.out +++ b/src/test/regress/expected/multi_mx_function_call_delegation.out @@ -630,18 +630,6 @@ PL/pgSQL function mx_call_func(integer,integer) line XX at assignment (1 row) -- test forms we don't distribute -select * from mx_call_func(2, 0); -DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_function_call_delegation.mx_call_dist_table_1 t1 JOIN multi_mx_function_call_delegation.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) -CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_function_call_delegation.mx_call_dist_table_1 t1 join multi_mx_function_call_delegation.mx_call_dist_table_2 t2 on t1.id = t2.id)" -PL/pgSQL function mx_call_func(integer,integer) line XX at assignment -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer -CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_function_call_delegation.mx_call_dist_table_1 t1 join multi_mx_function_call_delegation.mx_call_dist_table_2 t2 on t1.id = t2.id)" -PL/pgSQL function mx_call_func(integer,integer) line XX at assignment - y ---------------------------------------------------------------------- - 29 -(1 row) - select mx_call_func(2, 0) where mx_call_func(0, 2) = 0; DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_function_call_delegation.mx_call_dist_table_1 t1 JOIN multi_mx_function_call_delegation.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_function_call_delegation.mx_call_dist_table_1 t1 join multi_mx_function_call_delegation.mx_call_dist_table_2 t2 on t1.id = t2.id)" @@ -671,6 +659,58 @@ PL/pgSQL function mx_call_func(integer,integer) line XX at assignment 29 | 27 (1 row) +-- regular call in FROM can be pushed down +select * from mx_call_func(2, 0); +DEBUG: pushing down the function call + y +--------------------------------------------------------------------- + 28 +(1 row) + +-- prepared statement with 6 invocations to trigger generic plan +prepare call_func(int, int) as select $1 from mx_call_func($1, $2); +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + -- we do not delegate the call, but do push down the query -- that result in remote execution from workers select mx_call_func(id, 0) from mx_call_dist_table_1; diff --git a/src/test/regress/expected/multi_mx_function_call_delegation_0.out b/src/test/regress/expected/multi_mx_function_call_delegation_0.out index 06a7b320d..9125847b4 100644 --- a/src/test/regress/expected/multi_mx_function_call_delegation_0.out +++ b/src/test/regress/expected/multi_mx_function_call_delegation_0.out @@ -630,18 +630,6 @@ PL/pgSQL function mx_call_func(integer,integer) line XX at assignment (1 row) -- test forms we don't distribute -select * from mx_call_func(2, 0); -DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_function_call_delegation.mx_call_dist_table_1 t1 JOIN multi_mx_function_call_delegation.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) -CONTEXT: SQL statement "SELECT y + (select sum(t1.val + t2.val) from multi_mx_function_call_delegation.mx_call_dist_table_1 t1 join multi_mx_function_call_delegation.mx_call_dist_table_2 t2 on t1.id = t2.id)" -PL/pgSQL function mx_call_func(integer,integer) line XX at assignment -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))) -CONTEXT: SQL statement "SELECT y + (select sum(t1.val + t2.val) from multi_mx_function_call_delegation.mx_call_dist_table_1 t1 join multi_mx_function_call_delegation.mx_call_dist_table_2 t2 on t1.id = t2.id)" -PL/pgSQL function mx_call_func(integer,integer) line XX at assignment - y ---------------------------------------------------------------------- - 29 -(1 row) - select mx_call_func(2, 0) where mx_call_func(0, 2) = 0; DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_function_call_delegation.mx_call_dist_table_1 t1 JOIN multi_mx_function_call_delegation.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: SQL statement "SELECT y + (select sum(t1.val + t2.val) from multi_mx_function_call_delegation.mx_call_dist_table_1 t1 join multi_mx_function_call_delegation.mx_call_dist_table_2 t2 on t1.id = t2.id)" @@ -671,6 +659,58 @@ PL/pgSQL function mx_call_func(integer,integer) line XX at assignment 29 | 27 (1 row) +-- regular call in FROM can be pushed down +select * from mx_call_func(2, 0); +DEBUG: pushing down the function call + y +--------------------------------------------------------------------- + 28 +(1 row) + +-- prepared statement with 6 invocations to trigger generic plan +prepare call_func(int, int) as select $1 from mx_call_func($1, $2); +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + +execute call_func(2, 0); +DEBUG: pushing down the function call + ?column? +--------------------------------------------------------------------- + 2 +(1 row) + -- we do not delegate the call, but do push down the query -- that result in remote execution from workers select mx_call_func(id, 0) from mx_call_dist_table_1; diff --git a/src/test/regress/sql/forcedelegation_functions.sql b/src/test/regress/sql/forcedelegation_functions.sql index 77b171fc1..6f62c41d5 100644 --- a/src/test/regress/sql/forcedelegation_functions.sql +++ b/src/test/regress/sql/forcedelegation_functions.sql @@ -606,8 +606,9 @@ SELECT * FROM forcepushdown_schema.test_subquery ORDER BY 1; -- Query with targetList greater than 1 --- Function from FROM clause is not delegated outside of a BEGIN (for now) +-- Function from FROM clause is delegated outside of a BEGIN SELECT 1,2,3 FROM select_data(100); + BEGIN; -- Function from FROM clause is delegated SELECT 1,2,3 FROM select_data(100); diff --git a/src/test/regress/sql/multi_mx_function_call_delegation.sql b/src/test/regress/sql/multi_mx_function_call_delegation.sql index 206969456..0efcea922 100644 --- a/src/test/regress/sql/multi_mx_function_call_delegation.sql +++ b/src/test/regress/sql/multi_mx_function_call_delegation.sql @@ -274,10 +274,21 @@ select mx_call_func((select x + 1 from mx_call_add(3, 4) x), 2); select mx_call_func(floor(random())::int, 2); -- test forms we don't distribute -select * from mx_call_func(2, 0); select mx_call_func(2, 0) where mx_call_func(0, 2) = 0; select mx_call_func(2, 0), mx_call_func(0, 2); +-- regular call in FROM can be pushed down +select * from mx_call_func(2, 0); + +-- prepared statement with 6 invocations to trigger generic plan +prepare call_func(int, int) as select $1 from mx_call_func($1, $2); +execute call_func(2, 0); +execute call_func(2, 0); +execute call_func(2, 0); +execute call_func(2, 0); +execute call_func(2, 0); +execute call_func(2, 0); + -- we do not delegate the call, but do push down the query -- that result in remote execution from workers select mx_call_func(id, 0) from mx_call_dist_table_1;