Skip to content

Commit 895b7f3

Browse files
committed
Disable jdbc params for scheme and unknown queries
1 parent 9fff37b commit 895b7f3

File tree

4 files changed

+40
-25
lines changed

4 files changed

+40
-25
lines changed

jdbc/src/main/java/tech/ydb/jdbc/YdbConst.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public final class YdbConst {
144144
// All indexed parameters will have this 'p' as a prefix, setInteger(1, "test") -> setInteger("p1", "test")
145145
public static final String INDEXED_PARAMETER_PREFIX = "p";
146146
public static final String VARIABLE_PARAMETER_PREFIX = "$";
147+
public static final String AUTO_GENERATED_PARAMETER_PREFIX = VARIABLE_PARAMETER_PREFIX + "jp";
147148
public static final String DEFAULT_BATCH_PARAMETER = "$values";
148149
public static final String OPTIONAL_TYPE_SUFFIX = "?";
149150

jdbc/src/main/java/tech/ydb/jdbc/query/JdbcQueryLexer.java

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ public class JdbcQueryLexer {
1313
*
1414
* @param builder Ydb query builder
1515
* @param options Options of parsing
16-
* @throws tech.ydb.jdbc.exception.YdbNonRetryableException if query contains errors
16+
* @throws java.sql.SQLException if query contains mix of query types
1717
*/
1818
public static void buildQuery(YdbQueryBuilder builder, YdbQueryOptions options) throws SQLException {
1919
int fragmentStart = 0;
2020

2121
boolean nextExpression = true;
22+
boolean detectJdbcArgs = false;
2223

2324
char[] chars = builder.getOriginSQL().toCharArray();
2425

@@ -42,19 +43,21 @@ public static void buildQuery(YdbQueryBuilder builder, YdbQueryOptions options)
4243
break;
4344
case ';': // next chars will be new expression
4445
nextExpression = true;
46+
detectJdbcArgs = false;
4547
break;
4648
case '?':
47-
builder.append(chars, fragmentStart, i - fragmentStart);
48-
if (i + 1 < chars.length && chars[i + 1] == '?') /* replace ?? with ? */ {
49-
builder.append('?');
50-
i++; // make sure the coming ? is not treated as a bind
51-
} else {
52-
String binded = builder.createNextArgName();
53-
builder.append(binded);
49+
if (detectJdbcArgs) {
50+
builder.append(chars, fragmentStart, i - fragmentStart);
51+
if (i + 1 < chars.length && chars[i + 1] == '?') /* replace ?? with ? */ {
52+
builder.append('?');
53+
i++; // make sure the coming ? is not treated as a bind
54+
} else {
55+
String binded = builder.createNextArgName();
56+
builder.append(binded);
57+
}
58+
fragmentStart = i + 1;
5459
}
55-
fragmentStart = i + 1;
5660
break;
57-
5861
default:
5962
if (nextExpression && Character.isJavaIdentifierStart(ch)) {
6063
nextExpression = false;
@@ -71,6 +74,7 @@ public static void buildQuery(YdbQueryBuilder builder, YdbQueryOptions options)
7174
|| parseReplaceKeyword(chars, i)
7275
) {
7376
builder.setQueryType(QueryType.DATA_QUERY);
77+
detectJdbcArgs = options.isDetectJdbcParameters();
7478
break;
7579
}
7680

@@ -85,16 +89,22 @@ public static void buildQuery(YdbQueryBuilder builder, YdbQueryOptions options)
8589
// Detect scan expression - starts with SCAN
8690
if (parseScanKeyword(chars, i)) {
8791
builder.setQueryType(QueryType.SCAN_QUERY);
92+
detectJdbcArgs = options.isDetectJdbcParameters();
93+
94+
// Skip SCAN prefix
8895
builder.append(chars, fragmentStart, i - fragmentStart);
89-
fragmentStart = i + 5; // Skip SCAN prefix
96+
fragmentStart = i + 5;
9097
break;
9198
}
9299

93100
// Detect explain expression - starts with EXPLAIN
94101
if (parseExplainKeyword(chars, i)) {
95102
builder.setQueryType(QueryType.EXPLAIN_QUERY);
103+
detectJdbcArgs = options.isDetectJdbcParameters();
104+
105+
// Skip EXPLAIN prefix
96106
builder.append(chars, fragmentStart, i - fragmentStart);
97-
fragmentStart = i + 8; // Skip EXPLAIN prefix
107+
fragmentStart = i + 8;
98108
break;
99109
}
100110
}

jdbc/src/main/java/tech/ydb/jdbc/query/YdbQueryBuilder.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
* @author Aleksandr Gorshenin
1313
*/
1414
public class YdbQueryBuilder {
15-
private final static String JDBC_ARG_PREFIX = "$jp";
16-
1715
private final String origin;
1816
private final StringBuilder query;
1917
private final List<String> args = new ArrayList<>();
@@ -29,7 +27,7 @@ public YdbQueryBuilder(String origin) {
2927
public String createNextArgName() {
3028
while (true) {
3129
argsCounter += 1;
32-
String next = JDBC_ARG_PREFIX + argsCounter;
30+
String next = YdbConst.AUTO_GENERATED_PARAMETER_PREFIX + argsCounter;
3331
if (!origin.contains(next)) {
3432
args.add(next);
3533
return next;

jdbc/src/test/java/tech/ydb/jdbc/query/QueryLexerTest.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@
1111
*/
1212
public class QueryLexerTest {
1313

14-
private QueryType parseQuery(YdbQueryOptions opts, String sql) throws SQLException {
14+
private QueryType parseQueryType(YdbQueryOptions opts, String sql) throws SQLException {
1515
YdbQueryBuilder builder = new YdbQueryBuilder(sql);
1616
JdbcQueryLexer.buildQuery(builder, opts);
1717
return builder.getQueryType();
1818
}
1919

20+
private String parseQuery(YdbQueryOptions opts, String sql) throws SQLException {
21+
YdbQueryBuilder builder = new YdbQueryBuilder(sql);
22+
JdbcQueryLexer.buildQuery(builder, opts);
23+
return builder.buildYQL();
24+
}
25+
2026
private void assertMixType(YdbQueryOptions opts, String types, String sql) {
2127
SQLException ex = Assertions.assertThrows(SQLException.class, () -> {
2228
YdbQueryBuilder builder = new YdbQueryBuilder(sql);
@@ -29,38 +35,38 @@ private void assertMixType(YdbQueryOptions opts, String types, String sql) {
2935
public void queryTypesTest() throws SQLException {
3036
YdbQueryOptions opts = new YdbQueryOptions(true, false, false, false);
3137

32-
Assertions.assertEquals(QueryType.SCHEME_QUERY, parseQuery(opts,
38+
Assertions.assertEquals(QueryType.SCHEME_QUERY, parseQueryType(opts,
3339
"CREATE TABLE test_table (id int, value text)"
3440
));
35-
Assertions.assertEquals(QueryType.SCHEME_QUERY, parseQuery(opts,
41+
Assertions.assertEquals(QueryType.SCHEME_QUERY, parseQueryType(opts,
3642
"\tcreate TABLE test_table2 (id int, value text);"
3743
));
3844

39-
Assertions.assertEquals(QueryType.SCHEME_QUERY, parseQuery(opts,
45+
Assertions.assertEquals(QueryType.SCHEME_QUERY, parseQueryType(opts,
4046
" drop TABLE test_table1 (id int, value text);" +
4147
"ALTER TABLE test_table2 (id int, value text);"
4248
));
4349

44-
Assertions.assertEquals(QueryType.DATA_QUERY, parseQuery(opts,
50+
Assertions.assertEquals(QueryType.DATA_QUERY, parseQueryType(opts,
4551
"SELECT id, value FROM test_table"
4652
));
47-
Assertions.assertEquals(QueryType.DATA_QUERY, parseQuery(opts,
53+
Assertions.assertEquals(QueryType.DATA_QUERY, parseQueryType(opts,
4854
"UPSERT INTO test_table VALUES (?, ?)"
4955
));
50-
Assertions.assertEquals(QueryType.DATA_QUERY, parseQuery(opts,
56+
Assertions.assertEquals(QueryType.DATA_QUERY, parseQueryType(opts,
5157
"DELETE FROM test_table"
5258
));
53-
Assertions.assertEquals(QueryType.DATA_QUERY, parseQuery(opts,
59+
Assertions.assertEquals(QueryType.DATA_QUERY, parseQueryType(opts,
5460
"SELECT id, value FROM test_table;\n" +
5561
"UPSERT INTO test_table VALUES (?, ?);" +
5662
"DELETE FROM test_table"
5763
));
5864

59-
Assertions.assertEquals(QueryType.SCAN_QUERY, parseQuery(opts,
65+
Assertions.assertEquals(QueryType.SCAN_QUERY, parseQueryType(opts,
6066
"SCAN SELECT id, value FROM test_table"
6167
));
6268

63-
Assertions.assertEquals(QueryType.EXPLAIN_QUERY, parseQuery(opts,
69+
Assertions.assertEquals(QueryType.EXPLAIN_QUERY, parseQueryType(opts,
6470
"EXPLAIN SELECT id, value FROM test_table"
6571
));
6672
}

0 commit comments

Comments
 (0)