risingwavelabs/risingwave · error · ParserError
function definition
Error message
function definition
What it means
Raised by `parse_function_definition` when parsing a CREATE FUNCTION ... AS <body> clause. The body must be a single-quoted string, a dollar-quoted string, or an identifier; any other token fails and yields 'expected function definition'. It reports that the function body/language definition after AS was not a recognized form.
Solutions
- Quote the function body as a string: `AS 'body'` or dollar-quoted `AS $$body$$`.
- Use a bare identifier if referring to a named definition: `AS my_func_impl`.
- Escape/verify quotes survived shell and template processing before executing the DDL.
Example fix
// before CREATE FUNCTION f() RETURNS int AS SELECT 1; // after CREATE FUNCTION f() RETURNS int AS 'SELECT 1';
Defensive patterns
Strategy: validation
Validate before calling
// function body must be quoted or a bare identifier
function validFunctionDefinition(body) {
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(body) || /^'.*'$/.test(body) || /^\$\$[\s\S]*\$\$$/.test(body);
} Prevention
- Always wrap CREATE FUNCTION bodies in single quotes or dollar quotes.
- Beware shell/template escaping stripping quotes from the body.
- Test DDL files end-to-end; truncation after AS is a common cause.
When it happens
Trigger: Parsing `CREATE FUNCTION f() ... AS <bad-token>` where the body is missing entirely, unquoted, or uses double quotes/parens, e.g. `AS SELECT 1` or `AS "body"` or a truncated statement ending at AS.
Common situations: Porting UDF definitions from other engines; scripts where the quoted body string lost its quotes through shell escaping or templating; truncated SQL files.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/7214589b7c8e4113.
Report an issue: GitHub.
Appendix: source
Thrown at src/sqlparser/src/parser.rs:4374
Value::Number(v) => Ok(v),
_ => self.expected_at(checkpoint, "literal number"),
}
}
pub fn parse_literal_u32(&mut self) -> ModalResult<u32> {
literal_u32(self)
}
pub fn parse_literal_u64(&mut self) -> ModalResult<u64> {
literal_u64(self)
}
pub fn parse_function_definition(&mut self) -> ModalResult<FunctionDefinition> {
alt((
single_quoted_string.map(FunctionDefinition::SingleQuotedDef),
dollar_quoted_string.map(FunctionDefinition::DoubleDollarDef),
Self::parse_identifier.map(|i| FunctionDefinition::Identifier(i.value)),
fail.expect("function definition"),
))
.parse_next(self)
}
/// Parse a literal string
pub fn parse_literal_string(&mut self) -> ModalResult<String> {
let checkpoint = *self;
let token = self.next_token();
match token.token {
Token::SingleQuotedString(s) => Ok(s),
Token::DollarQuotedString(s) => Ok(s.value),
_ => self.expected_at(checkpoint, "literal string"),
}
}
/// Parse a SQL datatype (in the context of a CREATE TABLE statement for example)
pub fn parse_data_type(&mut self) -> ModalResult<DataType> {
parser_v2::data_type(self)View on GitHub (pinned to 6469eb736d)