Header And Logo

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

Defines | Functions

parsetree.h File Reference

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

Go to the source code of this file.

Defines

#define rt_fetch(rangetable_index, rangetable)   ((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1))
#define getrelid(rangeindex, rangetable)   (rt_fetch(rangeindex, rangetable)->relid)

Functions

char * get_rte_attribute_name (RangeTblEntry *rte, AttrNumber attnum)
void get_rte_attribute_type (RangeTblEntry *rte, AttrNumber attnum, Oid *vartype, int32 *vartypmod, Oid *varcollid)
bool get_rte_attribute_is_dropped (RangeTblEntry *rte, AttrNumber attnum)
TargetEntryget_tle_by_resno (List *tlist, AttrNumber resno)
RowMarkClauseget_parse_rowmark (Query *qry, Index rtindex)

Define Documentation

#define getrelid (   rangeindex,
  rangetable 
)    (rt_fetch(rangeindex, rangetable)->relid)

Definition at line 41 of file parsetree.h.

Referenced by ExecOpenScanRelation(), expand_targetlist(), and InitPlan().

#define rt_fetch (   rangetable_index,
  rangetable 
)    ((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1))

Function Documentation

RowMarkClause* get_parse_rowmark ( Query qry,
Index  rtindex 
)

Definition at line 2391 of file parse_relation.c.

References lfirst, Query::rowMarks, and RowMarkClause::rti.

Referenced by AcquireRewriteLocks(), applyLockingClause(), ApplyRetrieveRule(), create_indexscan_plan(), fireRIRrules(), postgresGetForeignPlan(), and ScanQueryForLocks().

{
    ListCell   *l;

    foreach(l, qry->rowMarks)
    {
        RowMarkClause *rc = (RowMarkClause *) lfirst(l);

        if (rc->rti == rtindex)
            return rc;
    }
    return NULL;
}

bool get_rte_attribute_is_dropped ( RangeTblEntry rte,
AttrNumber  attnum 
)

Definition at line 2269 of file parse_relation.c.

References ATTNUM, elog, ERROR, exprType(), RangeTblEntry::funcexpr, GETSTRUCT, HeapTupleIsValid, Int16GetDatum, IsA, RangeTblEntry::joinaliasvars, list_length(), list_nth(), ObjectIdGetDatum, OidIsValid, ReleaseSysCache(), RangeTblEntry::relid, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_RELATION, RTE_SUBQUERY, RTE_VALUES, RangeTblEntry::rtekind, SearchSysCache2, and typeidTypeRelid().

Referenced by AcquireRewriteLocks().

{
    bool        result;

    switch (rte->rtekind)
    {
        case RTE_RELATION:
            {
                /*
                 * Plain relation RTE --- get the attribute's catalog entry
                 */
                HeapTuple   tp;
                Form_pg_attribute att_tup;

                tp = SearchSysCache2(ATTNUM,
                                     ObjectIdGetDatum(rte->relid),
                                     Int16GetDatum(attnum));
                if (!HeapTupleIsValid(tp))      /* shouldn't happen */
                    elog(ERROR, "cache lookup failed for attribute %d of relation %u",
                         attnum, rte->relid);
                att_tup = (Form_pg_attribute) GETSTRUCT(tp);
                result = att_tup->attisdropped;
                ReleaseSysCache(tp);
            }
            break;
        case RTE_SUBQUERY:
        case RTE_VALUES:
        case RTE_CTE:
            /* Subselect, Values, CTE RTEs never have dropped columns */
            result = false;
            break;
        case RTE_JOIN:
            {
                /*
                 * A join RTE would not have dropped columns when constructed,
                 * but one in a stored rule might contain columns that were
                 * dropped from the underlying tables, if said columns are
                 * nowhere explicitly referenced in the rule.  This will be
                 * signaled to us by a NULL Const in the joinaliasvars list.
                 */
                Var        *aliasvar;

                if (attnum <= 0 ||
                    attnum > list_length(rte->joinaliasvars))
                    elog(ERROR, "invalid varattno %d", attnum);
                aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);

                result = IsA(aliasvar, Const);
            }
            break;
        case RTE_FUNCTION:
            {
                /* Function RTE */
                Oid         funcrettype = exprType(rte->funcexpr);
                Oid         funcrelid = typeidTypeRelid(funcrettype);

                if (OidIsValid(funcrelid))
                {
                    /*
                     * Composite data type, i.e. a table's row type
                     *
                     * Same as ordinary relation RTE
                     */
                    HeapTuple   tp;
                    Form_pg_attribute att_tup;

                    tp = SearchSysCache2(ATTNUM,
                                         ObjectIdGetDatum(funcrelid),
                                         Int16GetDatum(attnum));
                    if (!HeapTupleIsValid(tp))  /* shouldn't happen */
                        elog(ERROR, "cache lookup failed for attribute %d of relation %u",
                             attnum, funcrelid);
                    att_tup = (Form_pg_attribute) GETSTRUCT(tp);
                    result = att_tup->attisdropped;
                    ReleaseSysCache(tp);
                }
                else
                {
                    /*
                     * Must be a base data type, i.e. scalar
                     */
                    result = false;
                }
            }
            break;
        default:
            elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
            result = false;     /* keep compiler quiet */
    }

    return result;
}

