diff --git a/cmd/explaintest/r/explain_generate_column_substitute.result b/cmd/explaintest/r/explain_generate_column_substitute.result index f61e8796fe168..5162adb37f49c 100644 --- a/cmd/explaintest/r/explain_generate_column_substitute.result +++ b/cmd/explaintest/r/explain_generate_column_substitute.result @@ -558,3 +558,15 @@ select * from PK_S_MULTI_30_tmp use index (eidx) where truncate(col1, 3) <= trun COL1 COL2 COL3 -1.7976931348623157e308 0 0 -1.7976931348623157e308 1 0 +create table t004(a date); +insert into t004 values ('2021-08-20'); +select * from t004 where timestampadd(microsecond, 1, a) = timestampadd(microsecond, 1, '2021-08-20'); +a +2021-08-20 +alter table t004 add index eidx ((timestampadd(microsecond, 1, a))); +select * from t004 use index(eidx) where timestampadd(microsecond, 1, a) = timestampadd(microsecond, 1, '2021-08-20'); +a +2021-08-20 +select * from t004 ignore index (eidx) where timestampadd(microsecond, 1, a) = timestampadd(microsecond, 1, '2021-08-20'); +a +2021-08-20 diff --git a/cmd/explaintest/t/explain_generate_column_substitute.test b/cmd/explaintest/t/explain_generate_column_substitute.test index 06a546a05c6e5..152d2c2a6dc7f 100644 --- a/cmd/explaintest/t/explain_generate_column_substitute.test +++ b/cmd/explaintest/t/explain_generate_column_substitute.test @@ -252,3 +252,10 @@ select * from `PK_S_MULTI_30_tmp` ignore index (expression_index) where floor(c alter table PK_S_MULTI_30_tmp add index eidx ((truncate(col1, 3))); select * from PK_S_MULTI_30_tmp ignore index (eidx) where truncate(col1, 3) <= truncate(-1.7976931348623157e308, 3); select * from PK_S_MULTI_30_tmp use index (eidx) where truncate(col1, 3) <= truncate(-1.7976931348623157e308, 3); + +create table t004(a date); +insert into t004 values ('2021-08-20'); +select * from t004 where timestampadd(microsecond, 1, a) = timestampadd(microsecond, 1, '2021-08-20'); +alter table t004 add index eidx ((timestampadd(microsecond, 1, a))); +select * from t004 use index(eidx) where timestampadd(microsecond, 1, a) = timestampadd(microsecond, 1, '2021-08-20'); +select * from t004 ignore index (eidx) where timestampadd(microsecond, 1, a) = timestampadd(microsecond, 1, '2021-08-20'); diff --git a/expression/builtin_time.go b/expression/builtin_time.go index dcaac7b8556e7..e6a61019a40e6 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -6714,7 +6714,20 @@ func (c *timestampAddFunctionClass) getFunction(ctx sessionctx.Context, args []E if err != nil { return nil, err } - bf.tp = &types.FieldType{Tp: mysql.TypeString, Flen: mysql.MaxDatetimeWidthNoFsp, Decimal: types.UnspecifiedLength} + flen := mysql.MaxDatetimeWidthNoFsp + con, ok := args[0].(*Constant) + if !ok { + return nil, errors.New("should not happened") + } + unit, null, err := con.EvalString(ctx, chunk.Row{}) + if null || err != nil { + return nil, errors.New("should not happened") + } + if unit == ast.TimeUnitMicrosecond.String() { + flen = mysql.MaxDatetimeWidthWithFsp + } + + bf.tp.Flen = flen sig := &builtinTimestampAddSig{bf} sig.setPbCode(tipb.ScalarFuncSig_TimestampAdd) return sig, nil diff --git a/expression/typeinfer_test.go b/expression/typeinfer_test.go index 8cba8c5ef6b8f..9c526712419ec 100644 --- a/expression/typeinfer_test.go +++ b/expression/typeinfer_test.go @@ -1232,13 +1232,14 @@ func (s *InferTypeSuite) createTestCase4TimeFuncs() []typeInferTestCase { {`date_format('2017-06-15', '%r%r%r%r')`, mysql.TypeVarString, charset.CharsetUTF8MB4, mysql.NotNullFlag, 44, types.UnspecifiedLength}, {`date_format(151113102019.12, '%r%r%r%r')`, mysql.TypeVarString, charset.CharsetUTF8MB4, mysql.NotNullFlag, 44, types.UnspecifiedLength}, - {"timestampadd(HOUR, c_int_d, c_timestamp_d)", mysql.TypeString, charset.CharsetUTF8MB4, 0, 19, types.UnspecifiedLength}, - {"timestampadd(minute, c_double_d, c_timestamp_d)", mysql.TypeString, charset.CharsetUTF8MB4, 0, 19, types.UnspecifiedLength}, - {"timestampadd(SeconD, c_int_d, c_char)", mysql.TypeString, charset.CharsetUTF8MB4, 0, 19, types.UnspecifiedLength}, - {"timestampadd(SeconD, c_varchar, c_time_d)", mysql.TypeString, charset.CharsetUTF8MB4, 0, 19, types.UnspecifiedLength}, - {"timestampadd(SeconD, c_int_d, c_datetime)", mysql.TypeString, charset.CharsetUTF8MB4, 0, 19, types.UnspecifiedLength}, - {"timestampadd(SeconD, c_double_d, c_bchar)", mysql.TypeString, charset.CharsetUTF8MB4, 0, 19, types.UnspecifiedLength}, - {"timestampadd(SeconD, c_int_d, c_blob_d)", mysql.TypeString, charset.CharsetUTF8MB4, 0, 19, types.UnspecifiedLength}, + {"timestampadd(HOUR, c_int_d, c_timestamp_d)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, types.UnspecifiedLength}, + {"timestampadd(minute, c_double_d, c_timestamp_d)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, types.UnspecifiedLength}, + {"timestampadd(SeconD, c_int_d, c_char)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, types.UnspecifiedLength}, + {"timestampadd(SeconD, c_varchar, c_time_d)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, types.UnspecifiedLength}, + {"timestampadd(SeconD, c_int_d, c_datetime)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, types.UnspecifiedLength}, + {"timestampadd(SeconD, c_double_d, c_bchar)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, types.UnspecifiedLength}, + {"timestampadd(SeconD, c_int_d, c_blob_d)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthNoFsp, types.UnspecifiedLength}, + {"timestampadd(microsecond, c_int_d, c_blob_d)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, mysql.MaxDatetimeWidthWithFsp, types.UnspecifiedLength}, {"to_seconds(c_char)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag, 20, 0}, {"to_days(c_char)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag, 20, 0},