@@ -184,9 +184,8 @@ ParametersInfo convertPositionalParametersToNamedParametersInternal(char paramCh
184184 * Note: This is an internal API and breaking changes can be made without prior notice.
185185 *
186186 * <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.
190189 *
191190 * <p>The following example will return a set containing ("$1", "$2"). <code>
192191 * select col1, col2, "col$4"
@@ -195,7 +194,7 @@ ParametersInfo convertPositionalParametersToNamedParametersInternal(char paramCh
195194 * and not col3=$1 and col4='$3'
196195 * </code>
197196 *
198- * @param sql the SQL-string to check for parameters. Must not contain comments.
197+ * @param sql the SQL-string to check for parameters.
199198 * @return A set containing all the parameters in the SQL-string.
200199 */
201200 @ InternalApi
@@ -233,12 +232,56 @@ private int skip(String sql, int currentIndex, @Nullable StringBuilder result) {
233232 return skipQuoted (
234233 sql , currentIndex + dollarTag .length () + 1 , currentChar , dollarTag , result );
235234 }
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 );
236243 }
237244
238245 appendIfNotNull (result , currentChar );
239246 return currentIndex + 1 ;
240247 }
241248
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+
242285 private int skipQuoted (
243286 String sql , int startIndex , char startQuote , @ Nullable StringBuilder result ) {
244287 return skipQuoted (sql , startIndex , startQuote , null , result );
@@ -285,6 +328,12 @@ private void appendIfNotNull(@Nullable StringBuilder result, char currentChar) {
285328 }
286329 }
287330
331+ private static void appendIfNotNull (@ Nullable StringBuilder result , String suffix ) {
332+ if (result != null ) {
333+ result .append (suffix );
334+ }
335+ }
336+
288337 private void appendIfNotNull (
289338 @ Nullable StringBuilder result , char prefix , String tag , char suffix ) {
290339 if (result != null ) {
0 commit comments