Repository navigation
Conversation
…on bodies Find the body of a SQL function by the string constant after AS instead of searching for its text, which failed when the body contains a doubled quote and could match an earlier occurrence of the same text. Statements of '...' bodies keep a map of their offsets through the unescaping, which diagnostics, semantic tokens, inlay hints, hover and completions use. The statements of BEGIN ATOMIC bodies, and the expression of RETURN bodies, are statements of their own, like the statements of quoted bodies.
This was referenced Oct 24, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #914.
Statements in
BEGIN ATOMICbodies,RETURNbodies, and'...'bodies containing''got no semantic tokens, inlay hints, hover, or lint diagnostics. This is workspace code shared with the linter, so it applies to linting too: these bodies are now linted like$$bodies.What was wrong
get_sql_fn_bodyfound the body withcontent.find(&body), using the unescaped body text. With a doubled quote in the source the text isn't there, so the body was never a statement of its own. And it could match an earlier occurrence of the same text, like a parameter default'select 1'beforeas 'select 1'.CreateFunctionStmt.sql_body(BEGIN ATOMIC ... ENDandRETURN expr) wasn't looked at, andget_sql_fn_signaturerequired aLANGUAGEoption, which these bodies don't need.What changed
get_sql_fn_bodies(server/sql_function.rs) scans theCREATE FUNCTIONstatement and returns its body statements:AS '...'/AS $tag$...$tag$: the string constant right after anAStoken whose value is the body. For'...', it records where the''escapes are.BEGIN ATOMIC: one statement per;, tracking parentheses andCASE ... END, up to theENDthat starts a statement. If the count doesn't match the parsed body, nothing is returned.RETURN expr: resolved asselect expr, which has the same length, so offsets don't move.E'...'andU&'...'bodies are not supported (their unescaped value won't match).pgls_analyser::StatementOffsetsmaps offsets between a statement's text and the document through the unescaping.AnalysableStatementcarries it, withdocument_range,document_offsetandstatement_offset. The analyser maps diagnostic spans with it; fixes on such statements were already dropped because the lengths differ. The workspace uses it for semantic tokens, inlay hints,references_at, hover and completions (CompletionsResult::with_offsetbecamewith_ranges).Document::statement_offsetsrecomputes the map from the parent only for body statements that contain a'.ParseIteratorqueues every body statement, in order.E'...'bodies.Tests
sql_functionunit tests: a default with the same text as the body,$body$quoting, the offset map through'',BEGIN ATOMICwithCASE ... ENDand two statements,RETURNwithout aLANGUAGEoption.StatementOffsetsunit test, both directions, including the second byte of an escape.unknownColumndiagnostic inBEGIN ATOMIC,RETURNand''bodies; formatting of a''body (now formatted like other bodies, into$$) and an idempotentBEGIN ATOMICfunction.BEGIN ATOMICfunctions per version) with a throwaway test. No findings in the new kinds of bodies. There is one pre-existing false positive in a$$body on main,select array_prepend($1, $2)informarray(anyelement, variadic anyarray)(polymorphism.sql); the regression suite doesn't analyse function bodies, so it doesn't catch it.Risks / conflicts
ParseIterator::nextis also changed on main (recursion removed). Expect a small conflict in the body-queueing block.CREATE FUNCTIONstatement to find its body instead of a substring search. Repeated editor requests in perf(workspace): cache the walk of a document for hover, inlay hints and semantic tokens #930 skip the iteration.pg_query.rsstill usescontent.find.