diff --git a/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_in.json b/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_in.json index 873a09c892..b9f00c6ae6 100644 --- a/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_in.json +++ b/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_in.json @@ -8,7 +8,10 @@ "select * from t where name='a' and length(name)=1; -- without constant propagated", "select * from (select 'test' as b from t) n where length(b) > 2; -- can be substituted", "select foo.a, foo.b, bar.c from foo join bar on foo.a=bar.a where (foo.a,foo.b) in ((1,2),(3,4));", - "select foo.a, foo.b, bar.c from foo left join bar on foo.a=bar.a where (foo.a,foo.b) in ((1,2),(3,4));" + "select foo.a, foo.b, bar.c from foo left join bar on foo.a=bar.a where (foo.a,foo.b) in ((1,2),(3,4));", + "select foo.a, foo.b, bar.c from foo left join bar on foo.a=bar.a where (foo.a,foo.b) in ((1,2),(3,4));", + "select * from foo join bar on foo.a=bar.a where rand() > 0.5;", + "select * from foo join bar on foo.a=bar.a where foo.a = rand();" ] } ] diff --git a/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_out.json b/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_out.json index 9d7261eb78..458e2ee3fc 100644 --- a/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_out.json +++ b/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_out.json @@ -60,6 +60,50 @@ " └─TableRangeScan 2.00 cop[tikv] table:bar range: decided by [test.foo.a], keep order:false, stats:pseudo" ], "Warning": null + }, + { + "SQL": "select foo.a, foo.b, bar.c from foo left join bar on foo.a=bar.a where (foo.a,foo.b) in ((1,2),(3,4));", + "Plan": [ + "IndexJoin 2.50 root left outer join, inner:TableReader, left side:Selection, outer key:test.foo.a, inner key:test.bar.a, equal cond:eq(test.foo.a, test.bar.a)", + "├─Selection(Build) 2.00 root or(and(eq(test.foo.a, 1), eq(test.foo.b, 2)), and(eq(test.foo.a, 3), eq(test.foo.b, 4)))", + "│ └─Batch_Point_Get 2.00 root table:foo handle:[1 3], keep order:false, desc:false", + "└─TableReader(Probe) 2.00 root data:TableRangeScan", + " └─TableRangeScan 2.00 cop[tikv] table:bar range: decided by [test.foo.a], keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select * from foo join bar on foo.a=bar.a where rand() > 0.5;", + "Plan": [ + "MergeJoin 12500.00 root inner join, left key:test.foo.a, right key:test.bar.a, other cond:gt(rand(), 0.5)", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:bar keep order:true, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:foo keep order:true, stats:pseudo" + ], + "Warning": [ + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now." + ] + }, + { + "SQL": "select * from foo join bar on foo.a=bar.a where foo.a = rand();", + "Plan": [ + "Projection 10000.00 root test.foo.a, test.foo.b, test.foo.c, test.bar.a, test.bar.b, test.bar.c", + "└─MergeJoin 10000.00 root inner join, left key:test.bar.a, right key:test.foo.a", + " ├─Selection(Build) 8000.00 root eq(cast(test.foo.a, double BINARY), rand())", + " │ └─TableReader 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:foo keep order:true, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:bar keep order:true, stats:pseudo" + ], + "Warning": [ + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to storage layer now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now." + ] } ] } diff --git a/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_xut.json b/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_xut.json index 9d7261eb78..458e2ee3fc 100644 --- a/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_xut.json +++ b/pkg/planner/core/casetest/rule/testdata/predicate_pushdown_suite_xut.json @@ -60,6 +60,50 @@ " └─TableRangeScan 2.00 cop[tikv] table:bar range: decided by [test.foo.a], keep order:false, stats:pseudo" ], "Warning": null + }, + { + "SQL": "select foo.a, foo.b, bar.c from foo left join bar on foo.a=bar.a where (foo.a,foo.b) in ((1,2),(3,4));", + "Plan": [ + "IndexJoin 2.50 root left outer join, inner:TableReader, left side:Selection, outer key:test.foo.a, inner key:test.bar.a, equal cond:eq(test.foo.a, test.bar.a)", + "├─Selection(Build) 2.00 root or(and(eq(test.foo.a, 1), eq(test.foo.b, 2)), and(eq(test.foo.a, 3), eq(test.foo.b, 4)))", + "│ └─Batch_Point_Get 2.00 root table:foo handle:[1 3], keep order:false, desc:false", + "└─TableReader(Probe) 2.00 root data:TableRangeScan", + " └─TableRangeScan 2.00 cop[tikv] table:bar range: decided by [test.foo.a], keep order:false, stats:pseudo" + ], + "Warning": null + }, + { + "SQL": "select * from foo join bar on foo.a=bar.a where rand() > 0.5;", + "Plan": [ + "MergeJoin 12500.00 root inner join, left key:test.foo.a, right key:test.bar.a, other cond:gt(rand(), 0.5)", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:bar keep order:true, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:foo keep order:true, stats:pseudo" + ], + "Warning": [ + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now." + ] + }, + { + "SQL": "select * from foo join bar on foo.a=bar.a where foo.a = rand();", + "Plan": [ + "Projection 10000.00 root test.foo.a, test.foo.b, test.foo.c, test.bar.a, test.bar.b, test.bar.c", + "└─MergeJoin 10000.00 root inner join, left key:test.bar.a, right key:test.foo.a", + " ├─Selection(Build) 8000.00 root eq(cast(test.foo.a, double BINARY), rand())", + " │ └─TableReader 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:foo keep order:true, stats:pseudo", + " └─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:bar keep order:true, stats:pseudo" + ], + "Warning": [ + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to storage layer now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now.", + "Warning 1105 Scalar function 'rand'(signature: Rand, return type: double) is not supported to push down to tiflash now." + ] } ] } diff --git a/pkg/planner/core/operator/logicalop/logical_join.go b/pkg/planner/core/operator/logicalop/logical_join.go index 3868da8dda..cb0042ada3 100644 --- a/pkg/planner/core/operator/logicalop/logical_join.go +++ b/pkg/planner/core/operator/logicalop/logical_join.go @@ -1477,6 +1477,15 @@ func (p *LogicalJoin) ExtractOnCondition( // `columns` may be empty, if the condition is like `correlated_column op constant`, or `constant`, // push this kind of constant condition down according to join type. if len(columns) == 0 { + // The IsMutableEffectsExpr check is primarily designed to prevent mutable expressions + // like rand() > 0.5 from being pushed down; instead, such expressions should remain + // in other conditions. + // Checking len(columns) == 0 first is to let filter like rand() > tbl.col + // to be able pushdown as left or right condition + if expression.IsMutableEffectsExpr(expr) { + otherCond = append(otherCond, expr) + continue + } leftCond, rightCond = p.pushDownConstExpr(expr, leftCond, rightCond, deriveLeft || deriveRight) continue } diff --git a/pkg/sessionctx/variable/tests/main_test.go b/pkg/sessionctx/variable/tests/main_test.go index dcae9ab78e..eaa52297b5 100644 --- a/pkg/sessionctx/variable/tests/main_test.go +++ b/pkg/sessionctx/variable/tests/main_test.go @@ -29,6 +29,7 @@ func TestMain(m *testing.M) { goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"), goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), + goleak.IgnoreTopFunction("internal/poll.runtime_pollWait"), } goleak.VerifyTestMain(m, opts...) }