@@ -20,6 +20,7 @@ public class YdbQueryParser {
2020 private final boolean isDetectJdbcParameters ;
2121
2222 private final List <QueryStatement > statements = new ArrayList <>();
23+ private final YqlBatcher batcher = new YqlBatcher ();
2324
2425 public YdbQueryParser (boolean isDetectQueryType , boolean isDetectJdbcParameters ) {
2526 this .isDetectQueryType = isDetectQueryType ;
@@ -30,6 +31,10 @@ public List<QueryStatement> getStatements() {
3031 return this .statements ;
3132 }
3233
34+ public YqlBatcher getYqlBatcher () {
35+ return this .batcher ;
36+ }
37+
3338 public QueryType detectQueryType () throws SQLException {
3439 QueryType type = null ;
3540 for (QueryStatement st : statements ) {
@@ -53,6 +58,7 @@ public QueryType detectQueryType() throws SQLException {
5358 @ SuppressWarnings ("MethodLength" )
5459 public String parseSQL (String origin ) throws SQLException {
5560 this .statements .clear ();
61+ this .batcher .clear ();
5662
5763 int fragmentStart = 0 ;
5864
@@ -73,20 +79,22 @@ public String parseSQL(String origin) throws SQLException {
7379 char ch = chars [i ];
7480 boolean isInsideKeyword = false ;
7581 switch (ch ) {
76- case '(' :
77- parenLevel ++;
78- break ;
79-
80- case ')' :
81- parenLevel --;
82- break ;
83-
8482 case '\'' : // single-quotes
85- i = parseSingleQuotes (chars , i );
83+ int singleQuitesEnd = parseSingleQuotes (chars , i );
84+ batcher .readSingleQuoteLiteral (chars , i , singleQuitesEnd - i + 1 );
85+ i = singleQuitesEnd ;
8686 break ;
8787
8888 case '"' : // double-quotes
89- i = parseDoubleQuotes (chars , i );
89+ int doubleQuitesEnd = parseDoubleQuotes (chars , i );
90+ batcher .readDoubleQuoteLiteral (chars , i , doubleQuitesEnd - i + 1 );
91+ i = doubleQuitesEnd ;
92+ break ;
93+
94+ case '`' : // backtick-quotes
95+ int backstickQuitesEnd = parseBacktickQuotes (chars , i );
96+ batcher .readIdentifier (chars , i , backstickQuitesEnd - i + 1 );
97+ i = backstickQuitesEnd ;
9098 break ;
9199
92100 case '-' : // possibly -- style comment
@@ -101,6 +109,7 @@ public String parseSQL(String origin) throws SQLException {
101109 parsed .append (chars , fragmentStart , i - fragmentStart );
102110 if (i + 1 < chars .length && chars [i + 1 ] == '?' ) /* replace ?? with ? */ {
103111 parsed .append ('?' );
112+ batcher .readIdentifier (chars , i , 1 );
104113 i ++; // make sure the coming ? is not treated as a bind
105114 } else {
106115 String binded = argNameGenerator .createArgName (origin );
@@ -110,6 +119,8 @@ public String parseSQL(String origin) throws SQLException {
110119 : null ;
111120 currStatement .addParameter (binded , type );
112121 parsed .append (binded );
122+
123+ batcher .readParameter ();
113124 }
114125 fragmentStart = i + 1 ;
115126 }
@@ -129,8 +140,11 @@ public String parseSQL(String origin) throws SQLException {
129140
130141 if (keywordStart >= 0 && (!isInsideKeyword || (i == chars .length - 1 ))) {
131142 lastKeywordIsOffsetLimit = false ;
143+ int keywordLength = isInsideKeyword ? i - keywordStart - 1 : i - keywordStart ;
132144
133145 if (currStatement != null ) {
146+ batcher .readIdentifier (chars , keywordStart , keywordLength );
147+
134148 // Detect RETURNING keyword
135149 if (parenLevel == 0 && parseReturningKeyword (chars , keywordStart )) {
136150 currStatement .setHasReturning (true );
@@ -147,11 +161,17 @@ public String parseSQL(String origin) throws SQLException {
147161 if (parseSelectKeyword (chars , keywordStart )) {
148162 currStatement = new QueryStatement (QueryType .DATA_QUERY , QueryCmd .SELECT );
149163 }
164+
150165 // starts with INSERT, UPSERT
151- if (parseInsertKeyword (chars , keywordStart )
152- || parseUpsertKeyword (chars , keywordStart )) {
166+ if (parseInsertKeyword (chars , keywordStart )) {
153167 currStatement = new QueryStatement (QueryType .DATA_QUERY , QueryCmd .INSERT_UPSERT );
168+ batcher .readInsert ();
154169 }
170+ if (parseUpsertKeyword (chars , keywordStart )) {
171+ currStatement = new QueryStatement (QueryType .DATA_QUERY , QueryCmd .INSERT_UPSERT );
172+ batcher .readUpsert ();
173+ }
174+
155175 // starts with UPDATE, REPLACE, DELETE
156176 if (parseUpdateKeyword (chars , keywordStart )
157177 || parseDeleteKeyword (chars , keywordStart )
@@ -165,6 +185,7 @@ public String parseSQL(String origin) throws SQLException {
165185 || parseDropKeyword (chars , keywordStart )) {
166186 currStatement = new QueryStatement (QueryType .SCHEME_QUERY , QueryCmd .CREATE_ALTER_DROP );
167187 }
188+
168189 if (isDetectQueryType ) {
169190 // Detect scan expression - starts with SCAN
170191 if (parseScanKeyword (chars , keywordStart )) {
@@ -186,21 +207,33 @@ public String parseSQL(String origin) throws SQLException {
186207 detectJdbcArgs = currStatement .getType () != QueryType .SCHEME_QUERY
187208 && currStatement .getType () != QueryType .UNKNOWN
188209 && isDetectJdbcParameters ;
189-
190- if (parseAlterKeyword (chars , i )
191- || parseCreateKeyword (chars , i )
192- || parseDropKeyword (chars , i )) {
193- currStatement = new QueryStatement (QueryType .SCHEME_QUERY , QueryCmd .CREATE_ALTER_DROP );
194- statements .add (currStatement );
195- }
196210 }
197211
198212 keywordStart = -1 ;
199213 }
200214
201- if (ch == ';' && parenLevel == 0 ) {
202- currStatement = null ;
203- detectJdbcArgs = false ;
215+ switch (ch ) {
216+ case '(' :
217+ parenLevel ++;
218+ batcher .readOpenParen ();
219+ break ;
220+ case ')' :
221+ parenLevel --;
222+ batcher .readCloseParen ();
223+ break ;
224+ case ',' :
225+ batcher .readComma ();
226+ break ;
227+ case ';' :
228+ batcher .readSemiColon ();
229+ if (parenLevel == 0 ) {
230+ currStatement = null ;
231+ detectJdbcArgs = false ;
232+ }
233+ break ;
234+ default :
235+ // nothing
236+ break ;
204237 }
205238 }
206239
@@ -250,6 +283,14 @@ private static int parseDoubleQuotes(final char[] query, int offset) {
250283 return offset ;
251284 }
252285
286+ @ SuppressWarnings ("EmptyBlock" )
287+ private static int parseBacktickQuotes (final char [] query , int offset ) {
288+ while (++offset < query .length && query [offset ] != '`' ) {
289+ // do nothing
290+ }
291+ return offset ;
292+ }
293+
253294 private static int parseLineComment (final char [] query , int offset ) {
254295 if (offset + 1 < query .length && query [offset + 1 ] == '-' ) {
255296 while (offset + 1 < query .length ) {
0 commit comments