@@ -322,10 +322,10 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation,
322
322
}
323
323
324
324
/*
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
329
329
* ignoring the information.)
330
330
*/
331
331
if (vardata -> isunique && vardata -> rel && vardata -> rel -> tuples >= 1.0 )
@@ -484,10 +484,10 @@ var_eq_non_const(VariableStatData *vardata, Oid oproid, Oid collation,
484
484
}
485
485
486
486
/*
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
491
491
* ignoring the information.)
492
492
*/
493
493
if (vardata -> isunique && vardata -> rel && vardata -> rel -> tuples >= 1.0 )
@@ -5018,11 +5018,11 @@ ReleaseDummy(HeapTuple tuple)
5018
5018
* atttype, atttypmod: actual type/typmod of the "var" expression. This is
5019
5019
* commonly the same as the exposed type of the variable argument,
5020
5020
* 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.)
5026
5026
* acl_ok: true if current user has permission to read the column(s)
5027
5027
* underlying the pg_statistic entry. This is consulted by
5028
5028
* statistic_proc_security_check().
@@ -5680,15 +5680,14 @@ examine_simple_variable(PlannerInfo *root, Var *var,
5680
5680
Assert (IsA (subquery , Query ));
5681
5681
5682
5682
/*
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
5686
5686
* relevant to only the leftmost subselect...) DISTINCT is also
5687
5687
* problematic, but we check that later because there is a possibility
5688
5688
* of learning something even with it.
5689
5689
*/
5690
5690
if (subquery -> setOperations ||
5691
- subquery -> groupClause ||
5692
5691
subquery -> groupingSets )
5693
5692
return ;
5694
5693
@@ -5718,6 +5717,16 @@ examine_simple_variable(PlannerInfo *root, Var *var,
5718
5717
return ;
5719
5718
}
5720
5719
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
+
5721
5730
/*
5722
5731
* If the sub-query originated from a view with the security_barrier
5723
5732
* attribute, we must not look at the variable's statistics, though it
@@ -5869,11 +5878,11 @@ get_variable_numdistinct(VariableStatData *vardata, bool *isdefault)
5869
5878
}
5870
5879
5871
5880
/*
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.
5877
5886
*/
5878
5887
if (vardata -> isunique )
5879
5888
stadistinct = -1.0 * (1.0 - stanullfrac );
0 commit comments