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 (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;
                } else if (ch == ':') {
                    if (nextCh == ch) { // skip PostgreSQL-like type conversion
                        i = i + 1;
                    } else if (Character.isJavaIdentifierStart(nextCh)) {
                        String part = partIndex != i ? originalQuery.substring(partIndex, i) : "";
                        String paramName = null;
                        String paramType = null;
                        StringBuilder builder = new StringBuilder().append(nextCh);
                        for (i = i + 2; i < len; i++) {
                            char c = originalQuery.charAt(i);
                            if (Character.isJavaIdentifierPart(c)) {
                                builder.append(c);
                            } else {
                                if (c == '(') {
                                    int idx = ClickHouseUtils.skipBrackets(originalQuery, i, len, c);
                                    paramType = originalQuery.substring(i + 1, idx - 1);
                                    i = idx;
                                }
                                break;
                            }
                        }

                        partIndex = i--;

                        if (builder.length() > 0) {
                            paramName = builder.toString();
                            if (!names.containsKey(paramName)) {
                                paramIndex++;
                            }
                        }

                        parts.add(new QueryPart(config, part, paramIndex, paramName, paramType, names));
                    }
                }
            }
        }

        return partIndex < len ? originalQuery.substring(partIndex, len) : null;
    }
Parses the query given in constructor.

@return remaining part(right after the last parameter) after parsing, could
        be null
clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseParameterizedQuery.java