-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
*: Selection can control the conditions of the below scan plan. #2834
Changes from 8 commits
5db58a9
1fe024d
5ce9107
364e172
36283cf
7451287
053c2d4
e663291
a25a3eb
6aadeaa
ba29a95
02cbcf1
9a9ae32
ef178a3
8029c1e
9771129
7251827
e45f669
4e0012b
f0ec2e0
02db63c
c791ff7
8674c3f
107a042
3fd0435
8f29d17
088e9e6
6351036
97998fc
55f92e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -461,21 +461,91 @@ func (e *TableDualExec) Close() error { | |
return nil | ||
} | ||
|
||
func substituteCorCol2Constant(expr expression.Expression) (expression.Expression) { | ||
switch x := expr.(type) { | ||
case *expression.ScalarFunction: | ||
newArgs := make([]expression.Expression, 0, len(x.GetArgs())) | ||
for _, arg := range x.GetArgs() { | ||
newArgs = append(newArgs, substituteCorCol2Constant(arg)) | ||
} | ||
newSf, _ := expression.NewFunction(x.GetCtx(), x.FuncName.L, x.GetType(), newArgs...) | ||
return newSf, nil | ||
case *expression.CorrelatedColumn: | ||
return &expression.Constant{Value: x.Data, RetType: x.GetType()} | ||
default: | ||
return x.Clone() | ||
} | ||
} | ||
|
||
// SelectionExec represents a filter executor. | ||
type SelectionExec struct { | ||
Src Executor | ||
Condition expression.Expression | ||
ctx context.Context | ||
schema *expression.Schema | ||
|
||
// scanController will tell whether this selection need to | ||
// control the condition of below scan executor. | ||
scanController bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add comments for these two fields. |
||
controllerInit bool | ||
accessConditions []expression.Expression | ||
idxFilterConditions []expression.Expression | ||
tblFilterConditions []expression.Expression | ||
} | ||
|
||
// Schema implements the Executor Schema interface. | ||
func (e *SelectionExec) Schema() *expression.Schema { | ||
return e.schema | ||
} | ||
|
||
// initController will init the conditions of the below scan executor. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add more comments for this function. |
||
func (e *SelectionExec) initController() error { | ||
sc := e.ctx.GetSessionVars().StmtCtx | ||
client := e.ctx.GetClient() | ||
accesses := make([]expression.Expression, 0, len(e.accessConditions)) | ||
for _, cond := range e.accessConditions { | ||
newCond := substituteCorCol2Constant(cond) | ||
accesses = append(accesses, newCond) | ||
} | ||
switch x := e.Src.(type) { | ||
case *XSelectTableExec: | ||
ranges, err := plan.BuildTableRange(accesses, sc) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
x.ranges = ranges | ||
tblFilters := make([]expression.Expression, 0, len(e.tblFilterConditions)) | ||
for _, cond := range e.tblFilterConditions { | ||
newCond := substituteCorCol2Constant(cond) | ||
tblFilters = append(tblFilters, newCond) | ||
} | ||
var conds []expression.Expression | ||
x.where, _, conds = plan.ExpressionsToPB(sc, tblFilters, client) | ||
e.Condition = expression.ComposeCNFCondition(e.ctx, conds...) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. e.Condition don't need to be changed. |
||
return nil | ||
case *XSelectIndexExec: | ||
x.indexPlan.AccessCondition = accesses | ||
err := plan.BuildIndexRange(sc, x.indexPlan) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
x.indexPlan.IndexConditionPBExpr, _, _ = plan.ExpressionsToPB(sc, e.idxFilterConditions, client) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When do we update the e.idxFilterConditions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
x.indexPlan.TableConditionPBExpr, _, _ = plan.ExpressionsToPB(sc, e.tblFilterConditions, client) | ||
return nil | ||
default: | ||
return errors.New("Error type of PhysicalPlan") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. print %T to tout put the plan type |
||
} | ||
} | ||
|
||
// Next implements the Executor Next interface. | ||
func (e *SelectionExec) Next() (*Row, error) { | ||
if e.scanController && !e.controllerInit { | ||
err := e.initController() | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
e.controllerInit = true | ||
} | ||
for { | ||
srcRow, err := e.Src.Next() | ||
if err != nil { | ||
|
@@ -484,6 +554,9 @@ func (e *SelectionExec) Next() (*Row, error) { | |
if srcRow == nil { | ||
return nil, nil | ||
} | ||
if e.Condition == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can remove this. |
||
return srcRow, nil | ||
} | ||
match, err := expression.EvalBool(e.Condition, srcRow.Data, e.ctx) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
|
@@ -496,6 +569,9 @@ func (e *SelectionExec) Next() (*Row, error) { | |
|
||
// Close implements the Executor Close interface. | ||
func (e *SelectionExec) Close() error { | ||
if e.scanController { | ||
e.controllerInit = false | ||
} | ||
return e.Src.Close() | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,8 @@ import ( | |
"github.com/pingcap/tipb/go-tipb" | ||
) | ||
|
||
func expressionsToPB(sc *variable.StatementContext, exprs []expression.Expression, client kv.Client) (pbExpr *tipb.Expr, pushed []expression.Expression, remained []expression.Expression) { | ||
// ExpressionsToPB change expression to tipb.Expr. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change -> converts |
||
func ExpressionsToPB(sc *variable.StatementContext, exprs []expression.Expression, client kv.Client) (pbExpr *tipb.Expr, pushed []expression.Expression, remained []expression.Expression) { | ||
pc := pbConverter{client: client, sc: sc} | ||
for _, expr := range exprs { | ||
v := pc.exprToPB(expr) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,6 +146,13 @@ type Selection struct { | |
|
||
// onTable means if this selection's child is a table scan or index scan. | ||
onTable bool | ||
|
||
// If ScanController is true, then the child of this selection is a scan, | ||
// which use pk or index | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add |
||
ScanController bool | ||
AccessConditions []expression.Expression | ||
IdxConditions []expression.Expression | ||
TblConditions []expression.Expression | ||
} | ||
|
||
func (p *Selection) extractCorrelatedCols() []*expression.CorrelatedColumn { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you may consider the case of "Cast"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will look into this tonight.