Skip to content

Commit

Permalink
planner: add implementation rule for LogicalMemTable (pingcap#14577)
Browse files Browse the repository at this point in the history
  • Loading branch information
zz-jason authored Feb 4, 2020
1 parent e79b71d commit ccc43c0
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 12 deletions.
32 changes: 32 additions & 0 deletions planner/cascades/implementation_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ var defaultImplementationMap = map[memo.Operand][]ImplementationRule{
memo.OperandTableDual: {
&ImplTableDual{},
},
memo.OperandMemTableScan: {
&ImplMemTableScan{},
},
memo.OperandProjection: {
&ImplProjection{},
},
Expand Down Expand Up @@ -107,6 +110,35 @@ func (r *ImplTableDual) OnImplement(expr *memo.GroupExpr, reqProp *property.Phys
return []memo.Implementation{impl.NewTableDualImpl(dual)}, nil
}

// ImplMemTableScan implements LogicalMemTable as PhysicalMemTable.
type ImplMemTableScan struct {
}

// Match implements ImplementationRule Match interface.
func (r *ImplMemTableScan) Match(expr *memo.GroupExpr, prop *property.PhysicalProperty) (matched bool) {
if !prop.IsEmpty() {
return false
}
return true
}

// OnImplement implements ImplementationRule OnImplement interface.
func (r *ImplMemTableScan) OnImplement(
expr *memo.GroupExpr,
reqProp *property.PhysicalProperty,
) ([]memo.Implementation, error) {
logic := expr.ExprNode.(*plannercore.LogicalMemTable)
logicProp := expr.Group.Prop
physical := plannercore.PhysicalMemTable{
DBName: logic.DBName,
Table: logic.TableInfo,
Columns: logic.TableInfo.Columns,
Extractor: logic.Extractor,
}.Init(logic.SCtx(), logicProp.Stats.ScaleByExpectCnt(reqProp.ExpectedCnt), logic.SelectBlockOffset())
physical.SetSchema(logicProp.Schema)
return []memo.Implementation{impl.NewMemTableScanImpl(physical)}, nil
}

// ImplProjection implements LogicalProjection as PhysicalProjection.
type ImplProjection struct {
}
Expand Down
21 changes: 21 additions & 0 deletions planner/cascades/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,24 @@ func (s *testIntegrationSuite) TestApply(c *C) {
tk.MustQuery(sql).Check(testkit.Rows(output[i].Result...))
}
}

func (s *testIntegrationSuite) TestMemTableScan(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("set session tidb_enable_cascades_planner = 1")
var input []string
var output []struct {
SQL string
Plan []string
Result []string
}
s.testData.GetTestCases(c, &input, &output)
for i, sql := range input {
s.testData.OnRecord(func() {
output[i].SQL = sql
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + sql).Rows())
output[i].Result = s.testData.ConvertRowsToStrings(tk.MustQuery(sql).Rows())
})
tk.MustQuery("explain " + sql).Check(testkit.Rows(output[i].Plan...))
tk.MustQuery(sql).Check(testkit.Rows(output[i].Result...))
}
}
6 changes: 6 additions & 0 deletions planner/cascades/testdata/integration_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,11 @@
"select a = (select a from t2 where t1.b = t2.b order by a limit 1) from t1",
"select sum(a), (select t1.a from t1 where t1.a = t2.a limit 1), (select t1.b from t1 where t1.b = t2.b limit 1) from t2"
]
},
{
"name": "TestMemTableScan",
"cases": [
"select * from information_schema.processlist"
]
}
]
12 changes: 12 additions & 0 deletions planner/cascades/testdata/integration_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -570,5 +570,17 @@
]
}
]
},
{
"Name": "TestMemTableScan",
"Cases": [
{
"SQL": "select * from information_schema.processlist",
"Plan": [
"MemTableScan_3 10000.00 root "
],
"Result": null
}
]
}
]
6 changes: 3 additions & 3 deletions planner/core/find_best_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ func (p *LogicalMemTable) findBestTask(prop *property.PhysicalProperty) (t task,
return invalidTask, nil
}
memTable := PhysicalMemTable{
DBName: p.dbName,
Table: p.tableInfo,
Columns: p.tableInfo.Columns,
DBName: p.DBName,
Table: p.TableInfo,
Columns: p.TableInfo.Columns,
Extractor: p.Extractor,
}.Init(p.ctx, p.stats, p.blockOffset)
memTable.SetSchema(p.schema)
Expand Down
4 changes: 2 additions & 2 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2717,8 +2717,8 @@ func (b *PlanBuilder) buildMemTable(ctx context.Context, dbName model.CIStr, tab

// NOTE: Add a `LogicalUnionScan` if we support update memory table in the future
p := LogicalMemTable{
dbName: dbName,
tableInfo: tableInfo,
DBName: dbName,
TableInfo: tableInfo,
}.Init(b.ctx, b.getSelectOffset())
p.SetSchema(schema)
p.names = names
Expand Down
4 changes: 2 additions & 2 deletions planner/core/logical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ type LogicalMemTable struct {
logicalSchemaProducer

Extractor MemTablePredicateExtractor
dbName model.CIStr
tableInfo *model.TableInfo
DBName model.CIStr
TableInfo *model.TableInfo
}

// LogicalUnionScan is only used in non read-only txn.
Expand Down
8 changes: 4 additions & 4 deletions planner/core/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ func (p *LogicalTableDual) DeriveStats(childStats []*property.StatsInfo, selfSch

// DeriveStats implement LogicalPlan DeriveStats interface.
func (p *LogicalMemTable) DeriveStats(childStats []*property.StatsInfo, selfSchema *expression.Schema, childSchema []*expression.Schema) (*property.StatsInfo, error) {
statsTable := statistics.PseudoTable(p.tableInfo)
statsTable := statistics.PseudoTable(p.TableInfo)
stats := &property.StatsInfo{
RowCount: float64(statsTable.Count),
Cardinality: make([]float64, len(p.tableInfo.Columns)),
HistColl: statsTable.GenerateHistCollFromColumnInfo(p.tableInfo.Columns, p.schema.Columns),
Cardinality: make([]float64, len(p.TableInfo.Columns)),
HistColl: statsTable.GenerateHistCollFromColumnInfo(p.TableInfo.Columns, p.schema.Columns),
StatsVersion: statistics.PseudoVersion,
}
for i := range p.tableInfo.Columns {
for i := range p.TableInfo.Columns {
stats.Cardinality[i] = float64(statsTable.Count)
}
p.stats = stats
Expand Down
18 changes: 17 additions & 1 deletion planner/implementation/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
package implementation

import (
"math"

"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/kv"
plannercore "github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/planner/memo"
"github.com/pingcap/tidb/statistics"
"math"
)

// TableDualImpl implementation of PhysicalTableDual.
Expand All @@ -37,6 +38,21 @@ func (impl *TableDualImpl) CalcCost(outCount float64, children ...memo.Implement
return 0
}

// MemTableScanImpl implementation of PhysicalTableDual.
type MemTableScanImpl struct {
baseImpl
}

// NewMemTableScanImpl creates a new table dual Implementation.
func NewMemTableScanImpl(dual *plannercore.PhysicalMemTable) *MemTableScanImpl {
return &MemTableScanImpl{baseImpl{plan: dual}}
}

// CalcCost calculates the cost of the table dual Implementation.
func (impl *MemTableScanImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
return 0
}

// TableReaderImpl implementation of PhysicalTableReader.
type TableReaderImpl struct {
baseImpl
Expand Down
4 changes: 4 additions & 0 deletions planner/memo/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ const (
OperandLimit
// OperandTiKVSingleGather is the operand for TiKVSingleGather.
OperandTiKVSingleGather
// OperandMemTableScan is the operand for MemTableScan.
OperandMemTableScan
// OperandTableScan is the operand for TableScan.
OperandTableScan
// OperandIndexScan is the operand for IndexScan.
Expand Down Expand Up @@ -104,6 +106,8 @@ func GetOperand(p plannercore.LogicalPlan) Operand {
return OperandTiKVSingleGather
case *plannercore.LogicalTableScan:
return OperandTableScan
case *plannercore.LogicalMemTable:
return OperandMemTableScan
case *plannercore.LogicalIndexScan:
return OperandIndexScan
case *plannercore.LogicalShow:
Expand Down

0 comments on commit ccc43c0

Please sign in to comment.