Repository navigation
Commit 2ba64ed
authored
Evaluate EQ(REGEXP_EXTRACT) once per distinct value with RegexExtractEqQuery (#6819)
* Rewrite EQ(REGEXP_EXTRACT) predicates to RegexQuery when eligible
Lower a narrow calculated-field equality over REGEXP_EXTRACT into an
inverted-index RegexQuery for fast, indexed, raw string fields, so
search can avoid per-document JIT evaluation while preserving warmup.
* Allow unanchored EQ(REGEXP_EXTRACT) rewrite with swapped EQ args
Honor optional ^/$ by wrapping missing sides with .* and treat EQ as
commutative so literal/extract order does not block the RegexQuery path.
* Prefilter EQ(REGEXP_EXTRACT) with FST RegexQuery, keep exact JIT
Intersect an over-approximating RegexQuery with the original CalcField
predicate so unanchored log-style extracts stay semantically exact while
the FST path narrows candidates.
* Skip JIT for fully anchored EQ(REGEXP_EXTRACT) rewrites
When the extract pattern has both ^ and $, the FST RegexQuery alone is
equivalent, so drop the CalcField intersection; keep prefilter∧JIT otherwise.
* Always prefilter EQ(REGEXP_EXTRACT) with FST RegexQuery
Drop the Exact rewrite for fully anchored patterns: leftmost extract
semantics are not always equivalent to an FST whole-term match, so keep
CalcField as the exact filter and add a Criterion microbench.
* Parse REGEXP_EXTRACT pattern with regex-syntax for prefilter rewrite
Replace manual parenthesis scanning in substitute_single_capture with a
regex-syntax AST walk, and add a prefilter_only path to the bench to
separate FST cost from JIT cost.
* Fix soundness of EQ(REGEXP_EXTRACT) FST prefilter
- Require the capture group to be a direct part of the top-level concatenation.
- Wrap unanchored sides with (?s:.*) so multi-line values are not dropped.
- Reject fields whose fast field is normalized.
- Keep patterns whose rewrite needs look-arounds on the JIT path.
* Evaluate EQ(REGEXP_EXTRACT) on the fast-field dictionary with exact JIT semantics
Replace the term-dictionary rewrite with RegexExtractEqQuery, which walks the
fast-field dictionary with the FST prefilter, checks the capture on each
candidate value, and selects documents by the ordinal of their first value.
This matches the JIT predicate on multi-valued documents, on values longer
than MAX_TOKEN_LEN, and on normalized fast fields.
Documents are collected with range scans when the matching ordinals form a
few runs, with block decoding on full single-valued columns, and with a
per-document first-value loop otherwise.
Drop the regexp_extract_eq benchmark.
* Simplify RegexExtractEqQuery to a first-value document loop
Drop the range-scan and block-decoding strategies: collect matching
documents with a single loop over first-value ordinals. Move the
RegexExtractEqQuery end-to-end tests next to the query, document that
column errors are returned rather than treated as an absent column, and
use `regex_extract_eq` naming consistently.
* Read postings for EQ(REGEXP_EXTRACT) on raw-indexed fields
When the field is also indexed with the raw tokenizer and every matching
fast-field value is shorter than the raw tokenizer's length limit, visit
only the documents in the postings of the matching terms, still keeping a
document only when its first fast-field value matches. Otherwise fall
back to the first-value loop over every document.
Warm the field's term dictionary and postings with the prefilter regex.
On 10M-document low-cardinality corpora this takes 1.2-1.5ms instead of
19ms. When the prefilter accepts most of a high-cardinality dictionary,
walking the term dictionary a second time doubles the cost.
* Skip the first-value check on single-valued postings of EQ(REGEXP_EXTRACT)
A document of a full or optional column holds only the value of the term
whose postings contain it, and that value matches.
* Keep tantivy-common on the same rev as tantivy
Main moved tantivy to e229de6, which left two tantivy-common versions and
broke BitSetDocSet::from(BitSet) in RegexExtractEqQuery.
* Walk only the term dictionary when it holds every fast-field value
* Support any capture index in REGEXP_EXTRACT equality
* Clarify regex extract query documentation
* Clarify and simplify regex extract planning
* Rewrite REGEXP_EXTRACT capture isolation via regex-syntax AST
Avoid byte-offset string splicing and keep prefilters correct under multiline and verbose flags.
* Simplify verbose-flag wrapping in capture substitution
* Cache REGEXP_EXTRACT query regexes
* Remove unused search FST dependency1 parent 7b256dd commit 2ba64ed
10 files changed
Lines changed: 1431 additions & 16 deletions
File tree
- quickwit
- quickwit-doc-mapper/src
- quickwit-query
- benches
- src/query_ast
- quickwit-search
- src
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
386 | 386 | | |
387 | 387 | | |
388 | 388 | | |
| 389 | + | |
| 390 | + | |
389 | 391 | | |
390 | 392 | | |
391 | 393 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
380 | 380 | | |
381 | 381 | | |
382 | 382 | | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
383 | 395 | | |
384 | 396 | | |
385 | 397 | | |
| |||
400 | 412 | | |
401 | 413 | | |
402 | 414 | | |
403 | | - | |
| 415 | + | |
404 | 416 | | |
405 | 417 | | |
406 | 418 | | |
| |||
413 | 425 | | |
414 | 426 | | |
415 | 427 | | |
416 | | - | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
417 | 431 | | |
418 | 432 | | |
419 | 433 | | |
420 | | - | |
| 434 | + | |
| 435 | + | |
421 | 436 | | |
422 | 437 | | |
423 | 438 | | |
| |||
488 | 503 | | |
489 | 504 | | |
490 | 505 | | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
491 | 564 | | |
492 | 565 | | |
493 | 566 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
| 20 | + | |
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
| 25 | + | |
23 | 26 | | |
24 | 27 | | |
25 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
16 | 18 | | |
17 | 19 | | |
18 | 20 | | |
| |||
0 commit comments