@@ -184,9 +184,8 @@ ParametersInfo convertPositionalParametersToNamedParametersInternal(char paramCh
184
184
* Note: This is an internal API and breaking changes can be made without prior notice.
185
185
*
186
186
* <p>Returns the PostgreSQL-style query parameters ($1, $2, ...) in the given SQL string. The
187
- * SQL-string is assumed to not contain any comments. Use {@link #removeCommentsAndTrim(String)}
188
- * to remove all comments before calling this method. Occurrences of query-parameter like strings
189
- * inside quoted identifiers or string literals are ignored.
187
+ * SQL-string is allowed to contain comments. Occurrences of query-parameter like strings inside
188
+ * quoted identifiers or string literals are ignored.
190
189
*
191
190
* <p>The following example will return a set containing ("$1", "$2"). <code>
192
191
* select col1, col2, "col$4"
@@ -195,7 +194,7 @@ ParametersInfo convertPositionalParametersToNamedParametersInternal(char paramCh
195
194
* and not col3=$1 and col4='$3'
196
195
* </code>
197
196
*
198
- * @param sql the SQL-string to check for parameters. Must not contain comments.
197
+ * @param sql the SQL-string to check for parameters.
199
198
* @return A set containing all the parameters in the SQL-string.
200
199
*/
201
200
@ InternalApi
@@ -233,12 +232,56 @@ private int skip(String sql, int currentIndex, @Nullable StringBuilder result) {
233
232
return skipQuoted (
234
233
sql , currentIndex + dollarTag .length () + 1 , currentChar , dollarTag , result );
235
234
}
235
+ } else if (currentChar == HYPHEN
236
+ && sql .length () > (currentIndex + 1 )
237
+ && sql .charAt (currentIndex + 1 ) == HYPHEN ) {
238
+ return skipSingleLineComment (sql , currentIndex , result );
239
+ } else if (currentChar == SLASH
240
+ && sql .length () > (currentIndex + 1 )
241
+ && sql .charAt (currentIndex + 1 ) == ASTERISK ) {
242
+ return skipMultiLineComment (sql , currentIndex , result );
236
243
}
237
244
238
245
appendIfNotNull (result , currentChar );
239
246
return currentIndex + 1 ;
240
247
}
241
248
249
+ static int skipSingleLineComment (String sql , int currentIndex , @ Nullable StringBuilder result ) {
250
+ int endIndex = sql .indexOf ('\n' , currentIndex + 2 );
251
+ if (endIndex == -1 ) {
252
+ endIndex = sql .length ();
253
+ } else {
254
+ // Include the newline character.
255
+ endIndex ++;
256
+ }
257
+ appendIfNotNull (result , sql .substring (currentIndex , endIndex ));
258
+ return endIndex ;
259
+ }
260
+
261
+ static int skipMultiLineComment (String sql , int startIndex , @ Nullable StringBuilder result ) {
262
+ // Current position is start + '/*'.length().
263
+ int pos = startIndex + 2 ;
264
+ // PostgreSQL allows comments to be nested. That is, the following is allowed:
265
+ // '/* test /* inner comment */ still a comment */'
266
+ int level = 1 ;
267
+ while (pos < sql .length ()) {
268
+ if (sql .charAt (pos ) == SLASH && sql .length () > (pos + 1 ) && sql .charAt (pos + 1 ) == ASTERISK ) {
269
+ level ++;
270
+ }
271
+ if (sql .charAt (pos ) == ASTERISK && sql .length () > (pos + 1 ) && sql .charAt (pos + 1 ) == SLASH ) {
272
+ level --;
273
+ if (level == 0 ) {
274
+ pos += 2 ;
275
+ appendIfNotNull (result , sql .substring (startIndex , pos ));
276
+ return pos ;
277
+ }
278
+ }
279
+ pos ++;
280
+ }
281
+ appendIfNotNull (result , sql .substring (startIndex ));
282
+ return sql .length ();
283
+ }
284
+
242
285
private int skipQuoted (
243
286
String sql , int startIndex , char startQuote , @ Nullable StringBuilder result ) {
244
287
return skipQuoted (sql , startIndex , startQuote , null , result );
@@ -285,6 +328,12 @@ private void appendIfNotNull(@Nullable StringBuilder result, char currentChar) {
285
328
}
286
329
}
287
330
331
+ private static void appendIfNotNull (@ Nullable StringBuilder result , String suffix ) {
332
+ if (result != null ) {
333
+ result .append (suffix );
334
+ }
335
+ }
336
+
288
337
private void appendIfNotNull (
289
338
@ Nullable StringBuilder result , char prefix , String tag , char suffix ) {
290
339
if (result != null ) {
0 commit comments