static inline void agtype_lex_number()

in src/backend/utils/adt/agtype_parser.c [1041:1146]


static inline void agtype_lex_number(agtype_lex_context *lex, char *s,
                                     bool *num_err, int *total_len)
{
    bool error = false;
    int len = s - lex->input;

    /* assume we have an integer until proven otherwise */
    lex->token_type = AGTYPE_TOKEN_INTEGER;

    /* Part (1): leading sign indicator. */
    /* Caller already did this for us; so do nothing. */

    /* Part (2): parse main digit string. */
    if (len < lex->input_length && *s == '0')
    {
        s++;
        len++;
    }
    else if (len < lex->input_length && *s >= '1' && *s <= '9')
    {
        do
        {
            s++;
            len++;
        } while (len < lex->input_length && *s >= '0' && *s <= '9');
    }
    else
    {
        error = true;
    }

    /* Part (3): parse optional decimal portion. */
    if (len < lex->input_length && *s == '.')
    {
        /* since we have a decimal point, we have a float */
        lex->token_type = AGTYPE_TOKEN_FLOAT;

        s++;
        len++;
        if (len == lex->input_length || *s < '0' || *s > '9')
        {
            error = true;
        }
        else
        {
            do
            {
                s++;
                len++;
            } while (len < lex->input_length && *s >= '0' && *s <= '9');
        }
    }

    /* Part (4): parse optional exponent. */
    if (len < lex->input_length && (*s == 'e' || *s == 'E'))
    {
        /* since we have an exponent, we have a float */
        lex->token_type = AGTYPE_TOKEN_FLOAT;

        s++;
        len++;
        if (len < lex->input_length && (*s == '+' || *s == '-'))
        {
            s++;
            len++;
        }
        if (len == lex->input_length || *s < '0' || *s > '9')
        {
            error = true;
        }
        else
        {
            do
            {
                s++;
                len++;
            } while (len < lex->input_length && *s >= '0' && *s <= '9');
        }
    }

    /*
     * Check for trailing garbage.  As in agtype_lex(), any alphanumeric stuff
     * here should be considered part of the token for error-reporting
     * purposes.
     */
    for (; len < lex->input_length && AGTYPE_ALPHANUMERIC_CHAR(*s); s++, len++)
        error = true;

    if (total_len != NULL)
        *total_len = len;

    if (num_err != NULL)
    {
        /* let the caller handle any error */
        *num_err = error;
    }
    else
    {
        /* return token endpoint */
        lex->prev_token_terminator = lex->token_terminator;
        lex->token_terminator = s;
        /* handle error if any */
        if (error)
            report_invalid_token(lex);
    }
}