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

*: fix the flen type datetime for union/case-when/control-funcs #30588

Merged
merged 39 commits into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1a23a74
bugfix: pr-29498
bestwoody Dec 8, 2021
4211a19
Merge branch 'master' of https://github.com/pingcap/tidb
bestwoody Dec 8, 2021
2ba67ac
Merge branch 'pingcap:master' into bugfix29498
bestwoody Dec 9, 2021
a9669f3
Merge branch 'master' into bugfix29498
bestwoody Dec 9, 2021
4edd160
add test for issue 29498
bestwoody Dec 10, 2021
6e8db44
Merge branch 'bugfix29498' of github.com:bestwoody/tidb into bugfix29498
bestwoody Dec 10, 2021
5df7239
Merge branch 'master' into bugfix29498
bestwoody Dec 10, 2021
647d015
gofmt
bestwoody Dec 10, 2021
7baf630
Merge branch 'bugfix29498' of github.com:bestwoody/tidb into bugfix29498
bestwoody Dec 10, 2021
04603ea
code refine
bestwoody Dec 13, 2021
474886e
Merge branch 'master' into bugfix29498
bestwoody Dec 13, 2021
f2f6bf6
fix test
bestwoody Dec 13, 2021
151edd7
Merge branch 'bugfix29498' of github.com:bestwoody/tidb into bugfix29498
bestwoody Dec 13, 2021
71a8c67
Merge branch 'master' into bugfix29498
bestwoody Dec 13, 2021
e818f8d
update
bestwoody Dec 13, 2021
77c192d
Merge branch 'bugfix29498' of github.com:bestwoody/tidb into bugfix29498
bestwoody Dec 13, 2021
6060663
Merge branch 'master' into bugfix29498
bestwoody Dec 13, 2021
4033c2e
Merge branch 'master' into bugfix29498
bestwoody Dec 13, 2021
9832917
Merge branch 'master' into bugfix29498
bestwoody Dec 13, 2021
b6a61e8
Merge branch 'master' into bugfix29498
bestwoody Dec 13, 2021
b98106d
Merge branch 'master' into bugfix29498
bestwoody Dec 16, 2021
f7b6d7c
Merge branch 'master' into bugfix29498
bestwoody Dec 16, 2021
c1e43a2
fofmt
bestwoody Dec 16, 2021
09778cd
Merge branch 'master' into bugfix29498
bestwoody Dec 16, 2021
a3f77c4
comment format
bestwoody Dec 16, 2021
20ec855
Merge branch 'bugfix29498' of github.com:bestwoody/tidb into bugfix29498
bestwoody Dec 16, 2021
e369534
Merge branch 'master' into bugfix29498
bestwoody Dec 16, 2021
4af5cb8
Merge branch 'master' into bugfix29498
bestwoody Dec 16, 2021
0d8b5f9
Merge branch 'master' into bugfix29498
bestwoody Dec 16, 2021
80caa6b
remove useless code
bestwoody Dec 16, 2021
34e2ef0
Merge branch 'bugfix29498' of github.com:bestwoody/tidb into bugfix29498
bestwoody Dec 16, 2021
3054865
also fix cases of union, case_when
bestwoody Dec 16, 2021
fc6d156
Merge branch 'master' into bugfix29498
bestwoody Dec 16, 2021
20a6c20
remove duplicated code
bestwoody Dec 16, 2021
859ff44
Merge branch 'bugfix29498' of github.com:bestwoody/tidb into bugfix29498
bestwoody Dec 16, 2021
5c58e8a
update
bestwoody Dec 16, 2021
e9a26bc
add comment for export method TryToFixFlenOfDatetime
bestwoody Dec 16, 2021
0e77c27
update
bestwoody Dec 17, 2021
350c838
Merge branch 'master' into bugfix29498
bestwoody Dec 17, 2021
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
38 changes: 38 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9522,6 +9522,44 @@ func (s *testSerialSuite) TestIssue30289(c *C) {
c.Assert(err.Error(), Matches, "issue30289 build return error")
}

