@Override
    protected String parse() {
        int paramIndex = 0;
        int partIndex = 0;
        int len = originalQuery.length();
        for (int i = 0; i < len; i++) {
            char ch = originalQuery.charAt(i);
            if (ClickHouseUtils.isQuote(ch)) {
                i = ClickHouseUtils.skipQuotedString(originalQuery, i, len, ch) - 1;
            } else if (ch == '?') {
                int idx = ClickHouseUtils.skipContentsUntil(originalQuery, i + 2, len, '?', ':');
                if (idx < len && originalQuery.charAt(idx - 1) == ':' && originalQuery.charAt(idx) != ':'
                        && originalQuery.charAt(idx - 2) != ':') {
                    i = idx - 1;
                } else {
                    addPart(originalQuery.substring(partIndex, i), paramIndex++, null);
                    partIndex = i + 1;
                }
            } else if (ch == ';') {
                throw new IllegalArgumentException(ClickHouseUtils.format(
                        "Multi-statement query cannot be used in prepared statement. Please remove semicolon at %d and everything after it.",
                        i));
            } else if (i + 1 < len) {
                char nextCh = originalQuery.charAt(i + 1);
                if (ch == '-' && nextCh == ch) {
                    i = ClickHouseUtils.skipSingleLineComment(originalQuery, i + 2, len) - 1;
                } else if (ch == '/' && nextCh == '*') {
                    i = ClickHouseUtils.skipMultiLineComment(originalQuery, i + 2, len) - 1;
                }
            }
        }

        return partIndex < len ? originalQuery.substring(partIndex, len) : null;
    }
Creates an instance by parsing the given query.

@param config non-null configuration
@param query  non-empty SQL query
@return parameterized query
clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/JdbcParameterizedQuery.java