From a84eef567e93229f14866d76f0daabd4fbc2ae39 Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Fri, 12 Jul 2019 14:11:14 +0800 Subject: [PATCH] executor: fix bug of point get when meet null values (#11219) --- executor/point_get.go | 51 +++++++++++++------------------------- executor/point_get_test.go | 2 ++ 2 files changed, 19 insertions(+), 34 deletions(-) diff --git a/executor/point_get.go b/executor/point_get.go index cf351a777dbb8..e9dbed0617865 100644 --- a/executor/point_get.go +++ b/executor/point_get.go @@ -165,60 +165,43 @@ func (e *PointGetExecutor) get(key kv.Key) (val []byte, err error) { } func (e *PointGetExecutor) decodeRowValToChunk(rowVal []byte, chk *chunk.Chunk) error { - // One column could be filled for multi-times in the schema. e.g. select b, b, c, c from t where a = 1. - // We need to set the positions in the schema for the same column. - colID2DecodedPos := make(map[int64]int, e.schema.Len()) - decodedPos2SchemaPos := make([][]int, 0, e.schema.Len()) - for schemaPos, col := range e.schema.Columns { - if decodedPos, ok := colID2DecodedPos[col.ID]; !ok { - colID2DecodedPos[col.ID] = len(colID2DecodedPos) - decodedPos2SchemaPos = append(decodedPos2SchemaPos, []int{schemaPos}) - } else { - decodedPos2SchemaPos[decodedPos] = append(decodedPos2SchemaPos[decodedPos], schemaPos) + colID2CutPos := make(map[int64]int, e.schema.Len()) + for _, col := range e.schema.Columns { + if _, ok := colID2CutPos[col.ID]; !ok { + colID2CutPos[col.ID] = len(colID2CutPos) } } - decodedVals, err := tablecodec.CutRowNew(rowVal, colID2DecodedPos) + cutVals, err := tablecodec.CutRowNew(rowVal, colID2CutPos) if err != nil { return errors.Trace(err) } - if decodedVals == nil { - decodedVals = make([][]byte, len(colID2DecodedPos)) + if cutVals == nil { + cutVals = make([][]byte, len(colID2CutPos)) } decoder := codec.NewDecoder(chk, e.ctx.GetSessionVars().Location()) - for id, decodedPos := range colID2DecodedPos { - schemaPoses := decodedPos2SchemaPos[decodedPos] - firstPos := schemaPoses[0] - if e.tblInfo.PKIsHandle && mysql.HasPriKeyFlag(e.schema.Columns[firstPos].RetType.Flag) { - chk.AppendInt64(firstPos, e.handle) - // Fill other positions. - for i := 1; i < len(schemaPoses); i++ { - chk.MakeRef(firstPos, schemaPoses[i]) - } + for i, col := range e.schema.Columns { + if e.tblInfo.PKIsHandle && mysql.HasPriKeyFlag(col.RetType.Flag) { + chk.AppendInt64(i, e.handle) continue } - // ExtraHandleID is added when building plan, we can make sure that there's only one column's ID is this. - if id == model.ExtraHandleID { - chk.AppendInt64(firstPos, e.handle) + if col.ID == model.ExtraHandleID { + chk.AppendInt64(i, e.handle) continue } - if len(decodedVals[decodedPos]) == 0 { - // This branch only entered for updating and deleting. It won't have one column in multiple positions. - colInfo := getColInfoByID(e.tblInfo, id) + cutPos := colID2CutPos[col.ID] + if len(cutVals[cutPos]) == 0 { + colInfo := getColInfoByID(e.tblInfo, col.ID) d, err1 := table.GetColOriginDefaultValue(e.ctx, colInfo) if err1 != nil { return errors.Trace(err1) } - chk.AppendDatum(firstPos, &d) + chk.AppendDatum(i, &d) continue } - _, err = decoder.DecodeOne(decodedVals[decodedPos], firstPos, e.schema.Columns[firstPos].RetType) + _, err = decoder.DecodeOne(cutVals[cutPos], i, col.RetType) if err != nil { return errors.Trace(err) } - // Fill other positions. - for i := 1; i < len(schemaPoses); i++ { - chk.MakeRef(firstPos, schemaPoses[i]) - } } return nil } diff --git a/executor/point_get_test.go b/executor/point_get_test.go index f04c381354a49..cc7550e4f55bb 100644 --- a/executor/point_get_test.go +++ b/executor/point_get_test.go @@ -100,6 +100,8 @@ func (s *testPointGetSuite) TestPointGet(c *C) { tk.MustQuery(`select a, a, b, a, b, c, b, c, c from t where a = 5;`).Check(testkit.Rows( `5 5 6 5 6 7 6 7 7`, )) + tk.MustQuery(`select b, b from t where a = 1`).Check(testkit.Rows( + " ")) } func (s *testPointGetSuite) TestPointGetCharPK(c *C) {