Skip to content

Commit

Permalink
MB-33618 - change EXISTS syntax to match that of N1QL
Browse files Browse the repository at this point in the history
  • Loading branch information
nelio2k committed Apr 3, 2019
1 parent ebc2afa commit c0fbc1c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
63 changes: 44 additions & 19 deletions filterExprParser.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
// LHS = ConstFuncExpr | Boolean | Field | Value
// RHS = ConstFuncExpr | Boolean | Value | Field
// CompareOp = "=" | "<>" | ">" | ">=" | "<" | "<="
// CheckOp = "EXISTS" | ( "IS" [ "NOT" ] ( NULL | MISSING ) )
// CheckOp = ( "IS" [ "NOT" ] ( NULL | MISSING ) )
// Field = { @"-" } OnePath { "." OnePath } { MathOp MathValue }
// OnePath = ( PathFuncExpression | StringType ){ ArrayIndex }
// StringType = @String | @Ident | @RawString | @Char
Expand All @@ -39,9 +39,10 @@ import (
// MathOp = @"+" | @"-" | @"*" | @"/" | @"%"
// MathValue = @Int | @Float
// OnePathFuncNoArgName = "META"
// BooleanFuncExpr = BooleanFuncTwoArgs
// BooleanFuncExpr = BooleanFuncTwoArgs | ExistsClause
// BooleanFuncTwoArgs = BooleanFuncTwoArgsName "(" ConstFuncArgument "," ConstFuncArgumentRHS ")"
// BooleanFuncTwoArgsName = "REGEXP_CONTAINS"
// ExistsClause = ( "EXISTS" "(" Field ")" )

type FilterExpression struct {
AndConditions []*FEAndCondition `( @@ { "OR" @@ } )`
Expand Down Expand Up @@ -868,16 +869,11 @@ func (f *FECompareOp) OutputExpression(lhs Expression, rhs Expression) (Expressi
}

type FECheckOp struct {
Exists *bool `@"EXISTS" | ( "IS"`
Not *bool `[ @"NOT" ]`
Not *bool `( "IS" [ @"NOT" ]`
Null *bool `( @"NULL" |`
Missing *bool `@"MISSING" ) )`
}

func (feco *FECheckOp) IsExists() bool {
return feco.Exists != nil && *feco.Exists == true
}

func (feco *FECheckOp) isNot() bool {
return feco.Not != nil && *feco.Not == true
}
Expand Down Expand Up @@ -907,9 +903,7 @@ func (feco *FECheckOp) IsNotNull() bool {
}

func (feco *FECheckOp) String() string {
if feco.IsExists() {
return OperatorExists
} else if feco.IsMissing() {
if feco.IsMissing() {
return OperatorMissing
} else if feco.IsNotMissing() {
return OperatorNotMissing
Expand All @@ -923,7 +917,7 @@ func (feco *FECheckOp) String() string {
}

func (f *FECheckOp) OutputExpression(subExpr Expression) (Expression, error) {
if f.IsExists() || f.IsNotMissing() {
if f.IsNotMissing() {
return ExistsExpr{
subExpr,
}, nil
Expand Down Expand Up @@ -1279,22 +1273,27 @@ func (arg *FEConstFuncTwoArgsName) OutputExpression() (string, error) {
}

type FEBooleanFuncExpr struct {
BooleanFuncTwoArgs *FEBooleanFuncTwoArgs `@@`
BooleanFuncTwoArgs *FEBooleanFuncTwoArgs `@@ |`
ExistsClause *FEExistsClause `@@`
}

func (e *FEBooleanFuncExpr) String() string {
if e.BooleanFuncTwoArgs != nil {
return e.BooleanFuncTwoArgs.String()
func (f *FEBooleanFuncExpr) String() string {
if f.BooleanFuncTwoArgs != nil {
return f.BooleanFuncTwoArgs.String()
} else if f.ExistsClause != nil {
return f.ExistsClause.String()
} else {
return "?? (FEBooleanFuncExpr)"
}
}

func (f *FEBooleanFuncExpr) OutputExpression() (Expression, error) {
if f.BooleanFuncTwoArgs == nil {
return nil, fmt.Errorf("Invalid FEBooleanFuncExpr")
if f.BooleanFuncTwoArgs != nil {
return f.BooleanFuncTwoArgs.OutputExpression()
} else if f.ExistsClause != nil {
return f.ExistsClause.OutputExpression()
}
return f.BooleanFuncTwoArgs.OutputExpression()
return nil, fmt.Errorf("Invalid FEBooleanFuncExpr")
}

type FEBooleanFuncTwoArgs struct {
Expand Down Expand Up @@ -1358,6 +1357,32 @@ func (n *FEBooleanFuncTwoArgsName) OutputExpression() (Expression, error) {
}
}

type FEExistsClause struct {
Field *FEField `( "EXISTS" "(" @@ ")" )`
}

func (f *FEExistsClause) String() string {
if f.Field != nil {
return fmt.Sprintf("%v ( %v )", OperatorExists, f.Field.String())
} else {
return "?? (FEExistsClause)"
}
}

func (f *FEExistsClause) OutputExpression() (Expression, error) {
if f.Field != nil {
fieldExpr, err := f.Field.OutputExpression()
if err != nil {
return nil, err
}
return ExistsExpr{
fieldExpr,
}, nil
}

return nil, fmt.Errorf("Invalid FEExistsClause %v", f.String())
}

func parserWrapper(parser *participle.Parser, expression string, fe *FilterExpression, err *error) {
defer func() {
if r := recover(); r != nil {
Expand Down
6 changes: 5 additions & 1 deletion filterExprParser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ func TestFilterExpressionParser(t *testing.T) {
assert.Equal("metaKey", fe.AndConditions[0].OrConditions[0].Operand.LHS.Field.Path[1].String())
assert.True(fe.AndConditions[0].OrConditions[0].Operand.Op.IsEqual())
assert.Equal("value", fe.AndConditions[0].OrConditions[0].Operand.RHS.Value.String())
err = parser.ParseString("`[$%XDCRInternalMeta*%$]`.metaKey EXISTS AND `[$%XDCRInternalMeta*%$]`.metaKey = \"value\"", fe)
err = parser.ParseString("EXISTS (`[$%XDCRInternalMeta*%$]`.metaKey) AND `[$%XDCRInternalMeta*%$]`.metaKey = \"value\"", fe)
assert.Nil(err)
expr, err = fe.OutputExpression()
assert.Nil(err)
Expand Down Expand Up @@ -598,4 +598,8 @@ func TestFilterExpressionParser(t *testing.T) {
assert.NotNil(err)
_, _, err = NewFilterExpressionParser("`field is unfinished = \"unfinished_value")
assert.NotNil(err)

// Discontinued
_, _, err = NewFilterExpressionParser("SomeKey EXISTS")
assert.NotNil(err)
}

0 comments on commit c0fbc1c

Please sign in to comment.