Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: Refactoring reading logic of virtual generate column #12407

Merged
merged 41 commits into from
Nov 13, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
13c73e1
init
wjhuang2016 Sep 4, 2019
84413ca
save
wjhuang2016 Sep 18, 2019
22161ba
save
wjhuang2016 Sep 25, 2019
3e2342a
save
wjhuang2016 Sep 26, 2019
e6776b7
Merge remote-tracking branch 'upstream/master' into virtual_column_dev
wjhuang2016 Sep 26, 2019
71afaf5
clean
wjhuang2016 Sep 26, 2019
6861fee
clean
wjhuang2016 Sep 26, 2019
20f2ef5
fix a bug
wjhuang2016 Sep 26, 2019
5edee3e
remove unused code
wjhuang2016 Sep 26, 2019
a54a958
clean code
wjhuang2016 Sep 26, 2019
76e3e48
clean code
wjhuang2016 Sep 26, 2019
f505299
support index on virtual column
wjhuang2016 Oct 9, 2019
5ba3a4b
Fix mysql_test
wjhuang2016 Oct 9, 2019
d6e758f
clean code, move precompute logic to tableReaderExecutor
wjhuang2016 Oct 10, 2019
c7a8c1f
remove unused code
wjhuang2016 Oct 10, 2019
ca09907
clean code, put some logics into a function
wjhuang2016 Oct 10, 2019
0f8fa98
clean code, put some logics into a function
wjhuang2016 Oct 10, 2019
2e5371b
add some comment
wjhuang2016 Oct 10, 2019
b96543d
merge master
wjhuang2016 Oct 10, 2019
78a1bff
uncomment some tests
wjhuang2016 Oct 10, 2019
7115fae
sync some test with master
wjhuang2016 Oct 10, 2019
ff715e9
use FindColumnInfoByID
wjhuang2016 Oct 11, 2019
4c76749
Merge branch 'master' into virtual_column_dev
wjhuang2016 Oct 11, 2019
f62e6a8
Merge branch 'master' into virtual_column_dev
wjhuang2016 Oct 11, 2019
9ebfe1e
merge master
wjhuang2016 Oct 11, 2019
927eb33
merge master
wjhuang2016 Oct 16, 2019
a368d8d
clean code
wjhuang2016 Oct 16, 2019
5215d6a
clean code
wjhuang2016 Oct 18, 2019
4d6853e
fix typo and clean code
wjhuang2016 Oct 23, 2019
e6c946a
clean code
wjhuang2016 Oct 23, 2019
b09b110
Merge branch 'master' of https://github.com/pingcap/tidb into virtual…
wjhuang2016 Oct 23, 2019
132befe
clean code
wjhuang2016 Oct 25, 2019
54ed256
Merge branch 'master' of https://github.com/pingcap/tidb into virtual…
wjhuang2016 Oct 25, 2019
a1c7be5
clean code
wjhuang2016 Oct 29, 2019
966c6bc
clean code
wjhuang2016 Oct 30, 2019
f12af6e
add test
wjhuang2016 Oct 30, 2019
ba8ebc7
Merge remote-tracking branch 'upstream/master' into virtual_column_dev
wjhuang2016 Oct 30, 2019
f2b4969
Merge branch 'master' into virtual_column_dev
Deardrops Nov 1, 2019
993fe8c
Merge branch 'master' into virtual_column_dev
wjhuang2016 Nov 1, 2019
357e5b7
Merge branch 'master' into virtual_column_dev
wjhuang2016 Nov 5, 2019
54346df
Merge remote-tracking branch 'upstream/master' into virtual_column_dev
wjhuang2016 Nov 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
clean code, move precompute logic to tableReaderExecutor
  • Loading branch information
