aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/query/parser.go
diff options
context:
space:
mode:
authorJP Appel <jeanpierre.appel01@gmail.com>2025-06-28 01:15:44 -0400
committerJP Appel <jeanpierre.appel01@gmail.com>2025-06-28 01:15:44 -0400
commitb6d1375c7bdf0f06eb32f1273ad5fd4f7c0e5673 (patch)
tree07b6bcfa994ed5273dea6d7d2d9491bf1fe91c94 /pkg/query/parser.go
parent468b14ea9e60698a3340aa1f1f53794834dafe9f (diff)
Add leveld optimization wrapper
Diffstat (limited to 'pkg/query/parser.go')
-rw-r--r--pkg/query/parser.go31
1 files changed, 30 insertions, 1 deletions
diff --git a/pkg/query/parser.go b/pkg/query/parser.go
index 178665d..c52530e 100644
--- a/pkg/query/parser.go
+++ b/pkg/query/parser.go
@@ -322,6 +322,35 @@ func (s Statements) OperatorPartition() iter.Seq2[opType, Statements] {
}
}
+// Partition statements by their negated status without copying, similar to
+// CategoryPartition and OperatorPartition
+func (s Statements) NegatedPartition() iter.Seq2[bool, Statements] {
+ if !slices.IsSortedFunc(s, StatementCmp) {
+ slices.SortFunc(s, StatementCmp)
+ }
+
+ return func(yield func(bool, Statements) bool) {
+ firstNegated := -1
+ for i, stmt := range s {
+ if stmt.Negated {
+ firstNegated = i
+ }
+ }
+
+ if firstNegated > 0 {
+ if !yield(false, s[:firstNegated]) {
+ return
+ } else if !yield(true, s[firstNegated:]) {
+ return
+ }
+ } else {
+ if !yield(false, s) {
+ return
+ }
+ }
+ }
+}
+
func (c Clause) String() string {
b := &strings.Builder{}
c.buildString(b, 0)
@@ -459,7 +488,7 @@ func Parse(tokens []Token) (*Clause, error) {
}
clause.Operator = COP_OR
case TOK_OP_NEG:
- if !prevToken.Type.Any(TOK_CLAUSE_OR, TOK_CLAUSE_AND, TOK_VAL_STR, TOK_VAL_DATETIME) {
+ if !prevToken.Type.Any(TOK_CLAUSE_OR, TOK_CLAUSE_AND, TOK_VAL_STR, TOK_VAL_DATETIME, TOK_CLAUSE_END) {
return nil, &TokenError{
got: token,
gotPrev: prevToken,