feat: add relaxed quoting for qualified name tails #247
+471
−27
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.
feat: add relaxed quoting for qualified name tails
Summary
This PR reduces unnecessary quoting of identifiers that appear after a dot in qualified names (e.g.,
schema.name,table.column).PostgreSQL's grammar accepts all keyword categories—including
RESERVED_KEYWORDlikeselect,from,table—in qualified name positions. The previous implementation was over-conservative, quoting keywords likefloat,interval,booleaneven when they appeared after a dot where quoting isn't required.Before:
faker."float",faker."interval",pg_catalog."substring"After:
faker.float,faker.interval,pg_catalog.substringChanges:
quoteIdentifierAfterDot()method that only quotes for lexical reasons (uppercase, special chars, leading digits) not keyword reasonsquoteDottedName(parts[])helper that applies strict quoting to the first part and relaxed quoting to subsequent partsFuncCallandCreateFunctionStmtto usequoteDottedName()for function namesRangeVarandResTargetindirection handling to usequoteIdentifierAfterDot()quoteQualifiedIdentifier()to use relaxed quoting for the tail componentnquotesvariable fromquoteIdentifier()QUOTING-RULES.mddocumentation explaining the quoting strategy, PostgreSQL background, algorithms, and contributor guidanceReview & Testing Checklist for Human
CREATE FUNCTION faker.float() RETURNS float AS $$ SELECT 1.0; $$ LANGUAGE sqland similar statements actually parse in PostgreSQL without quotes.join('.')patterns) that might need updating to usequoteDottedName()name === 'pg_catalog.substring'etc. after quoting - verify these comparisons still match since the function names should remain unquotedRecommended test plan: Parse and deparse SQL like
CREATE FUNCTION faker.float() RETURNS float AS $$ SELECT 1.0; $$ LANGUAGE sqland verify the output is valid PostgreSQL that can be re-parsed.Notes
AlertLevelvsalertlevelquoteIdentifier()method remains unchanged as the strict PostgreSQL-faithful port for standalone identifiersQUOTING-RULES.mddocumentation covers: PostgreSQL identifier folding, keyword categories, the strict vs relaxed quoting algorithms, composition helpers, deparser integration rules, and common pitfallsLink to Devin run: https://app.devin.ai/sessions/019c4a70e9164830aef1f807aad33e1d
Requested by: Dan Lynch (@pyramation)