You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.9 KiB
100 lines
2.9 KiB
// Copyright 2019 PingCAP, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package executor
|
|
|
|
import (
|
|
"math/rand"
|
|
|
|
. "github.com/pingcap/check"
|
|
"github.com/pingcap/parser/mysql"
|
|
"github.com/pingcap/tidb/planner/core"
|
|
"github.com/pingcap/tidb/types"
|
|
"github.com/pingcap/tidb/util/chunk"
|
|
)
|
|
|
|
var _ = Suite(&testSuiteJoiner{})
|
|
|
|
type testSuiteJoiner struct{}
|
|
|
|
func (s *testSuiteJoiner) SetUpSuite(c *C) {
|
|
}
|
|
|
|
func (s *testSuiteJoiner) TestRequiredRows(c *C) {
|
|
joinTypes := []core.JoinType{core.InnerJoin, core.LeftOuterJoin, core.RightOuterJoin}
|
|
lTypes := [][]byte{
|
|
{mysql.TypeLong},
|
|
{mysql.TypeFloat},
|
|
{mysql.TypeLong, mysql.TypeFloat},
|
|
}
|
|
rTypes := lTypes
|
|
|
|
convertTypes := func(mysqlTypes []byte) []*types.FieldType {
|
|
fieldTypes := make([]*types.FieldType, 0, len(mysqlTypes))
|
|
for _, t := range mysqlTypes {
|
|
fieldTypes = append(fieldTypes, types.NewFieldType(t))
|
|
}
|
|
return fieldTypes
|
|
}
|
|
|
|
for _, joinType := range joinTypes {
|
|
for _, ltype := range lTypes {
|
|
for _, rtype := range rTypes {
|
|
maxChunkSize := defaultCtx().GetSessionVars().MaxChunkSize
|
|
lfields := convertTypes(ltype)
|
|
rfields := convertTypes(rtype)
|
|
outerRow := genTestChunk(maxChunkSize, 1, lfields).GetRow(0)
|
|
innerChk := genTestChunk(maxChunkSize, maxChunkSize, rfields)
|
|
var defaultInner []types.Datum
|
|
for i, f := range rfields {
|
|
defaultInner = append(defaultInner, innerChk.GetRow(0).GetDatum(i, f))
|
|
}
|
|
joiner := newJoiner(defaultCtx(), joinType, false, defaultInner, nil, lfields, rfields, nil)
|
|
|
|
fields := make([]*types.FieldType, 0, len(lfields)+len(rfields))
|
|
fields = append(fields, rfields...)
|
|
fields = append(fields, lfields...)
|
|
result := chunk.New(fields, maxChunkSize, maxChunkSize)
|
|
|
|
for i := 0; i < 10; i++ {
|
|
required := rand.Int()%maxChunkSize + 1
|
|
result.SetRequiredRows(required, maxChunkSize)
|
|
result.Reset()
|
|
it := chunk.NewIterator4Chunk(innerChk)
|
|
it.Begin()
|
|
_, _, err := joiner.tryToMatchInners(outerRow, it, result)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(result.NumRows(), Equals, required)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func genTestChunk(maxChunkSize int, numRows int, fields []*types.FieldType) *chunk.Chunk {
|
|
chk := chunk.New(fields, maxChunkSize, maxChunkSize)
|
|
for numRows > 0 {
|
|
numRows--
|
|
for col, field := range fields {
|
|
switch field.Tp {
|
|
case mysql.TypeLong:
|
|
chk.AppendInt64(col, 0)
|
|
case mysql.TypeFloat:
|
|
chk.AppendFloat32(col, 0)
|
|
default:
|
|
panic("not support")
|
|
}
|
|
}
|
|
}
|
|
return chk
|
|
}
|
|
|