Skip to content

fix(trino): parse string-to-json casts with JSON_PARSE - #12100

Open
gabrielecalvo wants to merge 1 commit into
ibis-project:mainfrom
gabrielecalvo:main
Open

gabrielecalvo wants to merge 1 commit into
ibis-project:mainfrom
gabrielecalvo:main

Conversation

@gabrielecalvo

Copy link
Copy Markdown

Description of changes

CAST(varchar AS JSON) in Trino wraps the string as a JSON string scalar rather than parsing its contents, so .cast("json") on a column of JSON text produced a JSON string, and every downstream field access silently returned NULL. JSON_PARSE parses the varchar as JSON.

String-to-JSON casts now compile to JSON_PARSE; other casts, including json-to-json, are unchanged. Athena inherits the fix since its compiler falls through to Trino's for casts.

Added a compiler-level regression test asserting the generated SQL, and an execution-level test in the shared cross-backend JSON suite (ibis/backends/tests/test_json.py) so it runs against every JSON-capable backend, not just Trino.

Verified locally against a real Trino container: the execution test fails on the pre-fix compiler with the same symptom as the issue (None instead of the parsed value), and passes after the fix. Also verified each backend-skip mark individually against real duckdb/sqlite/mysql/polars/flink execution rather than copying them from the unrelated JSON-literal test; mysql turned out to already work and its mark was dropped, and flink's mark's reason was corrected to the actual Calcite error observed. Athena and pyspark could not be exercised in this environment (no AWS credentials; local Java version too old for pyspark) and are left unmarked pending CI.

Issues closed

`CAST(varchar AS JSON)` in Trino wraps the string as a JSON string
scalar rather than parsing its contents, so `.cast("json")` on a
column of JSON text produced a JSON string and every downstream field
access silently returned NULL. JSON_PARSE parses the varchar as JSON.

String-to-JSON casts now compile to JSON_PARSE; other casts, including
json-to-json, are unchanged. Athena inherits the fix since its
compiler falls through to Trino's for casts.

Added a compiler-level regression test asserting the generated SQL,
and an execution-level test in the shared cross-backend JSON suite
(ibis/backends/tests/test_json.py) so it runs against every
JSON-capable backend, not just Trino.

Verified locally against a real Trino container: the execution test
fails on the pre-fix compiler with the same symptom as the issue
(None instead of the parsed value), and passes after the fix. Also
verified each backend-skip mark individually against real
duckdb/sqlite/mysql/polars/flink execution rather than copying them
from the unrelated JSON-literal test; mysql turned out to already
work and its mark was dropped, and flink's mark's reason was corrected
to the actual Calcite error observed. athena and pyspark could not be
exercised in this environment (no AWS credentials; local Java version
too old for pyspark) and are left unmarked pending CI.

Closes ibis-project#12073
@github-actions github-actions Bot added tests Issues or PRs related to tests sql Backends that generate SQL labels Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sql Backends that generate SQL tests Issues or PRs related to tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Trino backend: .cast(\"json\") on a string column silently produces NULL instead of parsing the JSON

1 participant