|
14 | 14 | *
|
15 | 15 | *
|
16 | 16 | * IDENTIFICATION
|
17 |
| - * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.108 2008/08/03 19:10:52 tgl Exp $ |
| 17 | + * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.109 2008/08/05 02:43:17 tgl Exp $ |
18 | 18 | *
|
19 | 19 | *-------------------------------------------------------------------------
|
20 | 20 | */
|
|
66 | 66 | * PlannerInfo field and not a passed parameter is that the low-level routines
|
67 | 67 | * in indxpath.c need to see it.)
|
68 | 68 | *
|
69 |
| - * Note: the PlannerInfo node also includes group_pathkeys and sort_pathkeys, |
70 |
| - * which like query_pathkeys need to be canonicalized once the info is |
71 |
| - * available. |
| 69 | + * Note: the PlannerInfo node also includes group_pathkeys, distinct_pathkeys, |
| 70 | + * and sort_pathkeys, which like query_pathkeys need to be canonicalized once |
| 71 | + * the info is available. |
72 | 72 | *
|
73 | 73 | * tuple_fraction is interpreted as follows:
|
74 | 74 | * 0: expect all tuples to be retrieved (normal case)
|
@@ -120,6 +120,8 @@ query_planner(PlannerInfo *root, List *tlist,
|
120 | 120 | root->query_pathkeys);
|
121 | 121 | root->group_pathkeys = canonicalize_pathkeys(root,
|
122 | 122 | root->group_pathkeys);
|
| 123 | + root->distinct_pathkeys = canonicalize_pathkeys(root, |
| 124 | + root->distinct_pathkeys); |
123 | 125 | root->sort_pathkeys = canonicalize_pathkeys(root,
|
124 | 126 | root->sort_pathkeys);
|
125 | 127 | return;
|
@@ -237,10 +239,12 @@ query_planner(PlannerInfo *root, List *tlist,
|
237 | 239 | /*
|
238 | 240 | * We have completed merging equivalence sets, so it's now possible to
|
239 | 241 | * convert the requested query_pathkeys to canonical form. Also
|
240 |
| - * canonicalize the groupClause and sortClause pathkeys for use later. |
| 242 | + * canonicalize the groupClause, distinctClause and sortClause pathkeys |
| 243 | + * for use later. |
241 | 244 | */
|
242 | 245 | root->query_pathkeys = canonicalize_pathkeys(root, root->query_pathkeys);
|
243 | 246 | root->group_pathkeys = canonicalize_pathkeys(root, root->group_pathkeys);
|
| 247 | + root->distinct_pathkeys = canonicalize_pathkeys(root, root->distinct_pathkeys); |
244 | 248 | root->sort_pathkeys = canonicalize_pathkeys(root, root->sort_pathkeys);
|
245 | 249 |
|
246 | 250 | /*
|
@@ -286,9 +290,11 @@ query_planner(PlannerInfo *root, List *tlist,
|
286 | 290 | /*
|
287 | 291 | * If both GROUP BY and ORDER BY are specified, we will need two
|
288 | 292 | * levels of sort --- and, therefore, certainly need to read all the
|
289 |
| - * tuples --- unless ORDER BY is a subset of GROUP BY. |
| 293 | + * tuples --- unless ORDER BY is a subset of GROUP BY. Likewise if |
| 294 | + * we have both DISTINCT and GROUP BY. |
290 | 295 | */
|
291 |
| - if (!pathkeys_contained_in(root->sort_pathkeys, root->group_pathkeys)) |
| 296 | + if (!pathkeys_contained_in(root->sort_pathkeys, root->group_pathkeys) || |
| 297 | + !pathkeys_contained_in(root->distinct_pathkeys, root->group_pathkeys)) |
292 | 298 | tuple_fraction = 0.0;
|
293 | 299 | }
|
294 | 300 | else if (parse->hasAggs || root->hasHavingQual)
|
|
0 commit comments