char* get_rte_attribute_name ( RangeTblEntry rte,
AttrNumber  attnum 
)

Definition at line 2072 of file parse_relation.c.

References RangeTblEntry::alias, Alias::aliasname, Alias::colnames, elog, RangeTblEntry::eref, ERROR, get_relid_attribute_name(), InvalidAttrNumber, list_length(), list_nth(), RangeTblEntry::relid, RTE_RELATION, RangeTblEntry::rtekind, and strVal.

Referenced by check_ungrouped_columns_walker(), get_name_for_var_field(), get_variable(), and print_expr().

{
    if (attnum == InvalidAttrNumber)
        return "*";

    /*
     * If there is a user-written column alias, use it.
     */
    if (rte->alias &&
        attnum > 0 && attnum <= list_length(rte->alias->colnames))
        return strVal(list_nth(rte->alias->colnames, attnum - 1));

    /*
     * If the RTE is a relation, go to the system catalogs not the
     * eref->colnames list.  This is a little slower but it will give the
     * right answer if the column has been renamed since the eref list was
     * built (which can easily happen for rules).
     */
    if (rte->rtekind == RTE_RELATION)
        return get_relid_attribute_name(rte->relid, attnum);

    /*
     * Otherwise use the column name from eref.  There should always be one.
     */
    if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
        return strVal(list_nth(rte->eref->colnames, attnum - 1));

    /* else caller gave us a bogus attnum */
    elog(ERROR, "invalid attnum %d for rangetable entry %s",
         attnum, rte->eref->aliasname);
    return NULL;                /* keep compiler quiet */
}

void get_rte_attribute_type ( RangeTblEntry rte,
AttrNumber  attnum,
Oid vartype,
int32 vartypmod,
Oid varcollid 
)

Definition at line 2110 of file parse_relation.c.

References Alias::aliasname, Assert, ATTNUM, tupleDesc::attrs, RangeTblEntry::ctecolcollations, RangeTblEntry::ctecoltypes, RangeTblEntry::ctecoltypmods, elog, RangeTblEntry::eref, ereport, errcode(), errmsg(), ERROR, TargetEntry::expr, exprCollation(), exprType(), exprTypmod(), RangeTblEntry::funccolcollations, RangeTblEntry::funccoltypes, RangeTblEntry::funccoltypmods, RangeTblEntry::funcexpr, get_expr_result_type(), get_rel_name(), get_tle_by_resno(), GETSTRUCT, HeapTupleIsValid, Int16GetDatum, RangeTblEntry::joinaliasvars, linitial, list_length(), list_nth(), list_nth_int(), list_nth_oid(), NameStr, tupleDesc::natts, NULL, ObjectIdGetDatum, ReleaseSysCache(), RangeTblEntry::relid, TargetEntry::resjunk, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_RELATION, RTE_SUBQUERY, RTE_VALUES, RangeTblEntry::rtekind, SearchSysCache2, RangeTblEntry::subquery, Query::targetList, TYPEFUNC_COMPOSITE, TYPEFUNC_RECORD, TYPEFUNC_SCALAR, RangeTblEntry::values_collations, and RangeTblEntry::values_lists.

Referenced by make_var().

