diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 2a28d21ba..a291445f6 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -10707,6 +10707,7 @@ ColDataType ColDataType(): List array = new ArrayList(); List name; ColDataType arrayType; + ColDataType nestedType = null; int precision = -1; int scale = -1; @@ -10755,6 +10756,9 @@ ColDataType ColDataType(): [ LOOKAHEAD(2) "(" {tk2 =null;} ( + ( + LOOKAHEAD(( | ) "(") nestedType=ColDataType() + | ( ( ( tk= | tk= ) [ LOOKAHEAD(2) (tk2= | tk2=) ] @@ -10765,9 +10769,15 @@ ColDataType ColDataType(): tk= | tk= + ) ) { - argumentsStringList.add(tk.image + (tk2!=null?" " + tk2.image:"")); + if (nestedType != null) { + argumentsStringList.add(nestedType.toString()); + nestedType = null; + } else { + argumentsStringList.add(tk.image + (tk2!=null?" " + tk2.image:"")); + } } [ "," ] diff --git a/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java b/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java index a7046ada0..6d5dae30a 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java @@ -140,4 +140,16 @@ public void testMultipleSettingsClauseIssue2362() throws JSQLParserException { Assertions.assertNotNull(select.getSettings()); Assertions.assertEquals(2, select.getSettings().size()); } + + @Test + public void testCastToNestedParametricTypeIssue2441() throws JSQLParserException { + // ClickHouse allows parametric (constructor-style) data types as a CAST target, + // including nested ones such as Nullable(Decimal(p, s)). + String sql = "SELECT CAST(x AS Nullable(Decimal(10, 2))) FROM cast_demo"; + assertSqlCanBeParsedAndDeparsed(sql, true); + + // The inner parametric type may itself be wrapped by another parametric type. + sql = "SELECT CAST(x AS LowCardinality(Decimal(10, 2))) FROM cast_demo"; + assertSqlCanBeParsedAndDeparsed(sql, true); + } }