[bugfix] Propagate MSQ distinct early termination as partial results#18648
[bugfix] Propagate MSQ distinct early termination as partial results#18648xiangfu0 wants to merge 1 commit into
Conversation
f306c8d to
4a3b9cf
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #18648 +/- ##
============================================
+ Coverage 64.40% 64.45% +0.05%
Complexity 1291 1291
============================================
Files 3365 3365
Lines 208058 208096 +38
Branches 32480 32487 +7
============================================
+ Hits 133992 134132 +140
+ Misses 63295 63197 -98
+ Partials 10771 10767 -4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Propagates distinct early-termination metadata from single-stage leaf execution into multi-stage query responses, ensuring MSQ clients can detect partial DISTINCT results via the V2 broker response.
Changes:
- Read
EARLY_TERMINATION_REASONfrom leaf SSE metadata and aggregate it into MSQ leaf stats. - Expose aggregated reasons in
BrokerResponseNativeV2asearlyTerminationReasonsand treat presence aspartialResult=true. - Add a focused unit test covering the leaf bridge behavior and the serialized V2 response shape (including absence of legacy per-reason flags).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/LeafOperator.java | Merge SSE early-termination reason metadata into a new aggregated leaf stat key. |
| pinot-common/src/main/java/org/apache/pinot/common/response/broker/BrokerResponseNativeV2.java | Add earlyTerminationReasons field (derived from broker stats), merge helper, and include it in partialResult. |
| pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafOperatorTest.java | Add unit coverage validating propagation + JSON response shape for early termination reasons. |
4a3b9cf to
ca80bf9
Compare
bdd349d to
248de7c
Compare
|
I think it is important to say that we have a completely different concept of EarlyTermination in MSE. This is fired when a downstream operator notifies its inputs (aka children or upstream) that no more data will be needed (ie when there is an exception or a limit is reached). This doesn't mean this PR is wrong, but we have a terminology issue we need to clarify. TBH I don't like to name this as early termination because that concept doesn't imply an actual error. As said, early termination could be produced by a correct business logic as a limit. Why don't we just return this early incorrect termination as an error and serialize the partial data in case of error? |
248de7c to
98086fc
Compare
|
Updated the implementation to use |
yes, this query option is similar to the |
What changed
This PR propagates distinct early-termination metadata from single-stage leaf execution into multi-stage query responses.
EARLY_TERMINATION_REASONmetadata into MSQ leaf stats.earlyTerminationReasonsarray toBrokerResponseNativeV2instead of one response field per reason.partialResult=truewhen any early-termination reason is present.StatMap.Type.STRING_SETand stores early-termination reasons as an ordered set stat, avoiding delimiter parsing/joining entirely.EarlyTerminationReason.NONEand unknown metadata values during leaf stat propagation.queryOptions=maxRowsInDistinct=1, verifying the V2 response is partial and includesDISTINCT_MAX_ROWS.This PR intentionally does not add native MSQ distinct operator early-termination behavior.
Why
PR #17247 added distinct early-termination query options for single-stage execution. When a multi-stage query uses a leaf stage backed by the single-stage engine, the leaf metadata can contain an early-termination reason, but
LeafOperatordid not propagate that metadata into the V2 broker response. As a result, the MSQ response could omit both the partial-result marker and the reason.User manual
For multi-stage queries whose leaf-stage single-stage execution early-terminates distinct processing, the V2 broker response now includes
earlyTerminationReasonsand setspartialResulttotrue.Example response fields:
{ "partialResult": true, "earlyTerminationReasons": ["DISTINCT_MAX_ROWS"] }Possible distinct reasons propagated from the single-stage leaf metadata include:
DISTINCT_MAX_ROWSmaxRowsInDistinctDISTINCT_MAX_ROWS_WITHOUT_CHANGEmaxRowsWithoutChangeInDistinctDISTINCT_MAX_EXECUTION_TIMEmaxExecutionTimeMsInDistinctSample SQL:
Sample API request using query options:
{ "sql": "SELECT DISTINCT userId FROM events LIMIT 10000", "queryOptions": "maxRowsInDistinct=1" }Validation
Results:
StatMapTestandBrokerResponseNativeV2Test: 39 common-module tests passed, 6 skipped.LeafOperatorTest: 18 tests passed.DistinctQueriesTest: 3 integration tests passed, includingtestMultiStageMaxRowsInDistinctEarlyTermination.pinot-commonandpinot-query-runtime.