diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2024-12-19 17:02:25 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2024-12-19 17:02:25 -0500 |
commit | 8d96f57d5cc79c0c51050bb707c19bf07d2895eb (patch) | |
tree | 6d67ac0e73bee8d2d7fc9c977f3539fbc0430a46 /src/backend/optimizer/plan/planner.c | |
parent | 27627929528e24a547d1058a5444b35491057a56 (diff) | |
download | postgresql-8d96f57d5cc79c0c51050bb707c19bf07d2895eb.tar.gz postgresql-8d96f57d5cc79c0c51050bb707c19bf07d2895eb.zip |
Improve planner's handling of SetOp plans.
Remove the code for inserting flag columns in the inputs of a SetOp.
That was the only reason why there would be resjunk columns in a
set-operations plan tree, so we can get rid of some code that
supported that, too.
Get rid of choose_hashed_setop() in favor of building Paths for
the hashed and sorted alternatives, and letting them fight it out
within add_path().
Remove set_operation_ordered_results_useful(), which was giving wrong
answers due to examining the wrong ancestor node: we need to examine
the immediate SetOperationStmt parent not the topmost node. Instead
make each caller of recurse_set_operations() pass down the relevant
parent node. (This thinko seems to have led only to wasted planning
cycles and possibly-inferior plans, not wrong query answers. Perhaps
we should back-patch it, but I'm not doing so right now.)
Teach generate_nonunion_paths() to consider pre-sorted inputs for
sorted SetOps, rather than always generating a Sort node.
Patch by me; thanks to Richard Guo and David Rowley for review.
Discussion: https://postgr.es/m/1850138.1731549611@sss.pgh.pa.us
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index f3856c519f6..7468961b017 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -616,7 +616,7 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, * setops is used for set operation subqueries to provide the subquery with * the context in which it's being used so that Paths correctly sorted for the * set operation can be generated. NULL when not planning a set operation - * child. + * child, or when a child of a set op that isn't interested in sorted input. * * Basically, this routine does the stuff that should only be done once * per Query object. It then calls grouping_planner. At one time, @@ -1350,7 +1350,7 @@ preprocess_phv_expression(PlannerInfo *root, Expr *expr) * setops is used for set operation subqueries to provide the subquery with * the context in which it's being used so that Paths correctly sorted for the * set operation can be generated. NULL when not planning a set operation - * child. + * child, or when a child of a set op that isn't interested in sorted input. * * Returns nothing; the useful output is in the Paths we attach to the * (UPPERREL_FINAL, NULL) upperrel in *root. In addition, @@ -3467,8 +3467,7 @@ standard_qp_callback(PlannerInfo *root, void *extra) tlist); /* setting setop_pathkeys might be useful to the union planner */ - if (qp_extra->setop != NULL && - set_operation_ordered_results_useful(qp_extra->setop)) + if (qp_extra->setop != NULL) { List *groupClauses; bool sortable; |