diff options
| author | JP Appel <jeanpierre.appel01@gmail.com> | 2025-06-28 01:15:44 -0400 |
|---|---|---|
| committer | JP Appel <jeanpierre.appel01@gmail.com> | 2025-06-28 01:15:44 -0400 |
| commit | b6d1375c7bdf0f06eb32f1273ad5fd4f7c0e5673 (patch) | |
| tree | 07b6bcfa994ed5273dea6d7d2d9491bf1fe91c94 /pkg/query/parser.go | |
| parent | 468b14ea9e60698a3340aa1f1f53794834dafe9f (diff) | |
Add leveld optimization wrapper
Diffstat (limited to 'pkg/query/parser.go')
| -rw-r--r-- | pkg/query/parser.go | 31 |
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, |