func (s *testSerialSuite) TestIssue29498(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("DROP TABLE IF EXISTS t1;")
tk.MustExec("CREATE TABLE t1 (t3 TIME(3), d DATE, t TIME);")
tk.MustExec("INSERT INTO t1 VALUES ('00:00:00.567', '2002-01-01', '00:00:02');")

res := tk.MustQuery("SELECT CONCAT(IFNULL(t3, d)) AS col1 FROM t1;")
row := res.Rows()[0][0].(string)
c.Assert(len(row), Equals, mysql.MaxDatetimeWidthNoFsp+3+1)
c.Assert(row[len(row)-12:], Equals, "00:00:00.567")

res = tk.MustQuery("SELECT IFNULL(t3, d) AS col1 FROM t1;")
row = res.Rows()[0][0].(string)
c.Assert(len(row), Equals, mysql.MaxDatetimeWidthNoFsp+3+1)
c.Assert(row[len(row)-12:], Equals, "00:00:00.567")

res = tk.MustQuery("SELECT CONCAT(IFNULL(t, d)) AS col1 FROM t1;")
row = res.Rows()[0][0].(string)
c.Assert(len(row), Equals, mysql.MaxDatetimeWidthNoFsp)
c.Assert(row[len(row)-8:], Equals, "00:00:02")

res = tk.MustQuery("SELECT IFNULL(t, d) AS col1 FROM t1;")
row = res.Rows()[0][0].(string)
c.Assert(len(row), Equals, mysql.MaxDatetimeWidthNoFsp)
c.Assert(row[len(row)-8:], Equals, "00:00:02")

res = tk.MustQuery("SELECT CONCAT(xx) FROM (SELECT t3 AS xx FROM t1 UNION SELECT d FROM t1) x ORDER BY -xx LIMIT 1;")
row = res.Rows()[0][0].(string)
c.Assert(len(row), Equals, mysql.MaxDatetimeWidthNoFsp+3+1)
c.Assert(row[len(row)-12:], Equals, "00:00:00.567")

res = tk.MustQuery("SELECT CONCAT(CASE WHEN d IS NOT NULL THEN t3 ELSE d END) AS col1 FROM t1;")
row = res.Rows()[0][0].(string)
c.Assert(len(row), Equals, mysql.MaxDatetimeWidthNoFsp+3+1)
c.Assert(row[len(row)-12:], Equals, "00:00:00.567")
}

