Skip to content

Commit f9dd217

Browse files
committed
Fixed CTE and some minor bugs
1 parent 25549e7 commit f9dd217

File tree

7 files changed

+63
-37
lines changed

7 files changed

+63
-37
lines changed

client-v2/src/test/java/com/clickhouse/client/datatypes/DataTypeTests.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.io.IOException;
3131
import java.lang.reflect.Method;
3232
import java.math.BigDecimal;
33+
import java.math.RoundingMode;
3334
import java.time.Instant;
3435
import java.time.LocalDateTime;
3536
import java.time.Period;
@@ -539,6 +540,9 @@ public void testDynamicWithPrimitives() throws Exception {
539540
case Decimal128:
540541
case Decimal256:
541542
BigDecimal tmpDec = row.getBigDecimal("field").stripTrailingZeros();
543+
if (tmpDec.divide((BigDecimal)value, RoundingMode.FLOOR).equals(BigDecimal.ONE)) {
544+
continue;
545+
}
542546
strValue = tmpDec.toPlainString();
543547
break;
544548
case IntervalMicrosecond:
@@ -739,7 +743,7 @@ public void testTime64() throws Exception {
739743
return; // time64 was introduced in 25.6
740744
}
741745

742-
String table = "test_time64_type";
746+
String table = "data_type_tests_time64";
743747
client.execute("DROP TABLE IF EXISTS " + table).get();
744748
client.execute(tableDefinition(table, "o_num UInt32", "t_sec Time64(0)", "t_ms Time64(3)", "t_us Time64(6)", "t_ns Time64(9)"),
745749
(CommandSettings) new CommandSettings().serverSetting("allow_experimental_time_time64_type", "1")).get();

client-v2/src/test/java/com/clickhouse/client/query/QueryTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2146,7 +2146,7 @@ public void testGetDynamicValue() throws Exception {
21462146
} else if (decision == 1) {
21472147
return rnd.nextInt();
21482148
} else {
2149-
return rnd.nextDouble();
2149+
return rnd.nextLong();
21502150
}
21512151
}), 1000);
21522152

jdbc-v2/src/main/antlr4/com/clickhouse/jdbc/internal/parser/ClickHouseParser.g4

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ query
2828
| killStmt // DDL
2929
| optimizeStmt // DDL
3030
| renameStmt // DDL
31-
| selectUnionStmt
3231
| setStmt
3332
| setRoleStmt
3433
| showStmt
@@ -38,33 +37,14 @@ query
3837
| updateStmt
3938
| useStmt
4039
| watchStmt
41-
| ctes? selectStmt
40+
| selectStmt
41+
| selectUnionStmt
4242
| grantStmt
4343
| revokeStmt
4444
| exchangeStmt
4545
| moveStmt
4646
;
4747

48-
// CTE statement
49-
ctes
50-
: LPAREN? WITH cteUnboundCol? (COMMA cteUnboundCol)* COMMA? namedQuery (COMMA namedQuery)* RPAREN?
51-
;
52-
53-
namedQuery
54-
: name = identifier (columnAliases)? AS LPAREN query RPAREN
55-
;
56-
57-
columnAliases
58-
: LPAREN identifier (',' identifier)* RPAREN
59-
;
60-
61-
cteUnboundCol
62-
: (literal AS identifier) # CteUnboundColLiteral
63-
| (QUERY AS identifier) # CteUnboundColParam
64-
| LPAREN? columnExpr RPAREN? AS identifier # CteUnboundColExpr
65-
| LPAREN ctes? selectStmt RPAREN AS identifier # CteUnboundNestedSelect
66-
;
67-
6848
// DELETE statement
6949

7050
deleteStmt
@@ -480,7 +460,7 @@ selectStmtWithParens
480460
;
481461

