From baac99a80e84739d0eaa221298a1d27b7c4792fa Mon Sep 17 00:00:00 2001 From: chenjianjin <2322485950@qq.com> Date: Sat, 8 Aug 2026 06:07:31 +0800 Subject: [PATCH] fix: support ClickHouse tuple positional access --- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 25 +++++++++++++------ .../statement/select/ClickHouseTest.java | 6 +++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 00620fde9..e1fc47ba3 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -9559,6 +9559,7 @@ Function InternalFunction(boolean escaped): Expression expr = null; Expression attributeExpression = null; Column attributeColumn = null; + Token attributeToken = null; Limit limit; List keywordArgs = null; } @@ -9624,14 +9625,24 @@ Function InternalFunction(boolean escaped): ] - [ LOOKAHEAD(2) "." ( - // tricky lookahead since we do need to support the following constructs - // schema.f1().f2() - Function with Function Column - // schema.f1().f2.f3 - Function with Attribute Column - LOOKAHEAD( 6 ) attributeExpression=Function() { retval.setAttribute(attributeExpression); } + [ + LOOKAHEAD(2) + ( + LOOKAHEAD({ getToken(1).kind == S_DOUBLE + && getToken(1).image.matches("\\.[0-9]+") }) + attributeToken= { + retval.setAttribute(new LongValue(attributeToken.image.substring(1))); + } | - attributeColumn=Column() { retval.setAttribute(attributeColumn); } - ) + "." ( + // tricky lookahead since we do need to support the following constructs + // schema.f1().f2() - Function with Function Column + // schema.f1().f2.f3 - Function with Attribute Column + LOOKAHEAD( 6 ) attributeExpression=Function() { retval.setAttribute(attributeExpression); } + | + attributeColumn=Column() { retval.setAttribute(attributeColumn); } + ) + ) ] [ LOOKAHEAD(2) ( 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 6d5dae30a..90f69ffd4 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/ClickHouseTest.java @@ -78,6 +78,12 @@ public void testFunctionWithAttributesIssue1742() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed(sql, true); } + @Test + public void testTuplePositionalAccessIssue2442() throws JSQLParserException { + String sql = "SELECT tuple(1, 2, 3).2 FROM tuple_demo"; + assertSqlCanBeParsedAndDeparsed(sql, true); + } + @Test public void testGlobalIn() throws JSQLParserException { String sql =