{
    switch (rte->rtekind)
    {
        case RTE_RELATION:
            {
                /* Plain relation RTE --- get the attribute's type info */
                HeapTuple   tp;
                Form_pg_attribute att_tup;

                tp = SearchSysCache2(ATTNUM,
                                     ObjectIdGetDatum(rte->relid),
                                     Int16GetDatum(attnum));
                if (!HeapTupleIsValid(tp))      /* shouldn't happen */
                    elog(ERROR, "cache lookup failed for attribute %d of relation %u",
                         attnum, rte->relid);
                att_tup = (Form_pg_attribute) GETSTRUCT(tp);

                /*
                 * If dropped column, pretend it ain't there.  See notes in
                 * scanRTEForColumn.
                 */
                if (att_tup->attisdropped)
                    ereport(ERROR,
                            (errcode(ERRCODE_UNDEFINED_COLUMN),
                    errmsg("column \"%s\" of relation \"%s\" does not exist",
                           NameStr(att_tup->attname),
                           get_rel_name(rte->relid))));
                *vartype = att_tup->atttypid;
                *vartypmod = att_tup->atttypmod;
                *varcollid = att_tup->attcollation;
                ReleaseSysCache(tp);
            }
            break;
        case RTE_SUBQUERY:
            {
                /* Subselect RTE --- get type info from subselect's tlist */
                TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
                                                   attnum);

                if (te == NULL || te->resjunk)
                    elog(ERROR, "subquery %s does not have attribute %d",
                         rte->eref->aliasname, attnum);
                *vartype = exprType((Node *) te->expr);
                *vartypmod = exprTypmod((Node *) te->expr);
                *varcollid = exprCollation((Node *) te->expr);
            }
            break;
        case RTE_FUNCTION:
            {
                /* Function RTE */
                TypeFuncClass functypclass;
                Oid         funcrettype;
                TupleDesc   tupdesc;

                functypclass = get_expr_result_type(rte->funcexpr,
                                                    &funcrettype,
                                                    &tupdesc);

                if (functypclass == TYPEFUNC_COMPOSITE)
                {
                    /* Composite data type, e.g. a table's row type */
                    Form_pg_attribute att_tup;

                    Assert(tupdesc);
                    /* this is probably a can't-happen case */
                    if (attnum < 1 || attnum > tupdesc->natts)
                        ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_COLUMN),
                        errmsg("column %d of relation \"%s\" does not exist",
                               attnum,
                               rte->eref->aliasname)));

                    att_tup = tupdesc->attrs[attnum - 1];

                    /*
                     * If dropped column, pretend it ain't there.  See notes
                     * in scanRTEForColumn.
                     */
                    if (att_tup->attisdropped)
                        ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_COLUMN),
                                 errmsg("column \"%s\" of relation \"%s\" does not exist",
                                        NameStr(att_tup->attname),
                                        rte->eref->aliasname)));
                    *vartype = att_tup->atttypid;
                    *vartypmod = att_tup->atttypmod;
                    *varcollid = att_tup->attcollation;
                }
                else if (functypclass == TYPEFUNC_SCALAR)
                {
                    /* Base data type, i.e. scalar */
                    *vartype = funcrettype;
                    *vartypmod = -1;
                    *varcollid = exprCollation(rte->funcexpr);
                }
                else if (functypclass == TYPEFUNC_RECORD)
                {
                    *vartype = list_nth_oid(rte->funccoltypes, attnum - 1);
                    *vartypmod = list_nth_int(rte->funccoltypmods, attnum - 1);
                    *varcollid = list_nth_oid(rte->funccolcollations, attnum - 1);
                }
                else
                {
                    /* addRangeTableEntryForFunction should've caught this */
                    elog(ERROR, "function in FROM has unsupported return type");
                }
            }
            break;
        case RTE_VALUES:
            {
                /* Values RTE --- get type info from first sublist */
                /* collation is stored separately, though */
                List       *collist = (List *) linitial(rte->values_lists);
                Node       *col;

                if (attnum < 1 || attnum > list_length(collist))
                    elog(ERROR, "values list %s does not have attribute %d",
                         rte->eref->aliasname, attnum);
                col = (Node *) list_nth(collist, attnum - 1);
                *vartype = exprType(col);
                *vartypmod = exprTypmod(col);
                *varcollid = list_nth_oid(rte->values_collations, attnum - 1);
            }
            break;
        case RTE_JOIN:
            {
                /*
                 * Join RTE --- get type info from join RTE's alias variable
                 */
                Node       *aliasvar;

                Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
                aliasvar = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
                *vartype = exprType(aliasvar);
                *vartypmod = exprTypmod(aliasvar);
                *varcollid = exprCollation(aliasvar);
            }
            break;
        case RTE_CTE:
            {
                /* CTE RTE --- get type info from lists in the RTE */
                Assert(attnum > 0 && attnum <= list_length(rte->ctecoltypes));
                *vartype = list_nth_oid(rte->ctecoltypes, attnum - 1);
                *vartypmod = list_nth_int(rte->ctecoltypmods, attnum - 1);
                *varcollid = list_nth_oid(rte->ctecolcollations, attnum - 1);
            }
            break;
        default:
            elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
    }
}

TargetEntry* get_tle_by_resno ( List tlist,
AttrNumber  resno 
)