From 3bdece19dad997f24dd2ba7e40f11f46de3aeb24 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 13 Jan 2020 19:43:00 +0200 Subject: [PATCH] Fix another crash in JSON/YAML-format EXPLAIN, due to missing Flow. This is similar to commit 51257848, but this time it was a Bitmap Index Scan node that was missing the Flow information. Fix by populating the Flow for Bitmap Index Scans. This class of bugs seem to happen pretty often, so make the explain code more defensives so that it does not crash if this happens again. In both of these bugs, the Flow information is only needed so that we can print the # of segments in the EXPLAIN output. That's not critical, so in production, it seems better to print possible incorrect information than crash. Keep the Assert, though, so that we still catch these in development. Fixes github issue https://github.com/greenplum-db/gpdb/issues/9404. Commit to 6X_STABLE, like the previous issue. Reviewed-by: Georgios Kokolatos Reviewed-by: Ning Yu --- src/backend/commands/explain.c | 19 +++++-- src/backend/optimizer/plan/createplan.c | 7 +++ src/test/regress/expected/explain_format.out | 49 +++++++++++++++++++ .../expected/explain_format_optimizer.out | 40 +++++++++++++++ src/test/regress/sql/explain_format.sql | 10 ++++ 5 files changed, 122 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index d3c23e0bfe..fb4c45f592 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -933,9 +933,22 @@ show_dispatch_info(Slice *slice, ExplainState *es, Plan *plan) fplan = fplan->lefttree; Assert(!IsA(fplan, Motion)); - Assert(fplan->flow); - - if (fplan->flow->flotype == FLOW_SINGLETON) + if (!fplan->flow) + { + /* + * This shouldn't happen, but just in case the planner + * failed to decorate a node with a flow, don't panic + * in production. Not all nodes need to be marked with a + * flow, as long as the Motions, and the nodes immediately + * below a Motion are, so this just leads to incorrect + * information in EXPLAIN output. We'd still like to fix + * such cases, though so Assert so that we catch them + * during development. + */ + Assert(fplan->flow); + segments = 1; + } + else if (fplan->flow->flotype == FLOW_SINGLETON) segments = 1; else segments = fplan->flow->numsegments; diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 028d683735..701c3dfa51 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -2509,6 +2509,13 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, plan->plan_rows = clamp_row_est(ipath->indexselectivity * ipath->path.parent->tuples); plan->plan_width = 0; /* meaningless */ + + /* decorate the node with a Flow node, for EXPLAIN. */ + plan->flow = cdbpathtoplan_create_flow(root, + ipath->path.locus, + ipath->path.parent->relids, + plan); + *qual = get_actual_clauses(ipath->indexclauses); *indexqual = get_actual_clauses(ipath->indexquals); foreach(l, ipath->indexinfo->indpred) diff --git a/src/test/regress/expected/explain_format.out b/src/test/regress/expected/explain_format.out index 4a5e1e92d9..d2361afd00 100644 --- a/src/test/regress/expected/explain_format.out +++ b/src/test/regress/expected/explain_format.out @@ -627,6 +627,55 @@ QUERY PLAN } ] (1 row) +-- Test for similar bug of missing flow with bitmap index scan. +-- (github issue #9404). +CREATE INDEX ss_f1 on SUBSELECT_TBL(f1); +begin; +set local enable_seqscan=off; +set local enable_indexscan=off; +set local enable_bitmapscan=on; +explain (format json, costs off) select * from subselect_tbl where f1 < 10; +QUERY PLAN +[ + { + "Plan": { + "Node Type": "Gather Motion", + "Senders": 3, + "Receivers": 1, + "Slice": 1, + "Segments": 3, + "Gang Type": "primary reader", + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Slice": 1, + "Segments": 3, + "Gang Type": "primary reader", + "Relation Name": "subselect_tbl", + "Alias": "subselect_tbl", + "Recheck Cond": "(f1 < 10)", + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Slice": 1, + "Segments": 3, + "Gang Type": "primary reader", + "Index Name": "ss_f1", + "Index Cond": "(f1 < 10)" + } + ] + } + ] + }, + "Settings": { + "Optimizer": "Postgres query optimizer" + } + } +] +(1 row) +commit; -- Cleanup DROP TABLE boxes; DROP TABLE apples; diff --git a/src/test/regress/expected/explain_format_optimizer.out b/src/test/regress/expected/explain_format_optimizer.out index 0043fe2c94..50690ecf14 100644 --- a/src/test/regress/expected/explain_format_optimizer.out +++ b/src/test/regress/expected/explain_format_optimizer.out @@ -626,6 +626,46 @@ QUERY PLAN } ] (1 row) +-- Test for similar bug of missing flow with bitmap index scan. +-- (github issue #9404). +CREATE INDEX ss_f1 on SUBSELECT_TBL(f1); +begin; +set local enable_seqscan=off; +set local enable_indexscan=off; +set local enable_bitmapscan=on; +explain (format json, costs off) select * from subselect_tbl where f1 < 10; +QUERY PLAN +[ + { + "Plan": { + "Node Type": "Gather Motion", + "Senders": 3, + "Receivers": 1, + "Slice": 1, + "Segments": 3, + "Gang Type": "primary reader", + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Slice": 1, + "Segments": 3, + "Gang Type": "primary reader", + "Scan Direction": "Forward", + "Index Name": "ss_f1", + "Relation Name": "subselect_tbl", + "Alias": "subselect_tbl", + "Index Cond": "(f1 < 10)" + } + ] + }, + "Settings": { + "Optimizer": "Pivotal Optimizer (GPORCA) version 3.87.0" + } + } +] +(1 row) +commit; -- Cleanup DROP TABLE boxes; DROP TABLE apples; diff --git a/src/test/regress/sql/explain_format.sql b/src/test/regress/sql/explain_format.sql index 2b324dbd95..3170c86025 100644 --- a/src/test/regress/sql/explain_format.sql +++ b/src/test/regress/sql/explain_format.sql @@ -111,6 +111,16 @@ explain (format json) SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELEC WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f2 IN (SELECT f1 FROM SUBSELECT_TBL)); +-- Test for similar bug of missing flow with bitmap index scan. +-- (github issue #9404). +CREATE INDEX ss_f1 on SUBSELECT_TBL(f1); +begin; +set local enable_seqscan=off; +set local enable_indexscan=off; +set local enable_bitmapscan=on; +explain (format json, costs off) select * from subselect_tbl where f1 < 10; +commit; + -- Cleanup DROP TABLE boxes; DROP TABLE apples; -- GitLab