Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

readfuncs.h File Reference

#include "nodes/nodes.h"
Include dependency graph for readfuncs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

char * pg_strtok (int *length)
char * debackslash (char *token, int length)
void * nodeRead (char *token, int tok_len)
NodeparseNodeString (void)

Function Documentation

char* debackslash ( char *  token,
int  length 
)

Definition at line 168 of file read.c.

References palloc().

Referenced by nodeRead().

{
    char       *result = palloc(length + 1);
    char       *ptr = result;

    while (length > 0)
    {
        if (*token == '\\' && length > 1)
            token++, length--;
        *ptr++ = *token++;
        length--;
    }
    *ptr = '\0';
    return result;
}

void* nodeRead ( char *  token,
int  tok_len 
)

Definition at line 278 of file read.c.

References debackslash(), elog, ERROR, lappend(), lappend_int(), lappend_oid(), LEFT_BRACE, LEFT_PAREN, makeBitString(), makeFloat(), makeInteger(), makeString(), nodeRead(), nodeTokenType(), NULL, OTHER_TOKEN, palloc(), parseNodeString(), pg_strtok(), RIGHT_PAREN, T_BitString, T_Float, T_Integer, T_String, and val.

Referenced by nodeRead(), and stringToNode().

{
    Node       *result;
    NodeTag     type;

    if (token == NULL)          /* need to read a token? */
    {
        token = pg_strtok(&tok_len);

        if (token == NULL)      /* end of input */
            return NULL;
    }

    type = nodeTokenType(token, tok_len);

    switch ((int) type)
    {
        case LEFT_BRACE:
            result = parseNodeString();
            token = pg_strtok(&tok_len);
            if (token == NULL || token[0] != '}')
                elog(ERROR, "did not find '}' at end of input node");
            break;
        case LEFT_PAREN:
            {
                List       *l = NIL;

                /*----------
                 * Could be an integer list:    (i int int ...)
                 * or an OID list:              (o int int ...)
                 * or a list of nodes/values:   (node node ...)
                 *----------
                 */
                token = pg_strtok(&tok_len);
                if (token == NULL)
                    elog(ERROR, "unterminated List structure");
                if (tok_len == 1 && token[0] == 'i')
                {
                    /* List of integers */
                    for (;;)
                    {
                        int         val;
                        char       *endptr;

                        token = pg_strtok(&tok_len);
                        if (token == NULL)
                            elog(ERROR, "unterminated List structure");
                        if (token[0] == ')')
                            break;
                        val = (int) strtol(token, &endptr, 10);
                        if (endptr != token + tok_len)
                            elog(ERROR, "unrecognized integer: \"%.*s\"",
                                 tok_len, token);
                        l = lappend_int(l, val);
                    }
                }
                else if (tok_len == 1 && token[0] == 'o')
                {
                    /* List of OIDs */
                    for (;;)
                    {
                        Oid         val;
                        char       *endptr;

                        token = pg_strtok(&tok_len);
                        if (token == NULL)
                            elog(ERROR, "unterminated List structure");
                        if (token[0] == ')')
                            break;
                        val = (Oid) strtoul(token, &endptr, 10);
                        if (endptr != token + tok_len)
                            elog(ERROR, "unrecognized OID: \"%.*s\"",
                                 tok_len, token);
                        l = lappend_oid(l, val);
                    }
                }
                else
                {
                    /* List of other node types */
                    for (;;)
                    {
                        /* We have already scanned next token... */
                        if (token[0] == ')')
                            break;
                        l = lappend(l, nodeRead(token, tok_len));
                        token = pg_strtok(&tok_len);
                        if (token == NULL)
                            elog(ERROR, "unterminated List structure");
                    }
                }
                result = (Node *) l;
                break;
            }
        case RIGHT_PAREN:
            elog(ERROR, "unexpected right parenthesis");
            result = NULL;      /* keep compiler happy */
            break;
        case OTHER_TOKEN:
            if (tok_len == 0)
            {
                /* must be "<>" --- represents a null pointer */
                result = NULL;
            }
            else
            {
                elog(ERROR, "unrecognized token: \"%.*s\"", tok_len, token);
                result = NULL;  /* keep compiler happy */
            }
            break;
        case T_Integer:

            /*
             * we know that the token terminates on a char atol will stop at
             */
            result = (Node *) makeInteger(atol(token));
            break;
        case T_Float:
            {
                char       *fval = (char *) palloc(tok_len + 1);

                memcpy(fval, token, tok_len);
                fval[tok_len] = '\0';
                result = (Node *) makeFloat(fval);
            }
            break;
        case T_String:
            /* need to remove leading and trailing quotes, and backslashes */
            result = (Node *) makeString(debackslash(token + 1, tok_len - 2));
            break;
        case T_BitString:
            {
                char       *val = palloc(tok_len);

                /* skip leading 'b' */
                memcpy(val, token + 1, tok_len - 1);
                val[tok_len - 1] = '\0';
                result = (Node *) makeBitString(val);
                break;
            }
        default:
            elog(ERROR, "unrecognized node type: %d", (int) type);
            result = NULL;      /* keep compiler happy */
            break;
    }

    return (void *) result;
}

