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: adjust int constant when compare with year type (#21099) #21283

Merged
merged 7 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6285,22 +6285,16 @@ func (s *testSuite) TestIssue19667(c *C) {
tk.MustQuery(`SELECT DATE_ADD(a, INTERVAL 1 SECOND) FROM t`).Check(testkit.Rows("1988-04-17 02:00:00"))
}

func (s *testSuite) TestTxnRetry(c *C) {
func (s *testSuite) TestIssue20305(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk2 := testkit.NewTestKit(c, s.store)
tk.MustExec("use test;")
tk2.MustExec("use test;")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int);")
tk.MustExec("insert into t values (1)")
tk.MustExec("set @@tidb_disable_txn_auto_retry=0;")
tk.MustExec("set autocommit=0;")
tk.MustQuery("select * from t;").Check(testkit.Rows("1"))
tk.MustExec("SET SQL_SELECT_LIMIT=DEFAULT;")

tk2.MustExec("update t set a=2")

tk.MustExec("update t set a=3")
tk.MustExec("commit")
tk.MustQuery("select * from t").Check(testkit.Rows("3"))
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t2 (a year(4))")
tk.MustExec("insert into t2 values(69)")
tk.MustQuery("select * from t2 where a <= 69").Check(testkit.Rows("2069"))
// the following test is a regression test that matches MySQL's behavior.
tk.MustExec("drop table if exists t3")
tk.MustExec("CREATE TABLE `t3` (`y` year DEFAULT NULL, `a` int DEFAULT NULL)")
tk.MustExec("INSERT INTO `t3` VALUES (2069, 70), (2010, 11), (2155, 2156), (2069, 69)")
tk.MustQuery("SELECT * FROM `t3` where y <= a").Check(testkit.Rows("2155 2156"))
}
19 changes: 18 additions & 1 deletion expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,8 @@ func RefineComparedConstant(ctx sessionctx.Context, targetFieldType types.FieldT
}

// refineArgs will rewrite the arguments if the compare expression is `int column <cmp> non-int constant` or
// `non-int constant <cmp> int column`. E.g., `a < 1.1` will be rewritten to `a < 2`.
// `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.
func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Expression) []Expression {
if ContainMutableConst(ctx, args) {
return args
Expand Down Expand Up @@ -1325,6 +1326,22 @@ func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Express
}
}
}
// int constant [cmp] year type
if arg0IsCon && arg0IsInt && arg1Type.Tp == mysql.TypeYear {
adjusted, failed := types.AdjustYear(arg0.Value.GetInt64(), false)
if failed == nil {
arg0.Value.SetInt64(adjusted)
finalArg0 = arg0
}
}
// year type [cmp] int constant
if arg1IsCon && arg1IsInt && arg0Type.Tp == mysql.TypeYear {
adjusted, failed := types.AdjustYear(arg1.Value.GetInt64(), false)
if failed == nil {
arg1.Value.SetInt64(adjusted)
finalArg1 = arg1
}
}
if isExceptional && (c.op == opcode.EQ || c.op == opcode.NullEQ) {
// This will always be false.
return []Expression{NewZero(), NewOne()}
Expand Down
4 changes: 2 additions & 2 deletions types/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -1224,8 +1224,8 @@ func adjustYear(y int) int {
}

// AdjustYear is used for adjusting year and checking its validation.
func AdjustYear(y int64, shouldAdjust bool) (int64, error) {
if y == 0 && !shouldAdjust {
func AdjustYear(y int64, adjustZero bool) (int64, error) {
if y == 0 && !adjustZero {
return y, nil
}
y = int64(adjustYear(int(y)))
Expand Down
18 changes: 13 additions & 5 deletions util/ranger/ranger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1234,6 +1234,7 @@ func (s *testRangerSuite) TestIndexRangeForYear(c *C) {
testKit.MustExec("INSERT INTO t VALUES (1), (70), (99), (0), ('0')")
testKit.MustQuery("SELECT * FROM t WHERE a < 15698").Check(testkit.Rows("0", "1970", "1999", "2000", "2001"))
testKit.MustQuery("SELECT * FROM t WHERE a <= 0").Check(testkit.Rows("0"))
testKit.MustQuery("SELECT * FROM t WHERE a <= 1").Check(testkit.Rows("0", "1970", "1999", "2000", "2001"))
testKit.MustQuery("SELECT * FROM t WHERE a < 2000").Check(testkit.Rows("0", "1970", "1999"))
testKit.MustQuery("SELECT * FROM t WHERE a > -1").Check(testkit.Rows("0", "1970", "1999", "2000", "2001"))

Expand Down Expand Up @@ -1261,14 +1262,21 @@ func (s *testRangerSuite) TestIndexRangeForYear(c *C) {
{
indexPos: 0,
exprStr: `a not in (1, 2, 70)`,
accessConds: "[not(in(test.t.a, 1, 2, 70))]",
accessConds: "[not(in(test.t.a, 1, 2, 70))]", // this is in accordance with MySQL, MySQL won't interpret 70 here as 1970
filterConds: "[]",
resultStr: `[(NULL,1970) (1970,2001) (2002,+inf]]`,
},
{
indexPos: 0,
exprStr: `a = 1 or a = 2 or a = 70`,
accessConds: "[or(eq(test.t.a, 2001), or(eq(test.t.a, 2002), eq(test.t.a, 1970)))]", // this is in accordance with MySQL, MySQL won't interpret 70 here as 1970
filterConds: "[]",
resultStr: `[[1970,1970] [2001,2002]]`,
},
{
indexPos: 0,
exprStr: `a not in (99)`,
accessConds: "[ne(test.t.a, 99)]",
accessConds: "[ne(test.t.a, 1999)]", // this is in accordance with MySQL
filterConds: "[]",
resultStr: `[[-inf,1999) (1999,+inf]]`,
},
Expand Down Expand Up @@ -1296,7 +1304,7 @@ func (s *testRangerSuite) TestIndexRangeForYear(c *C) {
{
indexPos: 0,
exprStr: `a != 1`,
accessConds: "[ne(test.t.a, 1)]",
accessConds: "[ne(test.t.a, 2001)]",
filterConds: "[]",
resultStr: `[[-inf,2001) (2001,+inf]]`,
},
Expand All @@ -1309,13 +1317,13 @@ func (s *testRangerSuite) TestIndexRangeForYear(c *C) {
},
{
exprStr: "a < 99 or a > 01",
accessConds: "[or(lt(test.t.a, 99), gt(test.t.a, 1))]",
accessConds: "[or(lt(test.t.a, 1999), gt(test.t.a, 2001))]",
filterConds: "[]",
resultStr: "[[-inf,1999) (2001,+inf]]",
},
{
exprStr: "a >= 70 and a <= 69",
accessConds: "[ge(test.t.a, 70) le(test.t.a, 69)]",
accessConds: "[ge(test.t.a, 1970) le(test.t.a, 2069)]",
filterConds: "[]",
resultStr: "[[1970,2069]]",
},
Expand Down