diff --git a/model/model.go b/model/model.go index f817eecb245b6..9e2c46ec69687 100644 --- a/model/model.go +++ b/model/model.go @@ -87,6 +87,9 @@ func (c *ColumnInfo) IsGenerated() bool { // for use of execution phase. const ExtraHandleID = -1 +// ExtraHandleName is the name of ExtraHandle Column. +var ExtraHandleName = NewCIStr("_rowid") + // TableInfo provides meta data describing a DB table. type TableInfo struct { ID int64 `json:"id"` @@ -169,6 +172,16 @@ func (t *TableInfo) GetPkColInfo() *ColumnInfo { return nil } +// NewExtraHandleColInfo mocks a column info for extra handle column. +func NewExtraHandleColInfo() *ColumnInfo { + colInfo := &ColumnInfo{ + ID: ExtraHandleID, + Name: ExtraHandleName, + } + colInfo.Flag = mysql.PriKeyFlag + return colInfo +} + // ColumnIsInIndex checks whether c is included in any indices of t. func (t *TableInfo) ColumnIsInIndex(c *ColumnInfo) bool { for _, index := range t.Indices { diff --git a/plan/column_pruning.go b/plan/column_pruning.go index 9bb1b5cc9af61..917177fe8af9a 100644 --- a/plan/column_pruning.go +++ b/plan/column_pruning.go @@ -18,6 +18,7 @@ import ( "github.com/pingcap/tidb/ast" "github.com/pingcap/tidb/context" "github.com/pingcap/tidb/expression" + "github.com/pingcap/tidb/model" "github.com/pingcap/tidb/util/types" ) @@ -167,7 +168,6 @@ func (p *DataSource) PruneColumns(parentUsedCols []*expression.Column) { if p.unionScanSchema != nil { used[handleIdx] = true } - firstCol, firstColInfo := p.schema.Columns[0], p.Columns[0] for i := len(used) - 1; i >= 0; i-- { if !used[i] { p.schema.Columns = append(p.schema.Columns[:i], p.schema.Columns[i+1:]...) @@ -181,8 +181,8 @@ func (p *DataSource) PruneColumns(parentUsedCols []*expression.Column) { // For SQL like `select 1 from t`, tikv's response will be empty if no column is in schema. // So we'll force to push one if schema doesn't have any column. if p.schema.Len() == 0 { - p.schema.Append(firstCol) - p.Columns = append(p.Columns, firstColInfo) + p.Columns = append(p.Columns, model.NewExtraHandleColInfo()) + p.schema.Append(p.newExtraHandleSchemaCol()) } } diff --git a/plan/explain_test.go b/plan/explain_test.go index 71952c66bd23d..b0d033f7a284e 100644 --- a/plan/explain_test.go +++ b/plan/explain_test.go @@ -260,13 +260,13 @@ func (s *testExplainSuite) TestExplain(c *C) { { "select sum(6 in (select c2 from t2)) from t1", []string{ - "TableScan_22 cop table:t1, range:(-inf,+inf), keep order:true 8000", - "TableReader_23 HashSemiJoin_20 root data:TableScan_22 8000", + "TableScan_11 cop table:t1, range:(-inf,+inf), keep order:false 8000", + "TableReader_12 HashSemiJoin_10 root data:TableScan_11 8000", "TableScan_13 Selection_14 cop table:t2, range:(-inf,+inf), keep order:false 10", "Selection_14 TableScan_13 cop eq(6, test.t2.c2) 10", - "TableReader_15 HashSemiJoin_20 root data:Selection_14 10", - "HashSemiJoin_20 StreamAgg_9 TableReader_23,TableReader_15 root right:TableReader_15, aux 8000", - "StreamAgg_9 HashSemiJoin_20 root type:stream, funcs:sum(5_aux_0) 1", + "TableReader_15 HashSemiJoin_10 root data:Selection_14 10", + "HashSemiJoin_10 HashAgg_8 TableReader_12,TableReader_15 root right:TableReader_15, aux 8000", + "HashAgg_8 HashSemiJoin_10 root type:complete, funcs:sum(5_aux_0) 1", }, }, } diff --git a/plan/logical_plan_builder.go b/plan/logical_plan_builder.go index db544cd3751fa..f066c2a26bf69 100644 --- a/plan/logical_plan_builder.go +++ b/plan/logical_plan_builder.go @@ -1209,6 +1209,18 @@ func (b *planBuilder) buildTableDual() LogicalPlan { return dual } +func (ds *DataSource) newExtraHandleSchemaCol() *expression.Column { + return &expression.Column{ + FromID: ds.id, + DBName: ds.DBName, + TblName: ds.tableInfo.Name, + ColName: model.ExtraHandleName, + RetType: types.NewFieldType(mysql.TypeLonglong), + Position: len(ds.tableInfo.Columns), // set a unique position + ID: model.ExtraHandleID, + } +} + func (b *planBuilder) buildDataSource(tn *ast.TableName) LogicalPlan { handle := sessionctx.GetDomain(b.ctx).StatsHandle() var statisticTable *statistics.Table