diff --git a/executor/executor.go b/executor/executor.go index 4dc68b9d98858..892ddba6c184e 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -1591,7 +1591,6 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { sc.Priority = opts.Priority sc.NotFillCache = !opts.SQLCache } - sc.PadCharToFullLength = ctx.GetSessionVars().SQLMode.HasPadCharToFullLengthMode() sc.CastStrToIntStrict = true case *ast.ShowStmt: sc.IgnoreTruncate = true diff --git a/executor/point_get.go b/executor/point_get.go index a2b26299fd126..50f9359165811 100644 --- a/executor/point_get.go +++ b/executor/point_get.go @@ -27,7 +27,6 @@ import ( "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" - "github.com/pingcap/tidb/util/ranger" ) func (b *executorBuilder) buildPointGet(p *plannercore.PointGetPlan) Executor { @@ -185,8 +184,13 @@ func encodeIndexKey(e *baseExecutor, tblInfo *model.TableInfo, idxInfo *model.In sc := e.ctx.GetSessionVars().StmtCtx for i := range idxVals { colInfo := tblInfo.Columns[idxInfo.Columns[i].Offset] + // table.CastValue will append 0x0 if the string value's length is smaller than the BINARY column's length. + // So we don't use CastValue for string value for now. + // TODO: merge two if branch. if colInfo.Tp == mysql.TypeString || colInfo.Tp == mysql.TypeVarString || colInfo.Tp == mysql.TypeVarchar { - idxVals[i], err = ranger.HandlePadCharToFullLength(sc, &colInfo.FieldType, idxVals[i]) + var str string + str, err = idxVals[i].ToString() + idxVals[i].SetString(str) } else { idxVals[i], err = table.CastValue(e.ctx, idxVals[i], colInfo) } diff --git a/executor/point_get_test.go b/executor/point_get_test.go index aa6a1c23a94bd..7734480b227ba 100644 --- a/executor/point_get_test.go +++ b/executor/point_get_test.go @@ -109,57 +109,36 @@ func (s *testPointGetSuite) TestPointGetCharPK(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 char(2) primary key, b char(2));`) + tk.MustExec(`create table t(a char(4) primary key, b char(4));`) tk.MustExec(`insert into t values("aa", "bb");`) - // Test truncate without sql mode `PAD_CHAR_TO_FULL_LENGTH`. + // Test CHAR type. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t where a = "aa";`).Check(testkit.Rows(`aa bb`)) tk.MustPointGet(`select * from t where a = "aab";`).Check(testkit.Rows()) - // Test truncate with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t where a = "aa";`).Check(testkit.Rows(`aa bb`)) - tk.MustPointGet(`select * from t where a = "aab";`).Check(testkit.Rows()) - tk.MustExec(`truncate table t;`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows(`a b`)) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) - - // // Test CHAR BINARY. + // Test CHAR BINARY. tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(a char(2) binary primary key, b char(2));`) tk.MustExec(`insert into t values(" ", " ");`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) + tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) + tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) + tk.MustPointGet(`select * from t where a = "";`).Check(testkit.Rows(` `)) + tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows()) + tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows()) + } func (s *testPointGetSuite) TestPointGetAliasTableCharPK(c *C) { @@ -169,54 +148,31 @@ func (s *testPointGetSuite) TestPointGetAliasTableCharPK(c *C) { tk.MustExec(`create table t(a char(2) primary key, b char(2));`) tk.MustExec(`insert into t values("aa", "bb");`) - // Test truncate without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t tmp where a = "aa";`).Check(testkit.Rows(`aa bb`)) tk.MustPointGet(`select * from t tmp where a = "aab";`).Check(testkit.Rows()) - // Test truncate with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t tmp where a = "aa";`).Check(testkit.Rows(`aa bb`)) - tk.MustPointGet(`select * from t tmp where a = "aab";`).Check(testkit.Rows()) - tk.MustExec(`truncate table t;`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t tmp where a = "a";`).Check(testkit.Rows(`a b`)) tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t tmp where a = "a";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) - // Test CHAR BINARY. tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(a char(2) binary primary key, b char(2));`) tk.MustExec(`insert into t values(" ", " ");`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t tmp where a = "a";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) - - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t tmp where a = "a";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) + tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) + tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) + tk.MustPointGet(`select * from t tmp where a = "";`).Check(testkit.Rows(` `)) + tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows()) + tk.MustPointGet(`select * from t tmp where a = " ";`).Check(testkit.Rows()) // Test both wildcard and column name exist in select field list tk.MustExec(`set @@sql_mode="";`) @@ -260,7 +216,6 @@ func (s *testPointGetSuite) TestIndexLookupChar(c *C) { tk.MustExec(`create table t(a char(2), b char(2), index idx_1(a));`) tk.MustExec(`insert into t values("aa", "bb");`) - // Test truncate without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustIndexLookup(`select * from t where a = "aa";`).Check(testkit.Rows(`aa bb`)) tk.MustIndexLookup(`select * from t where a = "aab";`).Check(testkit.Rows()) @@ -269,58 +224,29 @@ func (s *testPointGetSuite) TestIndexLookupChar(c *C) { tk.MustIndexLookup(`select * from t tmp where a = "aa";`).Check(testkit.Rows(`aa bb`)) tk.MustIndexLookup(`select * from t tmp where a = "aab";`).Check(testkit.Rows()) - // Test truncate with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustIndexLookup(`select * from t where a = "aa";`).Check(testkit.Rows(`aa bb`)) - tk.MustTableDual(`select * from t where a = "aab";`).Check(testkit.Rows()) - tk.MustExec(`truncate table t;`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustIndexLookup(`select * from t where a = "a";`).Check(testkit.Rows(`a b`)) tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustTableDual(`select * from t where a = "a";`).Check(testkit.Rows()) - tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustTableDual(`select * from t where a = "a ";`).Check(testkit.Rows()) - // Test CHAR BINARY. tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(a char(2) binary, b char(2), index idx_1(a));`) tk.MustExec(`insert into t values(" ", " ");`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. tk.MustExec(`set @@sql_mode="";`) tk.MustIndexLookup(`select * from t where a = "a";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustIndexLookup(`select * from t where a = "a";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - - // Test query with table alias in `PAD_CHAR_TO_FULL_LENGTH` mode - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustIndexLookup(`select * from t tmp where a = "a";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b`)) - tk.MustIndexLookup(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) - tk.MustIndexLookup(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) - tk.MustIndexLookup(`select * from t tmp where a = " ";`).Check(testkit.Rows(` `)) + tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) + tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) + tk.MustIndexLookup(`select * from t where a = "";`).Check(testkit.Rows(` `)) + tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows()) + tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows()) + tk.MustIndexLookup(`select * from t where a = " ";`).Check(testkit.Rows()) + } func (s *testPointGetSuite) TestPointGetVarcharPK(c *C) { @@ -330,60 +256,32 @@ func (s *testPointGetSuite) TestPointGetVarcharPK(c *C) { tk.MustExec(`create table t(a varchar(2) primary key, b varchar(2));`) tk.MustExec(`insert into t values("aa", "bb");`) - // Test truncate without sql mode `PAD_CHAR_TO_FULL_LENGTH`. - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t where a = "aa";`).Check(testkit.Rows(`aa bb`)) tk.MustPointGet(`select * from t where a = "aab";`).Check(testkit.Rows()) - // Test truncate with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t where a = "aa";`).Check(testkit.Rows(`aa bb`)) - tk.MustPointGet(`select * from t where a = "aab";`).Check(testkit.Rows()) - tk.MustExec(`truncate table t;`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. tk.MustExec(`set @@sql_mode="";`) tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) - // // Test VARCHAR BINARY. tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(a varchar(2) binary primary key, b varchar(2));`) tk.MustExec(`insert into t values(" ", " ");`) tk.MustExec(`insert into t values("a ", "b ");`) - // Test trailing spaces without sql mode `PAD_CHAR_TO_FULL_LENGTH`. - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. tk.MustExec(`set @@sql_mode="";`) - tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows(`a b `)) + tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) + tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) + tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) + tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows()) - // Test trailing spaces with sql mode `PAD_CHAR_TO_FULL_LENGTH`. - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows(`a b `)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) - tk.MustPointGet(`select * from t where a = " ";`).Check(testkit.Rows(` `)) } func (s *testPointGetSuite) TestPointGetBinaryPK(c *C) { @@ -399,19 +297,11 @@ func (s *testPointGetSuite) TestPointGetBinaryPK(c *C) { tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t where a = "a\0";`).Check(testkit.Rows("a\x00 b\x00")) - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t where a = "a\0";`).Check(testkit.Rows("a\x00 b\x00")) - tk.MustExec(`insert into t values("a ", "b ");`) tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. tk.MustPointGet(`select * from t where a = "a";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) tk.MustPointGet(`select * from t where a = "a ";`).Check(testkit.Rows()) @@ -430,19 +320,11 @@ func (s *testPointGetSuite) TestPointGetAliasTableBinaryPK(c *C) { tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t tmp where a = "a\0";`).Check(testkit.Rows("a\x00 b\x00")) - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustPointGet(`select * from t tmp where a = "a";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) - tk.MustPointGet(`select * from t tmp where a = "a\0";`).Check(testkit.Rows("a\x00 b\x00")) - tk.MustExec(`insert into t values("a ", "b ");`) tk.MustPointGet(`select * from t tmp where a = "a";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b `)) tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. tk.MustPointGet(`select * from t tmp where a = "a";`).Check(testkit.Rows()) tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b `)) tk.MustPointGet(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) @@ -468,27 +350,15 @@ func (s *testPointGetSuite) TestIndexLookupBinary(c *C) { tk.MustIndexLookup(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) tk.MustIndexLookup(`select * from t tmp where a = "a\0";`).Check(testkit.Rows("a\x00 b\x00")) - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. - tk.MustExec(`set @@sql_mode="PAD_CHAR_TO_FULL_LENGTH";`) - tk.MustIndexLookup(`select * from t where a = "a";`).Check(testkit.Rows()) - tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) - tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) - tk.MustIndexLookup(`select * from t where a = "a\0";`).Check(testkit.Rows("a\x00 b\x00")) - tk.MustExec(`insert into t values("a ", "b ");`) tk.MustIndexLookup(`select * from t where a = "a";`).Check(testkit.Rows()) tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) - // `PAD_CHAR_TO_FULL_LENGTH` should not affect the result. tk.MustIndexLookup(`select * from t where a = "a";`).Check(testkit.Rows()) tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows(`a b `)) tk.MustIndexLookup(`select * from t where a = "a ";`).Check(testkit.Rows()) - // Test query with table alias in `PAD_CHAR_TO_FULL_LENGTH` mode - tk.MustIndexLookup(`select * from t tmp where a = "a";`).Check(testkit.Rows()) - tk.MustIndexLookup(`select * from t tmp where a = "a ";`).Check(testkit.Rows(`a b `)) - tk.MustIndexLookup(`select * from t tmp where a = "a ";`).Check(testkit.Rows()) } func (s *testPointGetSuite) TestIssue10448(c *C) { diff --git a/expression/column.go b/expression/column.go index 98601053c328d..c18d1aae25d3d 100644 --- a/expression/column.go +++ b/expression/column.go @@ -106,10 +106,6 @@ func (col *CorrelatedColumn) EvalString(ctx sessionctx.Context, row chunk.Row) ( return "", true, nil } res, err := col.Data.ToString() - resLen := len([]rune(res)) - if resLen < col.RetType.Flen && ctx.GetSessionVars().StmtCtx.PadCharToFullLength { - res = res + strings.Repeat(" ", col.RetType.Flen-resLen) - } return res, err != nil, err } @@ -268,7 +264,7 @@ func (col *Column) VecEvalReal(ctx sessionctx.Context, input *chunk.Chunk, resul // VecEvalString evaluates this expression in a vectorized manner. func (col *Column) VecEvalString(ctx sessionctx.Context, input *chunk.Chunk, result *chunk.Column) error { - if col.RetType.Hybrid() || ctx.GetSessionVars().StmtCtx.PadCharToFullLength { + if col.RetType.Hybrid() { it := chunk.NewIterator4Chunk(input) result.ReserveString(input.NumRows()) for row := it.Begin(); row != it.End(); row = it.Next() { @@ -380,12 +376,6 @@ func (col *Column) EvalString(ctx sessionctx.Context, row chunk.Row) (string, bo } val := row.GetString(col.Index) - if ctx.GetSessionVars().StmtCtx.PadCharToFullLength && col.GetType().Tp == mysql.TypeString { - valLen := len([]rune(val)) - if valLen < col.RetType.Flen { - val = val + strings.Repeat(" ", col.RetType.Flen-valLen) - } - } return val, false, nil } diff --git a/expression/column_test.go b/expression/column_test.go index 38a7384773272..0a80ce470454e 100644 --- a/expression/column_test.go +++ b/expression/column_test.go @@ -229,27 +229,3 @@ func (s *testEvaluatorSuite) TestColHybird(c *C) { c.Assert(v, Equals, result.GetString(i)) } } - -func (s *testEvaluatorSuite) TestPadCharToFullLength(c *C) { - ctx := mock.NewContext() - ctx.GetSessionVars().StmtCtx.PadCharToFullLength = true - - ft := types.NewFieldType(mysql.TypeString) - ft.Flen = 10 - col := &Column{RetType: ft, Index: 0} - input := chunk.New([]*types.FieldType{ft}, 1024, 1024) - for i := 0; i < 1024; i++ { - input.AppendString(0, "xy") - } - result, err := newBuffer(types.ETString, 1024) - c.Assert(err, IsNil) - c.Assert(col.VecEvalString(ctx, input, result), IsNil) - - it := chunk.NewIterator4Chunk(input) - for row, i := it.Begin(), 0; row != it.End(); row, i = it.Next(), i+1 { - v, _, err := col.EvalString(ctx, row) - c.Assert(err, IsNil) - c.Assert(len(v), Equals, ft.Flen) - c.Assert(v, Equals, result.GetString(i)) - } -} diff --git a/planner/core/task.go b/planner/core/task.go index 07ec780fed065..0ce4c483afc6d 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -410,14 +410,13 @@ func (p *PhysicalIndexJoin) GetCost(outerTask, innerTask task) float64 { } func (p *PhysicalHashJoin) avgRowSize(inner PhysicalPlan) (size float64) { - padChar := p.ctx.GetSessionVars().StmtCtx.PadCharToFullLength if inner.statsInfo().HistColl != nil { - size = inner.statsInfo().HistColl.GetAvgRowSizeListInDisk(inner.Schema().Columns, padChar) + size = inner.statsInfo().HistColl.GetAvgRowSizeListInDisk(inner.Schema().Columns) } else { // Estimate using just the type info. cols := inner.Schema().Columns for _, col := range cols { - size += float64(chunk.EstimateTypeWidth(padChar, col.GetType())) + size += float64(chunk.EstimateTypeWidth(col.GetType())) } } return diff --git a/sessionctx/stmtctx/stmtctx.go b/sessionctx/stmtctx/stmtctx.go index ed6d95ba086e0..7c2fe82eb7ddf 100644 --- a/sessionctx/stmtctx/stmtctx.go +++ b/sessionctx/stmtctx/stmtctx.go @@ -68,7 +68,6 @@ type StatementContext struct { OverflowAsWarning bool InShowWarning bool UseCache bool - PadCharToFullLength bool BatchCheck bool InNullRejectCheck bool AllowInvalidDate bool @@ -502,9 +501,6 @@ func (sc *StatementContext) PushDownFlags() uint64 { if sc.DividedByZeroAsWarning { flags |= model.FlagDividedByZeroAsWarning } - if sc.PadCharToFullLength { - flags |= model.FlagPadCharToFullLength - } if sc.InLoadDataStmt { flags |= model.FlagInLoadDataStmt } @@ -590,7 +586,6 @@ func (sc *StatementContext) CopTasksDetails() *CopTasksDetails { func (sc *StatementContext) SetFlagsFromPBFlag(flags uint64) { sc.IgnoreTruncate = (flags & model.FlagIgnoreTruncate) > 0 sc.TruncateAsWarning = (flags & model.FlagTruncateAsWarning) > 0 - sc.PadCharToFullLength = (flags & model.FlagPadCharToFullLength) > 0 sc.InInsertStmt = (flags & model.FlagInInsertStmt) > 0 sc.InSelectStmt = (flags & model.FlagInSelectStmt) > 0 sc.OverflowAsWarning = (flags & model.FlagOverflowAsWarning) > 0 diff --git a/sessionctx/stmtctx/stmtctx_test.go b/sessionctx/stmtctx/stmtctx_test.go index 01926518c644a..c786d5e10fcbf 100644 --- a/sessionctx/stmtctx/stmtctx_test.go +++ b/sessionctx/stmtctx/stmtctx_test.go @@ -84,7 +84,6 @@ func (s *stmtctxSuit) TestStatementContextPushDownFLags(c *C) { {&stmtctx.StatementContext{OverflowAsWarning: true}, 64}, {&stmtctx.StatementContext{IgnoreZeroInDate: true}, 128}, {&stmtctx.StatementContext{DividedByZeroAsWarning: true}, 256}, - {&stmtctx.StatementContext{PadCharToFullLength: true}, 4}, {&stmtctx.StatementContext{InLoadDataStmt: true}, 1024}, {&stmtctx.StatementContext{InSelectStmt: true, TruncateAsWarning: true}, 34}, {&stmtctx.StatementContext{DividedByZeroAsWarning: true, IgnoreTruncate: true}, 257}, diff --git a/statistics/table.go b/statistics/table.go index f56352a4ef1a4..78c1550d81191 100644 --- a/statistics/table.go +++ b/statistics/table.go @@ -696,10 +696,10 @@ func (coll *HistColl) GetAvgRowSize(cols []*expression.Column, isEncodedKey bool } // GetAvgRowSizeListInDisk computes average row size for given columns. -func (coll *HistColl) GetAvgRowSizeListInDisk(cols []*expression.Column, padChar bool) (size float64) { +func (coll *HistColl) GetAvgRowSizeListInDisk(cols []*expression.Column) (size float64) { if coll.Pseudo || len(coll.Columns) == 0 || coll.Count == 0 { for _, col := range cols { - size += float64(chunk.EstimateTypeWidth(padChar, col.GetType())) + size += float64(chunk.EstimateTypeWidth(col.GetType())) } } else { for _, col := range cols { @@ -707,7 +707,7 @@ func (coll *HistColl) GetAvgRowSizeListInDisk(cols []*expression.Column, padChar // Normally this would not happen, it is for compatibility with old version stats which // does not include TotColSize. if !ok || (!colHist.IsHandle && colHist.TotColSize == 0 && (colHist.NullCount != coll.Count)) { - size += float64(chunk.EstimateTypeWidth(padChar, col.GetType())) + size += float64(chunk.EstimateTypeWidth(col.GetType())) continue } size += colHist.AvgColSizeListInDisk(coll.Count) diff --git a/store/mockstore/mocktikv/cop_handler_dag.go b/store/mockstore/mocktikv/cop_handler_dag.go index c9a628e2b1bae..8201dfa93bbf3 100644 --- a/store/mockstore/mocktikv/cop_handler_dag.go +++ b/store/mockstore/mocktikv/cop_handler_dag.go @@ -426,7 +426,6 @@ func flagsToStatementContext(flags uint64) *stmtctx.StatementContext { sc := new(stmtctx.StatementContext) sc.IgnoreTruncate = (flags & model.FlagIgnoreTruncate) > 0 sc.TruncateAsWarning = (flags & model.FlagTruncateAsWarning) > 0 - sc.PadCharToFullLength = (flags & model.FlagPadCharToFullLength) > 0 sc.InInsertStmt = (flags & model.FlagInInsertStmt) > 0 sc.InSelectStmt = (flags & model.FlagInSelectStmt) > 0 sc.OverflowAsWarning = (flags & model.FlagOverflowAsWarning) > 0 diff --git a/types/const_test.go b/types/const_test.go index b9a2c64fb37c8..e5e46037e796a 100644 --- a/types/const_test.go +++ b/types/const_test.go @@ -255,38 +255,6 @@ func (s *testMySQLConstSuite) TestIgnoreSpaceMode(c *C) { } -func (s *testMySQLConstSuite) TestPadCharToFullLengthMode(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - // test type `CHAR(n)` - tk.MustExec("drop table if exists t1") - tk.MustExec("create table t1 (a char(10));") - tk.MustExec("insert into t1 values ('xy');") - tk.MustExec("set sql_mode='';") - r := tk.MustQuery(`SELECT a='xy ', char_length(a) FROM t1;`) - r.Check(testkit.Rows("0 2")) - r = tk.MustQuery(`SELECT count(*) FROM t1 WHERE a='xy ';`) - r.Check(testkit.Rows("0")) - tk.MustExec("set sql_mode='PAD_CHAR_TO_FULL_LENGTH';") - r = tk.MustQuery(`SELECT a='xy ', char_length(a) FROM t1;`) - r.Check(testkit.Rows("1 10")) - r = tk.MustQuery(`SELECT count(*) FROM t1 WHERE a='xy ';`) - r.Check(testkit.Rows("1")) - - // test type `VARCHAR(n)` - tk.MustExec("drop table if exists t1") - tk.MustExec("create table t1 (a varchar(10));") - tk.MustExec("insert into t1 values ('xy');") - tk.MustExec("set sql_mode='';") - r = tk.MustQuery(`SELECT a='xy ', char_length(a) FROM t1;`) - r.Check(testkit.Rows("0 2")) - r = tk.MustQuery(`SELECT count(*) FROM t1 WHERE a='xy ';`) - r.Check(testkit.Rows("0")) - tk.MustExec("set sql_mode='PAD_CHAR_TO_FULL_LENGTH';") - r = tk.MustQuery(`SELECT a='xy ', char_length(a) FROM t1;`) - r.Check(testkit.Rows("0 2")) -} - func (s *testMySQLConstSuite) TestNoBackslashEscapesMode(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("set sql_mode=''") diff --git a/util/chunk/codec.go b/util/chunk/codec.go index 51ef7b6baa718..2858fb89b55a7 100644 --- a/util/chunk/codec.go +++ b/util/chunk/codec.go @@ -195,7 +195,7 @@ func GetFixedLen(colType *types.FieldType) int { // it's OK (and expected) to guess if we don't know for sure. // // mostly study from https://github.com/postgres/postgres/blob/REL_12_STABLE/src/backend/utils/cache/lsyscache.c#L2356 -func EstimateTypeWidth(padChar bool, colType *types.FieldType) int { +func EstimateTypeWidth(colType *types.FieldType) int { colLen := getFixedLen(colType) // Easy if it's a fixed-width type if colLen != varElemLen { @@ -204,13 +204,6 @@ func EstimateTypeWidth(padChar bool, colType *types.FieldType) int { colLen = colType.Flen if colLen > 0 { - /* - * If PAD_CHAR_TO_FULL_LENGTH is enabled, and type is CHAR, - * the colType.Flen is also the only width. - */ - if padChar && colType.Tp == mysql.TypeString { - return colLen - } if colLen <= 32 { return colLen } diff --git a/util/chunk/codec_test.go b/util/chunk/codec_test.go index 5e22a3c8f10cb..1979f32b37293 100644 --- a/util/chunk/codec_test.go +++ b/util/chunk/codec_test.go @@ -81,22 +81,19 @@ func (s *testCodecSuite) TestEstimateTypeWidth(c *check.C) { var colType *types.FieldType colType = &types.FieldType{Tp: mysql.TypeLonglong} - c.Assert(EstimateTypeWidth(false, colType), check.Equals, 8) // fixed-witch type - - colType = &types.FieldType{Tp: mysql.TypeString, Flen: 100000} - c.Assert(EstimateTypeWidth(true, colType), check.Equals, 100000) // PAD_CHAR_TO_FULL_LENGTH + c.Assert(EstimateTypeWidth(colType), check.Equals, 8) // fixed-witch type colType = &types.FieldType{Tp: mysql.TypeString, Flen: 31} - c.Assert(EstimateTypeWidth(false, colType), check.Equals, 31) // colLen <= 32 + c.Assert(EstimateTypeWidth(colType), check.Equals, 31) // colLen <= 32 colType = &types.FieldType{Tp: mysql.TypeString, Flen: 999} - c.Assert(EstimateTypeWidth(false, colType), check.Equals, 515) // colLen < 1000 + c.Assert(EstimateTypeWidth(colType), check.Equals, 515) // colLen < 1000 colType = &types.FieldType{Tp: mysql.TypeString, Flen: 2000} - c.Assert(EstimateTypeWidth(false, colType), check.Equals, 516) // colLen < 1000 + c.Assert(EstimateTypeWidth(colType), check.Equals, 516) // colLen < 1000 colType = &types.FieldType{Tp: mysql.TypeString} - c.Assert(EstimateTypeWidth(false, colType), check.Equals, 32) // value after guessing + c.Assert(EstimateTypeWidth(colType), check.Equals, 32) // value after guessing } func BenchmarkEncodeChunk(b *testing.B) { diff --git a/util/ranger/points.go b/util/ranger/points.go index ed1a8d198067c..f139803ddd99a 100644 --- a/util/ranger/points.go +++ b/util/ranger/points.go @@ -17,15 +17,12 @@ import ( "fmt" "math" "sort" - "strings" "github.com/pingcap/errors" "github.com/pingcap/parser/ast" - "github.com/pingcap/parser/charset" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" "github.com/pingcap/tidb/expression" - "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" @@ -240,11 +237,6 @@ func (r *builder) buildFormBinOp(expr *expression.ScalarFunction) []point { return nil } - value, err = HandlePadCharToFullLength(r.sc, ft, value) - if err != nil { - return nil - } - value, op, isValidRange := handleUnsignedIntCol(ft, value, op) if !isValidRange { return nil @@ -281,64 +273,6 @@ func (r *builder) buildFormBinOp(expr *expression.ScalarFunction) []point { return nil } -// HandlePadCharToFullLength handles the "PAD_CHAR_TO_FULL_LENGTH" sql mode for -// CHAR[N] index columns. -// NOTE: kv.ErrNotExist is returned to indicate that this value can not match -// any (key, value) pair in tikv storage. This error should be handled by -// the caller. -func HandlePadCharToFullLength(sc *stmtctx.StatementContext, ft *types.FieldType, val types.Datum) (types.Datum, error) { - isChar := (ft.Tp == mysql.TypeString) - isBinary := (isChar && ft.Collate == charset.CollationBin) - isVarchar := (ft.Tp == mysql.TypeVarString || ft.Tp == mysql.TypeVarchar) - isVarBinary := (isVarchar && ft.Collate == charset.CollationBin) - - if !isChar && !isVarchar && !isBinary && !isVarBinary { - return val, nil - } - - hasBinaryFlag := mysql.HasBinaryFlag(ft.Flag) - targetStr, err := val.ToString() - if err != nil { - return val, err - } - - switch { - case isBinary || isVarBinary: - val.SetString(targetStr) - return val, nil - case isVarchar && hasBinaryFlag: - noTrailingSpace := strings.TrimRight(targetStr, " ") - if numSpacesToFill := ft.Flen - len(noTrailingSpace); numSpacesToFill > 0 { - noTrailingSpace += strings.Repeat(" ", numSpacesToFill) - } - val.SetString(noTrailingSpace) - return val, nil - case isVarchar && !hasBinaryFlag: - val.SetString(targetStr) - return val, nil - case isChar && hasBinaryFlag: - noTrailingSpace := strings.TrimRight(targetStr, " ") - val.SetString(noTrailingSpace) - return val, nil - case isChar && !hasBinaryFlag && !sc.PadCharToFullLength: - val.SetString(targetStr) - return val, nil - case isChar && !hasBinaryFlag && sc.PadCharToFullLength: - if len(targetStr) != ft.Flen { - // return kv.ErrNotExist to indicate that this value can not match any - // (key, value) pair in tikv storage. - return val, kv.ErrNotExist - } - // Trailing spaces of data typed "CHAR[N]" is trimed in the storage, we - // need to trim these trailing spaces as well. - noTrailingSpace := strings.TrimRight(targetStr, " ") - val.SetString(noTrailingSpace) - return val, nil - default: - return val, nil - } -} - // handleUnsignedIntCol handles the case when unsigned column meets negative integer value. // The three returned values are: fixed constant value, fixed operator, and a boolean // which indicates whether the range is valid or not.