* Transform a single expression within a GROUP BY clause or grouping set. * * The expression is added to the targetlist if not already present, and to the * flatresult list (which will become the groupClause) if not already present * there. The sortClause is consulted for operator and sort order hints. * * Returns the ressortgroupref of the expression. * * flatresult reference to flat lis
| 2451 | * toplevel false if within any grouping set |
| 2452 | */ |
| 2453 | static Index |
| 2454 | transformGroupClauseExpr(List **flatresult, Bitmapset *seen_local, |
| 2455 | ParseState *pstate, Node *gexpr, |
| 2456 | List **targetlist, List *sortClause, |
| 2457 | ParseExprKind exprKind, bool useSQL99, bool toplevel) |
| 2458 | { |
| 2459 | TargetEntry *tle; |
| 2460 | bool found = false; |
| 2461 | |
| 2462 | if (useSQL99) |
| 2463 | tle = findTargetlistEntrySQL99(pstate, gexpr, |
| 2464 | targetlist, exprKind); |
| 2465 | else |
| 2466 | tle = findTargetlistEntrySQL92(pstate, gexpr, |
| 2467 | targetlist, exprKind); |
| 2468 | |
| 2469 | if (tle->ressortgroupref > 0) |
| 2470 | { |
| 2471 | ListCell *sl; |
| 2472 | |
| 2473 | /* |
| 2474 | * Eliminate duplicates (GROUP BY x, x) but only at local level. |
| 2475 | * (Duplicates in grouping sets can affect the number of returned |
| 2476 | * rows, so can't be dropped indiscriminately.) |
| 2477 | * |
| 2478 | * Since we don't care about anything except the sortgroupref, we can |
| 2479 | * use a bitmapset rather than scanning lists. |
| 2480 | */ |
| 2481 | if (bms_is_member(tle->ressortgroupref, seen_local)) |
| 2482 | return 0; |
| 2483 | |
| 2484 | /* |
| 2485 | * If we're already in the flat clause list, we don't need to consider |
| 2486 | * adding ourselves again. |
| 2487 | */ |
| 2488 | found = targetIsInSortList(tle, InvalidOid, *flatresult); |
| 2489 | if (found) |
| 2490 | return tle->ressortgroupref; |
| 2491 | |
| 2492 | /* |
| 2493 | * If the GROUP BY tlist entry also appears in ORDER BY, copy operator |
| 2494 | * info from the (first) matching ORDER BY item. This means that if |
| 2495 | * you write something like "GROUP BY foo ORDER BY foo USING <<<", the |
| 2496 | * GROUP BY operation silently takes on the equality semantics implied |
| 2497 | * by the ORDER BY. There are two reasons to do this: it improves the |
| 2498 | * odds that we can implement both GROUP BY and ORDER BY with a single |
| 2499 | * sort step, and it allows the user to choose the equality semantics |
| 2500 | * used by GROUP BY, should she be working with a datatype that has |
| 2501 | * more than one equality operator. |
| 2502 | * |
| 2503 | * If we're in a grouping set, though, we force our requested ordering |
| 2504 | * to be NULLS LAST, because if we have any hope of using a sorted agg |
| 2505 | * for the job, we're going to be tacking on generated NULL values |
| 2506 | * after the corresponding groups. If the user demands nulls first, |
| 2507 | * another sort step is going to be inevitable, but that's the |
| 2508 | * planner's problem. |
| 2509 | */ |
| 2510 |
no test coverage detected