private static ProcessedInput processSqlStatement(final String sql) {
        Map<String, String> parsedSqlResult = new HashMap<String, String>();

        Set<String> namedParameters = new HashSet<String>();
        String sqlToUse = sql;
        List<ParameterHolder> parameterList = new ArrayList<ParameterHolder>();

        char[] statement = sql.toCharArray();
        int namedParameterCount = 0;
        int unnamedParameterCount = 0;
        int totalParameterCount = 0;

        int escapes = 0;
        int i = 0;
        while (i < statement.length) {
            int skipToPosition = i;
            while (i < statement.length) {
                skipToPosition = skipCommentsAndQuotes(statement, i);
                if (i == skipToPosition) {
                    break;
                } else {
                    i = skipToPosition;
                }
            }
            if (i >= statement.length) {
                break;
            }
            char c = statement[i];
            if (c == ':' || c == '&') {
                int j = i + 1;
                if (j < statement.length && statement[j] == ':' && c == ':') {
                    // Postgres-style "::" casting operator - to be skipped.
                    i = i + 2;
                    continue;
                }
                String parameter = null;
                if (j < statement.length && c == ':' && statement[j] == '{') {
                    // :{x} style parameter
                    while (j < statement.length && !('}' == statement[j])) {
                        j++;
                        if (':' == statement[j] || '{' == statement[j]) {
                            throw new IllegalArgumentException("Parameter name contains invalid character '"
                                    + statement[j] + "' at position " + i + " in statement " + sql);
                        }
                    }
                    if (j >= statement.length) {
                        throw new IllegalArgumentException("Non-terminated named parameter declaration at position "
                                + i + " in statement " + sql);
                    }
                    if (j - i > 3) {
                        parameter = sql.substring(i + 2, j);
                        namedParameterCount = addNewNamedParameter(namedParameters, namedParameterCount, parameter);
                        totalParameterCount = addNamedParameter(parameterList, totalParameterCount, escapes, i, j + 1, parameter);
                    }
                    j++;
                } else {
                    while (j < statement.length && !isParameterSeparator(statement[j])) {
                        j++;
                    }
                    if (j - i > 1) {
                        parameter = sql.substring(i + 1, j);
                        namedParameterCount = addNewNamedParameter(namedParameters, namedParameterCount, parameter);
                        totalParameterCount = addNamedParameter(parameterList, totalParameterCount, escapes, i, j, parameter);
                    }
                }
                i = j - 1;
            } else {
                if (c == '\\') {
                    int j = i + 1;
                    if (j < statement.length && statement[j] == ':') {
                        // this is an escaped : and should be skipped
                        sqlToUse = sqlToUse.substring(0, i - escapes) + sqlToUse.substring(i - escapes + 1);
                        escapes++;
                        i = i + 2;
                        continue;
                    }
                }
                if (c == '?') {
                    unnamedParameterCount++;
                    totalParameterCount++;
                }
            }
            i++;
        }
        ProcessedInput processedInput = new ProcessedInput(sql);

        for (ParameterHolder ph : parameterList) {
            processedInput.addParameter(ph.getParameterName(), ph.getStartIndex(), ph.getEndIndex());
        }

        return processedInput;
    }
private static ProcessedInput processSqlStatement ( final String sql ) { Map < String , String > parsedSqlResult = new HashMap < String , String > ( ) ; Set < String > namedParameters = new HashSet < String > ( ) ; String sqlToUse = sql ; List < ParameterHolder > parameterList = new ArrayList < ParameterHolder > ( ) ; char [ ] statement = sql . toCharArray ( ) ; int namedParameterCount = 0 ; int unnamedParameterCount = 0 ; int totalParameterCount = 0 ; int escapes = 0 ; int i = 0 ; while ( i < statement . length ) { int skipToPosition = i ; while ( i < statement . length ) { skipToPosition = skipCommentsAndQuotes ( statement , i ) ; if ( i == skipToPosition ) { break ; } else { i = skipToPosition ; } } if ( i >= statement . length ) { break ; } char c = statement [ i ] ; if ( c == ':' || c == '&' ) { int j = i + 1 ; if ( j < statement . length && statement [ j ] == ':' && c == ':' ) { i = i + 2 ; continue ; } String parameter = null ; if ( j < statement . length && c == ':' && statement [ j ] == '{' ) { while ( j < statement . length && ! ( '}' == statement [ j ] ) ) { j ++ ; if ( ':' == statement [ j ] || '{' == statement [ j ] ) { throw new IllegalArgumentException ( "Parameter name contains invalid character '" + statement [ j ] + "' at position " + i + " in statement " + sql ) ; } } if ( j >= statement . length ) { throw new IllegalArgumentException ( "Non-terminated named parameter declaration at position " + i + " in statement " + sql ) ; } if ( j - i > 3 ) { parameter = sql . substring ( i + 2 , j ) ; namedParameterCount = addNewNamedParameter ( namedParameters , namedParameterCount , parameter ) ; totalParameterCount = addNamedParameter ( parameterList , totalParameterCount , escapes , i , j + 1 , parameter ) ; } j ++ ; } else { while ( j < statement . length && ! isParameterSeparator ( statement [ j ] ) ) { j ++ ; } if ( j - i > 1 ) { parameter = sql . substring ( i + 1 , j ) ; namedParameterCount = addNewNamedParameter ( namedParameters , namedParameterCount , parameter ) ; totalParameterCount = addNamedParameter ( parameterList , totalParameterCount , escapes , i , j , parameter ) ; } } i = j - 1 ; } else { if ( c == '\\' ) { int j = i + 1 ; if ( j < statement . length && statement [ j ] == ':' ) { sqlToUse = sqlToUse . substring ( 0 , i - escapes ) + sqlToUse . substring ( i - escapes + 1 ) ; escapes ++ ; i = i + 2 ; continue ; } } if ( c == '?' ) { unnamedParameterCount ++ ; totalParameterCount ++ ; } } i ++ ; } ProcessedInput processedInput = new ProcessedInput ( sql ) ; for ( ParameterHolder ph : parameterList ) { processedInput . addParameter ( ph . getParameterName ( ) , ph . getStartIndex ( ) , ph . getEndIndex ( ) ) ; } return processedInput ; }
Parse the SQL statement and locate any placeholders or named parameters.
Named parameters are substituted for a JDBC placeholder.

@param sql the SQL statement
@return the parsed statement, represented as ParsedSql instance