wjhuang2016 committed Oct 10, 2019
commit d6e758f95da2ddd086fc1c72107627af83a88e87
1 change: 1 addition & 0 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1862,6 +1862,7 @@ func buildNoRangeTableReader(b *executorBuilder, v *plannercore.PhysicalTableRea
corColInAccess: b.corColInAccess(v.TablePlans[0]),
plans: v.TablePlans,
}
e.buildVirtualColumnInfo()
if containsLimit(dagReq.Executors) {
e.feedback = statistics.NewQueryFeedback(0, nil, 0, ts.Desc)
} else {
Expand Down
1 change: 1 addition & 0 deletions executor/distsql.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ func (e *IndexLookUpExecutor) buildTableReader(ctx context.Context, handles []in
corColInFilter: e.corColInTblSide,
plans: e.tblPlans,
}
tableReaderExec.buildVirtualColumnInfo()
tableReader, err := e.dataReaderBuilder.buildTableReaderFromHandles(ctx, tableReaderExec, handles)
if err != nil {
logutil.Logger(ctx).Error("build table reader from handles failed", zap.Error(err))
Expand Down
61 changes: 32 additions & 29 deletions executor/table_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"github.com/opentracing/opentracing-go"
"github.com/pingcap/parser/model"
"github.com/pingcap/tidb/distsql"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/kv"
plannercore "github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/sessionctx"
Expand Down Expand Up @@ -62,7 +61,7 @@ type TableReaderExecutor struct {
// kvRanges are only use for union scan.
kvRanges []kv.KeyRange
dagPB *tipb.DAGRequest
// columns are only required by union scan.
// columns are only required by union scan and virtual column.
columns []*model.ColumnInfo

// resultHandler handles the order of the result. Since (MAXInt64, MAXUint64] stores before [0, MaxInt64] physically
Expand All @@ -81,6 +80,11 @@ type TableReaderExecutor struct {
corColInFilter bool
// corColInAccess tells whether there's correlated column in access conditions.
corColInAccess bool
// virtualColumnIndex records all the indices of virtual columns and sort them in definition
// to make sure we can compute the virtual column in right order.
virtualColumnIndex []int
// virtualColumnRetFieldTypes records the RetFieldTypes of virtual columns.
virtualColumnRetFieldTypes []*types.FieldType
}

// Open initialzes necessary variables for using this executor.
Expand Down Expand Up @@ -159,43 +163,22 @@ func (e *TableReaderExecutor) Next(ctx context.Context, req *chunk.Chunk) error
return err
}

// If e.schema contains virtual column, compute the virtual column and put them into the chunk
// TODO: move them to other place so that we don't need to compute every Next()
virColTypes := make([]*types.FieldType, 0)
virColDef := make([]*expression.Column, 0)
virColIndex := make([]int, 0)
virColOrder := make([]int, 0)
for i, col := range e.schema.Columns {
if col.VirtualExpr != nil {
virColTypes = append(virColTypes, col.RetType)
virColDef = append(virColDef, col)
virColIndex = append(virColIndex, i)
virColOrder = append(virColOrder, len(virColOrder))
}
}
if len(virColOrder) > 0 {
sort.Slice(virColOrder, func(i, j int) bool {
return model.FindColumnInfo(e.columns, virColDef[i].OrigColName.String()).Offset <
model.FindColumnInfo(e.columns, virColDef[j].OrigColName.String()).Offset
})
}

virCols := chunk.NewChunkWithCapacity(virColTypes, req.Capacity())
virCols := chunk.NewChunkWithCapacity(e.virtualColumnRetFieldTypes, req.Capacity())
iter := chunk.NewIterator4Chunk(req)

for _, j := range virColOrder {
for i, idx := range e.virtualColumnIndex {
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
datum, err := virColDef[j].EvalVirtualColumn(row)
datum, err := e.schema.Columns[idx].EvalVirtualColumn(row)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EvalVirtualDatum converts the result to Datum, which is not efficient

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To use CastValue ,we have to get datum

if err != nil {
return err
}
castDatum, err := table.CastValue(e.ctx, datum, e.columns[virColIndex[j]])
castDatum, err := table.CastValue(e.ctx, datum, e.columns[idx])
if err != nil {
return err
}
virCols.AppendDatum(j, &castDatum)
virCols.AppendDatum(i, &castDatum)
}
req.SetCol(virColIndex[j], virCols.Column(j))
req.SetCol(idx, virCols.Column(i))
}

return nil
Expand Down Expand Up @@ -239,6 +222,26 @@ func (e *TableReaderExecutor) buildResp(ctx context.Context, ranges []*ranger.Ra
return result, nil
}

// buildVirtualColumnInfo saves virtual column indices and sort them in definition order
func (e *TableReaderExecutor) buildVirtualColumnInfo() {
e.virtualColumnIndex = make([]int, 0)
for i, col := range e.schema.Columns {
if col.VirtualExpr != nil {
e.virtualColumnIndex = append(e.virtualColumnIndex, i)
}
}
sort.Slice(e.virtualColumnIndex, func(i, j int) bool {
return model.FindColumnInfo(e.columns, e.schema.Columns[e.virtualColumnIndex[i]].OrigColName.String()).Offset <
model.FindColumnInfo(e.columns, e.schema.Columns[e.virtualColumnIndex[j]].OrigColName.String()).Offset
})
if len(e.virtualColumnIndex) > 0 {
e.virtualColumnRetFieldTypes = make([]*types.FieldType, 0)
for _, idx := range e.virtualColumnIndex {
e.virtualColumnRetFieldTypes = append(e.virtualColumnRetFieldTypes, e.schema.Columns[idx].RetType)
}
}
}

type tableResultHandler struct {
// If the pk is unsigned and we have KeepOrder=true and want ascending order,
// `optionalResult` will handles the request whose range is in signed int range, and
Expand Down