From d07cee1f8e2ccda7bea7a15d334ba302aed5f483 Mon Sep 17 00:00:00 2001 From: Zhang Jian Date: Tue, 12 Feb 2019 11:48:55 +0800 Subject: [PATCH] expression: handle ENUM in builtin function Values() (#9225) --- expression/builtin_other.go | 21 +++++++++++++++------ expression/column.go | 12 ++++-------- expression/integration_test.go | 11 +++++++++++ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/expression/builtin_other.go b/expression/builtin_other.go index 6e8cdfe21555a..cf9e95da35f4c 100644 --- a/expression/builtin_other.go +++ b/expression/builtin_other.go @@ -615,13 +615,22 @@ func (b *builtinValuesStringSig) evalString(_ chunk.Row) (string, bool, error) { if row.IsEmpty() { return "", true, errors.New("Session current insert values is nil") } - if b.offset < row.Len() { - if row.IsNull(b.offset) { - return "", true, nil - } - return row.GetString(b.offset), false, nil + if b.offset >= row.Len() { + return "", true, errors.Errorf("Session current insert values len %d and column's offset %v don't match", row.Len(), b.offset) } - return "", true, errors.Errorf("Session current insert values len %d and column's offset %v don't match", row.Len(), b.offset) + + if row.IsNull(b.offset) { + return "", true, nil + } + + // Specially handle the ENUM/SET/BIT input value. + if retType := b.getRetTp(); retType.Hybrid() { + val := row.GetDatum(b.offset, retType) + res, err := val.ToString() + return res, err != nil, err + } + + return row.GetString(b.offset), false, nil } type builtinValuesTimeSig struct { diff --git a/expression/column.go b/expression/column.go index 551ad98a76a2e..fdae386632503 100644 --- a/expression/column.go +++ b/expression/column.go @@ -230,18 +230,14 @@ func (col *Column) EvalString(ctx sessionctx.Context, row chunk.Row) (string, bo if row.IsNull(col.Index) { return "", true, nil } + + // Specially handle the ENUM/SET/BIT input value. if col.GetType().Hybrid() { val := row.GetDatum(col.Index, col.RetType) - if val.IsNull() { - return "", true, nil - } res, err := val.ToString() - resLen := len([]rune(res)) - if ctx.GetSessionVars().StmtCtx.PadCharToFullLength && col.GetType().Tp == mysql.TypeString && resLen < col.RetType.Flen { - res = res + strings.Repeat(" ", col.RetType.Flen-resLen) - } - return res, err != nil, errors.Trace(err) + return res, err != nil, err } + val := row.GetString(col.Index) if ctx.GetSessionVars().StmtCtx.PadCharToFullLength && col.GetType().Tp == mysql.TypeString { valLen := len([]rune(val)) diff --git a/expression/integration_test.go b/expression/integration_test.go index c01f8364a24ec..65b15106812b6 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -3802,3 +3802,14 @@ func (s *testIntegrationSuite) TestValuesFloat32(c *C) { tk.MustExec(`insert into t values (1, 0.02) on duplicate key update j = values (j);`) tk.MustQuery(`select * from t;`).Check(testkit.Rows(`1 0.02`)) } + +func (s *testIntegrationSuite) TestValuesEnum(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t (a bigint primary key, b enum('a','b','c'));`) + tk.MustExec(`insert into t values (1, "a");`) + tk.MustQuery(`select * from t;`).Check(testkit.Rows(`1 a`)) + tk.MustExec(`insert into t values (1, "b") on duplicate key update b = values(b);`) + tk.MustQuery(`select * from t;`).Check(testkit.Rows(`1 b`)) +}