diff --git a/enginetest/join_planning_tests.go b/enginetest/join_planning_tests.go index 67c75297b7..ac886391d8 100644 --- a/enginetest/join_planning_tests.go +++ b/enginetest/join_planning_tests.go @@ -1788,6 +1788,34 @@ join uv d on d.u = c.x`, }, }, }, + { + name: "single look up plan does not drop complex equality filters", + setup: []string{ + "create table t1 (i int primary key);", + "create table t2 (j int);", + "create table t3 (k int);", + "insert into t1 values (1), (2);", + "insert into t2 values (1), (2);", + "insert into t3 values (3);", + }, + tests: []JoinPlanTest{ + { + q: "select * from t1 cross join t2 join (select * from t3) v3 on v3.k = t2.j;", + types: []plan.JoinType{plan.JoinTypeHash, plan.JoinTypeCross}, + exp: []sql.Row{}, + }, + { + q: "select * from t1 cross join t2 join (select * from t3) v3 on v3.k >= t2.j order by i, j, k;", + types: []plan.JoinType{plan.JoinTypeInner, plan.JoinTypeCross}, + exp: []sql.Row{ + {1, 1, 3}, + {1, 2, 3}, + {2, 1, 3}, + {2, 2, 3}, + }, + }, + }, + }, } func TestJoinPlanning(t *testing.T, harness Harness) { diff --git a/sql/memo/join_order_builder.go b/sql/memo/join_order_builder.go index ab8787a738..e51042d857 100644 --- a/sql/memo/join_order_builder.go +++ b/sql/memo/join_order_builder.go @@ -285,7 +285,7 @@ func (j *joinOrderBuilder) buildSingleLookupPlan() bool { } filter := edge.filters[0] _, tables, _ := getExprScalarProps(filter) - if tables.Len() != 2 { + if tables.Len() != 2 || !isSimpleEquality(filter) { // We have encountered a filter condition more complicated than a simple equality check. // We probably can't optimize this, so bail out. return false @@ -319,7 +319,6 @@ func (j *joinOrderBuilder) buildSingleLookupPlan() bool { for idx, ok := remainingVertexes.next(0); ok; idx, ok = remainingVertexes.next(idx + 1) { nextVertex := newBitSet(idx) j.addJoin(plan.JoinTypeCross, currentlyJoinedVertexes, nextVertex, nil, nil, false) - currentlyJoinedVertexes = currentlyJoinedVertexes.union(nextVertex) } return false diff --git a/sql/memo/rel_props.go b/sql/memo/rel_props.go index 951ce63403..f1cc8d5d17 100644 --- a/sql/memo/rel_props.go +++ b/sql/memo/rel_props.go @@ -538,6 +538,21 @@ func getExprScalarProps(e sql.Expression) (sql.ColSet, sql.FastIntSet, bool) { return cols, tables, nullRej } +func isSimpleEquality(expr sql.Expression) bool { + hasOnlyEquals := true + transform.InspectExpr(expr, func(e sql.Expression) bool { + switch e.(type) { + case *expression.GetField: + case *expression.Equals, *expression.NullSafeEquals: + default: + hasOnlyEquals = false + return true + } + return false + }) + return hasOnlyEquals +} + // allTableCols returns the full schema of a table ignoring // declared projections. func allTableCols(rel SourceRel) sql.Schema {