diff options
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index d3d1e485bb2..c2918c9c831 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -322,10 +322,10 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, } /* - * If we matched the var to a unique index or DISTINCT clause, assume - * there is exactly one match regardless of anything else. (This is - * slightly bogus, since the index or clause's equality operator might be - * different from ours, but it's much more likely to be right than + * If we matched the var to a unique index, DISTINCT or GROUP-BY clause, + * assume there is exactly one match regardless of anything else. (This + * is slightly bogus, since the index or clause's equality operator might + * be different from ours, but it's much more likely to be right than * ignoring the information.) */ if (vardata->isunique && vardata->rel && vardata->rel->tuples >= 1.0) @@ -484,10 +484,10 @@ var_eq_non_const(VariableStatData *vardata, Oid oproid, Oid collation, } /* - * If we matched the var to a unique index or DISTINCT clause, assume - * there is exactly one match regardless of anything else. (This is - * slightly bogus, since the index or clause's equality operator might be - * different from ours, but it's much more likely to be right than + * If we matched the var to a unique index, DISTINCT or GROUP-BY clause, + * assume there is exactly one match regardless of anything else. (This + * is slightly bogus, since the index or clause's equality operator might + * be different from ours, but it's much more likely to be right than * ignoring the information.) */ if (vardata->isunique && vardata->rel && vardata->rel->tuples >= 1.0) @@ -5018,11 +5018,11 @@ ReleaseDummy(HeapTuple tuple) * atttype, atttypmod: actual type/typmod of the "var" expression. This is * commonly the same as the exposed type of the variable argument, * but can be different in binary-compatible-type cases. - * isunique: true if we were able to match the var to a unique index or a - * single-column DISTINCT clause, implying its values are unique for - * this query. (Caution: this should be trusted for statistical - * purposes only, since we do not check indimmediate nor verify that - * the exact same definition of equality applies.) + * isunique: true if we were able to match the var to a unique index, a + * single-column DISTINCT or GROUP-BY clause, implying its values are + * unique for this query. (Caution: this should be trusted for + * statistical purposes only, since we do not check indimmediate nor + * verify that the exact same definition of equality applies.) * acl_ok: true if current user has permission to read the column(s) * underlying the pg_statistic entry. This is consulted by * statistic_proc_security_check(). @@ -5680,15 +5680,14 @@ examine_simple_variable(PlannerInfo *root, Var *var, Assert(IsA(subquery, Query)); /* - * Punt if subquery uses set operations or GROUP BY, as these will - * mash underlying columns' stats beyond recognition. (Set ops are - * particularly nasty; if we forged ahead, we would return stats + * Punt if subquery uses set operations or grouping sets, as these + * will mash underlying columns' stats beyond recognition. (Set ops + * are particularly nasty; if we forged ahead, we would return stats * relevant to only the leftmost subselect...) DISTINCT is also * problematic, but we check that later because there is a possibility * of learning something even with it. */ if (subquery->setOperations || - subquery->groupClause || subquery->groupingSets) return; @@ -5718,6 +5717,16 @@ examine_simple_variable(PlannerInfo *root, Var *var, return; } + /* The same idea as with DISTINCT clause works for a GROUP-BY too */ + if (subquery->groupClause) + { + if (list_length(subquery->groupClause) == 1 && + targetIsInSortList(ste, InvalidOid, subquery->groupClause)) + vardata->isunique = true; + /* cannot go further */ + return; + } + /* * If the sub-query originated from a view with the security_barrier * attribute, we must not look at the variable's statistics, though it @@ -5869,11 +5878,11 @@ get_variable_numdistinct(VariableStatData *vardata, bool *isdefault) } /* - * If there is a unique index or DISTINCT clause for the variable, assume - * it is unique no matter what pg_statistic says; the statistics could be - * out of date, or we might have found a partial unique index that proves - * the var is unique for this query. However, we'd better still believe - * the null-fraction statistic. + * If there is a unique index, DISTINCT or GROUP-BY clause for the + * variable, assume it is unique no matter what pg_statistic says; the + * statistics could be out of date, or we might have found a partial + * unique index that proves the var is unique for this query. However, + * we'd better still believe the null-fraction statistic. */ if (vardata->isunique) stadistinct = -1.0 * (1.0 - stanullfrac); |