GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix: allow reserved keywords as JSON path names (Snowflake, Databricks) by harryfoster2006 · Pull Request #2913 · JSQLParser/JSqlParser

Conversation

@harryfoster2006

@harryfoster2006 harryfoster2006 commented Nov 11, 2026

Copy link
Copy Markdown

Fixes a ParseException on JSON paths whose element names are reserved keywords. For example:

INSERT INTO "MY_DB"."MY_SCHEMA"."T" ("c")
SELECT "F"."DATA_VALUE":window::VARCHAR
FROM "MY_DB"."MY_SCHEMA"."RAW_TRACES" AS "F"

Produces error[SqlParseException]: unexpected ":" (DOUBLE_COLON)

Path elements after : were parsed as ordinary column names or expressions. Reserved words such as WINDOW, OUTPUT, FROM and SELECT have no identifier token, so the parser threw. After : a name is mandatory, so any word there is a name, reserved or not.

Changes

The two grammar sites that read a path element (PrimaryExpression and JsonExpression) now go through a new JsonPathElement production. It looks ahead before choosing how to parse:

  • isKeywordJsonPathName(): the word after : is a keyword and is not followed by (. It is parsed by the new JsonPathKeyword production, which takes the token as the name. It then continues like a primary expression: further steps, :: casts and the same arithmetic tier as before, including MySQL's lower floor.
  • isJsonPathWithKeywordAfterDot(): the path starts with an identifier but reaches a keyword after a ., such as v:a.output or v:a[0].from.x. The expression parser would read that as a qualified column name, which doesn't accept a keyword as a part. A new JsonPathStep production takes the keyword as an element name.

Behaviour that stays the same:

  • A word followed by ( stays a function call (v:left(x)).
  • Keywords after a . outside a JSON path are still rejected (SELECT t.output still throws).
  • Paths with no keywords take the same parsing route as before.

AST links

JsonPathKeyword linked the previous element before building each step, so the last step or cast of a path never got an AST node (for example the cast in v:select::INT, or v:from::INT + 1). ASTNodeCoverageTest didn't catch this because it only walks the SQL test resources. Each step and cast is now linked where it's built.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
harryfoster2006 and others added 2 commits November 11, 2026 15:14
@harryfoster2006 @claude
fix: allow keywords as Snowflake JSON path names
e125308
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@harryfoster2006 @claude
fix: allow keywords after a dot in Snowflake JSON paths and link thei…
9fc1980
…r AST nodes

The previous commit lets a keyword name the first element after ":" in a
JSON path. A keyword further along the path still threw a ParseException:

  SELECT v:a.output, v:a.b.from::INT, v:a[0].from.x[1] FROM t

The expression parser reads v:a.output as a qualified column name, and a
qualified name does not accept a keyword as a part. JsonPathElement now
also looks ahead with isJsonPathWithKeywordAfterDot(), which walks the
identifiers, dots and [...] subscripts of the path and reports whether a
keyword follows a ".". If so, JsonPathKeyword parses the path, with a new
JsonPathStep production taking a keyword after "." as an element name.
isKeywordJsonPathName() shares its keyword test with it through
isKeywordWord(). A word followed by "(" stays a function call, and
t.output outside a JSON path is still rejected.

JsonPathKeyword also left the last step or cast of a path without an AST
node, for example the cast in v:select::INT or v:from::INT + 1. It linked
the previous element before building each step, so the one built last was
never linked. ASTNodeCoverageTest did not notice, as it only walks the SQL
resources. Each step and cast is now linked where it is built, and the
keyword-path cases are added to testStatementsTheCorpusLacks.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
sethdragos
sethdragos approved these changes Nov 11, 2026
View reviewed changes

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

1 more reviewer
@sethdragos sethdragos sethdragos approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@harryfoster2006 @sethdragos
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.