{"record":{"id":"d2623500ed38e928","repo":"risingwavelabs/risingwave","slug":"match-recognize-only-supports-the-default-ascendin","errorCode":null,"errorMessage":"MATCH_RECOGNIZE only supports the default ascending ORDER BY, got {:?}","messagePattern":"MATCH_RECOGNIZE only supports the default ascending ORDER BY, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/from_proto/match_recognize.rs","lineNumber":79,"sourceCode":"            MatchRecognizeInputMode::Unspecified | MatchRecognizeInputMode::EventTime => {}\n            other => {\n                return Err(\n                    anyhow::anyhow!(\"unsupported MATCH_RECOGNIZE input mode: {other:?}\").into(),\n                );\n            }\n        }\n\n        let partition_key_indices = node.partition_by.iter().map(|&i| i as usize).collect();\n        // ORDER BY is carried as `ColumnOrder`. v1 only supports the default ascending order (the\n        // binder rejects anything else); assert it here too so a non-ascending plan fails fast\n        // rather than being silently sorted ascending by the executor.\n        let order_key_indices = node\n            .order_by\n            .iter()\n            .map(|c| {\n                let co = ColumnOrder::from_protobuf(c);\n                if co.order_type != OrderType::ascending() {\n                    return Err(anyhow::anyhow!(\n                        \"MATCH_RECOGNIZE only supports the default ascending ORDER BY, got {:?}\",\n                        co.order_type\n                    )\n                    .into());\n                }\n                Ok(co.column_index)\n            })\n            .collect::<StreamResult<Vec<usize>>>()?;\n        // The executor reads the leading ORDER BY column unconditionally; an empty list is a\n        // corrupt plan and must fail here, not index-panic there.\n        if order_key_indices.is_empty() {\n            return Err(anyhow::anyhow!(\"MATCH_RECOGNIZE plan carries an empty ORDER BY\").into());\n        }\n\n        let defines = node\n            .defines\n            .iter()\n            .map(|d| CompiledDefine::from_protobuf(d, params.eval_error_report.clone()))","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/from_proto/match_recognize.rs#L61-L97","documentation":"MATCH_RECOGNIZE v1 supports only the default ascending ORDER BY on its event-time column. During decode, each ORDER BY entry is converted to a `ColumnOrder`; if any entry's `order_type` is not ascending, the executor refuses to build, since descending/other orderings are not implemented in the NFA event-time handling.","triggerScenarios":"`new_boxed_executor` decodes `node.order_by` and encounters a `ColumnOrder` whose `order_type` differs from `OrderType::ascending()` — e.g. the frontend emitted `ORDER BY ts DESC` inside MATCH_RECOGNIZE.","commonSituations":"Writing `MATCH_RECOGNIZE ( ORDER BY ts DESC ... )` in SQL; planner bugs emitting non-default order types; plan proto hand-editing or version skew introducing new order types.","solutions":["Rewrite the MATCH_RECOGNIZE ORDER BY to use ascending order (the default), e.g. `ORDER BY ts` not `ORDER BY ts DESC`.","If reverse ordering is intended, invert the pattern logic instead of the sort direction.","Check the frontend version and re-plan if an older planner emitted a non-ascending order type.","Implement descending-order support in the executor if it becomes a product requirement."],"exampleFix":"-- before\nMATCH_RECOGNIZE ( ORDER BY ts DESC ... )\n-- after\nMATCH_RECOGNIZE ( ORDER BY ts ... )","handlingStrategy":"validation","validationCode":"-- SQL guard: ascending-only ORDER BY inside MATCH_RECOGNIZE\nMATCH_RECOGNIZE ( ORDER BY ts ASC ... ) -- never ORDER BY ts DESC","typeGuard":"fn is_ascending(co: &ColumnOrder) -> bool { co.order_type == OrderType::ascending() }","tryCatchPattern":"if co.order_type != OrderType::ascending() { return Err(anyhow!(\"MATCH_RECOGNIZE only supports the default ascending ORDER BY, got {:?}\", co.order_type).into()); }","preventionTips":["Omit the direction keyword in MATCH_RECOGNIZE ORDER BY (default is ascending).","Add a frontend planner check that rejects DESC in MATCH_RECOGNIZE early with a clear message.","Cover ORDER BY variants in planner tests."],"tags":["rust","streaming","match-recognize","sql"],"backgroundTag":"unsupported-operation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}