Skip to content

Commit

Permalink
fix(join): skip substitution of non-field references in join chains (#…
Browse files Browse the repository at this point in the history
…9595)

Co-authored-by: Phillip Cloud <417981+cpcloud@users.noreply.github.com>
  • Loading branch information
coroa and cpcloud authored Jul 15, 2024
1 parent 1b02b18 commit 61ef0ed
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
65 changes: 65 additions & 0 deletions ibis/expr/tests/test_newrels.py
Original file line number Diff line number Diff line change
Expand Up @@ -1764,3 +1764,68 @@ def test_projections_with_similar_expressions_have_different_names():
assert b.op().name in fields

assert expr.schema() == ibis.schema({a.op().name: "string", b.op().name: "string"})


def test_expr_in_join_projection():
t1 = ibis.table({"a": "int64", "b": "string"}, name="t1")
t2 = ibis.table({"c": "int64", "b": "string"}, name="t2")
t3 = ibis.table({"a": "int64", "d": "int64", "e": "string"}, name="t3")
expr = t1.inner_join(t2, "b").select(
"a", lit1=1, lit2=2 * t1.a, lit3=_.c - 5, lit4=t2.b.length() / 2.0
)

op = expr.op()
assert isinstance(op, ops.JoinChain)
assert op.schema == ibis.schema(
{
"a": "int64",
"lit1": "int8",
"lit2": "int64",
"lit3": "int64",
"lit4": "float64",
}
)

# simple chain selection
expr2 = expr.inner_join(t3, "a").select("a", "d", "lit1", "lit2", "lit3", "lit4")
op2 = expr2.op()
assert isinstance(op2, ops.JoinChain)
assert op2.schema == ibis.schema(
{
"a": "int64",
"d": "int64",
"lit1": "int8",
"lit2": "int64",
"lit3": "int64",
"lit4": "float64",
}
)

# chain with expressions from all three tables in the join
expr = (
t1.inner_join(t2, "b")
.inner_join(t3, t2.b == t3.e)
.select(
"a",
lit1=1,
lit2=2 * t1.a,
lit3=_.c - 5,
lit4=t2.b.length() / 2.0,
lit5=_.e.cast("int") * 3,
lit6=t3.d + 1,
)
)

op = expr.op()
assert isinstance(op, ops.JoinChain)
assert op.schema == ibis.schema(
{
"a": "int64",
"lit1": "int8",
"lit2": "int64",
"lit3": "int64",
"lit4": "float64",
"lit5": "int64",
"lit6": "int64",
}
)
6 changes: 5 additions & 1 deletion ibis/expr/types/joins.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,11 @@ def prepare_predicates(
The comparison operation to construct if the input is a pair of
expression-like objects
"""
reverse = {ops.Field(chain, k): v for k, v in chain.values.items()}
reverse = {
ops.Field(chain, k): v
for k, v in chain.values.items()
if isinstance(v, ops.Field)
}
deref_right = DerefMap.from_targets(right)
deref_left = DerefMap.from_targets(chain.tables, extra=reverse)
deref_both = DerefMap.from_targets([*chain.tables, right], extra=reverse)
Expand Down

0 comments on commit 61ef0ed

Please sign in to comment.