func (b *executorBuilder) buildIndexScan(v *plan.IndexScan) Executor { txn, err := b.ctx.GetTxn(false) if err != nil { b.err = err return nil } tbl, _ := b.is.TableByID(v.Table.ID) client := txn.GetClient() var memDB bool switch v.Fields()[0].DBName.L { case "information_schema", "performance_schema": memDB = true } if !memDB && client.SupportRequestType(kv.ReqTypeIndex, 0) && txn.IsReadOnly() { log.Debug("xapi select index") e := &XSelectIndexExec{ table: tbl, ctx: b.ctx, indexPlan: v, } where := conditionsToPBExpression(v.FilterConditions...) if xapi.SupportExpression(client, where) { e.where = where return e } return b.buildFilter(e, v.FilterConditions) } var idx *column.IndexedCol for _, val := range tbl.Indices() { if val.IndexInfo.Name.L == v.Index.Name.L { idx = val break } } e := &IndexScanExec{ tbl: tbl, idx: idx, fields: v.Fields(), ctx: b.ctx, Desc: v.Desc, valueTypes: make([]*types.FieldType, len(idx.Columns)), } for i, ic := range idx.Columns { col := tbl.Cols()[ic.Offset] e.valueTypes[i] = &col.FieldType } e.Ranges = make([]*IndexRangeExec, len(v.Ranges)) for i, val := range v.Ranges { e.Ranges[i] = b.buildIndexRange(e, val) } return b.buildFilter(e, v.FilterConditions) }
func (b *executorBuilder) buildTableScan(v *plan.TableScan) Executor { txn, err := b.ctx.GetTxn(false) if err != nil { b.err = err return nil } table, _ := b.is.TableByID(v.Table.ID) client := txn.GetClient() var memDB bool switch v.Fields()[0].DBName.L { case "information_schema", "performance_schema": memDB = true } if !memDB && client.SupportRequestType(kv.ReqTypeSelect, 0) && txn.IsReadOnly() { log.Debug("xapi select table") e := &XSelectTableExec{ table: table, ctx: b.ctx, tablePlan: v, } where := conditionsToPBExpression(v.FilterConditions...) if xapi.SupportExpression(client, where) { e.where = where return e } return b.buildFilter(e, v.FilterConditions) } e := &TableScanExec{ t: table, fields: v.Fields(), ctx: b.ctx, ranges: v.Ranges, seekHandle: math.MinInt64, } return b.buildFilter(e, v.FilterConditions) }