postgres.git / summary / log / commit / refs

commit    8bf66dedd88673f94122c3f3337e7d58e561ef4f
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Tue Oct 18 14:44:34 2022 +0000
First released in: 16.0

    Fix confusion about havingQual vs hasHavingQual in planner.
    
    Preprocessing of the HAVING clause will reduce havingQual to NIL
    if the clause is constant-TRUE.  This is one case where that
    convention is rather unfortunate, because "HAVING TRUE" is not at all
    the same as not having any HAVING clause at all.  (Per the SQL spec,
    it still forces the query to be grouped.)  The planner deals with this
    by having a boolean hasHavingQual that records whether havingQual was
    originally nonempty; places that just want to check whether HAVING
    was specified are supposed to consult that.
    
    I found three places that got that wrong.  Fortunately, these could
    only affect cost estimates not correctness.  It'd be hard even
    to demonstrate the errors; for example, the one in allpaths.c would
    only matter in a query that has HAVING TRUE but no GROUP BY and no
    aggregates, which would require a completely variable-free SELECT
    list, making the case probably of only academic interest.  Hence,
    while these are worth fixing before someone copies the incorrect
    coding somewhere more critical, they don't seem worth back-patching.
    I didn't bother trying to devise regression tests, either.
    
    Discussion: https://postgr.es/m/2503888.1666042643@sss.pgh.pa.us


contrib/postgres_fdw/postgres_fdw.c | 4 ++-- src/backend/optimizer/path/allpaths.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index d98709e5e88..8d7500abfbd 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -3357,7 +3357,7 @@ estimate_path_cost_size(PlannerInfo *root, * Get the retrieved_rows and rows estimates. If there are HAVING * quals, account for their selectivity. */ - if (root->parse->havingQual) + if (root->hasHavingQual) { /* Factor in the selectivity of the remotely-checked quals */ retrieved_rows = @@ -3405,7 +3405,7 @@ estimate_path_cost_size(PlannerInfo *root, run_cost += cpu_tuple_cost * numGroups; /* Account for the eval cost of HAVING quals, if any */ - if (root->parse->havingQual) + if (root->hasHavingQual) { QualCost remote_cost; diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 8fc28007f54..4ddaed31a44 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -2575,7 +2575,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, if (parse->hasAggs || parse->groupClause || parse->groupingSets || - parse->havingQual || + root->hasHavingQual || parse->distinctClause || parse->sortClause || has_multiple_baserels(root)) [parent: 997cd15c7c16]