Skip to content

Commit

Permalink
MB-32691 Detect nested correlation in FROM clause
Browse files Browse the repository at this point in the history
Currently correlation is checked by references in the query block,
and marked on the SELECT. In the repro case we have nested subqueries
in the FROM clause. We correctly detected the inner most query block
as correlated, but not the intermediate subquery level since the
only correlation is in the FROM clause subquery which is currently
not detected.

Add a function to detect correlation in the FROM term interface
such that any correlated subquery or expression term in the FROM
clause can be easily determined, and set the correlation flag
in SELECT if such correlation is detected.

Change-Id: I2c9512ab7f7c79c58013af5d62162d6e1b0e192e
Reviewed-on: http://review.couchbase.org/c/query/+/142590
Reviewed-by: Sitaram Vemulapalli <sitaram.vemulapalli@couchbase.com>
Tested-by: Bingjie Miao <bingjie.miao@couchbase.com>
  • Loading branch information
miaobingjie committed Dec 22, 2020
1 parent 09430b6 commit 7ee61e9
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 0 deletions.
5 changes: 5 additions & 0 deletions algebra/from.go
Expand Up @@ -58,6 +58,11 @@ type FromTerm interface {
Represents alias string.
*/
Alias() string

/*
Contains correlation reference?
*/
IsCorrelated() bool
}

type SimpleFromTerm interface {
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_join.go
Expand Up @@ -158,6 +158,13 @@ func (this *Join) Outer() bool {
return this.outer
}

/*
Returns whether contains correlation reference
*/
func (this *Join) IsCorrelated() bool {
return this.left.IsCorrelated() || this.right.IsCorrelated()
}

/*
Marshals input JOIN terms.
*/
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_join_ansi.go
Expand Up @@ -235,6 +235,13 @@ func (this *AnsiJoin) SetHintError(hintError string) {
}
}

/*
Returns whether contains correlation reference
*/
func (this *AnsiJoin) IsCorrelated() bool {
return this.left.IsCorrelated() || this.right.IsCorrelated()
}

/*
Marshals input JOIN terms.
*/
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_join_index.go
Expand Up @@ -171,6 +171,13 @@ func (this *IndexJoin) For() string {
return this.keyFor
}

/*
Returns whether contains correlation reference
*/
func (this *IndexJoin) IsCorrelated() bool {
return this.left.IsCorrelated() || this.right.IsCorrelated()
}

/*
Marshals input JOIN terms.
*/
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_keyspace.go
Expand Up @@ -487,6 +487,13 @@ func (this *KeyspaceTerm) SetIndexJoinNest() {
this.property |= TERM_INDEX_JOIN_NEST
}

/*
Return whether correlated
*/
func (this *KeyspaceTerm) IsCorrelated() bool {
return false
}

/*
Marshals the input keyspace into a byte array.
*/
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_nest.go
Expand Up @@ -162,6 +162,13 @@ func (this *Nest) Outer() bool {
return this.outer
}

/*
Returns whether contains correlation reference
*/
func (this *Nest) IsCorrelated() bool {
return this.left.IsCorrelated() || this.right.IsCorrelated()
}

/*
Marshals input NEST terms into byte array.
*/
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_nest_ansi.go
Expand Up @@ -217,6 +217,13 @@ func (this *AnsiNest) SetHintError(hintError string) {
}
}

/*
Returns whether contains correlation reference
*/
func (this *AnsiNest) IsCorrelated() bool {
return this.left.IsCorrelated() || this.right.IsCorrelated()
}

/*
Marshals input NEST terms into byte array.
*/
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_nest_index.go
Expand Up @@ -174,6 +174,13 @@ func (this *IndexNest) For() string {
return this.keyFor
}

/*
Returns whether contains correlation reference
*/
func (this *IndexNest) IsCorrelated() bool {
return this.left.IsCorrelated() || this.right.IsCorrelated()
}

/*
Marshals input NEST terms into byte array.
*/
Expand Down
7 changes: 7 additions & 0 deletions algebra/from_subquery.go
Expand Up @@ -188,3 +188,10 @@ Set ANSI NEST property
func (this *SubqueryTerm) SetAnsiNest() {
this.property |= TERM_ANSI_NEST
}

/*
Return whether correlated
*/
func (this *SubqueryTerm) IsCorrelated() bool {
return this.subquery.IsCorrelated()
}
7 changes: 7 additions & 0 deletions algebra/from_unnest.go
Expand Up @@ -175,6 +175,13 @@ func (this *Unnest) Outer() bool {
return this.outer
}

/*
Returns whether contains correlation reference
*/
func (this *Unnest) IsCorrelated() bool {
return this.left.IsCorrelated()
}

/*
Marshals input unnest terms into byte array.
*/
Expand Down
4 changes: 4 additions & 0 deletions algebra/select_sub.go
Expand Up @@ -142,6 +142,10 @@ func (this *Subselect) Formalize(parent *expression.Formalizer) (f *expression.F
}
}

if !this.correlated && this.from != nil && this.from.IsCorrelated() {
this.correlated = true
}

return f, nil
}

Expand Down

0 comments on commit 7ee61e9

Please sign in to comment.