JSONPath parser raises unhandled ValueError for exponent-form integer indexes
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
The failure is in _parse_literal() in sqlglot/jsonpath.py, where int(number) runs on a NUMBER token that can contain exponent notation such as 2E or 1e5. Reproduce with jsonpath.parse("[2E]", dialect="snowflake") and check that Dialect.to_json_path() also lets the ValueError escape. Done means the invalid index raises sqlglot.errors.ParseError with a message naming the bad index, and existing integer-index tests still pass.
Written by the indexing model from the issue text.
Description
- Read dialect:
snowflake(using the directsqlglot.jsonpath.parse()API withdialect="snowflake"). - Write dialect: N/A (this is a parsing issue; no SQL generation is involved).
- Checked on main: Yes, reproduced on commit
3b1fc58.
Fully reproducible code snippet
from sqlglot import jsonpath
jsonpath.parse("[2E]", dialect="snowflake")
Actual output:
ValueError: invalid literal for int() with base 10: '2E'
The same failure can be reproduced with:
from sqlglot import jsonpath
jsonpath.parse("[1e5]", dialect="snowflake")
jsonpath.parse("[-2E]", dialect="snowflake")
Expected output:
A controlled sqlglot.errors.ParseError indicating that the JSONPath index is invalid, rather than an uncaught Python ValueError.
For example:
ParseError: Invalid integer index: 2E at index 2: [2E]
Notes
The issue originates in sqlglot/jsonpath.py, inside _parse_literal():
number = "-" if _match(TokenType.DASH) else ""
token = _match(TokenType.NUMBER)
if token:
number += token.text
if number:
return int(number)
The JSONPath tokenizer can produce a numeric token containing exponent notation. However, JSONPath array indexes must be decimal integers.
Consequently, int(number) raises ValueError when the token contains exponent notation, such as 2E or 1e5.
The exception is not converted into SQLGlot's expected ParseError.
This also affects the dialect-level JSONPath conversion path. Dialect.to_json_path() catches ParseError and TokenError, but not ValueError. Consequently, this exception bypasses the existing error-handling mechanism.
This is distinct from the previously addressed JSONPath TokenError handling in [PR #8260](https://github.com/tobymao/sqlglot/pull/8260), which does not address this integer-conversion failure.
Suggested fix
In sqlglot/jsonpath.py:
if number:
try:
return int(number)
except ValueError as e:
raise ParseError(
_error(f"Invalid integer index: {number}")
) from e
This preserves the existing integer-index behavior while converting invalid numeric indexes into the parser's expected exception type.
Official Documentation
- [RFC 9535 — JSONPath, Section 2.3.3.1: Index Selector Syntax](https://www.rfc-editor.org/rfc/rfc9535.html#section-2.3.3.1)
- [SQLGlot JSONPath implementation](https://github.com/tobymao/sqlglot/blob/main/sqlglot/jsonpath.py)
- [SQLGlot Dialect implementation](https://github.com/tobymao/sqlglot/blob/main/sqlglot/dialects/dialect.py)
LLM assistance: An LLM was used to assist with drafting this report. The reproducer and relevant implementation path were independently examined.
- Dominant language
- Python
- Stars
- 9.7k
- Forks
- 1.4k
- Avg merge
- 13h 20m
- Merged PRs (30d)
- 217
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from tobymao/sqlglot
-
BigQuery: quoted identifiers escape a backtick by doubling it and leave a backslash unescaped, which BigQuery reads differentlyPossibly taken @ege-arhan claimed this today. Open
Difficulty 3/5 1-2 days Newbie friendliness 45/100
Maintainers usually reply within 1 day
-
Hive: UNIONTYPE<...> data type fails to parsePossibly taken @shenhui027-arch claimed this 1 day ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
Optimizer drops LEFT JOIN when a cast collapses distinct join keysPossibly taken @finnhoang05 claimed this 2 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 30/100
Maintainers usually reply within 1 day
-
duckdb <-> sqlite: CAST of a fractional number to INTEGER rounds in DuckDB but truncates in SQLitePossibly taken @simpleqt claimed this today. Open
Difficulty 3/5 1-2 days Newbie friendliness 65/100
tobymao/sqlglot#8853 · 1 comment ·
Maintainers usually reply within 1 day
-
unnest_subqueries produces wrong results for COALESCE(SUM(...), k) and for nullable CASE expressions containing COUNTPossibly taken @treysp claimed this 9 days ago. Open
tobymao/sqlglot#8752 · 2 comments · 1 assignee ·
Maintainers usually reply within 1 day
Similar issues
-
URLValidator ignores an explicit empty scheme allowlistPossibly taken @IlyaKhalafi claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
tortoise/tortoise-orm#2393 ·
Maintainers usually reply within 2 days
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
frappe/frappe_docker#2046 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
complete_box_iou_loss / complete_box_iou: NaN gradients for zero-height boxes, NaN for point boxesOpen
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
AXI SMU SPEC
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
tenstorrent/tt-oca-harness#3556 ·
Maintainers usually reply within 1 day