Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expression: Fix different behaviors with MySQL when comparing datetime column with numeric constant | tidb-test=pr/2198 (#45945) #46087

42 changes: 42 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6511,3 +6511,45 @@ func TestProcessInfoOfSubQuery(t *testing.T) {
tk2.MustQuery("select 1 from information_schema.processlist where TxnStart != '' and info like 'select%sleep% from t%'").Check(testkit.Rows("1"))
wg.Wait()
}

func TestCompareIssue38361(t *testing.T) {
//store := testkit.CreateMockStore(t)

//tk := testkit.NewTestKit(t, store)
//tk.MustExec("drop database if exists TEST1")
//tk.MustExec("create database TEST1")
//tk.MustExec("use TEST1")
//tk.MustExec("create table t(a datetime, b bigint, c bigint)")
//tk.MustExec("insert into t values(cast('2023-08-09 00:00:00' as datetime), 20230809, 20231310)")

//tk.MustQuery("select a > 20230809 from t").Check(testkit.Rows("0"))
//tk.MustQuery("select a = 20230809 from t").Check(testkit.Rows("1"))
//tk.MustQuery("select a < 20230810 from t").Check(testkit.Rows("1"))
//// 20231310 can't be converted to valid datetime, thus should be compared using real date type,and datetime will be
//// converted to something like 'YYYYMMDDHHMMSS', bigger than 20231310
//tk.MustQuery("select a < 20231310 from t").Check(testkit.Rows("0"))
//tk.MustQuery("select 20230809 < a from t").Check(testkit.Rows("0"))
//tk.MustQuery("select 20230809 = a from t").Check(testkit.Rows("1"))
//tk.MustQuery("select 20230810 > a from t").Check(testkit.Rows("1"))
//tk.MustQuery("select 20231310 > a from t").Check(testkit.Rows("0"))

//// constant datetime cmp numeric constant should be compared as real data type
//tk.MustQuery("select cast('2023-08-09 00:00:00' as datetime) > 20230809 from t").Check(testkit.Rows("1"))
//tk.MustQuery("select cast('2023-08-09 00:00:00' as datetime) = 20230809 from t").Check(testkit.Rows("0"))
//tk.MustQuery("select cast('2023-08-09 00:00:00' as datetime) < 20230810 from t").Check(testkit.Rows("0"))
//tk.MustQuery("select cast('2023-08-09 00:00:00' as datetime) < 20231310 from t").Check(testkit.Rows("0"))
//tk.MustQuery("select 20230809 < cast('2023-08-09 00:00:00' as datetime) from t").Check(testkit.Rows("1"))
//tk.MustQuery("select 20230809 = cast('2023-08-09 00:00:00' as datetime) from t").Check(testkit.Rows("0"))
//tk.MustQuery("select 20230810 > cast('2023-08-09 00:00:00' as datetime) from t").Check(testkit.Rows("0"))
//tk.MustQuery("select 20231310 > cast('2023-08-09 00:00:00' as datetime) from t").Check(testkit.Rows("0"))

//// datetime column cmp numeric column should be compared as real data type
//tk.MustQuery("select a > b from t").Check(testkit.Rows("1"))
//tk.MustQuery("select a = b from t").Check(testkit.Rows("0"))
//tk.MustQuery("select a < b + 1 from t").Check(testkit.Rows("0"))
//tk.MustQuery("select a < c from t").Check(testkit.Rows("0"))
//tk.MustQuery("select b < a from t").Check(testkit.Rows("1"))
//tk.MustQuery("select b = a from t").Check(testkit.Rows("0"))
//tk.MustQuery("select b > a from t").Check(testkit.Rows("0"))
//tk.MustQuery("select c > a from t").Check(testkit.Rows("0"))
}
2 changes: 1 addition & 1 deletion expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,7 @@ func allowCmpArgsRefining4PlanCache(ctx sessionctx.Context, args []Expression) (
// `non-int constant <cmp> int column`. E.g., `a < 1.1` will be rewritten to `a < 2`. It also handles comparing year type
// with int constant if the int constant falls into a sensible year representation.
// This refine operation depends on the values of these args, but these values can change when using plan-cache.
// So we have to skip this operation or mark the plan as over-optimized when using plan-cache.
// So we have to skip this operation or mark the plan as over-optimized when using plan-caches.
func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Expression) []Expression {
arg0Type, arg1Type := args[0].GetType(), args[1].GetType()
arg0IsInt := arg0Type.EvalType() == types.ETInt
Expand Down