public Token scan()

in apm-agent-plugin-sdk/src/main/java/co/elastic/apm/agent/sdk/internal/db/signature/Scanner.java [76:178]


    public Token scan() {
        if (!hasNext()) {
            return Token.EOF;
        }
        char c = next();
        while (Character.isSpaceChar(c) || filter.skip(this, c)) {
            if (hasNext()) {
                c = next();
            } else {
                return Token.EOF;
            }
        }
        start = pos - 1;
        if (c == '_' || Character.isLetter(c)) {
            return scanKeywordOrIdentifier(c != '_');
        } else if (Character.isDigit(c)) {
            return scanNumericLiteral();
        }
        switch (c) {
            case '\'':
                // Standard string literal
                return scanStringLiteral();
            case '"':
                // Standard double-quoted identifier.
                //
                // NOTE(axw) MySQL will treat " as a
                // string literal delimiter by default,
                // but we assume standard SQL and treat
                // it as a identifier delimiter.
                return scanQuotedIdentifier('"');
            case '[':
                // T-SQL bracket-quoted identifier
                return scanQuotedIdentifier(']');
            case '`':
                // MySQL-style backtick-quoted identifier
                return scanQuotedIdentifier('`');
            case '(':
                return Token.LPAREN;
            case ')':
                return Token.RPAREN;
            case '-':
                if (isNextChar('-')) {
                    // -- comment
                    next();
                    return scanSimpleComment();
                }
                return Token.OTHER;
            case '/':
                if (isNextChar('*')) {
                    // /* comment */
                    next();
                    return scanBracketedComment();
                } else if (isNextChar('/')) {
                    // // line comment (ex. Cassandra QL)
                    next();
                    return scanSimpleComment();
                }
                return Token.OTHER;
            case '.':
                return Token.PERIOD;
            case '$':
                if (!hasNext()) {
                    return Token.OTHER;
                }
                char next = peek();
                if (Character.isDigit(next)) {
                    while (hasNext()) {
                        if (!Character.isDigit(peek())) {
                            break;
                        } else {
                            next();
                        }
                    }
                    return Token.OTHER;
                } else if (next == '$' || next == '_' || Character.isLetter(next)) {
                    // PostgreSQL supports dollar-quoted string literal syntax, like $foo$...$foo$.
                    // The tag (foo in this case) is optional, and if present follows identifier rules.
                    while (hasNext()) {
                        c = next();
                        if (c == '$') {
                            // This marks the end of the initial $foo$.
                            final String text = text();
                            int i = input.indexOf(text, pos);
                            if (i >= 0) {
                                end = i + text.length();
                                pos = i + text.length();
                                return Token.STRING;
                            }
                            return Token.OTHER;
                        } else if (Character.isLetter(c) || Character.isDigit(c) || c == '_') {
                            // Identifier char, consume
                        } else if (Character.isSpaceChar(c)) {
                            end--;
                            return Token.OTHER;
                        }
                    }
                    // Unknown token starting with $ until EOF, just ignore it.
                    return Token.OTHER;
                }
            default:
                return Token.OTHER;
        }
    }