@@ -74,32 +74,47 @@ func collectGenerateColumn(lp LogicalPlan, exprToColumn ExprColumnMap) {
74
74
}
75
75
}
76
76
77
- func tryToSubstituteExpr (expr * expression.Expression , sctx sessionctx.Context , candidateExpr expression.Expression , tp types.EvalType , schema * expression.Schema , col * expression.Column ) {
78
- if (* expr ).Equal (sctx , candidateExpr ) && candidateExpr .GetType ().EvalType () == tp &&
77
+ func tryToSubstituteExpr (expr * expression.Expression , sessionCtx sessionctx.Context , candidateExpr expression.Expression , tp types.EvalType , schema * expression.Schema , col * expression.Column ) bool {
78
+ changed := false
79
+ if (* expr ).Equal (sessionCtx , candidateExpr ) && candidateExpr .GetType ().EvalType () == tp &&
79
80
schema .ColumnIndex (col ) != - 1 {
80
81
* expr = col
82
+ changed = true
81
83
}
84
+ return changed
82
85
}
83
86
84
- func substituteExpression (cond expression.Expression , sctx * stmtctx.StatementContext , sessionCtx sessionctx.Context , exprToColumn ExprColumnMap , schema * expression.Schema ) {
87
+ // SubstituteExpression is Exported for bench
88
+ func SubstituteExpression (cond expression.Expression , sctx * stmtctx.StatementContext , sessionCtx sessionctx.Context , exprToColumn ExprColumnMap , schema * expression.Schema ) bool {
89
+ return substituteExpression (cond , sctx , sessionCtx , exprToColumn , schema )
90
+ }
91
+
92
+ func substituteExpression (cond expression.Expression , sctx * stmtctx.StatementContext , sessionCtx sessionctx.Context , exprToColumn ExprColumnMap , schema * expression.Schema ) bool {
85
93
sf , ok := cond .(* expression.ScalarFunction )
86
94
if ! ok {
87
- return
95
+ return false
96
+ }
97
+ changed := false
98
+ collectChanged := func (partial bool ) {
99
+ if partial && ! changed {
100
+ changed = true
101
+ }
88
102
}
89
103
defer func () {
90
104
// If the argument is not changed, hash code doesn't need to recount again.
91
- // But we always do it to keep the code simple and stupid.
92
- expression .ReHashCode (sf , sctx )
105
+ if changed {
106
+ expression .ReHashCode (sf , sctx )
107
+ }
93
108
}()
94
109
var expr * expression.Expression
95
110
var tp types.EvalType
96
111
switch sf .FuncName .L {
97
112
case ast .EQ , ast .LT , ast .LE , ast .GT , ast .GE :
98
113
for candidateExpr , column := range exprToColumn {
99
- tryToSubstituteExpr (& sf .GetArgs ()[1 ], sessionCtx , candidateExpr , sf .GetArgs ()[0 ].GetType ().EvalType (), schema , column )
114
+ collectChanged ( tryToSubstituteExpr (& sf .GetArgs ()[1 ], sessionCtx , candidateExpr , sf .GetArgs ()[0 ].GetType ().EvalType (), schema , column ) )
100
115
}
101
116
for candidateExpr , column := range exprToColumn {
102
- tryToSubstituteExpr (& sf .GetArgs ()[0 ], sessionCtx , candidateExpr , sf .GetArgs ()[1 ].GetType ().EvalType (), schema , column )
117
+ collectChanged ( tryToSubstituteExpr (& sf .GetArgs ()[0 ], sessionCtx , candidateExpr , sf .GetArgs ()[1 ].GetType ().EvalType (), schema , column ) )
103
118
}
104
119
case ast .In :
105
120
expr = & sf .GetArgs ()[0 ]
@@ -115,21 +130,22 @@ func substituteExpression(cond expression.Expression, sctx *stmtctx.StatementCon
115
130
}
116
131
if canSubstitute {
117
132
for candidateExpr , column := range exprToColumn {
118
- tryToSubstituteExpr (expr , sessionCtx , candidateExpr , tp , schema , column )
133
+ collectChanged ( tryToSubstituteExpr (expr , sessionCtx , candidateExpr , tp , schema , column ) )
119
134
}
120
135
}
121
136
case ast .Like :
122
137
expr = & sf .GetArgs ()[0 ]
123
138
tp = sf .GetArgs ()[1 ].GetType ().EvalType ()
124
139
for candidateExpr , column := range exprToColumn {
125
- tryToSubstituteExpr (expr , sessionCtx , candidateExpr , tp , schema , column )
140
+ collectChanged ( tryToSubstituteExpr (expr , sessionCtx , candidateExpr , tp , schema , column ) )
126
141
}
127
142
case ast .LogicOr , ast .LogicAnd :
128
- substituteExpression (sf .GetArgs ()[0 ], sctx , sessionCtx , exprToColumn , schema )
129
- substituteExpression (sf .GetArgs ()[1 ], sctx , sessionCtx , exprToColumn , schema )
143
+ collectChanged ( substituteExpression (sf .GetArgs ()[0 ], sctx , sessionCtx , exprToColumn , schema ) )
144
+ collectChanged ( substituteExpression (sf .GetArgs ()[1 ], sctx , sessionCtx , exprToColumn , schema ) )
130
145
case ast .UnaryNot :
131
- substituteExpression (sf .GetArgs ()[0 ], sctx , sessionCtx , exprToColumn , schema )
146
+ collectChanged ( substituteExpression (sf .GetArgs ()[0 ], sctx , sessionCtx , exprToColumn , schema ) )
132
147
}
148
+ return changed
133
149
}
134
150
135
151
func (gc * gcSubstituter ) substitute (ctx context.Context , lp LogicalPlan , exprToColumn ExprColumnMap ) LogicalPlan {
0 commit comments