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

  1. Quote the function body as a string: `AS 'body'` or dollar-quoted `AS $$body$$`.
  2. Use a bare identifier if referring to a named definition: `AS my_func_impl`.
  3. 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

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)