{"record":{"id":"c70805cbfe2fc0ff","repo":"risingwavelabs/risingwave","slug":"invalid-struct-type","errorCode":null,"errorMessage":"invalid struct type","messagePattern":"invalid struct type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/macro/src/gen.rs","lineNumber":1471,"sourceCode":"        \"anyarray\" => quote! { SigDataType::AnyArray },\n        \"anymap\" => quote! { SigDataType::AnyMap },\n        \"vector\" => quote! { SigDataType::Vector },\n        \"struct\" => quote! { SigDataType::AnyStruct },\n        _ if ty.starts_with(\"struct\") && ty.contains(\"any\") => quote! { SigDataType::AnyStruct },\n        _ => {\n            let datatype = data_type(ty);\n            quote! { SigDataType::Exact(#datatype) }\n        }\n    }\n}\n\nfn data_type(ty: &str) -> TokenStream2 {\n    if let Some(ty) = ty.strip_suffix(\"[]\") {\n        let inner_type = data_type(ty);\n        return quote! { DataType::list(#inner_type) };\n    }\n    if ty.starts_with(\"struct<\") {\n        return quote! { DataType::Struct(#ty.parse().expect(\"invalid struct type\")) };\n    }\n    let variant = format_ident!(\"{}\", types::data_type(ty));\n    // TODO: enable the check\n    // assert!(\n    //     !matches!(ty, \"any\" | \"anyarray\" | \"anymap\" | \"struct\"),\n    //     \"{ty}, {variant}\"\n    // );\n\n    quote! { DataType::#variant }\n}\n\n/// Extract multiple output types.\n///\n/// ```ignore\n/// output_types(\"int4\") -> [\"int4\"]\n/// output_types(\"struct<key varchar, value jsonb>\") -> [\"varchar\", \"jsonb\"]\n/// ```\nfn output_types(ty: &str) -> Vec<&str> {","sourceCodeStart":1453,"sourceCodeEnd":1489,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/macro/src/gen.rs#L1453-L1489","documentation":"The `data_type` helper in src/expr/macro/src/gen.rs converts a type string (from function signatures like `struct<a int,b varchar>`) into a `DataType` TokenStream. Strings starting with `struct<` are parsed as a StructType via `DataType::Struct(#ty.parse().expect(\"invalid struct type\"))`; if the text after `struct<` is not a valid serialized struct type, the expect panics during macro expansion.","triggerScenarios":"Declaring a function signature whose argument or return type is `struct<...>` with malformed inner syntax — missing closing `>`, bad field specifiers, or a struct literal that the StructType parser cannot deserialize.","commonSituations":"Hand-writing struct types in `#[function(\"f(struct<a int>)\")]-style signatures; typos in the field/type syntax; copying struct type strings between formats that use different serialization.","solutions":["Fix the `struct<...>` string so it matches the StructType parse format, e.g. `struct<a int,b varchar>` with matching field-name/type pairs and a closing `>`.","Verify against existing struct-typed function declarations in the repo and copy a known-good example.","If a custom/nested shape is needed, build the type with `type_infer` returning a computed `DataType` instead of the inline struct string."],"exampleFix":"// before - missing type after field name breaks the parse\n#[function(\"f(struct<a int,b>)\")]\n\n// after\n#[function(\"f(struct<a int,b varchar>)\")]","handlingStrategy":"validation","validationCode":"// Validate struct type strings before putting them in a signature\nfn valid_struct_type(s: &str) -> bool {\n    s.starts_with(\"struct<\")\n        && s.ends_with('>')\n        && s[7..s.len() - 1].split(',').all(|f| {\n            let mut it = f.trim().split_whitespace();\n            it.next().map(|n| !n.is_empty()).unwrap_or(false).then(|| ()).and_then(|_| it.next()).is_some()\n        })\n}\nassert!(valid_struct_type(\"struct<a int,b varchar>\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the exact `struct<field type,field type>` serialization the macro expects, always with a closing `>`.","Copy struct type strings from existing declarations instead of writing them from scratch.","For complex shapes, prefer a `type_infer` fn returning DataType::Struct built programmatically."],"tags":["proc-macro","compile-time","struct-type","parsing"],"backgroundTag":"invalid-argument-format","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"}