Skip to content

Commit

Permalink
MB-28533 Properly formalize keyspace reference inside Meta() functions
Browse files Browse the repository at this point in the history
This is a regression from fix for MB-27706, where an identifier expression now
has a marking to indicate whether the identifier is a keyspace reference. Then
in Formalizer.VisitIdentifer() function this information is used to determine
whether a keyspace reference needs to be added in front of an identifier. The
issue with this defect is that when a meta() function adds a keyspace reference
it did not properly set the indicator, resulting in another keyspace reference
added in front of it.

The fix is to properly mark the new identifier as a keyspace reference. This is
done in a couple of places where new identifiers are generated.

Also a few code cleanup is done, including:
  - check this.indexScope() instead of this.mapSelf() for keyspace references
  - add keyspace marking to identifiers when it's a user-specified reference

Change-Id: Ie19d3463787be06ae6016fa9a3c8225bb6452761
Reviewed-on: http://review.couchbase.org/90612
Reviewed-by: Sitaram Vemulapalli <sitaram.vemulapalli@couchbase.com>
Tested-by: Bingjie Miao <bingjie.miao@couchbase.com>
  • Loading branch information
miaobingjie committed Mar 7, 2018
1 parent f2bbff1 commit efd797b
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions expression/formalizer.go
Expand Up @@ -223,8 +223,13 @@ func (this *Formalizer) VisitIdentifier(expr *Identifier) (interface{}, error) {
// process then treat it as a keyspace alias
ident_flags := uint32(ident_val.ActualForIndex().(int64))
tmp_flags := ident_flags & IDENT_IS_KEYSPACE
if !this.mapSelf() || !this.indexScope() || tmp_flags == 0 || expr.IsKeyspaceAlias() {
if !this.indexScope() || tmp_flags == 0 || expr.IsKeyspaceAlias() {
this.identifiers.SetField(identifier, ident_val)
// for user specified keyspace alias (such as alias.c1)
// set flag to indicate it's keyspace
if tmp_flags != 0 && !expr.IsKeyspaceAlias() {
expr.SetKeyspaceAlias(true)
}
return expr, nil
}
}
Expand Down Expand Up @@ -252,7 +257,9 @@ Formalize SELF functions defined on indexes.
*/
func (this *Formalizer) VisitSelf(expr *Self) (interface{}, error) {
if this.mapSelf() {
return NewIdentifier(this.keyspace), nil
keyspaceIdent := NewIdentifier(this.keyspace)
keyspaceIdent.SetKeyspaceAlias(true)
return keyspaceIdent, nil
} else {
return expr, nil
}
Expand All @@ -266,7 +273,9 @@ func (this *Formalizer) VisitFunction(expr Function) (interface{}, error) {
meta, ok := expr.(*Meta)
if ok && len(meta.Operands()) == 0 {
if this.keyspace != "" {
return NewMeta(NewIdentifier(this.keyspace)), nil
keyspaceIdent := NewIdentifier(this.keyspace)
keyspaceIdent.SetKeyspaceAlias(true)
return NewMeta(keyspaceIdent), nil
} else {
return nil, errors.NewAmbiguousMetaError()
}
Expand Down Expand Up @@ -312,7 +321,7 @@ func (this *Formalizer) PushBindings(bindings Bindings, push bool) (err error) {
tmp_flags2 := ident_flags &^ IDENT_IS_KEYSPACE
// when sarging index keys, allow variables used in index definition
// to be the same as a keyspace alias
if !this.mapSelf() || tmp_flags1 == 0 || tmp_flags2 != 0 {
if !this.indexScope() || tmp_flags1 == 0 || tmp_flags2 != 0 {
err = fmt.Errorf("Duplicate variable %v already in scope.", b.Variable())
return
}
Expand All @@ -330,7 +339,7 @@ func (this *Formalizer) PushBindings(bindings Bindings, push bool) (err error) {
ident_flags = uint32(ident_val.ActualForIndex().(int64))
tmp_flags1 := ident_flags & IDENT_IS_KEYSPACE
tmp_flags2 := ident_flags &^ IDENT_IS_KEYSPACE
if !this.mapSelf() || tmp_flags1 == 0 || tmp_flags2 != 0 {
if !this.indexScope() || tmp_flags1 == 0 || tmp_flags2 != 0 {
err = fmt.Errorf("Duplicate variable %v already in scope.", b.NameVariable())
return
}
Expand Down

0 comments on commit efd797b

Please sign in to comment.