// Test invoke Close without invoking Open before for each operators.
func (s *testSerialSuite) TestUnreasonablyClose(c *C) {
defer testleak.AfterTest(c)()
Expand Down
3 changes: 3 additions & 0 deletions expression/builtin_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ func InferType4ControlFuncs(ctx sessionctx.Context, funcName string, lexp, rexp
if resultFieldType.Tp == mysql.TypeEnum || resultFieldType.Tp == mysql.TypeSet {
resultFieldType.Tp = mysql.TypeVarchar
}
} else if resultFieldType.Tp == mysql.TypeDatetime {
types.TryToFixFlenOfDatetime(resultFieldType)
}
return resultFieldType, nil
}
Expand Down Expand Up @@ -204,6 +206,7 @@ func (c *caseWhenFunctionClass) getFunction(ctx sessionctx.Context, args []Expre
decimal = 0
}
fieldTp.Decimal, fieldTp.Flen = decimal, flen
types.TryToFixFlenOfDatetime(fieldTp)
if fieldTp.EvalType().IsStringKind() && !isBinaryStr {
fieldTp.Charset, fieldTp.Collate = DeriveCollationFromExprs(ctx, args...)
if fieldTp.Charset == charset.CharsetBin && fieldTp.Collate == charset.CollationBin {
Expand Down
4 changes: 4 additions & 0 deletions expression/typeinfer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,8 @@ func (s *InferTypeSuite) createTestCase4ControlFuncs() []typeInferTestCase {
{"ifnull(null, null)", mysql.TypeNull, charset.CharsetBin, mysql.BinaryFlag, 0, 0},
{"ifnull(c_double_d, c_timestamp_d)", mysql.TypeVarchar, charset.CharsetUTF8MB4, 0, 22, types.UnspecifiedLength},
{"ifnull(c_json, c_decimal)", mysql.TypeLongBlob, charset.CharsetUTF8MB4, 0, math.MaxUint32, types.UnspecifiedLength},
{"ifnull(c_time, c_date)", mysql.TypeDatetime, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp + 3 + 1, 3},
{"ifnull(c_time_d, c_date)", mysql.TypeDatetime, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, 0},
{"if(c_int_d, c_decimal, c_int_d)", mysql.TypeNewDecimal, charset.CharsetBin, mysql.BinaryFlag, 14, 3},
{"if(c_int_d, c_char, c_int_d)", mysql.TypeString, charset.CharsetUTF8MB4, mysql.BinaryFlag, 20, types.UnspecifiedLength},
{"if(c_int_d, c_binary, c_int_d)", mysql.TypeString, charset.CharsetBin, mysql.BinaryFlag, 20, types.UnspecifiedLength},
Expand All @@ -838,6 +840,8 @@ func (s *InferTypeSuite) createTestCase4ControlFuncs() []typeInferTestCase {
{"case when c_int_d > 1 then c_double_d else c_bchar end", mysql.TypeString, charset.CharsetUTF8MB4, mysql.BinaryFlag, 22, types.UnspecifiedLength},
{"case when c_int_d > 2 then c_double_d when c_int_d < 1 then c_decimal else c_double_d end", mysql.TypeDouble, charset.CharsetBin, mysql.BinaryFlag, 22, 3},
{"case when c_double_d > 2 then c_decimal else 1 end", mysql.TypeNewDecimal, charset.CharsetBin, mysql.BinaryFlag, 6, 3},
{"case when c_time is not null then c_time else c_date end", mysql.TypeDatetime, charset.CharsetUTF8MB4, mysql.BinaryFlag, mysql.MaxDatetimeWidthNoFsp + 3 + 1, 3},
{"case when c_time_d is not null then c_time_d else c_date end", mysql.TypeDatetime, charset.CharsetUTF8MB4, mysql.BinaryFlag, mysql.MaxDatetimeWidthNoFsp, 0},
{"case when null then null else null end", mysql.TypeNull, charset.CharsetBin, mysql.BinaryFlag, 0, types.UnspecifiedLength},
}
}
Expand Down
1 change: 1 addition & 0 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,7 @@ func unionJoinFieldType(a, b *types.FieldType) *types.FieldType {
resultTp.Decimal = mathutil.Max(a.Decimal, b.Decimal)
// `Flen - Decimal` is the fraction before '.'
resultTp.Flen = mathutil.Max(a.Flen-a.Decimal, b.Flen-b.Decimal) + resultTp.Decimal
types.TryToFixFlenOfDatetime(resultTp)
if resultTp.EvalType() != types.ETInt && (a.EvalType() == types.ETInt || b.EvalType() == types.ETInt) && resultTp.Flen < mysql.MaxIntWidth {
resultTp.Flen = mysql.MaxIntWidth
}
Expand Down
10 changes: 10 additions & 0 deletions types/field_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ func AggFieldType(tps []*FieldType) *FieldType {
return &currType
}

// TryToFixFlenOfDatetime try to fix flen of Datetime for specific func or other field merge cases
func TryToFixFlenOfDatetime(resultTp *FieldType) {
if resultTp.Tp == mysql.TypeDatetime {
resultTp.Flen = mysql.MaxDatetimeWidthNoFsp
if resultTp.Decimal > 0 {
resultTp.Flen += resultTp.Decimal + 1
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the returned bool value is useless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

}

// AggregateEvalType aggregates arguments' EvalType of a multi-argument function.
func AggregateEvalType(fts []*FieldType, flag *uint) EvalType {
var (
Expand Down