Lucene as a driving backend for shard-local count fragments#21867
Lucene as a driving backend for shard-local count fragments#21867alchemist51 wants to merge 6 commits into
Conversation
PR Reviewer Guide 🔍(Review updated until commit f5e771b)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to f5e771b Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit 3c7e5c7
Suggestions up to commit 8a49ea6
Suggestions up to commit 3500bba
Suggestions up to commit 3ca715a
|
|
❌ Gradle check result for 3ca715a: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit 69cd418.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
4fb86e5 to
3500bba
Compare
|
Persistent review updated to latest commit 3500bba |
|
❌ Gradle check result for 3500bba: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
3500bba to
8a49ea6
Compare
|
Persistent review updated to latest commit 8a49ea6 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #21867 +/- ##
============================================
- Coverage 73.51% 73.49% -0.03%
+ Complexity 75582 75548 -34
============================================
Files 6034 6034
Lines 342661 342661
Branches 49294 49294
============================================
- Hits 251918 251846 -72
- Misses 70712 70803 +91
+ Partials 20031 20012 -19 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Persistent review updated to latest commit 3c7e5c7 |
trackStart runs outside the per-upcall try/catch and trackEnd in the finally, so any escaping exception crosses the FFM boundary and aborts the JVM. Wrap both in try/catch(Throwable); on failure, log warn and return -1 from trackStart. Signed-off-by: Arpit Bandejiya <abandeji@amazon.com>
startFragment had grown three concerns inline: instruction-handler fan-out, delegation-handle ownership transfer, and per-task thread tracking. Pull each into a named helper. No behaviour change — same ordering, same failure cleanup, same idempotent close semantics. Signed-off-by: Arpit Bandejiya <abandeji@amazon.com>
81fc944 to
acafe55
Compare
Planner produces a Lucene StagePlan alternative for count(*)/count(col) over Lucene-indexable filters. Data node prefers Lucene, runs IndexSearcher.count, exports through Arrow C-Data so the result VSR survives Flight's VectorTransfer (pure-Java setSafe buffers don't). - ScanCapability.InvertedIndex variant: metadata-only scan declaration. - TableScan viability: strict for value backends, permissive (any field) for metadata-only. - LuceneFragmentConvertor: filter as NamedWriteable BoolQueryBuilder. - LuceneResultStream mirrors DatafusionResultStream.BatchIterator for Flight-safe buffers. - DelegatedPredicateCombiner.makePlaceholder no longer assumes Delegated.subtree() is a leaf AnnotatedPredicate — recursively unwraps markers from the bubble-up RexCall so Substrait conversion stays clean. Tests: CountFastPathIT covers Lucene-only, fused all-keyword AND/OR/NOT, DataFusion-only numeric, mixed AND/OR, MATCH, IN, NOT. Signed-off-by: Arpit Bandejiya <abandeji@amazon.com>
acafe55 to
1c32beb
Compare
Signed-off-by: Arpit Bandejiya <abandeji@amazon.com>
# Conflicts: # sandbox/plugins/analytics-engine/src/main/java/org/opensearch/analytics/AnalyticsPlugin.java
Signed-off-by: Arpit Bandejiya <abandeji@amazon.com>
|
Persistent review updated to latest commit f5e771b |
What changed
Lucene becomes a first-class driving backend for count fragments fully expressible against the inverted index (today:
count(*)/count(col)over Lucene-indexable filters).Capability surface
ScanCapability.InvertedIndex— a metadata-only scan that produces no row values. A backend declaring it can drive a stage iff every downstream op only needs document existence/cardinality, not column values.OpenSearchTableScanRuletwo-phase viability:lucene): viable if it covers some indexed field. Downstream ops that need a value-producing column self-restrict, andPlanForker's chain-agreement filter drops the driver for chains that aren't end-to-end metadata-only. The only chain that survives is the count fast-path shape.Coordinator-side alternative collapse
PlanAlternativeSelectorruns on the coordinator afterPlanForker+BackendPlanAdapterand beforeFragmentConversionDriver. Whenanalytics.planner.prefer_metadata_driver(default true) is set and a stage has alucenealternative, that alternative wins; the stage's alternative list collapses to a singleStagePlan.FragmentExecutionRequestships exactly onePlanAlternative; the data node skips alternative selection.Lucene driver path
LuceneFragmentConvertorlowers the stage to[outputColumnNames][hasFilter?][BoolQueryBuilder]overNamedWriteable.LuceneSearchExecEnginerunsIndexSearcher.count(boolQuery); the count is exported through Arrow C-Data (Data.exportVectorSchemaRoot) so Flight'stransferRootround-trips it without zeroing — pure-Java setSafe-built buffers don't survive transfer.LuceneSearcherState,LuceneSearchExecEngine,LuceneResultStream.Delegation combiner
analytics.delegation.fuse_dual_viable(default false): when on, an OR/NOT subtree where every leaf is dual-viable is fused into a single delegated boolean shipped to the peer driver, instead of carving the performance-delegated leaves back out.AnnotatedPredicatemarkers nested inside an OR/NOT carve-out — fixed by anunwrapAnnotations(RexNode)pass before re-wrapping in adelegation_possible(...)placeholder.Translation example
where userID = 'arpit' AND event_type = 'click' AND match(message, 'alpha') | stats count()If
userIDwere a numeric field with no inverted index, the strict gate would droplucenefrom the value-producing pool but the permissive gate keeps it for the count chain —PlanForker's chain-agreement still drops it because the=onuserIDcan't run on the metadata-only driver, and the stage falls back todatafusion.