aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/query/optimizer.go
diff options
context:
space:
mode:
authorJP Appel <jeanpierre.appel01@gmail.com>2025-07-28 01:20:01 -0400
committerJP Appel <jeanpierre.appel01@gmail.com>2025-07-28 01:20:01 -0400
commit3b8dcd30f5aca7624a22cff85a2f767d8d1fb583 (patch)
treedb01e57776ef9a8bc104403cd038e303c6831500 /pkg/query/optimizer.go
parent7b5cd075161bd4e1a05070d51cc64b38882ae74b (diff)
Add regex operator
Implemented regex operator using go flavored regular expressions. Added optimization to combine regex's in `OR` clauses.
Diffstat (limited to 'pkg/query/optimizer.go')
-rw-r--r--pkg/query/optimizer.go63
1 files changed, 62 insertions, 1 deletions
diff --git a/pkg/query/optimizer.go b/pkg/query/optimizer.go
index 3c435e8..2cc610a 100644
--- a/pkg/query/optimizer.go
+++ b/pkg/query/optimizer.go
@@ -1,6 +1,7 @@
package query
import (
+ "bytes"
"slices"
"strings"
"sync"
@@ -52,7 +53,6 @@ func (o Optimizer) Optimize(level int) {
if level < 0 {
return
} else if level == 0 {
- // TODO: determine smarter level determination strategy
level = o.root.Depth()
}
@@ -63,6 +63,7 @@ func (o Optimizer) Optimize(level int) {
o.StrictEquality()
o.Tighten()
o.Contradictions()
+ o.MergeRegex()
// parallel + serial
o.Tidy()
// purely serial
@@ -326,6 +327,66 @@ func (o Optimizer) StrictEquality() {
})
}
+// Merge regular within a clause
+func (o *Optimizer) MergeRegex() {
+ if !o.isSorted {
+ o.SortStatements()
+ }
+
+ pool := &sync.Pool{}
+ pool.New = func() any {
+ return &bytes.Buffer{}
+ }
+
+ o.parallel(func(c *Clause) {
+ if c.Operator != COP_OR {
+ return
+ }
+
+ buf := pool.Get().(*bytes.Buffer)
+ defer pool.Put(buf)
+ defer buf.Reset()
+ sortChanged := false
+ for _, catStmts := range c.Statements.CategoryPartition() {
+ for op, opStmts := range catStmts.OperatorPartition() {
+ if op != OP_RE {
+ continue
+ }
+
+ for _, stmts := range opStmts.NegatedPartition() {
+ if len(stmts) <= 1 {
+ continue
+ }
+ sortChanged = true
+
+ for i, stmt := range stmts {
+ if i == 0 {
+ buf.WriteByte('(')
+ buf.WriteString(stmt.Value.(StringValue).S)
+ buf.WriteByte('|')
+ } else if i == len(stmts)-1 {
+ buf.WriteString(stmt.Value.(StringValue).S)
+ buf.WriteByte(')')
+ stmts[i] = Statement{}
+ } else {
+ buf.WriteString(stmt.Value.(StringValue).S)
+ buf.WriteByte('|')
+ stmts[i] = Statement{}
+ }
+ }
+ stmts[0].Value = StringValue{S: buf.String()}
+ buf.Reset()
+ }
+
+ break
+ }
+ }
+ if sortChanged {
+ o.isSorted = false
+ }
+ })
+}
+
// Shrink approximate statements and ranges
//
// Examples: