| #
b1f7ba64
|
| 05-Jul-2026 |
Andreas Gohr <andi@splitbrain.org> |
fix(search): fatals on invalid short wildcard terms
Searches such as "wiki a*" could crash in QueryEvaluator::opAnd() with a TypeError. The query parser still emitted the wildcard term, but the full
fix(search): fatals on invalid short wildcard terms
Searches such as "wiki a*" could crash in QueryEvaluator::opAnd() with a TypeError. The query parser still emitted the wildcard term, but the fulltext search later dropped it because its non-wildcard base was below the minimum search term length.
That left the evaluator with an AND operator whose right-hand operand was missing, causing a stack underflow during RPN evaluation.
Fix this in two places: - filter invalid short wildcard terms already in Tokenizer::getWords() when wildcard parsing is enabled, so they never enter the parsed query - harden QueryEvaluator against missing operands for AND/OR/NOT to avoid fatals if tokens disappear during later processing
Add regression tests covering the parser output for "wiki a*" and the evaluator behavior when an operand is missing.
show more ...
|
| #
9369b4a9
|
| 08-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: rector, phpcs, type hint fixes
|
| #
6734bb8c
|
| 07-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: rewrite MetadataSearch to use Collection classes
Replace MetadataIndex usage in MetadataSearch with the new Collection/Index architecture. This completes the read-path migration so data
SearchIndex: rewrite MetadataSearch to use Collection classes
Replace MetadataIndex usage in MetadataSearch with the new Collection/Index architecture. This completes the read-path migration so data written by the Collection-based Indexer is read back correctly using TupleOps tuple format.
Generalize FrequencyCollectionSearch into CollectionSearch that works with any AbstractCollection type (Frequency, Lookup, Direct) and handles both split-by-length and non-split index layouts transparently. DirectCollection participates via resolveTokenFrequencies() which maps token RID = entity RID.
Key changes: - AbstractCollection gains isSplitByLength(), resolveTokenFrequencies(), getEntitiesWithData(), and groupToSuffix() with validation - Index groups are now int (0 = non-split, positive = token length) - CollectionSearch provides both addTerm()/execute() for fulltext and lookup() for metadata-style search (exact/wildcard/callback) - MetadataSearch delegates entirely to collection APIs - Shared filterPages() replaces duplicated page filtering logic - All callers updated from MetadataIndex to MetadataSearch - Tests moved to Search namespace with full coverage for new APIs
show more ...
|
| #
0b1bbbbb
|
| 06-Apr-2026 |
Andreas Gohr <andi@splitbrain.org> |
SearchIndex: rewrite FulltextSearch to use FrequencyCollectionSearch
Replace FulltextIndex->lookupWords() with FrequencyCollectionSearch which correctly handles the compact tuple format written by t
SearchIndex: rewrite FulltextSearch to use FrequencyCollectionSearch
Replace FulltextIndex->lookupWords() with FrequencyCollectionSearch which correctly handles the compact tuple format written by the new Indexer.
Introduce QueryEvaluator with typed stack entries (PageSet, NamespacePredicate, NegatedEntry) for RPN query evaluation. NOT wraps its operand instead of computing a universe complement, so AND with a negated operand becomes efficient set subtraction. The full page index is only loaded for standalone negative or namespace-only queries.
Move QueryParser and QueryEvaluator into the new Search\Query namespace along with the stack entry types.
Simplify FulltextSearch to orchestration: parse query, look up words, evaluate, filter, sort. Replace FT_SNIPPET_NUMBER constant with maxSnippets property. Combine ACL/existence/time filtering into a single pass.
show more ...
|