Skip to content

feat(trino): parse routine characteristics for inline UDFs [CLAUDE] - #7981

Open
rusackas wants to merge 2 commits into
tobymao:mainfrom
rusackas:trino-udf-2-routine-characteristics
Open

feat(trino): parse routine characteristics for inline UDFs [CLAUDE]#7981
rusackas wants to merge 2 commits into
tobymao:mainfrom
rusackas:trino-udf-2-routine-characteristics

Conversation

@rusackas

@rusackas rusackas commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

I'm back! :)

PR 2 of 7-ish, continuing to build on #7934.

Adds parsing/generation for the routine characteristics that can follow a Trino inline WITH FUNCTION UDF's RETURNS clause: LANGUAGE, DETERMINISTIC/NOT DETERMINISTIC, CALLED ON NULL INPUT/RETURNS NULL ON NULL INPUT, SECURITY DEFINER/INVOKER, and COMMENT (https://trino.io/docs/current/udf/sql.html):

WITH FUNCTION custom_sqrt(a integer)
  RETURNS double
  COMMENT 'Custom sqrt function'
  RETURNS NULL ON NULL INPUT
  NOT DETERMINISTIC
  LANGUAGE SQL
  SECURITY DEFINER
  RETURN a
SELECT custom_sqrt(4)

Most of this already worked for free: _parse_function_specification (from #7934) calls the base _parse_properties() between RETURNS and RETURN, so LANGUAGE, CALLED/RETURNS NULL ON NULL INPUT, SECURITY DEFINER/INVOKER, and COMMENT all parsed and generated correctly with zero new code, via existing exp.LanguageProperty/exp.CalledOnNullInputProperty/exp.SqlSecurityProperty/exp.SchemaCommentProperty + their existing generic generators.

Two things actually needed fixing:

  1. DETERMINISTIC/NOT DETERMINISTIC — reused exp.StabilityProperty (base already parses bare DETERMINISTIC into it), and mirrored BigQuery's existing StabilityProperty handling exactly: a NOT DETERMINISTIC entry in TrinoParser.PROPERTY_PARSERS, the same TrinoGenerator.TRANSFORMS lambda BigQuery uses, and the same tokenizer-level "NOT DETERMINISTIC" keyword-merge BigQuery has (_match_texts only inspects one token, so the two words need to merge into one before the parser can dispatch on them). Before this, bare DETERMINISTIC round-tripped as the invalid-for-Trino IMMUTABLE, and NOT DETERMINISTIC didn't parse at all.

  2. LANGUAGE SQL immediately followed by a SECURITY clause — the base tokenizer already merges SQL SECURITY into one TokenType.SQL_SECURITY token (for MySQL/StarRocks' ... SQL SECURITY DEFINER VIEW), which greedily ate the SQL that was supposed to be LANGUAGE's value, e.g. LANGUAGE SQL SECURITY DEFINER tokenized as LANGUAGE / SQL SECURITY / DEFINER instead of LANGUAGE / SQL / SECURITY / DEFINER. Trino has no SQL SECURITY phrase in its own grammar (only bare SECURITY DEFINER/INVOKER), and the base parser's PROPERTY_PARSERS already maps plain "SECURITY" to the identical _parse_sql_security the merged token maps to, so Trino.Tokenizer just pops the merged keyword (same idiom as its existing KEYWORDS.pop("/*+") on the Presto side, or BigQuery's KEYWORDS.pop("DIV")). Confirmed this doesn't affect MySQL/StarRocks, whose tokenizers are untouched.

Next steps (remaining follow-up PRs, each gated on the previous)

  1. Core WITH FUNCTION ... RETURNS ... RETURN ... (feat(trino): parse WITH FUNCTION ... RETURNS ... RETURN inline UDFs [CLAUDE] #7934)
  2. This PR — routine characteristics
  3. BEGIN...END block bodies + DECLARE/SET, including the semicolon/chunk-continuation handling so routine bodies don't get split as separate statements
  4. IF/ELSEIF/ELSE — reusing/extending exp.IfBlock
  5. CASE...WHEN...END CASE
  6. WHILE...DO...END WHILE — reusing/extending exp.WhileBlock with a label arg
  7. LOOP/REPEAT/ITERATE/LEAVE

Related: apache/superset#26162 (Superset issue asking for Trino inline SQL UDF support end-to-end).

Disclosure: implemented with Claude Code, reviewed, tested (make unit, make style) and understood by me.

LANGUAGE, DETERMINISTIC/NOT DETERMINISTIC, CALLED/RETURNS NULL ON NULL
INPUT, SECURITY DEFINER/INVOKER, and COMMENT now parse and generate
correctly for WITH FUNCTION inline UDFs (tobymao#7934 was PR 1 of ~7).
@treysp treysp self-assigned this Jul 28, 2026
Trino has no SQL SECURITY clause of its own; the merged base keyword
otherwise swallows the SQL in LANGUAGE SQL SECURITY DEFINER.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants