Skip to content

Commit b009b9c

Browse files
committed
MB-65809 Change how expression parsing is done when unmarshalling plan
To properly handle subqueries in plan stability, we need a mechansim to identify the subquery expressions as they are unmarshalled from the plan. To assist in this capability, we modify the way we parse expressions as plan unmarshalling is done, such that instead of directly calling the parser, we add a level of indirection, by introducing a new parsing member function for each operator. This new function will call the parser to parse the expressions, and that's all it's doing currently, but we'll add functionality later on to look for subqueries after the expression is generated from the parser. During unmarshal of plan, any time we are dealing with an expression that can potentially contain one or more subqueries, we'll call this new function; in places where we know the expression cannot contain any subqueries, we still leave the original parsing call alone, i.e. still use the expression parser directly. Some examples of expressions that cannot contain subqueries include: - index cover and filter cover expressions - index spans - early filter that gets pushed down to various operators such as Filter, ExpressionScan, Unnest, IndexScan3, NLJoin, NLNest, HashJoin, HashNest, Unnest, etc. The generation of these early filters discard subquery filters - GROUP BY keys, Aggregate expressions (including window aggregates) - expressions in DDL statements, UPDATE STATISTICS statement, INFER statement - join bit filter expressions (bloom filters) for hash join/nest - KEY, VALUE, OPTIONS expressions for SendInsert, SendUpdate, SendUpsert, SendDelete - value expressions for ValueScan - expressions used for IndexFtsSearch (in FtsSearchInfo) - expressions used for vector search - ASC/DESC and NullPos specifications for ORDER BY Change-Id: I94c27f4973f9d1cbf39515f007e691f779b47fd3 Reviewed-on: https://review.couchbase.org/c/query/+/242025 Tested-by: Bingjie Miao <bingjie.miao@couchbase.com> Reviewed-by: Sitaram Vemulapalli <sitaram.vemulapalli@couchbase.com>
1 parent d7048ae commit b009b9c

31 files changed

Lines changed: 73 additions & 63 deletions

plan/base.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ func (this *readonly) SetPlanContext(planContext *planContext) {
4343
this.planContext = planContext
4444
}
4545

46+
func (this *readonly) parseExpression(s string) (expression.Expression, error) {
47+
return parseWithContext(s, this.planContext)
48+
}
49+
4650
type readwrite struct {
4751
planContext *planContext
4852
}
@@ -66,6 +70,10 @@ func (this *readwrite) SetPlanContext(planContext *planContext) {
6670
this.planContext = planContext
6771
}
6872

73+
func (this *readwrite) parseExpression(s string) (expression.Expression, error) {
74+
return parseWithContext(s, this.planContext)
75+
}
76+
6977
// optimizer estimates
7078
type optEstimate struct {
7179
cost float64

plan/fetch.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/couchbase/query/datastore"
1616
"github.com/couchbase/query/errors"
1717
"github.com/couchbase/query/expression"
18-
"github.com/couchbase/query/expression/parser"
1918
)
2019

