Break up an 'order by' expression into individual column-expressions, without DESC/ASC/NULLS FIRST/NULLS LAST
(clause: Any)
| 367 | |
| 368 | |
| 369 | def unwrap_order_by(clause: Any) -> Any: |
| 370 | """Break up an 'order by' expression into individual column-expressions, |
| 371 | without DESC/ASC/NULLS FIRST/NULLS LAST""" |
| 372 | |
| 373 | cols = util.column_set() |
| 374 | result = [] |
| 375 | stack = deque([clause]) |
| 376 | |
| 377 | # examples |
| 378 | # column -> ASC/DESC == column |
| 379 | # column -> ASC/DESC -> label == column |
| 380 | # column -> label -> ASC/DESC -> label == column |
| 381 | # scalar_select -> label -> ASC/DESC == scalar_select -> label |
| 382 | |
| 383 | while stack: |
| 384 | t = stack.popleft() |
| 385 | if isinstance(t, ColumnElement) and ( |
| 386 | not isinstance(t, UnaryExpression) |
| 387 | or not operators.is_ordering_modifier(t.modifier) # type: ignore |
| 388 | ): |
| 389 | if isinstance(t, Label) and not isinstance( |
| 390 | t.element, ScalarSelect |
| 391 | ): |
| 392 | t = t.element |
| 393 | |
| 394 | if isinstance(t, Grouping): |
| 395 | t = t.element |
| 396 | |
| 397 | stack.append(t) |
| 398 | continue |
| 399 | elif isinstance(t, _label_reference): |
| 400 | t = t.element |
| 401 | |
| 402 | stack.append(t) |
| 403 | continue |
| 404 | if isinstance(t, (_textual_label_reference)): |
| 405 | continue |
| 406 | if t not in cols: |
| 407 | cols.add(t) |
| 408 | result.append(t) |
| 409 | |
| 410 | else: |
| 411 | for c in t.get_children(): |
| 412 | stack.append(c) |
| 413 | return result |
| 414 | |
| 415 | |
| 416 | def unwrap_label_reference(element): |
no test coverage detected