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'";