2120
type Fetch struct {
@@ -147,7 +146,7 @@ func (this *Fetch) UnmarshalJSON(body []byte) error {
147146

148147
if _unmarshalled.FromExpr != "" {
149148
var expr expression.Expression
150-
expr, err = parser.Parse(_unmarshalled.FromExpr)
149+
expr, err = this.parseExpression(_unmarshalled.FromExpr)
151150
if err == nil {
152151
this.term = algebra.NewKeyspaceTermFromExpression(expr, _unmarshalled.As, nil, nil, 0)
153152
}
@@ -266,7 +265,7 @@ func (this *DummyFetch) UnmarshalJSON(body []byte) error {
266265
unmarshalOptEstimate(&this.optEstimate, _unmarshalled.OptEstimate)
267266

268267
if _unmarshalled.FromExpr != "" {
269-
expr, err1 := parser.Parse(_unmarshalled.FromExpr)
268+
expr, err1 := this.parseExpression(_unmarshalled.FromExpr)
270269
if err1 != nil {
271270
return err1
272271
}

plan/filter.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"encoding/json"
1313

1414
"github.com/couchbase/query/expression"
15-
"github.com/couchbase/query/expression/parser"
1615
)
1716

1817
type Filter struct {
@@ -92,7 +91,7 @@ func (this *Filter) UnmarshalJSON(body []byte) error {
9291
}
9392

9493
if _unmarshalled.Condition != "" {
95-
this.cond, err = parser.Parse(_unmarshalled.Condition)
94+
this.cond, err = this.parseExpression(_unmarshalled.Condition)
9695
if err != nil {
9796
return err
9897
}

plan/join.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/couchbase/query/datastore"
1616
"github.com/couchbase/query/errors"
1717
"github.com/couchbase/query/expression"
18-
"github.com/couchbase/query/expression/parser"
1918
)
2019

2120
type Join struct {
@@ -151,7 +150,7 @@ func (this *Join) UnmarshalJSON(body []byte) error {
151150

152151
var keys_expr expression.Expression
153152
if _unmarshalled.On != "" {
154-
keys_expr, err = parser.Parse(_unmarshalled.On)
153+
keys_expr, err = this.parseExpression(_unmarshalled.On)
155154
if err != nil {
156155
return err
157156
}
@@ -169,7 +168,7 @@ func (this *Join) UnmarshalJSON(body []byte) error {
169168
}
170169

171170
if _unmarshalled.OnFilter != "" {
172-
this.onFilter, err = parser.Parse(_unmarshalled.OnFilter)
171+
this.onFilter, err = this.parseExpression(_unmarshalled.OnFilter)
173172
if err != nil {
174173
return err
175174
}

plan/join_hash.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func (this *HashJoin) UnmarshalJSON(body []byte) error {
164164
}
165165

166166
if _unmarshalled.Onclause != "" {
167-
this.onclause, err = parser.Parse(_unmarshalled.Onclause)
167+
this.onclause, err = this.parseExpression(_unmarshalled.Onclause)
168168
if err != nil {
169169
return err
170170
}

plan/join_index.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func (this *IndexJoin) UnmarshalJSON(body []byte) error {
203203

204204
var keys_expr expression.Expression
205205
if _unmarshalled.On != "" {
206-
keys_expr, err = parser.Parse(_unmarshalled.On)
206+
keys_expr, err = this.parseExpression(_unmarshalled.On)
207207
if err != nil {
208208
return err
209209
}

plan/join_nl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func (this *NLJoin) UnmarshalJSON(body []byte) error {
128128
}
129129

130130
if _unmarshalled.Onclause != "" {
131-
this.onclause, err = parser.Parse(_unmarshalled.Onclause)
131+
this.onclause, err = this.parseExpression(_unmarshalled.Onclause)
132132
if err != nil {
133133
return err
134134
}

plan/limit.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"encoding/json"
1313

1414
"github.com/couchbase/query/expression"
15-
"github.com/couchbase/query/expression/parser"
1615
)
1716

1817
type Limit struct {
@@ -69,7 +68,7 @@ func (this *Limit) UnmarshalJSON(body []byte) error {
6968
return err
7069
}
7170

72-
this.expr, err = parser.Parse(_unmarshalled.Expr)
71+
this.expr, err = this.parseExpression(_unmarshalled.Expr)
7372
if err != nil {
7473
return err
7574
}

plan/merge.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/couchbase/query/datastore"
1616
"github.com/couchbase/query/errors"
1717
"github.com/couchbase/query/expression"
18-
"github.com/couchbase/query/expression/parser"
1918
)
2019

2120
type Merge struct {
@@ -213,7 +212,7 @@ func (this *Merge) UnmarshalJSON(body []byte) error {
213212
}
214213

215214
if _unmarshalled.Key != "" {
216-
this.key, err = parser.Parse(_unmarshalled.Key)
215+
this.key, err = this.parseExpression(_unmarshalled.Key)
217216
if err != nil {
218217
return err
219218
}
@@ -223,7 +222,7 @@ func (this *Merge) UnmarshalJSON(body []byte) error {
223222
this.fastDiscard = _unmarshalled.FastDiscard
224223

225224
if _unmarshalled.Limit != "" {
226-
this.limit, err = parser.Parse(_unmarshalled.Limit)
225+
this.limit, err = this.parseExpression(_unmarshalled.Limit)
227226
if err != nil {
228227
return err
229228
}
@@ -268,19 +267,19 @@ func (this *Merge) UnmarshalJSON(body []byte) error {
268267
unmarshalOptEstimate(&this.optEstimate, _unmarshalled.OptEstimate)
269268

270269
if _unmarshalled.UpdateFilter != "" {
271-
if this.updateFilter, err = parser.Parse(_unmarshalled.UpdateFilter); err != nil {
270+
if this.updateFilter, err = this.parseExpression(_unmarshalled.UpdateFilter); err != nil {
272271
return err
273272
}
274273
}
275274

276275
if _unmarshalled.DeleteFilter != "" {
277-
if this.deleteFilter, err = parser.Parse(_unmarshalled.DeleteFilter); err != nil {
276+
if this.deleteFilter, err = this.parseExpression(_unmarshalled.DeleteFilter); err != nil {
278277
return err
279278
}
280279
}
281280

282281
if _unmarshalled.InsertFilter != "" {
283-
if this.insertFilter, err = parser.Parse(_unmarshalled.InsertFilter); err != nil {
282+
if this.insertFilter, err = this.parseExpression(_unmarshalled.InsertFilter); err != nil {
284283
return err
285284
}
286285
}

plan/nest.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/couchbase/query/datastore"
1616
"github.com/couchbase/query/errors"
1717
"github.com/couchbase/query/expression"
18-
"github.com/couchbase/query/expression/parser"
1918
)
2019

2120
type Nest struct {
@@ -151,7 +150,7 @@ func (this *Nest) UnmarshalJSON(body []byte) error {
151150

152151
var keys_expr expression.Expression
153152
if _unmarshalled.On != "" {
154-
keys_expr, err = parser.Parse(_unmarshalled.On)
153+
keys_expr, err = this.parseExpression(_unmarshalled.On)
155154
if err != nil {
156155
return err
157156
}
@@ -169,7 +168,7 @@ func (this *Nest) UnmarshalJSON(body []byte) error {
169168
}
170169

171170
if _unmarshalled.OnFilter != "" {
172-
this.onFilter, err = parser.Parse(_unmarshalled.OnFilter)
171+
this.onFilter, err = this.parseExpression(_unmarshalled.OnFilter)
173172
if err != nil {
174173
return err
175174
}

0 commit comments

Comments
 (0)