Skip to content

Commit

Permalink
executor: fix bug of point get when meet null values (#11219)
Browse files Browse the repository at this point in the history
  • Loading branch information
alivxxx authored Jul 12, 2019
1 parent 8443282 commit 0ba4d0b
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 34 deletions.
51 changes: 17 additions & 34 deletions executor/point_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,60 +196,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 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 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 err
}
// Fill other positions.
for i := 1; i < len(schemaPoses); i++ {
chk.MakeRef(firstPos, schemaPoses[i])
}
}
return nil
}
Expand Down
2 changes: 2 additions & 0 deletions executor/point_get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,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(
"<nil> <nil>"))
}

func (s *testPointGetSuite) TestPointGetCharPK(c *C) {
Expand Down

0 comments on commit 0ba4d0b

Please sign in to comment.