From f0db559c18930345b0d49156821f90b9d18718ec Mon Sep 17 00:00:00 2001 From: Hayssam Saleh Date: Wed, 19 Aug 2026 17:35:41 +0200 Subject: [PATCH] feat: parse BigQuery JSON string literals as implicit casts isImplicitCastAhead() only fired for DATA_TYPE and DT_ZONE tokens, but JSON lexes as K_JSON, so BigQuery literals like JSON '{"a": 1}' failed to parse even though DataType() accepts K_JSON as a data type. Accept K_JSON when directly followed by a string literal. Co-Authored-By: Claude Fable 5 --- .../jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt | 2 ++ .../sf/jsqlparser/expression/CastExpressionTest.java | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index fdfba2d10..4f164c6b8 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -477,6 +477,8 @@ public class CCJSqlParser extends AbstractJSqlParser { // DT_ZONE (TIMESTAMP WITH TIME ZONE / WITHOUT TIME ZONE) is also a valid // implicit cast type prefix handled by DataType(), but distinct from DATA_TYPE. if (k1 == DT_ZONE) return true; + // BigQuery JSON 'literal' - JSON lexes as K_JSON, but DataType() accepts it + if (k1 == K_JSON) return getToken(2).kind == S_CHAR_LITERAL; if (k1 != DATA_TYPE) return false; int k2 = getToken(2).kind; if (k2 != OPENING_BRACKET) return true; // DATA_TYPE literal - simple cast diff --git a/src/test/java/net/sf/jsqlparser/expression/CastExpressionTest.java b/src/test/java/net/sf/jsqlparser/expression/CastExpressionTest.java index 81c2ae58a..a14d5c9a0 100644 --- a/src/test/java/net/sf/jsqlparser/expression/CastExpressionTest.java +++ b/src/test/java/net/sf/jsqlparser/expression/CastExpressionTest.java @@ -52,6 +52,18 @@ void testImplicitCast() throws JSQLParserException { Assertions.assertTrue(select.getSelectItem(0).getExpression() instanceof CastExpression); } + @Test + void testImplicitCastJsonLiteral() throws JSQLParserException { + String sqlStr = "SELECT JSON '{\"name\": \"Jakob\"}'"; + PlainSelect select = (PlainSelect) TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + + Assertions.assertTrue(select.getSelectItem(0).getExpression() instanceof CastExpression); + + // BigQuery wraps JSON literals in functions, e. g. BOOL(JSON 'true') + sqlStr = "SELECT BOOL(JSON 'true') AS vacancy"; + TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } + @Test void testImplicitCastTimestampIssue1364() throws JSQLParserException { String sqlStr = "SELECT TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'";