@@ -322,10 +322,10 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation,
322322 }
323323
324324 /*
325- * If we matched the var to a unique index or DISTINCT clause, assume
326- * there is exactly one match regardless of anything else. (This is
327- * slightly bogus, since the index or clause's equality operator might be
328- * different from ours, but it's much more likely to be right than
325+ * If we matched the var to a unique index, DISTINCT or GROUP-BY clause,
326+ * assume there is exactly one match regardless of anything else. (This
327+ * is slightly bogus, since the index or clause's equality operator might
328+ * be different from ours, but it's much more likely to be right than
329329 * ignoring the information.)
330330 */
331331 if (vardata -> isunique && vardata -> rel && vardata -> rel -> tuples >= 1.0 )
@@ -484,10 +484,10 @@ var_eq_non_const(VariableStatData *vardata, Oid oproid, Oid collation,
484484 }
485485
486486 /*
487- * If we matched the var to a unique index or DISTINCT clause, assume
488- * there is exactly one match regardless of anything else. (This is
489- * slightly bogus, since the index or clause's equality operator might be
490- * different from ours, but it's much more likely to be right than
487+ * If we matched the var to a unique index, DISTINCT or GROUP-BY clause,
488+ * assume there is exactly one match regardless of anything else. (This
489+ * is slightly bogus, since the index or clause's equality operator might
490+ * be different from ours, but it's much more likely to be right than
491491 * ignoring the information.)
492492 */
493493 if (vardata -> isunique && vardata -> rel && vardata -> rel -> tuples >= 1.0 )
@@ -5018,11 +5018,11 @@ ReleaseDummy(HeapTuple tuple)
50185018 * atttype, atttypmod: actual type/typmod of the "var" expression. This is
50195019 * commonly the same as the exposed type of the variable argument,
50205020 * but can be different in binary-compatible-type cases.
5021- * isunique: true if we were able to match the var to a unique index or a
5022- * single-column DISTINCT clause, implying its values are unique for
5023- * this query. (Caution: this should be trusted for statistical
5024- * purposes only, since we do not check indimmediate nor verify that
5025- * the exact same definition of equality applies.)
5021+ * isunique: true if we were able to match the var to a unique index, a
5022+ * single-column DISTINCT or GROUP-BY clause, implying its values are
5023+ * unique for this query. (Caution: this should be trusted for
5024+ * statistical purposes only, since we do not check indimmediate nor
5025+ * verify that the exact same definition of equality applies.)
50265026 * acl_ok: true if current user has permission to read the column(s)
50275027 * underlying the pg_statistic entry. This is consulted by
50285028 * statistic_proc_security_check().
@@ -5680,15 +5680,14 @@ examine_simple_variable(PlannerInfo *root, Var *var,
56805680 Assert (IsA (subquery , Query ));
56815681
56825682 /*
5683- * Punt if subquery uses set operations or GROUP BY , as these will
5684- * mash underlying columns' stats beyond recognition. (Set ops are
5685- * particularly nasty; if we forged ahead, we would return stats
5683+ * Punt if subquery uses set operations or grouping sets , as these
5684+ * will mash underlying columns' stats beyond recognition. (Set ops
5685+ * are particularly nasty; if we forged ahead, we would return stats
56865686 * relevant to only the leftmost subselect...) DISTINCT is also
56875687 * problematic, but we check that later because there is a possibility
56885688 * of learning something even with it.
56895689 */
56905690 if (subquery -> setOperations ||
5691- subquery -> groupClause ||
56925691 subquery -> groupingSets )
56935692 return ;
56945693
@@ -5718,6 +5717,16 @@ examine_simple_variable(PlannerInfo *root, Var *var,
57185717 return ;
57195718 }
57205719
5720+ /* The same idea as with DISTINCT clause works for a GROUP-BY too */
5721+ if (subquery -> groupClause )
5722+ {
5723+ if (list_length (subquery -> groupClause ) == 1 &&
5724+ targetIsInSortList (ste , InvalidOid , subquery -> groupClause ))
5725+ vardata -> isunique = true;
5726+ /* cannot go further */
5727+ return ;
5728+ }
5729+
57215730 /*
57225731 * If the sub-query originated from a view with the security_barrier
57235732 * attribute, we must not look at the variable's statistics, though it
@@ -5869,11 +5878,11 @@ get_variable_numdistinct(VariableStatData *vardata, bool *isdefault)
58695878 }
58705879
58715880 /*
5872- * If there is a unique index or DISTINCT clause for the variable, assume
5873- * it is unique no matter what pg_statistic says; the statistics could be
5874- * out of date, or we might have found a partial unique index that proves
5875- * the var is unique for this query. However, we'd better still believe
5876- * the null-fraction statistic.
5881+ * If there is a unique index, DISTINCT or GROUP-BY clause for the
5882+ * variable, assume it is unique no matter what pg_statistic says; the
5883+ * statistics could be out of date, or we might have found a partial
5884+ * unique index that proves the var is unique for this query. However,
5885+ * we'd better still believe the null-fraction statistic.
58775886 */
58785887 if (vardata -> isunique )
58795888 stadistinct = -1.0 * (1.0 - stanullfrac );
0 commit comments