Fix MQE top_n raising a raw storage IO exception for an invalid attribute condition#13940
Merged
Merged
Conversation
…bute An MQE top_n(metric, N, order, attrX='value') whose attribute is not a queryable column of the metric reached the storage engine with a tag the measure does not define and failed there, surfacing the opaque "Internal IO exception, query metrics error.". Attribute columns (attr0..attrN) exist only on decorated metrics (service_*/endpoint_*/kubernetes_service_*, set to the layer via OAL .decorator()) and the MAL meter base; relations and database/cache/mq access carry none. MQEVisitor now validates each attribute key against the metric's registered queryable columns before the storage call and raises IllegalExpressionException (naming the attribute and metric), which the existing catch turns into a descriptive MQE error instead of the opaque storage exception.
There was a problem hiding this comment.
Pull request overview
This pull request adds an MQE-side validation guard for top_n(..., attrX='value') so invalid attribute conditions (attributes not present as queryable columns on the target metric) fail fast with a descriptive MQE error rather than propagating a backend IOException.
Changes:
- Add
MQEVisitor.checkAttributes(...)and invoke it before executingtop_nstorage queries to validate attribute keys against the metric model schema. - Add unit tests covering rejecting
=/!=for no-attribute metrics, allowing valid attributes, and allowing empty attribute lists. - Document the fix in the
CHANGESlog.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/mqe/rt/MQEVisitor.java | Adds schema-based attribute validation prior to top_n storage execution to prevent raw backend IO errors. |
| oap-server/server-query-plugin/query-graphql-plugin/src/test/java/org/apache/skywalking/oap/query/graphql/mqe/rt/MQEVisitorAttributeTest.java | Adds unit tests verifying the new attribute validation behavior. |
| docs/en/changes/changes.md | Records the MQE top_n attribute validation fix in release notes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
wankai123
approved these changes
Jul 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix
top_n(metric, N, order, attrX='value')returning a raw storageIOExceptionwhen the attribute is not a column of the metricWhy the bug exists. An MQE
top_n(...)query accepts attribute conditions (e.g.attr0='VIRTUAL_DATABASE',attr0!='MESH'). Theseattr0..attrNcolumns exist only on decorated metrics —service_*/endpoint_*/kubernetes_service_*, where OAL.decorator("ServiceDecorator"/"EndpointDecorator"/"K8SServiceDecorator")setsattr0to the entity's layer — plus the MALMeterbase class. Metrics whose source declares no attribute columns (service/instance/endpoint relations, anddatabase_access_*/cache_*/mq_*virtual-access metrics) carry noattr0tag at all.When such an attribute condition is passed for one of those metrics, nothing validated it before the storage call:
MQEVisitor.querySortMetrics→AggregationQueryService.sortMetrics→ the storage DAO builds a query filtering on a tag the measure does not define, and the backend fails. On BanyanDB theBanyanDBExceptionis wrapped asIOException, whichMQEVisitorflattens into the opaque, non-actionable"Internal IO exception, query metrics error."— indistinguishable from a genuine I/O fault. A well-formed MQE should never surface a storage I/O exception.How it's fixed.
MQEVisitor.checkAttributes(...)now runs before the storage call and validates each attribute key against the metric's registered queryable columns (viaIModelManager). If the attribute is not a column of the metric it raisesIllegalExpressionExceptionnaming the attribute and the metric, which the existingcatchinvisitMetricturns into a descriptiveExpressionResulterror (the same graceful path already used for "metric does not exist", "TopN value must be > 0", etc.). Decorated metrics and empty attribute lists are unaffected; the check is on the attribute key, so=and!=conditions are both covered.The guard lives only in
MQEVisitorbecause MQE is the sole caller that populatesTopNCondition.attributes(PromQL'sbuildTopNConditionnever sets them; the GraphQLTopNConditioninput does not exposeattributes).Unit test:
MQEVisitorAttributeTest(4 cases — reject=/!=on a no-attr metric, allow a valid attribute, allow empty attributes).CHANGESlog.