Skip to content

Commit

Permalink
expression,planner: fix to preserve the precision information of a ti…
Browse files Browse the repository at this point in the history
…mestamp-typed column in the plan cache (#8619)
  • Loading branch information
dbjoa authored and zz-jason committed Dec 10, 2018
1 parent e3f3ac2 commit 18b33fb
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 10 deletions.
6 changes: 1 addition & 5 deletions expression/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,7 @@ func (c *Constant) Eval(_ chunk.Row) (types.Datum, error) {
c.Value.SetNull()
return c.Value, nil
}
retType := types.NewFieldType(c.RetType.Tp)
if retType.Tp == mysql.TypeUnspecified {
retType.Tp = mysql.TypeVarString
}
val, err := dt.ConvertTo(sf.GetCtx().GetSessionVars().StmtCtx, retType)
val, err := dt.ConvertTo(sf.GetCtx().GetSessionVars().StmtCtx, c.RetType)
if err != nil {
return dt, err
}
Expand Down
3 changes: 1 addition & 2 deletions planner/core/expression_rewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -1242,8 +1242,7 @@ func (er *expressionRewriter) funcCallToExpression(v *ast.FuncCallExpr) {
er.ctxStack = er.ctxStack[:stackLen-len(v.Args)]
if _, ok := expression.DeferredFunctions[v.FnName.L]; er.useCache() && ok {
function, er.err = expression.NewFunctionBase(er.ctx, v.FnName.L, &v.Type, args...)
c := &expression.Constant{Value: types.NewDatum(nil), RetType: &v.Type, DeferredExpr: function}
c.GetType().Tp = function.GetType().Tp
c := &expression.Constant{Value: types.NewDatum(nil), RetType: types.CloneFieldType(function.GetType()), DeferredExpr: function}
er.ctxStack = append(er.ctxStack, c)
} else {
function, er.err = expression.NewFunction(er.ctx, v.FnName.L, &v.Type, args...)
Expand Down
4 changes: 2 additions & 2 deletions planner/core/prepare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (s *testPlanSuite) TestPrepareCacheDeferredFunction(c *C) {
tk.MustExec("prepare sel1 from 'select id, c1 from t1 where c1 < now(3)'")

sql1 := "execute sel1"
expectedPattern := `IndexReader\(Index\(t1.idx1\)\[\[-inf,[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9].000\)\]\)`
expectedPattern := `IndexReader\(Index\(t1.idx1\)\[\[-inf,[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9].[0-9][0-9][0-9]\)\]\)`

var cnt [2]float64
var planStr [2]string
Expand All @@ -176,7 +176,7 @@ func (s *testPlanSuite) TestPrepareCacheDeferredFunction(c *C) {
counter.Write(pb)
cnt[i] = pb.GetCounter().GetValue()
c.Check(cnt[i], Equals, float64(i))
time.Sleep(time.Second * 1)
time.Sleep(time.Millisecond * 10)
}
c.Assert(planStr[0] < planStr[1], IsTrue)
}
Expand Down
11 changes: 10 additions & 1 deletion types/field_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ func NewFieldType(tp byte) *FieldType {
}
}

// CloneFieldType clones the given FieldType.
func CloneFieldType(src *FieldType) *FieldType {
ft := *src
return &ft
}

// AggFieldType aggregates field types for a multi-argument function like `IF`, `IFNULL`, `COALESCE`
// whose return type is determined by the arguments' FieldTypes.
// Aggregation is performed by MergeFieldType function.
Expand Down Expand Up @@ -123,11 +129,14 @@ func setTypeFlag(flag *uint, flagItem uint, on bool) {
func DefaultParamTypeForValue(value interface{}, tp *FieldType) {
switch value.(type) {
case nil:
tp.Tp = mysql.TypeUnspecified
tp.Tp = mysql.TypeVarString
tp.Flen = UnspecifiedLength
tp.Decimal = UnspecifiedLength
default:
DefaultTypeForValue(value, tp)
if tp.Tp == mysql.TypeUnspecified {
tp.Tp = mysql.TypeVarString
}
}
}

Expand Down

0 comments on commit 18b33fb

Please sign in to comment.