Node* parseNodeString ( void   ) 

Definition at line 1248 of file readfuncs.c.

References _readAggref(), _readAlias(), _readArrayCoerceExpr(), _readArrayExpr(), _readArrayRef(), _readBooleanTest(), _readBoolExpr(), _readCaseExpr(), _readCaseTestExpr(), _readCaseWhen(), _readCoalesceExpr(), _readCoerceToDomain(), _readCoerceToDomainValue(), _readCoerceViaIO(), _readCollateExpr(), _readCommonTableExpr(), _readConst(), _readConvertRowtypeExpr(), _readCurrentOfExpr(), _readDeclareCursorStmt(), _readDistinctExpr(), _readFieldSelect(), _readFieldStore(), _readFromExpr(), _readFuncExpr(), _readIntoClause(), _readJoinExpr(), _readMinMaxExpr(), _readNamedArgExpr(), _readNotifyStmt(), _readNullIfExpr(), _readNullTest(), _readOpExpr(), _readParam(), _readQuery(), _readRangeTblEntry(), _readRangeTblRef(), _readRangeVar(), _readRelabelType(), _readRowCompareExpr(), _readRowExpr(), _readRowMarkClause(), _readScalarArrayOpExpr(), _readSetOperationStmt(), _readSetToDefault(), _readSortGroupClause(), _readSubLink(), _readTargetEntry(), _readVar(), _readWindowClause(), _readWindowFunc(), _readXmlExpr(), elog, ERROR, length(), MATCH, pg_strtok(), and READ_TEMP_LOCALS.

Referenced by nodeRead().

