(left_tab: table.Joinable, context: ContextType)
| 367 | @register(nodetype=sql_expr.Join) |
| 368 | def _join(node: sql_expr.Join, _context: ContextType) -> Callable: |
| 369 | def _wrap(left_tab: table.Joinable, context: ContextType): |
| 370 | right_tab, context = _run(node.args.pop("this"), context) |
| 371 | assert isinstance(right_tab, table.Joinable) |
| 372 | if (on_field := node.args.pop("on", None)) is not None: |
| 373 | |
| 374 | def _rec( |
| 375 | op: sql_expr.And | sql_expr.EQ, |
| 376 | ) -> list[expr.ColumnBinaryOpExpression]: |
| 377 | if isinstance(op, sql_expr.And): |
| 378 | return _rec(op.this) + _rec(op.expression) |
| 379 | else: |
| 380 | return [_run(op, context)] |
| 381 | |
| 382 | on_all = _rec(on_field) |
| 383 | |
| 384 | def _test(e: expr.ColumnExpression) -> bool: |
| 385 | if not isinstance(e, expr.ColumnBinaryOpExpression): |
| 386 | return False |
| 387 | if e._operator != operator.eq: |
| 388 | return False |
| 389 | left_side = e._left |
| 390 | if not isinstance(left_side, expr.ColumnReference): |
| 391 | return False |
| 392 | right_side = e._right |
| 393 | if not isinstance(right_side, expr.ColumnReference): |
| 394 | return False |
| 395 | return ( |
| 396 | left_side.table in left_tab._subtables() |
| 397 | and right_side.table in right_tab._subtables() |
| 398 | ) |
| 399 | |
| 400 | on = [] |
| 401 | postfilter = [] |
| 402 | for e in on_all: |
| 403 | if _test(e): |
| 404 | on.append(e) |
| 405 | else: |
| 406 | postfilter.append(e) |
| 407 | |
| 408 | elif using_field := node.args.pop("using", None): |
| 409 | on = [] |
| 410 | for arg in using_field: |
| 411 | name = _identifier(arg) |
| 412 | on.append(thisclass.left[name] == thisclass.right[name]) |
| 413 | postfilter = [] |
| 414 | else: |
| 415 | on = [] |
| 416 | postfilter = [] |
| 417 | |
| 418 | node.args.pop("kind", None) |
| 419 | side = node.args.pop("side", "") |
| 420 | _check_work_done(node) |
| 421 | |
| 422 | if side == "OUTER": |
| 423 | # TODO we should properly handle those cases |
| 424 | assert ( |
| 425 | len(postfilter) == 0 |
| 426 | ), "Not supported ON clause for OUTER JOIN, if possible use WHERE" |
nothing calls this directly
no test coverage detected