|
61 | 61 | from .operations.load import Load |
62 | 62 | from .operations.match import Match |
63 | 63 | from .operations.operation import Operation |
| 64 | +from .operations.order_by import OrderBy, SortField |
64 | 65 | from .operations.return_op import Return |
65 | 66 | from .operations.union import Union |
66 | 67 | from .operations.union_all import UnionAll |
@@ -146,6 +147,14 @@ def _parse_tokenized(self, is_sub_query: bool = False) -> ASTNode: |
146 | 147 | operation.add_sibling(where) |
147 | 148 | operation = where |
148 | 149 |
|
| 150 | + order_by = self._parse_order_by() |
| 151 | + if order_by is not None: |
| 152 | + if isinstance(operation, Return): |
| 153 | + operation.order_by = order_by |
| 154 | + else: |
| 155 | + operation.add_sibling(order_by) |
| 156 | + operation = order_by |
| 157 | + |
149 | 158 | limit = self._parse_limit() |
150 | 159 | if limit is not None: |
151 | 160 | if isinstance(operation, Return): |
@@ -694,6 +703,41 @@ def _parse_limit(self) -> Optional[Limit]: |
694 | 703 | self.set_next_token() |
695 | 704 | return limit |
696 | 705 |
|
| 706 | + def _parse_order_by(self) -> Optional[OrderBy]: |
| 707 | + self._skip_whitespace_and_comments() |
| 708 | + if not self.token.is_order(): |
| 709 | + return None |
| 710 | + self._expect_previous_token_to_be_whitespace_or_comment() |
| 711 | + self.set_next_token() |
| 712 | + self._expect_and_skip_whitespace_and_comments() |
| 713 | + if not self.token.is_by(): |
| 714 | + raise ValueError("Expected BY after ORDER") |
| 715 | + self.set_next_token() |
| 716 | + self._expect_and_skip_whitespace_and_comments() |
| 717 | + fields: list[SortField] = [] |
| 718 | + while True: |
| 719 | + if not self.token.is_identifier_or_keyword(): |
| 720 | + raise ValueError("Expected field name in ORDER BY") |
| 721 | + field = self.token.value |
| 722 | + self.set_next_token() |
| 723 | + self._skip_whitespace_and_comments() |
| 724 | + direction = "asc" |
| 725 | + if self.token.is_asc(): |
| 726 | + direction = "asc" |
| 727 | + self.set_next_token() |
| 728 | + self._skip_whitespace_and_comments() |
| 729 | + elif self.token.is_desc(): |
| 730 | + direction = "desc" |
| 731 | + self.set_next_token() |
| 732 | + self._skip_whitespace_and_comments() |
| 733 | + fields.append(SortField(field, direction)) |
| 734 | + if self.token.is_comma(): |
| 735 | + self.set_next_token() |
| 736 | + self._skip_whitespace_and_comments() |
| 737 | + else: |
| 738 | + break |
| 739 | + return OrderBy(fields) |
| 740 | + |
697 | 741 | def _parse_expressions( |
698 | 742 | self, alias_option: AliasOption = AliasOption.NOT_ALLOWED |
699 | 743 | ) -> Iterator[Expression]: |
|
0 commit comments