482462
selectStmt
483-
: withClause? SELECT DISTINCT? topClause? columnExprList fromClause? arrayJoinClause? windowClause? prewhereClause? whereClause? groupByClause? (
463+
: cteClause? SELECT DISTINCT? topClause? columnExprList fromClause? arrayJoinClause? windowClause? prewhereClause? whereClause? groupByClause? (
484464
WITH (CUBE | ROLLUP)
485465
)? (WITH TOTALS)? havingClause? orderByClause? limitByClause? limitClause? settingsClause?
486466
;
@@ -489,14 +469,35 @@ withClause
489469
: WITH columnExprList
490470
;
491471

472+
// CTE statement
473+
cteClause
474+
: WITH cteUnboundCol? (COMMA cteUnboundCol)* COMMA? namedQuery? (COMMA namedQuery)*
475+
;
476+
477+
478+
namedQuery
479+
: identifier (columnAliases)? AS LPAREN? ( selectStmt | selectStmtWithParens | selectUnionStmt) RPAREN?
480+
;
481+
482+
columnAliases
483+
: LPAREN identifier (',' identifier)* RPAREN
484+
;
485+
486+
cteUnboundCol
487+
: literal AS identifier # CteUnboundColLiteral
488+
| QUERY AS identifier # CteUnboundColParam
489+
| LPAREN? columnExpr RPAREN? AS? identifier? # CteUnboundColExpr
490+
// | LPAREN cteStmt? selectStmt RPAREN AS identifier # CteUnboundNestedSelect
491+
;
492+
492493
topClause
493494
: TOP DECIMAL_LITERAL (WITH TIES)?
494495
;
495496

496497
fromClause
497498
: FROM joinExpr
498499
| FROM identifier LPAREN QUERY RPAREN
499-
| FROM ctes
500+
| FROM selectStmt
500501
| FROM identifier LPAREN viewParam (COMMA viewParam)? RPAREN
501502
;
502503

@@ -1294,6 +1295,7 @@ keyword
12941295
| ROLLUP
12951296
| ROW
12961297
| ROWS
1298+
| REVOKE
12971299
| SAMPLE
12981300
| SELECT
12991301
| SEMI
@@ -1320,6 +1322,7 @@ keyword
13201322
| TRAILING
13211323
| TRIM
13221324
| TRUNCATE
1325+
| TRACKING
13231326
| TO
13241327
| TOP
13251328
| TTL
@@ -1364,6 +1367,7 @@ keywordForAlias
13641367
| HOUR
13651368
| MINUTE
13661369
| SECOND
1370+
| REVOKE
13671371
;
13681372

13691373
alias

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/SqlParser.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int
5151

5252
static boolean isStmtWithResultSet(ClickHouseParser.QueryStmtContext stmtContext) {
5353
ClickHouseParser.QueryContext qCtx = stmtContext.query();
54-
5554
return qCtx != null && (qCtx.selectStmt() != null || qCtx.selectUnionStmt() != null ||
5655
qCtx.showStmt() != null || qCtx.explainStmt() != null || qCtx.describeStmt() != null ||
57-
qCtx.existsStmt() != null || qCtx.checkStmt() != null);
56+
qCtx.existsStmt() != null || qCtx.checkStmt() != null );
5857
}
5958
}

jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ public void testTimeTypes() throws SQLException {
617617
Properties createProperties = new Properties();
618618
createProperties.put(ClientConfigProperties.serverSetting("allow_experimental_time_time64_type"), "1");
619619
runQuery("CREATE TABLE test_time64 (order Int8, "
620-
+ "time Time('UTC'), time64 Time64(9) "
620+
+ "time Time, time64 Time64(9) "
621621
+ ") ENGINE = MergeTree ORDER BY ()",
622622
createProperties);
623623

jdbc-v2/src/test/java/com/clickhouse/jdbc/PreparedStatementTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import static org.testng.Assert.assertThrows;
4545
import static org.testng.Assert.assertTrue;
4646
import static org.testng.Assert.expectThrows;
47+
import static org.testng.Assert.fail;
4748

4849
@Test(groups = { "integration" })
4950
public class PreparedStatementTest extends JdbcIntegrationTest {
@@ -1337,6 +1338,8 @@ public void testSelectWithTableAliasAsKeyword() throws Exception {
13371338
Assert.assertEquals(rs.getInt(1), 1000);
13381339
Assert.assertEquals(rs.getString(2), "test");
13391340
}
1341+
} catch (Exception e) {
1342+
fail("failed at keyword " + keyword, e);
13401343
}
13411344
}
13421345
}

jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/SqlParserTest.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,26 +233,42 @@ public static Object[][] testCreateStmtDP() {
233233

234234
@Test(dataProvider = "testCTEStmtsDP")
235235
public void testCTEStatements(String sql, int args) {
236+
System.out.println(sql);
236237
SqlParser parser = new SqlParser();
237238
ParsedPreparedStatement stmt = parser.parsePreparedStatement(sql);
238-
Assert.assertFalse(stmt.isHasErrors());
239-
Assert.assertEquals(stmt.getArgCount(), args);
240-
Assert.assertTrue(stmt.isHasResultSet());
239+
Assert.assertEquals(stmt.getArgCount(), args, "Args mismatch");
240+
Assert.assertFalse(stmt.isHasErrors(), "Statement has errors");
241+
Assert.assertTrue(stmt.isHasResultSet(), "show have a result set");
241242
}
242243

243244
@DataProvider
244245
public static Object[][] testCTEStmtsDP() {
245246
return new Object[][] {
246-
{"with ? as a, ? as b select a, b; -- two CTEs of the first form", 2},
247+
{"with 'a' as a select 1, a union with 'b' as a all select 2, a", 0},
248+
{"with 'a' as a select 1, a union all with 'b' as a select 2, a", 0},
249+
{"with ? as a, ? as b select a, b -- two CTEs of the first form", 2},
250+
{"with 'a' as a, 'b' as b select a, b -- two CTEs of the first form", 0},
247251
{"with a as (select ?), b as (select 2) select * from a, b; -- two CTEs of the second form", 1},
248-
{"(with a as (select ?) select * from a);", 1},
249-
{"with a as (select 1) select * from a; ", 0},
250-
{"(with ? as a select a);", 1},
252+
{"(with a as (select ?) select * from a)", 1},
253+
{"with a as (select ?) select * from a", 1},
254+
{"with a as (select 1) select * from a", 0},
255+
{"(select 1)", 0},
256+
{"(with ? as a select a)", 1},
257+
{"(with 'a' as a select a)", 0},
258+
{"with ? as a select a", 1},
259+
{"with 'a' as a select a", 0},
251260
{"select * from ( with x as ( select 9 ) select * from x );", 0},
252261
{"WITH toDateTime(?) AS target_time SELECT * FROM table", 1},
253262
{"WITH toDateTime('2025-08-20 12:34:56') AS target_time SELECT * FROM table", 0},
254263
{"WITH toDate('2025-08-20') as DATE_END, events AS ( SELECT 1 ) SELECT * FROM events", 0},
255-
{"WITH toDate(?) as DATE_END, events AS ( SELECT 1 ) SELECT * FROM events", 1}
264+
{"WITH toDate(?) as DATE_END, events AS ( SELECT 1 ) SELECT * FROM events", 1},
265+
{"WITH ? as a, ? as b, body as ( select ? ) select a, b, body.* from body", 3},
266+
{"WITH 'a_value' as a, 'b_value' as b, body as ( select 'html' ) select a, b, body.* from body", 0},
267+
{"WITH 'a_value' as a, 'b_value' as b, body as ( with 'data' as d select d, 'html' ) select a, b, body.* from body", 0},
268+
{"with date select date, 1 from (select now() date)", 0 },
269+
{COMPLEX_CTE, 4},
270+
{"WITH 'date' as const1, 'time' as const2, Tmp1 as (SELECT 1), Tmp2 as (SELECT * FROM Tmp1) SELECT * FROM Tmp2 ", 0},
271+
{"WITH query1 AS ( WITH 'a' as date1 SELECT * FROM tracking.event WHERE project='a' AND time>=starting_time AND time<ending_time GROUP BY date, user_id ) SELECT * FROM query1", 0},
256272
};
257273
}
258274

0 commit comments

Comments
 (0)