From ed2555a0ef3e28114260fdbec093202a5a28bb73 Mon Sep 17 00:00:00 2001 From: HuaiyuXu <391585975@qq.com> Date: Thu, 25 May 2017 14:39:03 +0800 Subject: [PATCH] *: add GetTypeClass() function for Expression interface (#3321) --- expression/column.go | 5 +++++ expression/expression.go | 26 ++++++++++++++++++-------- expression/scalar_function.go | 5 +++++ util/types/field_type.go | 2 +- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/expression/column.go b/expression/column.go index e860c0bcbc1ca..aa95fd3ee29b5 100644 --- a/expression/column.go +++ b/expression/column.go @@ -157,6 +157,11 @@ func (col *Column) GetType() *types.FieldType { return col.RetType } +// GetTypeClass implements Expression interface. +func (col *Column) GetTypeClass() types.TypeClass { + return col.RetType.ToClass() +} + // Eval implements Expression interface. func (col *Column) Eval(row []types.Datum) (types.Datum, error) { return row[col.Index], nil diff --git a/expression/expression.go b/expression/expression.go index 4cf7a8d7ca6e2..5acd656b8c575 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -75,6 +75,9 @@ type Expression interface { // GetType gets the type that the expression returns. GetType() *types.FieldType + // GetTypeClass gets the TypeClass that the expression returns. + GetTypeClass() types.TypeClass + // Clone copies an expression totally. Clone() Expression @@ -134,8 +137,7 @@ func evalExprToInt(expr Expression, row []types.Datum, sc *variable.StatementCon if val.IsNull() || err != nil { return res, val.IsNull(), errors.Trace(err) } - tc := expr.GetType().ToClass() - if tc == types.ClassInt { + if expr.GetTypeClass() == types.ClassInt { return val.GetInt64(), false, nil } else if IsHybridType(expr) { res, err = val.ToInt64(sc) @@ -150,8 +152,7 @@ func evalExprToReal(expr Expression, row []types.Datum, sc *variable.StatementCo if val.IsNull() || err != nil { return res, val.IsNull(), errors.Trace(err) } - tc := expr.GetType().ToClass() - if tc == types.ClassReal { + if expr.GetTypeClass() == types.ClassReal { return val.GetFloat64(), false, nil } else if IsHybridType(expr) { res, err = val.ToFloat64(sc) @@ -166,8 +167,7 @@ func evalExprToDecimal(expr Expression, row []types.Datum, sc *variable.Statemen if val.IsNull() || err != nil { return res, val.IsNull(), errors.Trace(err) } - tc := expr.GetType().ToClass() - if tc == types.ClassDecimal { + if expr.GetTypeClass() == types.ClassDecimal { return val.GetMysqlDecimal(), false, nil } else if IsHybridType(expr) { res, err = val.ToDecimal(sc) @@ -182,8 +182,7 @@ func evalExprToString(expr Expression, row []types.Datum, _ *variable.StatementC if val.IsNull() || err != nil { return res, val.IsNull(), errors.Trace(err) } - tc := expr.GetType().ToClass() - if tc == types.ClassString { + if expr.GetTypeClass() == types.ClassString { // We cannot use val.GetString() directly. // For example, `Bit` is regarded as ClassString, // while we can not use val.GetString() to get the value of a Bit variable, @@ -196,6 +195,9 @@ func evalExprToString(expr Expression, row []types.Datum, _ *variable.StatementC // evalExprToTime evaluates `expr` to TIME type. func evalExprToTime(expr Expression, row []types.Datum, _ *variable.StatementContext) (res types.Time, isNull bool, err error) { + if IsHybridType(expr) { + return res, true, nil + } val, err := expr.Eval(row) if val.IsNull() || err != nil { return res, val.IsNull(), errors.Trace(err) @@ -210,6 +212,9 @@ func evalExprToTime(expr Expression, row []types.Datum, _ *variable.StatementCon // evalExprToDuration evaluates `expr` to DURATION type. func evalExprToDuration(expr Expression, row []types.Datum, _ *variable.StatementContext) (res types.Duration, isNull bool, err error) { + if IsHybridType(expr) { + return res, true, nil + } val, err := expr.Eval(row) if val.IsNull() || err != nil { return res, val.IsNull(), errors.Trace(err) @@ -266,6 +271,11 @@ func (c *Constant) GetType() *types.FieldType { return c.RetType } +// GetTypeClass implements Expression interface. +func (c *Constant) GetTypeClass() types.TypeClass { + return c.RetType.ToClass() +} + // Eval implements Expression interface. func (c *Constant) Eval(_ []types.Datum) (types.Datum, error) { return c.Value, nil diff --git a/expression/scalar_function.go b/expression/scalar_function.go index eca9f8a0b27ce..7e6ed74e0e228 100644 --- a/expression/scalar_function.go +++ b/expression/scalar_function.go @@ -115,6 +115,11 @@ func (sf *ScalarFunction) GetType() *types.FieldType { return sf.RetType } +// GetTypeClass implements Expression interface. +func (sf *ScalarFunction) GetTypeClass() types.TypeClass { + return sf.RetType.ToClass() +} + // Equal implements Expression interface. func (sf *ScalarFunction) Equal(e Expression, ctx context.Context) bool { fun, ok := e.(*ScalarFunction) diff --git a/util/types/field_type.go b/util/types/field_type.go index 1e4ab1f780f37..763bb0a647ae2 100644 --- a/util/types/field_type.go +++ b/util/types/field_type.go @@ -26,7 +26,7 @@ const ( UnspecifiedLength int = -1 ) -// TypeClass classifies types, used for type inference. +// TypeClass classifies field types, used for type inference. type TypeClass byte // TypeClass values.