Skip to content

Commit

Permalink
fix full outer join uniform trait
Browse files Browse the repository at this point in the history
  • Loading branch information
feiniaofeiafei committed Nov 27, 2024
1 parent 93a5155 commit 1c2bb29
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.functions.ExpressionTrait;
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
import org.apache.doris.nereids.util.ImmutableEqualSet;

import com.google.common.collect.ImmutableMap;
Expand Down Expand Up @@ -190,6 +191,10 @@ public void addUniformSlot(DataTrait dataTrait) {
uniformSet.add(dataTrait.uniformSet);
}

public void addUniformSlotForOuterJoinNullableSide(DataTrait dataTrait) {
uniformSet.addUniformSlotForOuterJoinNullableSide(dataTrait.uniformSet);
}

public void addUniformSlotAndLiteral(Slot slot, Expression literal) {
uniformSet.add(slot, literal);
}
Expand Down Expand Up @@ -548,6 +553,15 @@ public void add(Slot slot, Expression literal) {
}
}

public void addUniformSlotForOuterJoinNullableSide(UniformDescription ud) {
for (Map.Entry<Slot, Optional<Expression>> entry : ud.slotUniformValue.entrySet()) {
if ((!entry.getValue().isPresent() && entry.getKey().nullable())
|| (entry.getValue().isPresent() && entry.getValue().get() instanceof NullLiteral)) {
add(entry.getKey(), entry.getValue().orElse(null));
}
}
}

public void removeNotContain(Set<Slot> slotSet) {
if (slotSet.isEmpty()) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,16 +535,35 @@ public void computeUniform(Builder builder) {
// TODO disable function dependence calculation for mark join, but need re-think this in future.
return;
}
// outer join cant have nullable side uniform properties
// (e.g. left join may produce null in right side, the uniform value is present and not null
// cannot deduce the slot is uniform and not null)
// TODO: left outer join right child uniform properties can be pull up when uniform slot const value
// is not present or const value is nullable (the right outer join left child is same)
if (!joinType.isLeftJoin()) {
builder.addUniformSlot(right().getLogicalProperties().getTrait());
}
if (!joinType.isRightJoin()) {
builder.addUniformSlot(left().getLogicalProperties().getTrait());
switch (joinType) {
case INNER_JOIN:
case CROSS_JOIN:
builder.addUniformSlot(left().getLogicalProperties().getTrait());
builder.addUniformSlot(right().getLogicalProperties().getTrait());
break;
case LEFT_SEMI_JOIN:
case LEFT_ANTI_JOIN:
case NULL_AWARE_LEFT_ANTI_JOIN:
builder.addUniformSlot(left().getLogicalProperties().getTrait());
break;
case RIGHT_SEMI_JOIN:
case RIGHT_ANTI_JOIN:
builder.addUniformSlot(right().getLogicalProperties().getTrait());
break;
case LEFT_OUTER_JOIN:
builder.addUniformSlot(left().getLogicalProperties().getTrait());
builder.addUniformSlotForOuterJoinNullableSide(right().getLogicalProperties().getTrait());
break;
case RIGHT_OUTER_JOIN:
builder.addUniformSlot(right().getLogicalProperties().getTrait());
builder.addUniformSlotForOuterJoinNullableSide(left().getLogicalProperties().getTrait());
break;
case FULL_OUTER_JOIN:
builder.addUniformSlotForOuterJoinNullableSide(left().getLogicalProperties().getTrait());
builder.addUniformSlotForOuterJoinNullableSide(right().getLogicalProperties().getTrait());
break;
default:
break;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,40 @@ cherry 3
2023-10-18 2 2023-10-18 2 6
2023-10-18 2 2023-10-21 2 6

-- !full_join_uniform_should_not_eliminate_group_by_key --
\N 1
105 1

-- !full2 --
1 \N
1 105

-- !left_join_right_side_should_not_eliminate_group_by_key --
\N 1
105 1

-- !left_join_left_side_should_eliminate_group_by_key --
\N 1
105 1

-- !right_join_left_side_should_not_eliminate_group_by_key --
1 \N
1 105

-- !right_join_right_side_should_eliminate_group_by_key --
1 \N
1 105

-- !left_semi_left_side --
1
1

-- !left_anti_left_side --
1

-- !right_semi_right_side --
105
105

-- !right_anti_right_side --

Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,23 @@ suite("eliminate_group_by_key_by_uniform") {
group by l_shipdate, l_orderkey, t.O_ORDERDATE, t.o_orderkey
order by 1,2,3,4,5
"""
sql "drop table if exists test1"
sql "drop table if exists test2"
sql "create table test1(a int, b int) distributed by hash(a) properties('replication_num'='1');"
sql "insert into test1 values(1,1),(2,1),(3,1);"
sql "create table test2(a int, b int) distributed by hash(a) properties('replication_num'='1');"
sql "insert into test2 values(1,105),(2,105);"
qt_full_join_uniform_should_not_eliminate_group_by_key "select t2.b,t1.b from test1 t1 full join (select * from test2 where b=105) t2 on t1.a=t2.a group by t2.b,t1.b order by 1,2;"
qt_full2 "select t2.b,t1.b from (select * from test2 where b=105) t1 full join test1 t2 on t1.a=t2.a group by t2.b,t1.b order by 1,2;"

qt_left_join_right_side_should_not_eliminate_group_by_key "select t2.b,t1.b from test1 t1 left join (select * from test2 where b=105) t2 on t1.a=t2.a group by t2.b,t1.b order by 1,2;"
qt_left_join_left_side_should_eliminate_group_by_key "select t2.b,t1.b from test1 t1 left join (select * from test2 where b=105) t2 on t1.a=t2.a where t1.b=1 group by t2.b,t1.b order by 1,2;"

qt_right_join_left_side_should_not_eliminate_group_by_key "select t2.b,t1.b from (select * from test2 where b=105) t1 right join test1 t2 on t1.a=t2.a group by t2.b,t1.b order by 1,2;"
qt_right_join_right_side_should_eliminate_group_by_key "select t2.b,t1.b from (select * from test2 where b=105) t1 right join test1 t2 on t1.a=t2.a where t2.b=1 group by t2.b,t1.b order by 1,2;"

qt_left_semi_left_side "select t1.b from test1 t1 left semi join (select * from test2 where b=105) t2 on t1.a=t2.a where t1.b=1 group by t1.b,t1.a order by 1;"
qt_left_anti_left_side "select t1.b from test1 t1 left anti join (select * from test2 where b=105) t2 on t1.a=t2.a where t1.b=1 group by t1.b,t1.a order by 1;"
qt_right_semi_right_side "select t2.b from test1 t1 right semi join (select * from test2 where b=105) t2 on t1.a=t2.a group by t2.b,t2.a order by 1;"
qt_right_anti_right_side "select t2.b from test1 t1 right anti join (select * from test2 where b=105) t2 on t1.a=t2.a group by t2.b,t2.a order by 1;"
}

0 comments on commit 1c2bb29

Please sign in to comment.