diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c index 78be10b3ddd..a9334b1d081 100644 --- a/src/backend/executor/nodeResult.c +++ b/src/backend/executor/nodeResult.c @@ -144,6 +144,15 @@ ExecResult(ResultState *node) node->rs_checkqual = false; if (!qualResult) { + /* + * CDB: We'll read no more from outer subtree. To keep our + * sibling QEs from being starved, tell source QEs not to clog + * up the pipeline with our never-to-be-consumed data. + */ + PlanState *outerPlan = outerPlanState(node); + if (outerPlan) + ExecSquelchNode(outerPlan); + return NULL; } } diff --git a/src/test/regress/expected/ic.out b/src/test/regress/expected/ic.out index a1ac56ddc1d..72d61867877 100644 --- a/src/test/regress/expected/ic.out +++ b/src/test/regress/expected/ic.out @@ -502,3 +502,28 @@ NOTICE: Success: t (1 row) +-- Use WITH RECURSIVE to construct a one-time filter result node that executed +-- on QD, meanwhile, let the result node has a outer node which contain motion. +-- It's used to test that result node on QD can send a stop message to sender in +-- one-time filter case. +RESET gp_interconnect_snd_queue_depth; +RESET gp_interconnect_queue_depth; +CREATE TABLE recursive_table_ic (a INT) DISTRIBUTED BY (a); +-- Insert enough data so interconnect sender don't quit earlier. +INSERT INTO recursive_table_ic SELECT * FROM generate_series(20, 30000); +WITH RECURSIVE +r(i) AS ( + SELECT 1 +), +y(i) AS ( + SELECT 1 + UNION ALL + SELECT i + 1 FROM y, recursive_table_ic WHERE NOT EXISTS (SELECT * FROM r LIMIT 10) +) +SELECT * FROM y LIMIT 10; + i +--- + 1 +(1 row) + +DROP TABLE recursive_table_ic; diff --git a/src/test/regress/sql/ic.sql b/src/test/regress/sql/ic.sql index dc5dd37eced..40ab7e81e47 100644 --- a/src/test/regress/sql/ic.sql +++ b/src/test/regress/sql/ic.sql @@ -212,3 +212,24 @@ SELECT gp_inject_fault('interconnect_setup_palloc', 'error', 1); SELECT * FROM a; DROP TABLE a; SELECT gp_inject_fault('interconnect_setup_palloc', 'reset', 1); + +-- Use WITH RECURSIVE to construct a one-time filter result node that executed +-- on QD, meanwhile, let the result node has a outer node which contain motion. +-- It's used to test that result node on QD can send a stop message to sender in +-- one-time filter case. +RESET gp_interconnect_snd_queue_depth; +RESET gp_interconnect_queue_depth; +CREATE TABLE recursive_table_ic (a INT) DISTRIBUTED BY (a); +-- Insert enough data so interconnect sender don't quit earlier. +INSERT INTO recursive_table_ic SELECT * FROM generate_series(20, 30000); +WITH RECURSIVE +r(i) AS ( + SELECT 1 +), +y(i) AS ( + SELECT 1 + UNION ALL + SELECT i + 1 FROM y, recursive_table_ic WHERE NOT EXISTS (SELECT * FROM r LIMIT 10) +) +SELECT * FROM y LIMIT 10; +DROP TABLE recursive_table_ic;