{
    void       *return_value;

    READ_TEMP_LOCALS();

    token = pg_strtok(&length);

#define MATCH(tokname, namelen) \
    (length == namelen && memcmp(token, tokname, namelen) == 0)

    if (MATCH("QUERY", 5))
        return_value = _readQuery();
    else if (MATCH("SORTGROUPCLAUSE", 15))
        return_value = _readSortGroupClause();
    else if (MATCH("WINDOWCLAUSE", 12))
        return_value = _readWindowClause();
    else if (MATCH("ROWMARKCLAUSE", 13))
        return_value = _readRowMarkClause();
    else if (MATCH("COMMONTABLEEXPR", 15))
        return_value = _readCommonTableExpr();
    else if (MATCH("SETOPERATIONSTMT", 16))
        return_value = _readSetOperationStmt();
    else if (MATCH("ALIAS", 5))
        return_value = _readAlias();
    else if (MATCH("RANGEVAR", 8))
        return_value = _readRangeVar();
    else if (MATCH("INTOCLAUSE", 10))
        return_value = _readIntoClause();
    else if (MATCH("VAR", 3))
        return_value = _readVar();
    else if (MATCH("CONST", 5))
        return_value = _readConst();
    else if (MATCH("PARAM", 5))
        return_value = _readParam();
    else if (MATCH("AGGREF", 6))
        return_value = _readAggref();
    else if (MATCH("WINDOWFUNC", 10))
        return_value = _readWindowFunc();
    else if (MATCH("ARRAYREF", 8))
        return_value = _readArrayRef();
    else if (MATCH("FUNCEXPR", 8))
        return_value = _readFuncExpr();
    else if (MATCH("NAMEDARGEXPR", 12))
        return_value = _readNamedArgExpr();
    else if (MATCH("OPEXPR", 6))
        return_value = _readOpExpr();
    else if (MATCH("DISTINCTEXPR", 12))
        return_value = _readDistinctExpr();
    else if (MATCH("NULLIFEXPR", 10))
        return_value = _readNullIfExpr();
    else if (MATCH("SCALARARRAYOPEXPR", 17))
        return_value = _readScalarArrayOpExpr();
    else if (MATCH("BOOLEXPR", 8))
        return_value = _readBoolExpr();
    else if (MATCH("SUBLINK", 7))
        return_value = _readSubLink();
    else if (MATCH("FIELDSELECT", 11))
        return_value = _readFieldSelect();
    else if (MATCH("FIELDSTORE", 10))
        return_value = _readFieldStore();
    else if (MATCH("RELABELTYPE", 11))
        return_value = _readRelabelType();
    else if (MATCH("COERCEVIAIO", 11))
        return_value = _readCoerceViaIO();
    else if (MATCH("ARRAYCOERCEEXPR", 15))
        return_value = _readArrayCoerceExpr();
    else if (MATCH("CONVERTROWTYPEEXPR", 18))
        return_value = _readConvertRowtypeExpr();
    else if (MATCH("COLLATE", 7))
        return_value = _readCollateExpr();
    else if (MATCH("CASE", 4))
        return_value = _readCaseExpr();
    else if (MATCH("WHEN", 4))
        return_value = _readCaseWhen();
    else if (MATCH("CASETESTEXPR", 12))
        return_value = _readCaseTestExpr();
    else if (MATCH("ARRAY", 5))
        return_value = _readArrayExpr();
    else if (MATCH("ROW", 3))
        return_value = _readRowExpr();
    else if (MATCH("ROWCOMPARE", 10))
        return_value = _readRowCompareExpr();
    else if (MATCH("COALESCE", 8))
        return_value = _readCoalesceExpr();
    else if (MATCH("MINMAX", 6))
        return_value = _readMinMaxExpr();
    else if (MATCH("XMLEXPR", 7))
        return_value = _readXmlExpr();
    else if (MATCH("NULLTEST", 8))
        return_value = _readNullTest();
    else if (MATCH("BOOLEANTEST", 11))
        return_value = _readBooleanTest();
    else if (MATCH("COERCETODOMAIN", 14))
        return_value = _readCoerceToDomain();
    else if (MATCH("COERCETODOMAINVALUE", 19))
        return_value = _readCoerceToDomainValue();
    else if (MATCH("SETTODEFAULT", 12))
        return_value = _readSetToDefault();
    else if (MATCH("CURRENTOFEXPR", 13))
        return_value = _readCurrentOfExpr();
    else if (MATCH("TARGETENTRY", 11))
        return_value = _readTargetEntry();
    else if (MATCH("RANGETBLREF", 11))
        return_value = _readRangeTblRef();
    else if (MATCH("JOINEXPR", 8))
        return_value = _readJoinExpr();
    else if (MATCH("FROMEXPR", 8))
        return_value = _readFromExpr();
    else if (MATCH("RTE", 3))
        return_value = _readRangeTblEntry();
    else if (MATCH("NOTIFY", 6))
        return_value = _readNotifyStmt();
    else if (MATCH("DECLARECURSOR", 13))
        return_value = _readDeclareCursorStmt();
    else
    {
        elog(ERROR, "badly formatted node string \"%.32s\"...", token);
        return_value = NULL;    /* keep compiler quiet */
    }

    return (Node *) return_value;
}

char* pg_strtok ( int *  length  ) 

Definition at line 107 of file read.c.

References pg_strtok_ptr.

Referenced by _readBitmapset(), _readBoolExpr(), _readConst(), nodeRead(), parseNodeString(), and readDatum().

{
    char       *local_str;      /* working pointer to string */
    char       *ret_str;        /* start of token to return */

    local_str = pg_strtok_ptr;

    while (*local_str == ' ' || *local_str == '\n' || *local_str == '\t')
        local_str++;

    if (*local_str == '\0')
    {
        *length = 0;
        pg_strtok_ptr = local_str;
        return NULL;            /* no more tokens */
    }

    /*
     * Now pointing at start of next token.
     */
    ret_str = local_str;

    if (*local_str == '(' || *local_str == ')' ||
        *local_str == '{' || *local_str == '}')
    {
        /* special 1-character token */
        local_str++;
    }
    else
    {
        /* Normal token, possibly containing backslashes */
        while (*local_str != '\0' &&
               *local_str != ' ' && *local_str != '\n' &&
               *local_str != '\t' &&
               *local_str != '(' && *local_str != ')' &&
               *local_str != '{' && *local_str != '}')
        {
            if (*local_str == '\\' && local_str[1] != '\0')
                local_str += 2;
            else
                local_str++;
        }
    }

    *length = local_str - ret_str;

    /* Recognize special case for "empty" token */
    if (*length == 2 && ret_str[0] == '<' && ret_str[1] == '>')
        *length = 0;

    pg_strtok_ptr = local_str;

    return ret_str;
}