| 556 | |
| 557 | |
| 558 | class DistinctOnClause(SyntaxExtension, expression.ClauseElement): |
| 559 | stringify_dialect = "postgresql" |
| 560 | __visit_name__ = "postgresql_distinct_on" |
| 561 | |
| 562 | _traverse_internals: _TraverseInternalsType = [ |
| 563 | ("_distinct_on", InternalTraversal.dp_clauseelement_tuple), |
| 564 | ] |
| 565 | |
| 566 | def __init__(self, distinct_on: Sequence[_ColumnExpressionArgument[Any]]): |
| 567 | self._distinct_on = tuple( |
| 568 | coercions.expect(roles.ByOfRole, e, apply_propagate_attrs=self) |
| 569 | for e in distinct_on |
| 570 | ) |
| 571 | |
| 572 | def apply_to_select(self, select_stmt: expression.Select[Any]) -> None: |
| 573 | if select_stmt._distinct_on: |
| 574 | raise exc.InvalidRequestError( |
| 575 | "Cannot mix ``select.ext(distinct_on(...))`` and " |
| 576 | "``select.distinct(...)``" |
| 577 | ) |
| 578 | # mark this select as a distinct |
| 579 | select_stmt.distinct.non_generative(select_stmt) |
| 580 | |
| 581 | select_stmt.apply_syntax_extension_point( |
| 582 | self._merge_other_distinct, "pre_columns" |
| 583 | ) |
| 584 | |
| 585 | def _merge_other_distinct( |
| 586 | self, existing: Sequence[elements.ClauseElement] |
| 587 | ) -> Sequence[elements.ClauseElement]: |
| 588 | res = [] |
| 589 | to_merge = () |
| 590 | for e in existing: |
| 591 | if isinstance(e, DistinctOnClause): |
| 592 | to_merge += e._distinct_on |
| 593 | else: |
| 594 | res.append(e) |
| 595 | if to_merge: |
| 596 | res.append(DistinctOnClause(to_merge + self._distinct_on)) |
| 597 | else: |
| 598 | res.append(self) |
| 599 | return res |
no outgoing calls
no test coverage detected