Skip to content

Commit 3e6f173

Browse files
committed
Fix detecting of offset & limit keywords
1 parent b63b14b commit 3e6f173

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ public String parseSQL(String origin) throws SQLException {
124124
}
125125
break;
126126
default:
127+
lastKeywordIsOffsetLimit = lastKeywordIsOffsetLimit && Character.isWhitespace(ch);
128+
127129
if (keywordStart >= 0) {
128130
isInsideKeyword = Character.isJavaIdentifierPart(ch);
129131
break;
@@ -136,6 +138,7 @@ public String parseSQL(String origin) throws SQLException {
136138
break;
137139
}
138140

141+
139142
if (keywordStart >= 0 && (!isInsideKeyword || (i == chars.length - 1))) {
140143
lastKeywordIsOffsetLimit = false;
141144
int keywordLength = (isInsideKeyword ? i + 1 : keywordEnd) - keywordStart;
@@ -150,7 +153,7 @@ public String parseSQL(String origin) throws SQLException {
150153

151154
if (parseOffsetKeyword(chars, keywordStart, keywordLength)
152155
|| parseLimitKeyword(chars, keywordStart, keywordLength)) {
153-
lastKeywordIsOffsetLimit = true;
156+
lastKeywordIsOffsetLimit = Character.isWhitespace(ch);
154157
}
155158
} else {
156159
boolean skipped = false;

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

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,29 +154,55 @@ public void scanSelectWithKeyTest() throws SQLException {
154154
Assertions.assertEquals(QueryType.SCAN_QUERY, parser.detectQueryType());
155155
}
156156

157-
@Test
158-
public void offsetParameterTest() throws SQLException {
159-
String query = ""
160-
+ "select * from test_table where true=true -- test request\n"
161-
+ " offset /* comment */ ? limit 20";
157+
@ParameterizedTest(name = "[{index}] {0} has offset or limit parameter")
158+
@ValueSource(strings = {
159+
"select * from test_table where true=true -- test request\noffset /* comment */ ? limit 20",
160+
"select * from test_table where true=true /*comm*/offset ?\tlimit\t\n?;",
161+
"select offset, limit from test_table offset 20 limit -- comment\n?;",
162+
})
163+
public void offsetParameterTest(String query) throws SQLException {
164+
YdbQueryParser parser = new YdbQueryParser(true, true);
165+
parser.parseSQL(query);
166+
167+
Assertions.assertEquals(1, parser.getStatements().size());
162168

169+
QueryStatement statement = parser.getStatements().get(0);
170+
Assertions.assertEquals(QueryType.DATA_QUERY, statement.getType());
171+
172+
Assertions.assertFalse(statement.getParams().isEmpty());
173+
int idx = 0;
174+
for (ParamDescription prm : statement.getParams()) {
175+
idx++;
176+
Assertions.assertEquals("$jp" + idx, prm.name());
177+
Assertions.assertNotNull(prm.type()); // forced UInt64 type
178+
Assertions.assertEquals(PrimitiveType.Uint64, prm.type().ydbType()); // forced UInt64 type
179+
}
180+
}
181+
182+
@ParameterizedTest(name = "[{index}] {0} hasn't offset or limit parameter")
183+
@ValueSource(strings = {
184+
"select * from test_table where limit = ? or offset = ?",
185+
"update test_table set limit = ?, offset = ? where id = ?",
186+
"select * from test_table where limit=? or offset=?",
187+
"update test_table set limit=?, offset=? where id=?",
188+
"select * from test_table where limit? or offset?",
189+
})
190+
public void noOffsetParameterTest(String query) throws SQLException {
163191
YdbQueryParser parser = new YdbQueryParser(true, true);
164-
String parsed = parser.parseSQL(query);
165-
Assertions.assertEquals(""
166-
+ "select * from test_table where true=true -- test request\n"
167-
+ " offset /* comment */ $jp1 limit 20",
168-
parsed);
192+
parser.parseSQL(query);
169193

170194
Assertions.assertEquals(1, parser.getStatements().size());
171195

172196
QueryStatement statement = parser.getStatements().get(0);
173197
Assertions.assertEquals(QueryType.DATA_QUERY, statement.getType());
174-
Assertions.assertEquals(1, statement.getParams().size());
175198

176-
ParamDescription prm1 = statement.getParams().get(0);
177-
Assertions.assertEquals("$jp1", prm1.name());
178-
Assertions.assertNotNull(prm1.type());
179-
Assertions.assertEquals(PrimitiveType.Uint64, prm1.type().ydbType());
199+
Assertions.assertFalse(statement.getParams().isEmpty());
200+
int idx = 0;
201+
for (ParamDescription prm : statement.getParams()) {
202+
idx++;
203+
Assertions.assertEquals("$jp" + idx, prm.name());
204+
Assertions.assertNull(prm.type()); // uknown type
205+
}
180206
}
181207

182208
@ParameterizedTest(name = "[{index}] {0} is batched insert query")

0 commit comments

Comments
 (0)