Skip to content

Commit

Permalink
fix unary in the beginning. add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
2403905 committed Sep 7, 2023
1 parent 6f2638a commit 338e928
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 9 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/kql-fix-unary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Fix: Fixed cunary in the beginning

Fixed case when the unary in the beginning lead to panic


https://github.com/owncloud/ocis/pull/7247
39 changes: 30 additions & 9 deletions services/search/pkg/query/bleve/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,18 @@ func (c Compiler) Compile(givenAst *ast.Ast) (bleveQuery.Query, error) {
}

func compile(a *ast.Ast) (bleveQuery.Query, error) {
q, _ := walk(0, a.Nodes)
q, _, err := walk(0, a.Nodes)
if err != nil {
return nil, err
}
switch q.(type) {
case *bleveQuery.ConjunctionQuery, *bleveQuery.DisjunctionQuery:
return q, nil
}
return bleve.NewConjunctionQuery(q), nil
}

func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int) {
func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
var prev, next bleveQuery.Query
var operator *ast.OperatorNode
var isGroup bool
Expand Down Expand Up @@ -113,7 +116,10 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int) {
if n.Key != "" {
n = normalizeGroupingProperty(n)
}
q, _ := walk(0, n.Nodes)
q, _, err := walk(0, n.Nodes)
if err != nil {
return nil, 0, err
}
if prev == nil {
prev = q
isGroup = true
Expand All @@ -124,10 +130,19 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int) {
if n.Value == kql.BoolAND || n.Value == kql.BoolOR {
operator = n
} else if n.Value == kql.BoolNOT {
next, offset = nextNode(i+1, nodes)
var err error
next, offset, err = nextNode(i+1, nodes)
if err != nil {
return nil, 0, err
}
q := bleve.NewBooleanQuery()
q.AddMustNot(next)
next = q
if prev == nil {
// unary in the beginning
prev = q
} else {
next = q
}
}
}
if prev != nil && next != nil && operator != nil {
Expand All @@ -140,13 +155,19 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int) {
i = offset
}
}
return prev, offset
if prev == nil {
return nil, 0, fmt.Errorf("can not compile the query")
}
return prev, offset, nil
}

func nextNode(offset int, nodes []ast.Node) (bleveQuery.Query, int) {
func nextNode(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
if n, ok := nodes[offset].(*ast.GroupNode); ok {
gq, _ := walk(0, n.Nodes)
return gq, offset + 1
gq, _, err := walk(0, n.Nodes)
if err != nil {
return nil, 0, err
}
return gq, offset + 1, nil
}
if n, ok := nodes[offset].(*ast.OperatorNode); ok {
if n.Value == kql.BoolNOT {
Expand Down
50 changes: 50 additions & 0 deletions services/search/pkg/query/bleve/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,56 @@ func Test_compile(t *testing.T) {
}),
wantErr: false,
},
{
name: `(tag:klass10) NOT tag:physik`,
args: &ast.Ast{
Nodes: []ast.Node{
&ast.GroupNode{
Key: "",
Nodes: []ast.Node{
&ast.StringNode{Key: "tag", Value: "klass10"},
},
},
&ast.OperatorNode{Value: "AND"},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "tag", Value: "physik"},
},
},
want: query.NewConjunctionQuery([]query.Query{
query.NewQueryStringQuery(`Tags:klass10`),
query.NewBooleanQuery(nil, nil, []query.Query{query.NewQueryStringQuery(`Tags:physik`)}),
}),
wantErr: false,
},
{
name: `tag:klass10 NOT tag:physik`,
args: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "tag", Value: "klass10"},
&ast.OperatorNode{Value: "OR"},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "tag", Value: "physik"},
},
},
want: query.NewDisjunctionQuery([]query.Query{
query.NewQueryStringQuery(`Tags:klass10`),
query.NewBooleanQuery(nil, nil, []query.Query{query.NewQueryStringQuery(`Tags:physik`)}),
}),
wantErr: false,
},
{
name: `NOT tag:physik`,
args: &ast.Ast{
Nodes: []ast.Node{
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "tag", Value: "physik"},
},
},
want: query.NewConjunctionQuery([]query.Query{
query.NewBooleanQuery(nil, nil, []query.Query{query.NewQueryStringQuery(`Tags:physik`)}),
}),
wantErr: false,
},
{
name: `ast.DateTimeNode`,
args: &ast.Ast{
Expand Down
1 change: 1 addition & 0 deletions services/search/pkg/query/kql/dictionary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ func TestParse(t *testing.T) {
},
},
},

{
name: "DateTimeRestrictionNode",
givenQuery: []string{
Expand Down
44 changes: 44 additions & 0 deletions services/search/pkg/query/kql/normalize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,50 @@ func TestNormalizeNodes(t *testing.T) {
&ast.DateTimeNode{Key: "mtime", Operator: &ast.OperatorNode{Value: "="}, Value: now},
},
},
// TODO
// This two expressions are contradictory
// (tag:klass10) NOT tag:physik will be transeted to tag:klass10 AND NOT tag:physik
// But
// tag:klass10 NOT tag:physik will be transeted to tag:klass10 OR NOT tag:physik
// How do we have to handle it?
{
name: "implicit AND - (tag:klass10) NOT tag:physik",
givenNodes: []ast.Node{
&ast.GroupNode{
Key: "",
Nodes: []ast.Node{
&ast.StringNode{Key: "tag", Value: "klass10"},
},
},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "tag", Value: "physik"},
},
expectedNodes: []ast.Node{
&ast.GroupNode{
Key: "",
Nodes: []ast.Node{
&ast.StringNode{Key: "tag", Value: "klass10"},
},
},
&ast.OperatorNode{Value: "AND"},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "tag", Value: "physik"},
},
},
{
name: "implicit AND - tag:klass10 NOT tag:physik",
givenNodes: []ast.Node{
&ast.StringNode{Key: "tag", Value: "klass10"},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "tag", Value: "physik"},
},
expectedNodes: []ast.Node{
&ast.StringNode{Key: "tag", Value: "klass10"},
&ast.OperatorNode{Value: "OR"},
&ast.OperatorNode{Value: "NOT"},
&ast.StringNode{Key: "tag", Value: "physik"},
},
},
}

assert := tAssert.New(t)
Expand Down

0 comments on commit 338e928

Please sign in to comment.