Skip to content

Commit

Permalink
Fixed incorrect detecting of keywords
Browse files Browse the repository at this point in the history
  • Loading branch information
alex268 committed Sep 18, 2024
1 parent d046114 commit b63b14b
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 44 deletions.
89 changes: 45 additions & 44 deletions jdbc/src/main/java/tech/ydb/jdbc/query/YdbQueryParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,34 +144,35 @@ public String parseSQL(String origin) throws SQLException {
batcher.readIdentifier(chars, keywordStart, keywordLength);

// Detect RETURNING keyword
if (parenLevel == 0 && parseReturningKeyword(chars, keywordStart)) {
if (parenLevel == 0 && parseReturningKeyword(chars, keywordStart, keywordLength)) {
statement.setHasReturning(true);
}

if (parseOffsetKeyword(chars, keywordStart) || parseLimitKeyword(chars, keywordStart)) {
if (parseOffsetKeyword(chars, keywordStart, keywordLength)
|| parseLimitKeyword(chars, keywordStart, keywordLength)) {
lastKeywordIsOffsetLimit = true;
}
} else {
boolean skipped = false;
if (isDetectQueryType) {
// Detect scan expression - starts with SCAN
if (parseScanKeyword(chars, keywordStart)) {
if (parseScanKeyword(chars, keywordStart, keywordLength)) {
type = QueryType.SCAN_QUERY;
// Skip SCAN prefix
parsed.append(chars, fragmentStart, keywordStart - fragmentStart);
fragmentStart = isInsideKeyword ? keywordEnd + 1 : keywordEnd;
skipped = true;
}
// Detect explain expression - starts with EXPLAIN
if (parseExplainKeyword(chars, keywordStart)) {
if (parseExplainKeyword(chars, keywordStart, keywordLength)) {
type = QueryType.EXPLAIN_QUERY;
// Skip EXPLAIN prefix
parsed.append(chars, fragmentStart, keywordStart - fragmentStart);
fragmentStart = isInsideKeyword ? keywordEnd + 1 : keywordEnd;
skipped = true;
}
// Detect bulk upsert expression - starts with BULK
if (parseBulkKeyword(chars, keywordStart)) {
if (parseBulkKeyword(chars, keywordStart, keywordLength)) {
type = QueryType.BULK_QUERY;
// Skip BULK prefix
parsed.append(chars, fragmentStart, keywordStart - fragmentStart);
Expand All @@ -185,33 +186,33 @@ public String parseSQL(String origin) throws SQLException {
statement = new QueryStatement(type, QueryType.UNKNOWN, QueryCmd.UNKNOWN);
// Detect data query expression - starts with SELECT, , UPSERT, DELETE, REPLACE
// starts with SELECT
if (parseSelectKeyword(chars, keywordStart)) {
if (parseSelectKeyword(chars, keywordStart, keywordLength)) {
statement = new QueryStatement(type, QueryType.DATA_QUERY, QueryCmd.SELECT);
batcher.readIdentifier(chars, keywordStart, keywordLength);
}

// starts with INSERT, UPSERT
if (parseInsertKeyword(chars, keywordStart)) {
if (parseInsertKeyword(chars, keywordStart, keywordLength)) {
statement = new QueryStatement(type, QueryType.DATA_QUERY, QueryCmd.INSERT_UPSERT);
batcher.readInsert();
}
if (parseUpsertKeyword(chars, keywordStart)) {
if (parseUpsertKeyword(chars, keywordStart, keywordLength)) {
statement = new QueryStatement(type, QueryType.DATA_QUERY, QueryCmd.INSERT_UPSERT);
batcher.readUpsert();
}

// starts with UPDATE, REPLACE, DELETE
if (parseUpdateKeyword(chars, keywordStart)
|| parseDeleteKeyword(chars, keywordStart)
|| parseReplaceKeyword(chars, keywordStart)) {
if (parseUpdateKeyword(chars, keywordStart, keywordLength)
|| parseDeleteKeyword(chars, keywordStart, keywordLength)
|| parseReplaceKeyword(chars, keywordStart, keywordLength)) {
statement = new QueryStatement(type, QueryType.DATA_QUERY, QueryCmd.UPDATE_REPLACE_DELETE);
batcher.readIdentifier(chars, keywordStart, keywordLength);
}

// Detect scheme expression - starts with ALTER, DROP, CREATE
if (parseAlterKeyword(chars, keywordStart)
|| parseCreateKeyword(chars, keywordStart)
|| parseDropKeyword(chars, keywordStart)) {
if (parseAlterKeyword(chars, keywordStart, keywordLength)
|| parseCreateKeyword(chars, keywordStart, keywordLength)
|| parseDropKeyword(chars, keywordStart, keywordLength)) {
statement = new QueryStatement(type, QueryType.SCHEME_QUERY, QueryCmd.CREATE_ALTER_DROP);
batcher.readIdentifier(chars, keywordStart, keywordLength);
}
Expand Down Expand Up @@ -349,8 +350,8 @@ private static int parseBlockComment(final char[] query, int offset) {
return offset;
}

private static boolean parseAlterKeyword(char[] query, int offset) {
if (query.length < (offset + 5)) {
private static boolean parseAlterKeyword(char[] query, int offset, int length) {
if (length != 5) {
return false;
}

Expand All @@ -361,8 +362,8 @@ private static boolean parseAlterKeyword(char[] query, int offset) {
&& (query[offset + 4] | 32) == 'r';
}

private static boolean parseCreateKeyword(char[] query, int offset) {
if (query.length < (offset + 6)) {
private static boolean parseCreateKeyword(char[] query, int offset, int length) {
if (length != 6) {
return false;
}

Expand All @@ -374,8 +375,8 @@ private static boolean parseCreateKeyword(char[] query, int offset) {
&& (query[offset + 5] | 32) == 'e';
}

private static boolean parseDropKeyword(char[] query, int offset) {
if (query.length < (offset + 4)) {
private static boolean parseDropKeyword(char[] query, int offset, int length) {
if (length != 4) {
return false;
}

Expand All @@ -385,8 +386,8 @@ private static boolean parseDropKeyword(char[] query, int offset) {
&& (query[offset + 3] | 32) == 'p';
}

private static boolean parseScanKeyword(char[] query, int offset) {
if (query.length < (offset + 4)) {
private static boolean parseScanKeyword(char[] query, int offset, int length) {
if (length != 4) {
return false;
}

Expand All @@ -396,8 +397,8 @@ private static boolean parseScanKeyword(char[] query, int offset) {
&& (query[offset + 3] | 32) == 'n';
}

private static boolean parseBulkKeyword(char[] query, int offset) {
if (query.length < (offset + 4)) {
private static boolean parseBulkKeyword(char[] query, int offset, int length) {
if (length != 4) {
return false;
}

Expand All @@ -407,8 +408,8 @@ private static boolean parseBulkKeyword(char[] query, int offset) {
&& (query[offset + 3] | 32) == 'k';
}

private static boolean parseExplainKeyword(char[] query, int offset) {
if (query.length < (offset + 7)) {
private static boolean parseExplainKeyword(char[] query, int offset, int length) {
if (length != 7) {
return false;
}

Expand All @@ -421,8 +422,8 @@ private static boolean parseExplainKeyword(char[] query, int offset) {
&& (query[offset + 6] | 32) == 'n';
}

private static boolean parseSelectKeyword(char[] query, int offset) {
if (query.length < (offset + 6)) {
private static boolean parseSelectKeyword(char[] query, int offset, int length) {
if (length != 6) {
return false;
}

Expand All @@ -434,8 +435,8 @@ private static boolean parseSelectKeyword(char[] query, int offset) {
&& (query[offset + 5] | 32) == 't';
}

private static boolean parseUpdateKeyword(char[] query, int offset) {
if (query.length < (offset + 6)) {
private static boolean parseUpdateKeyword(char[] query, int offset, int length) {
if (length != 6) {
return false;
}

Expand All @@ -447,8 +448,8 @@ private static boolean parseUpdateKeyword(char[] query, int offset) {
&& (query[offset + 5] | 32) == 'e';
}

private static boolean parseUpsertKeyword(char[] query, int offset) {
if (query.length < (offset + 6)) {
private static boolean parseUpsertKeyword(char[] query, int offset, int length) {
if (length != 6) {
return false;
}

Expand All @@ -460,8 +461,8 @@ private static boolean parseUpsertKeyword(char[] query, int offset) {
&& (query[offset + 5] | 32) == 't';
}

private static boolean parseInsertKeyword(char[] query, int offset) {
if (query.length < (offset + 6)) {
private static boolean parseInsertKeyword(char[] query, int offset, int length) {
if (length != 6) {
return false;
}

Expand All @@ -473,8 +474,8 @@ private static boolean parseInsertKeyword(char[] query, int offset) {
&& (query[offset + 5] | 32) == 't';
}

private static boolean parseDeleteKeyword(char[] query, int offset) {
if (query.length < (offset + 6)) {
private static boolean parseDeleteKeyword(char[] query, int offset, int length) {
if (length != 6) {
return false;
}

Expand All @@ -486,8 +487,8 @@ private static boolean parseDeleteKeyword(char[] query, int offset) {
&& (query[offset + 5] | 32) == 'e';
}

private static boolean parseReplaceKeyword(char[] query, int offset) {
if (query.length < (offset + 7)) {
private static boolean parseReplaceKeyword(char[] query, int offset, int length) {
if (length != 7) {
return false;
}

Expand All @@ -500,8 +501,8 @@ private static boolean parseReplaceKeyword(char[] query, int offset) {
&& (query[offset + 6] | 32) == 'e';
}

private static boolean parseReturningKeyword(char[] query, int offset) {
if (query.length < (offset + 9)) {
private static boolean parseReturningKeyword(char[] query, int offset, int length) {
if (length != 9) {
return false;
}

Expand All @@ -516,8 +517,8 @@ private static boolean parseReturningKeyword(char[] query, int offset) {
&& (query[offset + 8] | 32) == 'g';
}

private static boolean parseOffsetKeyword(char[] query, int offset) {
if (query.length < (offset + 6)) {
private static boolean parseOffsetKeyword(char[] query, int offset, int length) {
if (length != 6) {
return false;
}

Expand All @@ -529,8 +530,8 @@ private static boolean parseOffsetKeyword(char[] query, int offset) {
&& (query[offset + 5] | 32) == 't';
}

private static boolean parseLimitKeyword(char[] query, int offset) {
if (query.length < (offset + 5)) {
private static boolean parseLimitKeyword(char[] query, int offset, int length) {
if (length != 5) {
return false;
}

Expand Down
20 changes: 20 additions & 0 deletions jdbc/src/test/java/tech/ydb/jdbc/query/YdbQueryParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,26 @@ public void schemeQueryTest(String sql) throws SQLException {
Assertions.assertEquals(QueryCmd.CREATE_ALTER_DROP, statement.getCmd());
}

@ParameterizedTest(name = "[{index}] {0} is data query")
@ValueSource(strings = {
"ALTERED;",
"SCANER SELECT 1;",
"bulked select 1;",
"\ndrops;",
"BuLK_INSERT;",
})
public void unknownQueryTest(String sql) throws SQLException {
YdbQueryParser parser = new YdbQueryParser(true, true);
String parsed = parser.parseSQL(sql);

Assertions.assertEquals(sql, parsed);

Assertions.assertEquals(1, parser.getStatements().size());
QueryStatement statement = parser.getStatements().get(0);
Assertions.assertEquals(QueryType.UNKNOWN, statement.getType());
Assertions.assertEquals(QueryCmd.UNKNOWN, statement.getCmd());
}

@Test
public void wrongSqlCommandTest() throws SQLException {
String query = "SC;";
Expand Down

0 comments on commit b63b14b

Please sign in to comment.