executor: make seek value with the same length of the index columns.

For composite index with 2 columns, if we just pass one value in `Seek`, we will get the wrong result.
So this change create the seek value with the length of the composite index.
This commit is contained in:
Ewan Chou
2015-12-21 13:10:40 +08:00
parent 9bc1ea2610
commit abc4701b00
4 changed files with 33 additions and 6 deletions

View File

@ -84,7 +84,7 @@ func (b *executorBuilder) buildIndexScan(v *plan.IndexScan) Executor {
}
e := &IndexScanExec{
tbl: tbl,
idx: idx.X,
idx: idx,
fields: v.Fields(),
ctx: b.ctx,
Desc: v.Desc,

View File

@ -19,6 +19,7 @@ import (
"github.com/juju/errors"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/column"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/optimizer/evaluator"
@ -177,8 +178,8 @@ func (e *IndexRangeExec) Fields() []*ast.ResultField {
// Next implements Executor Next interface.
func (e *IndexRangeExec) Next() (*Row, error) {
if e.iter == nil {
seekVals := make([]interface{}, len(e.lowVals))
for i := 0; i < len(seekVals); i++ {
seekVals := make([]interface{}, len(e.scan.idx.Columns))
for i := 0; i < len(e.lowVals); i++ {
var err error
if e.lowVals[i] == plan.MinNotNullVal {
seekVals[i] = []byte{}
@ -189,12 +190,11 @@ func (e *IndexRangeExec) Next() (*Row, error) {
}
}
}
txn, err := e.scan.ctx.GetTxn(false)
if err != nil {
return nil, errors.Trace(err)
}
e.iter, _, err = e.scan.idx.Seek(txn, seekVals)
e.iter, _, err = e.scan.idx.X.Seek(txn, seekVals)
if err != nil {
return nil, types.EOFAsNil(err)
}
@ -315,7 +315,7 @@ func (e *IndexRangeExec) Close() error {
// IndexScanExec represents an index scan executor.
type IndexScanExec struct {
tbl table.Table
idx kv.Index
idx *column.IndexedCol
fields []*ast.ResultField
Ranges []*IndexRangeExec
Desc bool

View File

@ -143,3 +143,23 @@ func (s *testIndexSuite) TestIndex(c *C) {
err = txn.Commit()
c.Assert(err, IsNil)
}
func (s *testIndexSuite) TestCombineIndexSeek(c *C) {
index := kv.NewKVIndex("i", "test", 1, false)
txn, err := s.s.Begin()
c.Assert(err, IsNil)
values := []interface{}{"abc", "def"}
err = index.Create(txn, values, 1)
c.Assert(err, IsNil)
index2 := kv.NewKVIndex("i", "test", 1, false)
iter, hit, err := index2.Seek(txn, []interface{}{"abc", nil})
defer iter.Close()
c.Assert(err, IsNil)
c.Assert(hit, IsFalse)
_, h, err := iter.Next()
c.Assert(err, IsNil)
c.Assert(h, Equals, int64(1))
}

View File

@ -1364,6 +1364,13 @@ func (s *testSessionSuite) TestMultiColumnIndex(c *C) {
checkPlan(c, se, sql, expectedExplain)
mustExecMatch(c, se, sql, [][]interface{}{{1}})
// Test varchar type.
mustExecSQL(c, se, "drop table t;")
mustExecSQL(c, se, "create table t (c1 varchar(64), c2 varchar(64), index c1_c2 (c1, c2));")
mustExecSQL(c, se, "insert into t values ('abc', 'def')")
sql = "select c1 from t where c1 = 'abc'"
mustExecMatch(c, se, sql, [][]interface{}{{[]byte("abc")}})
err := se.Close()
c.Assert(err, IsNil)
}