Header And Logo

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

Defines | Functions

nodeFuncs.h File Reference

#include "nodes/parsenodes.h"
Include dependency graph for nodeFuncs.h:

Go to the source code of this file.

Defines

#define QTW_IGNORE_RT_SUBQUERIES   0x01
#define QTW_IGNORE_CTE_SUBQUERIES   0x02
#define QTW_IGNORE_RC_SUBQUERIES   0x03
#define QTW_IGNORE_JOINALIASES   0x04
#define QTW_IGNORE_RANGE_TABLE   0x08
#define QTW_EXAMINE_RTES   0x10
#define QTW_DONT_COPY_QUERY   0x20

Functions

Oid exprType (const Node *expr)
int32 exprTypmod (const Node *expr)
bool exprIsLengthCoercion (const Node *expr, int32 *coercedTypmod)
Noderelabel_to_typmod (Node *expr, int32 typmod)
bool expression_returns_set (Node *clause)
Oid exprCollation (const Node *expr)
Oid exprInputCollation (const Node *expr)
void exprSetCollation (Node *expr, Oid collation)
void exprSetInputCollation (Node *expr, Oid inputcollation)
int exprLocation (const Node *expr)
bool expression_tree_walker (Node *node, bool(*walker)(), void *context)
Nodeexpression_tree_mutator (Node *node, Node *(*mutator)(), void *context)
bool query_tree_walker (Query *query, bool(*walker)(), void *context, int flags)
Queryquery_tree_mutator (Query *query, Node *(*mutator)(), void *context, int flags)
bool range_table_walker (List *rtable, bool(*walker)(), void *context, int flags)
Listrange_table_mutator (List *rtable, Node *(*mutator)(), void *context, int flags)
bool query_or_expression_tree_walker (Node *node, bool(*walker)(), void *context, int flags)
Nodequery_or_expression_tree_mutator (Node *node, Node *(*mutator)(), void *context, int flags)
bool raw_expression_tree_walker (Node *node, bool(*walker)(), void *context)

Define Documentation

#define QTW_DONT_COPY_QUERY   0x20

Definition at line 26 of file nodeFuncs.h.

Referenced by query_tree_mutator().

#define QTW_EXAMINE_RTES   0x10
#define QTW_IGNORE_CTE_SUBQUERIES   0x02

Definition at line 21 of file nodeFuncs.h.

Referenced by query_tree_mutator(), and query_tree_walker().

#define QTW_IGNORE_JOINALIASES   0x04
#define QTW_IGNORE_RANGE_TABLE   0x08

Definition at line 24 of file nodeFuncs.h.

Referenced by assign_query_collations(), and query_tree_walker().

#define QTW_IGNORE_RC_SUBQUERIES   0x03
#define QTW_IGNORE_RT_SUBQUERIES   0x01

Definition at line 20 of file nodeFuncs.h.

Referenced by range_table_mutator(), and range_table_walker().


Function Documentation

Oid exprCollation ( const Node expr  ) 

Definition at line 659 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, elog, ERROR, EXPR_SUBLINK, exprCollation(), SubPlan::firstColCollation, IS_XMLSERIALIZE, IsA, linitial, nodeTag, SubPlan::subLinkType, SubLink::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SubLink, T_SubPlan, T_Var, T_WindowFunc, T_XmlExpr, and Query::targetList.

Referenced by analyzeCTE(), analyzeCTETargetList(), assign_collations_walker(), assign_nestloop_param_placeholdervar(), build_subplan(), canonicalize_ec_expression(), ComputeIndexAttrs(), convert_EXISTS_to_ANY(), DefineVirtualRelation(), eval_const_expressions_mutator(), ExecInitAgg(), ExecInitFunctionScan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprCollation(), exprSetCollation(), fix_indexqual_operand(), generate_setop_tlist(), generate_subquery_params(), get_first_col_type(), get_rte_attribute_type(), inline_function(), make_agg_subplan(), make_pathkey_from_sortop(), make_sort_from_groupcols(), make_sort_from_sortclauses(), makeVarFromTargetEntry(), makeWholeRowVar(), pg_get_indexdef_worker(), relabel_to_typmod(), replace_outer_placeholdervar(), scalararraysel(), set_dummy_tlist_references(), tlist_same_collations(), transformCaseExpr(), and transformSubLink().

{
    Oid         coll;

    if (!expr)
        return InvalidOid;

    switch (nodeTag(expr))
    {
        case T_Var:
            coll = ((const Var *) expr)->varcollid;
            break;
        case T_Const:
            coll = ((const Const *) expr)->constcollid;
            break;
        case T_Param:
            coll = ((const Param *) expr)->paramcollid;
            break;
        case T_Aggref:
            coll = ((const Aggref *) expr)->aggcollid;
            break;
        case T_WindowFunc:
            coll = ((const WindowFunc *) expr)->wincollid;
            break;
        case T_ArrayRef:
            coll = ((const ArrayRef *) expr)->refcollid;
            break;
        case T_FuncExpr:
            coll = ((const FuncExpr *) expr)->funccollid;
            break;
        case T_NamedArgExpr:
            coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
            break;
        case T_OpExpr:
            coll = ((const OpExpr *) expr)->opcollid;
            break;
        case T_DistinctExpr:
            coll = ((const DistinctExpr *) expr)->opcollid;
            break;
        case T_NullIfExpr:
            coll = ((const NullIfExpr *) expr)->opcollid;
            break;
        case T_ScalarArrayOpExpr:
            coll = InvalidOid;  /* result is always boolean */
            break;
        case T_BoolExpr:
            coll = InvalidOid;  /* result is always boolean */
            break;
        case T_SubLink:
            {
                const SubLink *sublink = (const SubLink *) expr;

                if (sublink->subLinkType == EXPR_SUBLINK ||
                    sublink->subLinkType == ARRAY_SUBLINK)
                {
                    /* get the collation of subselect's first target column */
                    Query      *qtree = (Query *) sublink->subselect;
                    TargetEntry *tent;

                    if (!qtree || !IsA(qtree, Query))
                        elog(ERROR, "cannot get collation for untransformed sublink");
                    tent = (TargetEntry *) linitial(qtree->targetList);
                    Assert(IsA(tent, TargetEntry));
                    Assert(!tent->resjunk);
                    coll = exprCollation((Node *) tent->expr);
                    /* collation doesn't change if it's converted to array */
                }
                else
                {
                    /* for all other sublink types, result is boolean */
                    coll = InvalidOid;
                }
            }
            break;
        case T_SubPlan:
            {
                const SubPlan *subplan = (const SubPlan *) expr;

                if (subplan->subLinkType == EXPR_SUBLINK ||
                    subplan->subLinkType == ARRAY_SUBLINK)
                {
                    /* get the collation of subselect's first target column */
                    coll = subplan->firstColCollation;
                    /* collation doesn't change if it's converted to array */
                }
                else
                {
                    /* for all other subplan types, result is boolean */
                    coll = InvalidOid;
                }
            }
            break;
        case T_AlternativeSubPlan:
            {
                const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;

                /* subplans should all return the same thing */
                coll = exprCollation((Node *) linitial(asplan->subplans));
            }
            break;
        case T_FieldSelect:
            coll = ((const FieldSelect *) expr)->resultcollid;
            break;
        case T_FieldStore:
            coll = InvalidOid;  /* result is always composite */
            break;
        case T_RelabelType:
            coll = ((const RelabelType *) expr)->resultcollid;
            break;
        case T_CoerceViaIO:
            coll = ((const CoerceViaIO *) expr)->resultcollid;
            break;
        case T_ArrayCoerceExpr:
            coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
            break;
        case T_ConvertRowtypeExpr:
            coll = InvalidOid;  /* result is always composite */
            break;
        case T_CollateExpr:
            coll = ((const CollateExpr *) expr)->collOid;
            break;
        case T_CaseExpr:
            coll = ((const CaseExpr *) expr)->casecollid;
            break;
        case T_CaseTestExpr:
            coll = ((const CaseTestExpr *) expr)->collation;
            break;
        case T_ArrayExpr:
            coll = ((const ArrayExpr *) expr)->array_collid;
            break;
        case T_RowExpr:
            coll = InvalidOid;  /* result is always composite */
            break;
        case T_RowCompareExpr:
            coll = InvalidOid;  /* result is always boolean */
            break;
        case T_CoalesceExpr:
            coll = ((const CoalesceExpr *) expr)->coalescecollid;
            break;
        case T_MinMaxExpr:
            coll = ((const MinMaxExpr *) expr)->minmaxcollid;
            break;
        case T_XmlExpr:

            /*
             * XMLSERIALIZE returns text from non-collatable inputs, so its
             * collation is always default.  The other cases return boolean or
             * XML, which are non-collatable.
             */
            if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
                coll = DEFAULT_COLLATION_OID;
            else
                coll = InvalidOid;
            break;
        case T_NullTest:
            coll = InvalidOid;  /* result is always boolean */
            break;
        case T_BooleanTest:
            coll = InvalidOid;  /* result is always boolean */
            break;
        case T_CoerceToDomain:
            coll = ((const CoerceToDomain *) expr)->resultcollid;
            break;
        case T_CoerceToDomainValue:
            coll = ((const CoerceToDomainValue *) expr)->collation;
            break;
        case T_SetToDefault:
            coll = ((const SetToDefault *) expr)->collation;
            break;
        case T_CurrentOfExpr:
            coll = InvalidOid;  /* result is always boolean */
            break;
        case T_PlaceHolderVar:
            coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
            break;
        default:
            elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
            coll = InvalidOid;  /* keep compiler quiet */
            break;
    }
    return coll;
}

bool expression_returns_set ( Node clause  ) 
Node* expression_tree_mutator ( Node node,
Node *(*)()  mutator,
void *  context 
)

Definition at line 2012 of file nodeFuncs.c.

References Aggref::aggdistinct, Aggref::aggorder, CoerceToDomain::arg, BooleanTest::arg, NullTest::arg, CaseExpr::arg, CollateExpr::arg, ConvertRowtypeExpr::arg, ArrayCoerceExpr::arg, CoerceViaIO::arg, RelabelType::arg, FieldStore::arg, FieldSelect::arg, NamedArgExpr::arg, XmlExpr::args, MinMaxExpr::args, CoalesceExpr::args, RowExpr::args, CaseExpr::args, SubPlan::args, BoolExpr::args, ScalarArrayOpExpr::args, OpExpr::args, FuncExpr::args, WindowFunc::args, Aggref::args, check_stack_depth(), copyObject(), CommonTableExpr::ctequery, CaseExpr::defresult, ArrayExpr::elements, elog, WindowClause::endOffset, ERROR, TargetEntry::expr, CaseWhen::expr, FieldStore::fieldnums, FLATCOPY, FromExpr::fromlist, lappend(), SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, list_copy(), MUTATE, XmlExpr::named_args, FieldStore::newvals, nodeTag, NULL, WindowClause::orderClause, WindowClause::partitionClause, PlaceHolderInfo::ph_var, PlaceHolderVar::phexpr, JoinExpr::quals, FromExpr::quals, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, ArrayRef::refassgnexpr, ArrayRef::refexpr, ArrayRef::reflowerindexpr, ArrayRef::refupperindexpr, CaseWhen::result, WindowClause::startOffset, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CaseWhen, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SubLink, T_SubPlan, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_XmlExpr, SubPlan::testexpr, SubLink::testexpr, and AppendRelInfo::translated_vars.

Referenced by adjust_appendrel_attrs_mutator(), convert_testexpr_mutator(), eval_const_expressions_mutator(), fix_join_expr_mutator(), fix_scan_expr_mutator(), fix_upper_expr_mutator(), flatten_join_alias_vars_mutator(), map_variable_attnos_mutator(), process_sublinks_mutator(), replace_aggs_with_params_mutator(), replace_correlation_vars_mutator(), replace_nestloop_params_mutator(), replace_rte_variables_mutator(), simplify_function(), substitute_actual_parameters_mutator(), and substitute_actual_srf_parameters_mutator().

{
    /*
     * The mutator has already decided not to modify the current node, but we
     * must call the mutator for any sub-nodes.
     */

#define FLATCOPY(newnode, node, nodetype)  \
    ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
      memcpy((newnode), (node), sizeof(nodetype)) )

#define CHECKFLATCOPY(newnode, node, nodetype)  \
    ( AssertMacro(IsA((node), nodetype)), \
      (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
      memcpy((newnode), (node), sizeof(nodetype)) )

#define MUTATE(newfield, oldfield, fieldtype)  \
        ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )

    if (node == NULL)
        return NULL;

    /* Guard against stack overflow due to overly complex expressions */
    check_stack_depth();

    switch (nodeTag(node))
    {
            /*
             * Primitive node types with no expression subnodes.  Var and
             * Const are frequent enough to deserve special cases, the others
             * we just use copyObject for.
             */
        case T_Var:
            {
                Var        *var = (Var *) node;
                Var        *newnode;

                FLATCOPY(newnode, var, Var);
                return (Node *) newnode;
            }
            break;
        case T_Const:
            {
                Const      *oldnode = (Const *) node;
                Const      *newnode;

                FLATCOPY(newnode, oldnode, Const);
                /* XXX we don't bother with datumCopy; should we? */
                return (Node *) newnode;
            }
            break;
        case T_Param:
        case T_CoerceToDomainValue:
        case T_CaseTestExpr:
        case T_SetToDefault:
        case T_CurrentOfExpr:
        case T_RangeTblRef:
        case T_SortGroupClause:
            return (Node *) copyObject(node);
        case T_Aggref:
            {
                Aggref     *aggref = (Aggref *) node;
                Aggref     *newnode;

                FLATCOPY(newnode, aggref, Aggref);
                MUTATE(newnode->args, aggref->args, List *);
                MUTATE(newnode->aggorder, aggref->aggorder, List *);
                MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
                return (Node *) newnode;
            }
            break;
        case T_WindowFunc:
            {
                WindowFunc *wfunc = (WindowFunc *) node;
                WindowFunc *newnode;

                FLATCOPY(newnode, wfunc, WindowFunc);
                MUTATE(newnode->args, wfunc->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_ArrayRef:
            {
                ArrayRef   *arrayref = (ArrayRef *) node;
                ArrayRef   *newnode;

                FLATCOPY(newnode, arrayref, ArrayRef);
                MUTATE(newnode->refupperindexpr, arrayref->refupperindexpr,
                       List *);
                MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr,
                       List *);
                MUTATE(newnode->refexpr, arrayref->refexpr,
                       Expr *);
                MUTATE(newnode->refassgnexpr, arrayref->refassgnexpr,
                       Expr *);
                return (Node *) newnode;
            }
            break;
        case T_FuncExpr:
            {
                FuncExpr   *expr = (FuncExpr *) node;
                FuncExpr   *newnode;

                FLATCOPY(newnode, expr, FuncExpr);
                MUTATE(newnode->args, expr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_NamedArgExpr:
            {
                NamedArgExpr *nexpr = (NamedArgExpr *) node;
                NamedArgExpr *newnode;

                FLATCOPY(newnode, nexpr, NamedArgExpr);
                MUTATE(newnode->arg, nexpr->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_OpExpr:
            {
                OpExpr     *expr = (OpExpr *) node;
                OpExpr     *newnode;

                FLATCOPY(newnode, expr, OpExpr);
                MUTATE(newnode->args, expr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_DistinctExpr:
            {
                DistinctExpr *expr = (DistinctExpr *) node;
                DistinctExpr *newnode;

                FLATCOPY(newnode, expr, DistinctExpr);
                MUTATE(newnode->args, expr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_NullIfExpr:
            {
                NullIfExpr *expr = (NullIfExpr *) node;
                NullIfExpr *newnode;

                FLATCOPY(newnode, expr, NullIfExpr);
                MUTATE(newnode->args, expr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_ScalarArrayOpExpr:
            {
                ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
                ScalarArrayOpExpr *newnode;

                FLATCOPY(newnode, expr, ScalarArrayOpExpr);
                MUTATE(newnode->args, expr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_BoolExpr:
            {
                BoolExpr   *expr = (BoolExpr *) node;
                BoolExpr   *newnode;

                FLATCOPY(newnode, expr, BoolExpr);
                MUTATE(newnode->args, expr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_SubLink:
            {
                SubLink    *sublink = (SubLink *) node;
                SubLink    *newnode;

                FLATCOPY(newnode, sublink, SubLink);
                MUTATE(newnode->testexpr, sublink->testexpr, Node *);

                /*
                 * Also invoke the mutator on the sublink's Query node, so it
                 * can recurse into the sub-query if it wants to.
                 */
                MUTATE(newnode->subselect, sublink->subselect, Node *);
                return (Node *) newnode;
            }
            break;
        case T_SubPlan:
            {
                SubPlan    *subplan = (SubPlan *) node;
                SubPlan    *newnode;

                FLATCOPY(newnode, subplan, SubPlan);
                /* transform testexpr */
                MUTATE(newnode->testexpr, subplan->testexpr, Node *);
                /* transform args list (params to be passed to subplan) */
                MUTATE(newnode->args, subplan->args, List *);
                /* but not the sub-Plan itself, which is referenced as-is */
                return (Node *) newnode;
            }
            break;
        case T_AlternativeSubPlan:
            {
                AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
                AlternativeSubPlan *newnode;

                FLATCOPY(newnode, asplan, AlternativeSubPlan);
                MUTATE(newnode->subplans, asplan->subplans, List *);
                return (Node *) newnode;
            }
            break;
        case T_FieldSelect:
            {
                FieldSelect *fselect = (FieldSelect *) node;
                FieldSelect *newnode;

                FLATCOPY(newnode, fselect, FieldSelect);
                MUTATE(newnode->arg, fselect->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_FieldStore:
            {
                FieldStore *fstore = (FieldStore *) node;
                FieldStore *newnode;

                FLATCOPY(newnode, fstore, FieldStore);
                MUTATE(newnode->arg, fstore->arg, Expr *);
                MUTATE(newnode->newvals, fstore->newvals, List *);
                newnode->fieldnums = list_copy(fstore->fieldnums);
                return (Node *) newnode;
            }
            break;
        case T_RelabelType:
            {
                RelabelType *relabel = (RelabelType *) node;
                RelabelType *newnode;

                FLATCOPY(newnode, relabel, RelabelType);
                MUTATE(newnode->arg, relabel->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_CoerceViaIO:
            {
                CoerceViaIO *iocoerce = (CoerceViaIO *) node;
                CoerceViaIO *newnode;

                FLATCOPY(newnode, iocoerce, CoerceViaIO);
                MUTATE(newnode->arg, iocoerce->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_ArrayCoerceExpr:
            {
                ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
                ArrayCoerceExpr *newnode;

                FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
                MUTATE(newnode->arg, acoerce->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_ConvertRowtypeExpr:
            {
                ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
                ConvertRowtypeExpr *newnode;

                FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
                MUTATE(newnode->arg, convexpr->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_CollateExpr:
            {
                CollateExpr *collate = (CollateExpr *) node;
                CollateExpr *newnode;

                FLATCOPY(newnode, collate, CollateExpr);
                MUTATE(newnode->arg, collate->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_CaseExpr:
            {
                CaseExpr   *caseexpr = (CaseExpr *) node;
                CaseExpr   *newnode;

                FLATCOPY(newnode, caseexpr, CaseExpr);
                MUTATE(newnode->arg, caseexpr->arg, Expr *);
                MUTATE(newnode->args, caseexpr->args, List *);
                MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_CaseWhen:
            {
                CaseWhen   *casewhen = (CaseWhen *) node;
                CaseWhen   *newnode;

                FLATCOPY(newnode, casewhen, CaseWhen);
                MUTATE(newnode->expr, casewhen->expr, Expr *);
                MUTATE(newnode->result, casewhen->result, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_ArrayExpr:
            {
                ArrayExpr  *arrayexpr = (ArrayExpr *) node;
                ArrayExpr  *newnode;

                FLATCOPY(newnode, arrayexpr, ArrayExpr);
                MUTATE(newnode->elements, arrayexpr->elements, List *);
                return (Node *) newnode;
            }
            break;
        case T_RowExpr:
            {
                RowExpr    *rowexpr = (RowExpr *) node;
                RowExpr    *newnode;

                FLATCOPY(newnode, rowexpr, RowExpr);
                MUTATE(newnode->args, rowexpr->args, List *);
                /* Assume colnames needn't be duplicated */
                return (Node *) newnode;
            }
            break;
        case T_RowCompareExpr:
            {
                RowCompareExpr *rcexpr = (RowCompareExpr *) node;
                RowCompareExpr *newnode;

                FLATCOPY(newnode, rcexpr, RowCompareExpr);
                MUTATE(newnode->largs, rcexpr->largs, List *);
                MUTATE(newnode->rargs, rcexpr->rargs, List *);
                return (Node *) newnode;
            }
            break;
        case T_CoalesceExpr:
            {
                CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
                CoalesceExpr *newnode;

                FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
                MUTATE(newnode->args, coalesceexpr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_MinMaxExpr:
            {
                MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
                MinMaxExpr *newnode;

                FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
                MUTATE(newnode->args, minmaxexpr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_XmlExpr:
            {
                XmlExpr    *xexpr = (XmlExpr *) node;
                XmlExpr    *newnode;

                FLATCOPY(newnode, xexpr, XmlExpr);
                MUTATE(newnode->named_args, xexpr->named_args, List *);
                /* assume mutator does not care about arg_names */
                MUTATE(newnode->args, xexpr->args, List *);
                return (Node *) newnode;
            }
            break;
        case T_NullTest:
            {
                NullTest   *ntest = (NullTest *) node;
                NullTest   *newnode;

                FLATCOPY(newnode, ntest, NullTest);
                MUTATE(newnode->arg, ntest->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_BooleanTest:
            {
                BooleanTest *btest = (BooleanTest *) node;
                BooleanTest *newnode;

                FLATCOPY(newnode, btest, BooleanTest);
                MUTATE(newnode->arg, btest->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_CoerceToDomain:
            {
                CoerceToDomain *ctest = (CoerceToDomain *) node;
                CoerceToDomain *newnode;

                FLATCOPY(newnode, ctest, CoerceToDomain);
                MUTATE(newnode->arg, ctest->arg, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_TargetEntry:
            {
                TargetEntry *targetentry = (TargetEntry *) node;
                TargetEntry *newnode;

                FLATCOPY(newnode, targetentry, TargetEntry);
                MUTATE(newnode->expr, targetentry->expr, Expr *);
                return (Node *) newnode;
            }
            break;
        case T_Query:
            /* Do nothing with a sub-Query, per discussion above */
            return node;
        case T_WindowClause:
            {
                WindowClause *wc = (WindowClause *) node;
                WindowClause *newnode;

                FLATCOPY(newnode, wc, WindowClause);
                MUTATE(newnode->partitionClause, wc->partitionClause, List *);
                MUTATE(newnode->orderClause, wc->orderClause, List *);
                MUTATE(newnode->startOffset, wc->startOffset, Node *);
                MUTATE(newnode->endOffset, wc->endOffset, Node *);
                return (Node *) newnode;
            }
            break;
        case T_CommonTableExpr:
            {
                CommonTableExpr *cte = (CommonTableExpr *) node;
                CommonTableExpr *newnode;

                FLATCOPY(newnode, cte, CommonTableExpr);

                /*
                 * Also invoke the mutator on the CTE's Query node, so it can
                 * recurse into the sub-query if it wants to.
                 */
                MUTATE(newnode->ctequery, cte->ctequery, Node *);
                return (Node *) newnode;
            }
            break;
        case T_List:
            {
                /*
                 * We assume the mutator isn't interested in the list nodes
                 * per se, so just invoke it on each list element. NOTE: this
                 * would fail badly on a list with integer elements!
                 */
                List       *resultlist;
                ListCell   *temp;

                resultlist = NIL;
                foreach(temp, (List *) node)
                {
                    resultlist = lappend(resultlist,
                                         mutator((Node *) lfirst(temp),
                                                 context));
                }
                return (Node *) resultlist;
            }
            break;
        case T_FromExpr:
            {
                FromExpr   *from = (FromExpr *) node;
                FromExpr   *newnode;

                FLATCOPY(newnode, from, FromExpr);
                MUTATE(newnode->fromlist, from->fromlist, List *);
                MUTATE(newnode->quals, from->quals, Node *);
                return (Node *) newnode;
            }
            break;
        case T_JoinExpr:
            {
                JoinExpr   *join = (JoinExpr *) node;
                JoinExpr   *newnode;

                FLATCOPY(newnode, join, JoinExpr);
                MUTATE(newnode->larg, join->larg, Node *);
                MUTATE(newnode->rarg, join->rarg, Node *);
                MUTATE(newnode->quals, join->quals, Node *);
                /* We do not mutate alias or using by default */
                return (Node *) newnode;
            }
            break;
        case T_SetOperationStmt:
            {
                SetOperationStmt *setop = (SetOperationStmt *) node;
                SetOperationStmt *newnode;

                FLATCOPY(newnode, setop, SetOperationStmt);
                MUTATE(newnode->larg, setop->larg, Node *);
                MUTATE(newnode->rarg, setop->rarg, Node *);
                /* We do not mutate groupClauses by default */
                return (Node *) newnode;
            }
            break;
        case T_PlaceHolderVar:
            {
                PlaceHolderVar *phv = (PlaceHolderVar *) node;
                PlaceHolderVar *newnode;

                FLATCOPY(newnode, phv, PlaceHolderVar);
                MUTATE(newnode->phexpr, phv->phexpr, Expr *);
                /* Assume we need not copy the relids bitmapset */
                return (Node *) newnode;
            }
            break;
        case T_AppendRelInfo:
            {
                AppendRelInfo *appinfo = (AppendRelInfo *) node;
                AppendRelInfo *newnode;

                FLATCOPY(newnode, appinfo, AppendRelInfo);
                MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
                return (Node *) newnode;
            }
            break;
        case T_PlaceHolderInfo:
            {
                PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
                PlaceHolderInfo *newnode;

                FLATCOPY(newnode, phinfo, PlaceHolderInfo);
                MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
                /* Assume we need not copy the relids bitmapsets */
                return (Node *) newnode;
            }
            break;
        default:
            elog(ERROR, "unrecognized node type: %d",
                 (int) nodeTag(node));
            break;
    }
    /* can't get here, but keep compiler happy */
    return NULL;
}

bool expression_tree_walker ( Node node,
bool(*)()  walker,
void *  context 
)

Definition at line 1526 of file nodeFuncs.c.

References Aggref::aggdistinct, Aggref::aggorder, CaseExpr::arg, FieldStore::arg, arg, XmlExpr::args, CaseExpr::args, SubPlan::args, BoolExpr::args, ScalarArrayOpExpr::args, OpExpr::args, FuncExpr::args, WindowFunc::args, Aggref::args, Assert, check_stack_depth(), CommonTableExpr::ctequery, CaseExpr::defresult, elog, WindowClause::endOffset, ERROR, CaseWhen::expr, expression_tree_walker(), FromExpr::fromlist, IsA, SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, XmlExpr::named_args, FieldStore::newvals, nodeTag, NULL, WindowClause::orderClause, WindowClause::partitionClause, JoinExpr::quals, FromExpr::quals, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, ArrayRef::refassgnexpr, ArrayRef::refexpr, ArrayRef::reflowerindexpr, ArrayRef::refupperindexpr, CaseWhen::result, WindowClause::startOffset, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SubLink, T_SubPlan, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_XmlExpr, SubPlan::testexpr, SubLink::testexpr, and AppendRelInfo::translated_vars.

Referenced by acquireLocksOnSubLinks(), assign_collations_walker(), attribute_used_walker(), ChangeVarNodes_walker(), check_agg_arguments(), check_agg_arguments_walker(), check_parameter_resolution_walker(), check_ungrouped_columns_walker(), checkExprHasSubLink_walker(), contain_agg_clause_walker(), contain_aggs_of_level_walker(), contain_leaky_functions_walker(), contain_mutable_functions_walker(), contain_nonstrict_functions_walker(), contain_subplans_walker(), contain_var_clause_walker(), contain_vars_of_level_walker(), contain_volatile_functions_walker(), contain_windowfuncs_walker(), cost_qual_eval_walker(), count_agg_clauses_walker(), expression_returns_set_rows_walker(), expression_returns_set_walker(), expression_tree_walker(), extract_query_dependencies_walker(), finalize_primnode(), find_expr_references_walker(), find_minmax_aggs_walker(), find_unaggregated_cols_walker(), find_window_functions_walker(), fireRIRonSubLink(), fix_opfuncids_walker(), fix_scan_expr_walker(), get_last_attnums(), IncrementVarSublevelsUp_walker(), isQueryUsingTempRelation_walker(), locate_agg_of_level_walker(), locate_var_of_level_walker(), locate_windowfunc_walker(), OffsetVarNodes_walker(), pull_var_clause_walker(), pull_varattnos_walker(), pull_varnos_walker(), pull_vars_walker(), query_contains_extern_params_walker(), rangeTableEntry_used_walker(), ScanQueryWalker(), setRuleCheckAsUser_walker(), and substitute_multiple_relids_walker().

{
    ListCell   *temp;

    /*
     * The walker has already visited the current node, and so we need only
     * recurse into any sub-nodes it has.
     *
     * We assume that the walker is not interested in List nodes per se, so
     * when we expect a List we just recurse directly to self without
     * bothering to call the walker.
     */
    if (node == NULL)
        return false;

    /* Guard against stack overflow due to overly complex expressions */
    check_stack_depth();

    switch (nodeTag(node))
    {
        case T_Var:
        case T_Const:
        case T_Param:
        case T_CoerceToDomainValue:
        case T_CaseTestExpr:
        case T_SetToDefault:
        case T_CurrentOfExpr:
        case T_RangeTblRef:
        case T_SortGroupClause:
            /* primitive node types with no expression subnodes */
            break;
        case T_Aggref:
            {
                Aggref     *expr = (Aggref *) node;

                /* recurse directly on List */
                if (expression_tree_walker((Node *) expr->args,
                                           walker, context))
                    return true;
                if (expression_tree_walker((Node *) expr->aggorder,
                                           walker, context))
                    return true;
                if (expression_tree_walker((Node *) expr->aggdistinct,
                                           walker, context))
                    return true;
            }
            break;
        case T_WindowFunc:
            {
                WindowFunc *expr = (WindowFunc *) node;

                /* recurse directly on List */
                if (expression_tree_walker((Node *) expr->args,
                                           walker, context))
                    return true;
            }
            break;
        case T_ArrayRef:
            {
                ArrayRef   *aref = (ArrayRef *) node;

                /* recurse directly for upper/lower array index lists */
                if (expression_tree_walker((Node *) aref->refupperindexpr,
                                           walker, context))
                    return true;
                if (expression_tree_walker((Node *) aref->reflowerindexpr,
                                           walker, context))
                    return true;
                /* walker must see the refexpr and refassgnexpr, however */
                if (walker(aref->refexpr, context))
                    return true;
                if (walker(aref->refassgnexpr, context))
                    return true;
            }
            break;
        case T_FuncExpr:
            {
                FuncExpr   *expr = (FuncExpr *) node;

                if (expression_tree_walker((Node *) expr->args,
                                           walker, context))
                    return true;
            }
            break;
        case T_NamedArgExpr:
            return walker(((NamedArgExpr *) node)->arg, context);
        case T_OpExpr:
        case T_DistinctExpr:    /* struct-equivalent to OpExpr */
        case T_NullIfExpr:      /* struct-equivalent to OpExpr */
            {
                OpExpr     *expr = (OpExpr *) node;

                if (expression_tree_walker((Node *) expr->args,
                                           walker, context))
                    return true;
            }
            break;
        case T_ScalarArrayOpExpr:
            {
                ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;

                if (expression_tree_walker((Node *) expr->args,
                                           walker, context))
                    return true;
            }
            break;
        case T_BoolExpr:
            {
                BoolExpr   *expr = (BoolExpr *) node;

                if (expression_tree_walker((Node *) expr->args,
                                           walker, context))
                    return true;
            }
            break;
        case T_SubLink:
            {
                SubLink    *sublink = (SubLink *) node;

                if (walker(sublink->testexpr, context))
                    return true;

                /*
                 * Also invoke the walker on the sublink's Query node, so it
                 * can recurse into the sub-query if it wants to.
                 */
                return walker(sublink->subselect, context);
            }
            break;
        case T_SubPlan:
            {
                SubPlan    *subplan = (SubPlan *) node;

                /* recurse into the testexpr, but not into the Plan */
                if (walker(subplan->testexpr, context))
                    return true;
                /* also examine args list */
                if (expression_tree_walker((Node *) subplan->args,
                                           walker, context))
                    return true;
            }
            break;
        case T_AlternativeSubPlan:
            return walker(((AlternativeSubPlan *) node)->subplans, context);
        case T_FieldSelect:
            return walker(((FieldSelect *) node)->arg, context);
        case T_FieldStore:
            {
                FieldStore *fstore = (FieldStore *) node;

                if (walker(fstore->arg, context))
                    return true;
                if (walker(fstore->newvals, context))
                    return true;
            }
            break;
        case T_RelabelType:
            return walker(((RelabelType *) node)->arg, context);
        case T_CoerceViaIO:
            return walker(((CoerceViaIO *) node)->arg, context);
        case T_ArrayCoerceExpr:
            return walker(((ArrayCoerceExpr *) node)->arg, context);
        case T_ConvertRowtypeExpr:
            return walker(((ConvertRowtypeExpr *) node)->arg, context);
        case T_CollateExpr:
            return walker(((CollateExpr *) node)->arg, context);
        case T_CaseExpr:
            {
                CaseExpr   *caseexpr = (CaseExpr *) node;

                if (walker(caseexpr->arg, context))
                    return true;
                /* we assume walker doesn't care about CaseWhens, either */
                foreach(temp, caseexpr->args)
                {
                    CaseWhen   *when = (CaseWhen *) lfirst(temp);

                    Assert(IsA(when, CaseWhen));
                    if (walker(when->expr, context))
                        return true;
                    if (walker(when->result, context))
                        return true;
                }
                if (walker(caseexpr->defresult, context))
                    return true;
            }
            break;
        case T_ArrayExpr:
            return walker(((ArrayExpr *) node)->elements, context);
        case T_RowExpr:
            /* Assume colnames isn't interesting */
            return walker(((RowExpr *) node)->args, context);
        case T_RowCompareExpr:
            {
                RowCompareExpr *rcexpr = (RowCompareExpr *) node;

                if (walker(rcexpr->largs, context))
                    return true;
                if (walker(rcexpr->rargs, context))
                    return true;
            }
            break;
        case T_CoalesceExpr:
            return walker(((CoalesceExpr *) node)->args, context);
        case T_MinMaxExpr:
            return walker(((MinMaxExpr *) node)->args, context);
        case T_XmlExpr:
            {
                XmlExpr    *xexpr = (XmlExpr *) node;

                if (walker(xexpr->named_args, context))
                    return true;
                /* we assume walker doesn't care about arg_names */
                if (walker(xexpr->args, context))
                    return true;
            }
            break;
        case T_NullTest:
            return walker(((NullTest *) node)->arg, context);
        case T_BooleanTest:
            return walker(((BooleanTest *) node)->arg, context);
        case T_CoerceToDomain:
            return walker(((CoerceToDomain *) node)->arg, context);
        case T_TargetEntry:
            return walker(((TargetEntry *) node)->expr, context);
        case T_Query:
            /* Do nothing with a sub-Query, per discussion above */
            break;
        case T_WindowClause:
            {
                WindowClause *wc = (WindowClause *) node;

                if (walker(wc->partitionClause, context))
                    return true;
                if (walker(wc->orderClause, context))
                    return true;
                if (walker(wc->startOffset, context))
                    return true;
                if (walker(wc->endOffset, context))
                    return true;
            }
            break;
        case T_CommonTableExpr:
            {
                CommonTableExpr *cte = (CommonTableExpr *) node;

                /*
                 * Invoke the walker on the CTE's Query node, so it can
                 * recurse into the sub-query if it wants to.
                 */
                return walker(cte->ctequery, context);
            }
            break;
        case T_List:
            foreach(temp, (List *) node)
            {
                if (walker((Node *) lfirst(temp), context))
                    return true;
            }
            break;
        case T_FromExpr:
            {
                FromExpr   *from = (FromExpr *) node;

                if (walker(from->fromlist, context))
                    return true;
                if (walker(from->quals, context))
                    return true;
            }
            break;
        case T_JoinExpr:
            {
                JoinExpr   *join = (JoinExpr *) node;

                if (walker(join->larg, context))
                    return true;
                if (walker(join->rarg, context))
                    return true;
                if (walker(join->quals, context))
                    return true;

                /*
                 * alias clause, using list are deemed uninteresting.
                 */
            }
            break;
        case T_SetOperationStmt:
            {
                SetOperationStmt *setop = (SetOperationStmt *) node;

                if (walker(setop->larg, context))
                    return true;
                if (walker(setop->rarg, context))
                    return true;

                /* groupClauses are deemed uninteresting */
            }
            break;
        case T_PlaceHolderVar:
            return walker(((PlaceHolderVar *) node)->phexpr, context);
        case T_AppendRelInfo:
            {
                AppendRelInfo *appinfo = (AppendRelInfo *) node;

                if (expression_tree_walker((Node *) appinfo->translated_vars,
                                           walker, context))
                    return true;
            }
            break;
        case T_PlaceHolderInfo:
            return walker(((PlaceHolderInfo *) node)->ph_var, context);
        default:
            elog(ERROR, "unrecognized node type: %d",
                 (int) nodeTag(node));
            break;
    }
    return false;
}

Oid exprInputCollation ( const Node expr  ) 

Definition at line 849 of file nodeFuncs.c.

References nodeTag, T_Aggref, T_DistinctExpr, T_FuncExpr, T_MinMaxExpr, T_NullIfExpr, T_OpExpr, T_ScalarArrayOpExpr, and T_WindowFunc.

Referenced by resolve_polymorphic_tupdesc().

{
    Oid         coll;

    if (!expr)
        return InvalidOid;

    switch (nodeTag(expr))
    {
        case T_Aggref:
            coll = ((const Aggref *) expr)->inputcollid;
            break;
        case T_WindowFunc:
            coll = ((const WindowFunc *) expr)->inputcollid;
            break;
        case T_FuncExpr:
            coll = ((const FuncExpr *) expr)->inputcollid;
            break;
        case T_OpExpr:
            coll = ((const OpExpr *) expr)->inputcollid;
            break;
        case T_DistinctExpr:
            coll = ((const DistinctExpr *) expr)->inputcollid;
            break;
        case T_NullIfExpr:
            coll = ((const NullIfExpr *) expr)->inputcollid;
            break;
        case T_ScalarArrayOpExpr:
            coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
            break;
        case T_MinMaxExpr:
            coll = ((const MinMaxExpr *) expr)->inputcollid;
            break;
        default:
            coll = InvalidOid;
            break;
    }
    return coll;
}

bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 485 of file nodeFuncs.c.

References FuncExpr::args, COERCE_EXPLICIT_CAST, COERCE_IMPLICIT_CAST, Const::constisnull, Const::consttype, Const::constvalue, DatumGetInt32, FuncExpr::funcformat, INT4OID, IsA, list_length(), lsecond, NULL, and ArrayCoerceExpr::resulttypmod.

Referenced by coerce_type(), deparseFuncExpr(), exprTypmod(), and get_func_expr().

{
    if (coercedTypmod != NULL)
        *coercedTypmod = -1;    /* default result on failure */

    /*
     * Scalar-type length coercions are FuncExprs, array-type length coercions
     * are ArrayCoerceExprs
     */
    if (expr && IsA(expr, FuncExpr))
    {
        const FuncExpr *func = (const FuncExpr *) expr;
        int         nargs;
        Const      *second_arg;

        /*
         * If it didn't come from a coercion context, reject.
         */
        if (func->funcformat != COERCE_EXPLICIT_CAST &&
            func->funcformat != COERCE_IMPLICIT_CAST)
            return false;

        /*
         * If it's not a two-argument or three-argument function with the
         * second argument being an int4 constant, it can't have been created
         * from a length coercion (it must be a type coercion, instead).
         */
        nargs = list_length(func->args);
        if (nargs < 2 || nargs > 3)
            return false;

        second_arg = (Const *) lsecond(func->args);
        if (!IsA(second_arg, Const) ||
            second_arg->consttype != INT4OID ||
            second_arg->constisnull)
            return false;

        /*
         * OK, it is indeed a length-coercion function.
         */
        if (coercedTypmod != NULL)
            *coercedTypmod = DatumGetInt32(second_arg->constvalue);

        return true;
    }

    if (expr && IsA(expr, ArrayCoerceExpr))
    {
        const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;

        /* It's not a length coercion unless there's a nondefault typmod */
        if (acoerce->resulttypmod < 0)
            return false;

        /*
         * OK, it is indeed a length-coercion expression.
         */
        if (coercedTypmod != NULL)
            *coercedTypmod = acoerce->resulttypmod;

        return true;
    }

    return false;
}

int exprLocation ( const Node expr  ) 

Definition at line 1105 of file nodeFuncs.c.

References TypeCast::arg, CoerceToDomain::arg, ConvertRowtypeExpr::arg, ArrayCoerceExpr::arg, CoerceViaIO::arg, RelabelType::arg, arg, NamedArgExpr::arg, FuncCall::args, XmlExpr::args, BoolExpr::args, ScalarArrayOpExpr::args, OpExpr::args, FuncExpr::args, exprLocation(), fc(), leftmostLoc(), A_Expr::lexpr, lfirst, TypeCast::location, TypeName::location, FuncCall::location, A_Expr::location, CoerceToDomain::location, XmlExpr::location, ConvertRowtypeExpr::location, ArrayCoerceExpr::location, CoerceViaIO::location, RelabelType::location, SubLink::location, BoolExpr::location, ScalarArrayOpExpr::location, OpExpr::location, NamedArgExpr::location, FuncExpr::location, nodeTag, NULL, T_A_ArrayExpr, T_A_Const, T_A_Expr, T_Aggref, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseWhen, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateClause, T_CollateExpr, T_ColumnRef, T_CommonTableExpr, T_Const, T_Constraint, T_ConvertRowtypeExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncCall, T_FuncExpr, T_IntoClause, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_ParamRef, T_PlaceHolderVar, T_RangeVar, T_RelabelType, T_ResTarget, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SortBy, T_SubLink, T_TargetEntry, T_TypeCast, T_TypeName, T_Var, T_WindowDef, T_WindowFunc, T_WithClause, T_XmlExpr, T_XmlSerialize, SubLink::testexpr, and TypeCast::typeName.

Referenced by addRangeTableEntryForFunction(), addTargetToSortList(), analyzeCTE(), assign_collations_walker(), checkWellFormedRecursion(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type(), exprLocation(), get_matching_location(), ParseFuncOrColumn(), parser_coercion_errposition(), select_common_type(), transformAExprOf(), transformAggregateCall(), transformArrayExpr(), transformArraySubscripts(), transformAssignedExpr(), transformDistinctClause(), transformDistinctOnClause(), transformGroupClause(), transformIndirection(), transformInsertRow(), transformInsertStmt(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), and transformValuesClause().

{
    int         loc;

    if (expr == NULL)
        return -1;
    switch (nodeTag(expr))
    {
        case T_RangeVar:
            loc = ((const RangeVar *) expr)->location;
            break;
        case T_Var:
            loc = ((const Var *) expr)->location;
            break;
        case T_Const:
            loc = ((const Const *) expr)->location;
            break;
        case T_Param:
            loc = ((const Param *) expr)->location;
            break;
        case T_Aggref:
            /* function name should always be the first thing */
            loc = ((const Aggref *) expr)->location;
            break;
        case T_WindowFunc:
            /* function name should always be the first thing */
            loc = ((const WindowFunc *) expr)->location;
            break;
        case T_ArrayRef:
            /* just use array argument's location */
            loc = exprLocation((Node *) ((const ArrayRef *) expr)->refexpr);
            break;
        case T_FuncExpr:
            {
                const FuncExpr *fexpr = (const FuncExpr *) expr;

                /* consider both function name and leftmost arg */
                loc = leftmostLoc(fexpr->location,
                                  exprLocation((Node *) fexpr->args));
            }
            break;
        case T_NamedArgExpr:
            {
                const NamedArgExpr *na = (const NamedArgExpr *) expr;

                /* consider both argument name and value */
                loc = leftmostLoc(na->location,
                                  exprLocation((Node *) na->arg));
            }
            break;
        case T_OpExpr:
        case T_DistinctExpr:    /* struct-equivalent to OpExpr */
        case T_NullIfExpr:      /* struct-equivalent to OpExpr */
            {
                const OpExpr *opexpr = (const OpExpr *) expr;

                /* consider both operator name and leftmost arg */
                loc = leftmostLoc(opexpr->location,
                                  exprLocation((Node *) opexpr->args));
            }
            break;
        case T_ScalarArrayOpExpr:
            {
                const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;

                /* consider both operator name and leftmost arg */
                loc = leftmostLoc(saopexpr->location,
                                  exprLocation((Node *) saopexpr->args));
            }
            break;
        case T_BoolExpr:
            {
                const BoolExpr *bexpr = (const BoolExpr *) expr;

                /*
                 * Same as above, to handle either NOT or AND/OR.  We can't
                 * special-case NOT because of the way that it's used for
                 * things like IS NOT BETWEEN.
                 */
                loc = leftmostLoc(bexpr->location,
                                  exprLocation((Node *) bexpr->args));
            }
            break;
        case T_SubLink:
            {
                const SubLink *sublink = (const SubLink *) expr;

                /* check the testexpr, if any, and the operator/keyword */
                loc = leftmostLoc(exprLocation(sublink->testexpr),
                                  sublink->location);
            }
            break;
        case T_FieldSelect:
            /* just use argument's location */
            loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
            break;
        case T_FieldStore:
            /* just use argument's location */
            loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
            break;
        case T_RelabelType:
            {
                const RelabelType *rexpr = (const RelabelType *) expr;

                /* Much as above */
                loc = leftmostLoc(rexpr->location,
                                  exprLocation((Node *) rexpr->arg));
            }
            break;
        case T_CoerceViaIO:
            {
                const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;

                /* Much as above */
                loc = leftmostLoc(cexpr->location,
                                  exprLocation((Node *) cexpr->arg));
            }
            break;
        case T_ArrayCoerceExpr:
            {
                const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;

                /* Much as above */
                loc = leftmostLoc(cexpr->location,
                                  exprLocation((Node *) cexpr->arg));
            }
            break;
        case T_ConvertRowtypeExpr:
            {
                const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;

                /* Much as above */
                loc = leftmostLoc(cexpr->location,
                                  exprLocation((Node *) cexpr->arg));
            }
            break;
        case T_CollateExpr:
            /* just use argument's location */
            loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
            break;
        case T_CaseExpr:
            /* CASE keyword should always be the first thing */
            loc = ((const CaseExpr *) expr)->location;
            break;
        case T_CaseWhen:
            /* WHEN keyword should always be the first thing */
            loc = ((const CaseWhen *) expr)->location;
            break;
        case T_ArrayExpr:
            /* the location points at ARRAY or [, which must be leftmost */
            loc = ((const ArrayExpr *) expr)->location;
            break;
        case T_RowExpr:
            /* the location points at ROW or (, which must be leftmost */
            loc = ((const RowExpr *) expr)->location;
            break;
        case T_RowCompareExpr:
            /* just use leftmost argument's location */
            loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
            break;
        case T_CoalesceExpr:
            /* COALESCE keyword should always be the first thing */
            loc = ((const CoalesceExpr *) expr)->location;
            break;
        case T_MinMaxExpr:
            /* GREATEST/LEAST keyword should always be the first thing */
            loc = ((const MinMaxExpr *) expr)->location;
            break;
        case T_XmlExpr:
            {
                const XmlExpr *xexpr = (const XmlExpr *) expr;

                /* consider both function name and leftmost arg */
                loc = leftmostLoc(xexpr->location,
                                  exprLocation((Node *) xexpr->args));
            }
            break;
        case T_NullTest:
            /* just use argument's location */
            loc = exprLocation((Node *) ((const NullTest *) expr)->arg);
            break;
        case T_BooleanTest:
            /* just use argument's location */
            loc = exprLocation((Node *) ((const BooleanTest *) expr)->arg);
            break;
        case T_CoerceToDomain:
            {
                const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;

                /* Much as above */
                loc = leftmostLoc(cexpr->location,
                                  exprLocation((Node *) cexpr->arg));
            }
            break;
        case T_CoerceToDomainValue:
            loc = ((const CoerceToDomainValue *) expr)->location;
            break;
        case T_SetToDefault:
            loc = ((const SetToDefault *) expr)->location;
            break;
        case T_TargetEntry:
            /* just use argument's location */
            loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
            break;
        case T_IntoClause:
            /* use the contained RangeVar's location --- close enough */
            loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
            break;
        case T_List:
            {
                /* report location of first list member that has a location */
                ListCell   *lc;

                loc = -1;       /* just to suppress compiler warning */
                foreach(lc, (const List *) expr)
                {
                    loc = exprLocation((Node *) lfirst(lc));
                    if (loc >= 0)
                        break;
                }
            }
            break;
        case T_A_Expr:
            {
                const A_Expr *aexpr = (const A_Expr *) expr;

                /* use leftmost of operator or left operand (if any) */
                /* we assume right operand can't be to left of operator */
                loc = leftmostLoc(aexpr->location,
                                  exprLocation(aexpr->lexpr));
            }
            break;
        case T_ColumnRef:
            loc = ((const ColumnRef *) expr)->location;
            break;
        case T_ParamRef:
            loc = ((const ParamRef *) expr)->location;
            break;
        case T_A_Const:
            loc = ((const A_Const *) expr)->location;
            break;
        case T_FuncCall:
            {
                const FuncCall *fc = (const FuncCall *) expr;

                /* consider both function name and leftmost arg */
                /* (we assume any ORDER BY nodes must be to right of name) */
                loc = leftmostLoc(fc->location,
                                  exprLocation((Node *) fc->args));
            }
            break;
        case T_A_ArrayExpr:
            /* the location points at ARRAY or [, which must be leftmost */
            loc = ((const A_ArrayExpr *) expr)->location;
            break;
        case T_ResTarget:
            /* we need not examine the contained expression (if any) */
            loc = ((const ResTarget *) expr)->location;
            break;
        case T_TypeCast:
            {
                const TypeCast *tc = (const TypeCast *) expr;

                /*
                 * This could represent CAST(), ::, or TypeName 'literal', so
                 * any of the components might be leftmost.
                 */
                loc = exprLocation(tc->arg);
                loc = leftmostLoc(loc, tc->typeName->location);
                loc = leftmostLoc(loc, tc->location);
            }
            break;
        case T_CollateClause:
            /* just use argument's location */
            loc = exprLocation(((const CollateClause *) expr)->arg);
            break;
        case T_SortBy:
            /* just use argument's location (ignore operator, if any) */
            loc = exprLocation(((const SortBy *) expr)->node);
            break;
        case T_WindowDef:
            loc = ((const WindowDef *) expr)->location;
            break;
        case T_TypeName:
            loc = ((const TypeName *) expr)->location;
            break;
        case T_Constraint:
            loc = ((const Constraint *) expr)->location;
            break;
        case T_XmlSerialize:
            /* XMLSERIALIZE keyword should always be the first thing */
            loc = ((const XmlSerialize *) expr)->location;
            break;
        case T_WithClause:
            loc = ((const WithClause *) expr)->location;
            break;
        case T_CommonTableExpr:
            loc = ((const CommonTableExpr *) expr)->location;
            break;
        case T_PlaceHolderVar:
            /* just use argument's location */
            loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
            break;
        default:
            /* for any other node type it's just unknown... */
            loc = -1;
            break;
    }
    return loc;
}

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 897 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, DEFAULT_COLLATION_OID, elog, ERROR, EXPR_SUBLINK, exprCollation(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial, nodeTag, OidIsValid, SubLink::subLinkType, SubLink::subselect, T_Aggref, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SubLink, T_Var, T_WindowFunc, T_XmlExpr, and Query::targetList.

Referenced by assign_collations_walker().

{
    switch (nodeTag(expr))
    {
        case T_Var:
            ((Var *) expr)->varcollid = collation;
            break;
        case T_Const:
            ((Const *) expr)->constcollid = collation;
            break;
        case T_Param:
            ((Param *) expr)->paramcollid = collation;
            break;
        case T_Aggref:
            ((Aggref *) expr)->aggcollid = collation;
            break;
        case T_WindowFunc:
            ((WindowFunc *) expr)->wincollid = collation;
            break;
        case T_ArrayRef:
            ((ArrayRef *) expr)->refcollid = collation;
            break;
        case T_FuncExpr:
            ((FuncExpr *) expr)->funccollid = collation;
            break;
        case T_NamedArgExpr:
            Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
            break;
        case T_OpExpr:
            ((OpExpr *) expr)->opcollid = collation;
            break;
        case T_DistinctExpr:
            ((DistinctExpr *) expr)->opcollid = collation;
            break;
        case T_NullIfExpr:
            ((NullIfExpr *) expr)->opcollid = collation;
            break;
        case T_ScalarArrayOpExpr:
            Assert(!OidIsValid(collation));     /* result is always boolean */
            break;
        case T_BoolExpr:
            Assert(!OidIsValid(collation));     /* result is always boolean */
            break;
        case T_SubLink:
#ifdef USE_ASSERT_CHECKING
            {
                SubLink    *sublink = (SubLink *) expr;

                if (sublink->subLinkType == EXPR_SUBLINK ||
                    sublink->subLinkType == ARRAY_SUBLINK)
                {
                    /* get the collation of subselect's first target column */
                    Query      *qtree = (Query *) sublink->subselect;
                    TargetEntry *tent;

                    if (!qtree || !IsA(qtree, Query))
                        elog(ERROR, "cannot set collation for untransformed sublink");
                    tent = (TargetEntry *) linitial(qtree->targetList);
                    Assert(IsA(tent, TargetEntry));
                    Assert(!tent->resjunk);
                    Assert(collation == exprCollation((Node *) tent->expr));
                }
                else
                {
                    /* for all other sublink types, result is boolean */
                    Assert(!OidIsValid(collation));
                }
            }
#endif   /* USE_ASSERT_CHECKING */
            break;
        case T_FieldSelect:
            ((FieldSelect *) expr)->resultcollid = collation;
            break;
        case T_FieldStore:
            Assert(!OidIsValid(collation));     /* result is always composite */
            break;
        case T_RelabelType:
            ((RelabelType *) expr)->resultcollid = collation;
            break;
        case T_CoerceViaIO:
            ((CoerceViaIO *) expr)->resultcollid = collation;
            break;
        case T_ArrayCoerceExpr:
            ((ArrayCoerceExpr *) expr)->resultcollid = collation;
            break;
        case T_ConvertRowtypeExpr:
            Assert(!OidIsValid(collation));     /* result is always composite */
            break;
        case T_CaseExpr:
            ((CaseExpr *) expr)->casecollid = collation;
            break;
        case T_ArrayExpr:
            ((ArrayExpr *) expr)->array_collid = collation;
            break;
        case T_RowExpr:
            Assert(!OidIsValid(collation));     /* result is always composite */
            break;
        case T_RowCompareExpr:
            Assert(!OidIsValid(collation));     /* result is always boolean */
            break;
        case T_CoalesceExpr:
            ((CoalesceExpr *) expr)->coalescecollid = collation;
            break;
        case T_MinMaxExpr:
            ((MinMaxExpr *) expr)->minmaxcollid = collation;
            break;
        case T_XmlExpr:
            Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
                   (collation == DEFAULT_COLLATION_OID) :
                   (collation == InvalidOid));
            break;
        case T_NullTest:
            Assert(!OidIsValid(collation));     /* result is always boolean */
            break;
        case T_BooleanTest:
            Assert(!OidIsValid(collation));     /* result is always boolean */
            break;
        case T_CoerceToDomain:
            ((CoerceToDomain *) expr)->resultcollid = collation;
            break;
        case T_CoerceToDomainValue:
            ((CoerceToDomainValue *) expr)->collation = collation;
            break;
        case T_SetToDefault:
            ((SetToDefault *) expr)->collation = collation;
            break;
        case T_CurrentOfExpr:
            Assert(!OidIsValid(collation));     /* result is always boolean */
            break;
        default:
            elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
            break;
    }
}

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1041 of file nodeFuncs.c.

References nodeTag, T_Aggref, T_DistinctExpr, T_FuncExpr, T_MinMaxExpr, T_NullIfExpr, T_OpExpr, T_ScalarArrayOpExpr, and T_WindowFunc.

Referenced by assign_collations_walker().

{
    switch (nodeTag(expr))
    {
        case T_Aggref:
            ((Aggref *) expr)->inputcollid = inputcollation;
            break;
        case T_WindowFunc:
            ((WindowFunc *) expr)->inputcollid = inputcollation;
            break;
        case T_FuncExpr:
            ((FuncExpr *) expr)->inputcollid = inputcollation;
            break;
        case T_OpExpr:
            ((OpExpr *) expr)->inputcollid = inputcollation;
            break;
        case T_DistinctExpr:
            ((DistinctExpr *) expr)->inputcollid = inputcollation;
            break;
        case T_NullIfExpr:
            ((NullIfExpr *) expr)->inputcollid = inputcollation;
            break;
        case T_ScalarArrayOpExpr:
            ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
            break;
        case T_MinMaxExpr:
            ((MinMaxExpr *) expr)->inputcollid = inputcollation;
            break;
        default:
            break;
    }
}

Oid exprType ( const Node expr  ) 

Definition at line 36 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, elog, ereport, errcode(), errmsg(), ERROR, EXPR_SUBLINK, exprType(), SubPlan::firstColType, format_type_be(), get_array_type(), IS_DOCUMENT, IS_XMLSERIALIZE, IsA, linitial, nodeTag, OidIsValid, ArrayRef::refarraytype, ArrayRef::refassgnexpr, ArrayRef::refelemtype, ArrayRef::reflowerindexpr, SubPlan::subLinkType, SubLink::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SubLink, T_SubPlan, T_Var, T_WindowFunc, T_XmlExpr, and Query::targetList.

Referenced by addTargetToGroupList(), addTargetToSortList(), analyzeCTE(), analyzeCTETargetList(), assign_collations_walker(), assign_nestloop_param_placeholdervar(), ATExecAlterColumnType(), ATPrepAlterColumnType(), build_column_default(), build_subplan(), canonicalize_ec_expression(), check_hashjoinable(), check_mergejoinable(), check_sql_fn_retval(), checkRuleResultList(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type(), compare_tlist_datatypes(), ComputeIndexAttrs(), ConstructTupleDescriptor(), contain_leaky_functions_walker(), contain_mutable_functions_walker(), contain_volatile_functions_walker(), convert_EXISTS_to_ANY(), cookDefault(), cost_qual_eval_walker(), count_agg_clauses_walker(), create_unique_path(), DefineVirtualRelation(), estimate_num_groups(), eval_const_expressions_mutator(), EvaluateParams(), examine_attribute(), examine_variable(), exec_simple_recheck_plan(), ExecCheckPlanOutput(), ExecEvalConvertRowtype(), ExecEvalXml(), ExecInitAgg(), ExecInitExpr(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), ExecWindowAgg(), expandRecordVariable(), ExpandRowReference(), expandRTE(), exprType(), exprTypmod(), find_minmax_aggs_walker(), find_placeholder_info(), fix_indexqual_operand(), foreign_expr_walker(), generate_append_tlist(), generate_join_implied_equalities_normal(), generate_setop_tlist(), generate_subquery_params(), generateClonedIndexStmt(), get_agg_expr(), get_call_expr_argtype(), get_expr_result_type(), get_first_col_type(), get_fn_expr_rettype(), get_func_expr(), get_name_for_var_field(), get_oper_expr(), get_rte_attribute_is_dropped(), get_rte_attribute_type(), get_rule_expr(), get_rule_orderby(), get_simple_binary_op_name(), get_sublink_expr(), get_windowfunc_expr(), hash_ok_operator(), initialize_peragg(), inline_function(), internal_get_result_type(), IsTidEqualClause(), make_agg_subplan(), make_op(), make_scalar_array_op(), makeVarFromTargetEntry(), makeWholeRowVar(), ParseFuncOrColumn(), pg_get_indexdef_worker(), postgresBeginForeignScan(), ProcedureCreate(), process_equivalence(), process_matched_tle(), recheck_cast_function_args(), relabel_to_typmod(), replace_outer_placeholdervar(), scalararraysel(), select_common_type(), set_append_rel_size(), set_dummy_tlist_references(), set_rel_width(), tlist_matches_coltypelist(), tlist_same_datatypes(), transformAExprNullIf(), transformAExprOf(), transformAggregateCall(), transformArrayExpr(), transformArraySubscripts(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCollateClause(), transformExprRecurse(), transformIndirection(), transformInsertStmt(), transformSetOperationTree(), transformSubLink(), transformTypeCast(), unknown_attribute(), and xmlelement().

{
    Oid         type;

    if (!expr)
        return InvalidOid;

    switch (nodeTag(expr))
    {
        case T_Var:
            type = ((const Var *) expr)->vartype;
            break;
        case T_Const:
            type = ((const Const *) expr)->consttype;
            break;
        case T_Param:
            type = ((const Param *) expr)->paramtype;
            break;
        case T_Aggref:
            type = ((const Aggref *) expr)->aggtype;
            break;
        case T_WindowFunc:
            type = ((const WindowFunc *) expr)->wintype;
            break;
        case T_ArrayRef:
            {
                const ArrayRef *arrayref = (const ArrayRef *) expr;

                /* slice and/or store operations yield the array type */
                if (arrayref->reflowerindexpr || arrayref->refassgnexpr)
                    type = arrayref->refarraytype;
                else
                    type = arrayref->refelemtype;
            }
            break;
        case T_FuncExpr:
            type = ((const FuncExpr *) expr)->funcresulttype;
            break;
        case T_NamedArgExpr:
            type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
            break;
        case T_OpExpr:
            type = ((const OpExpr *) expr)->opresulttype;
            break;
        case T_DistinctExpr:
            type = ((const DistinctExpr *) expr)->opresulttype;
            break;
        case T_NullIfExpr:
            type = ((const NullIfExpr *) expr)->opresulttype;
            break;
        case T_ScalarArrayOpExpr:
            type = BOOLOID;
            break;
        case T_BoolExpr:
            type = BOOLOID;
            break;
        case T_SubLink:
            {
                const SubLink *sublink = (const SubLink *) expr;

                if (sublink->subLinkType == EXPR_SUBLINK ||
                    sublink->subLinkType == ARRAY_SUBLINK)
                {
                    /* get the type of the subselect's first target column */
                    Query      *qtree = (Query *) sublink->subselect;
                    TargetEntry *tent;

                    if (!qtree || !IsA(qtree, Query))
                        elog(ERROR, "cannot get type for untransformed sublink");
                    tent = (TargetEntry *) linitial(qtree->targetList);
                    Assert(IsA(tent, TargetEntry));
                    Assert(!tent->resjunk);
                    type = exprType((Node *) tent->expr);
                    if (sublink->subLinkType == ARRAY_SUBLINK)
                    {
                        type = get_array_type(type);
                        if (!OidIsValid(type))
                            ereport(ERROR,
                                    (errcode(ERRCODE_UNDEFINED_OBJECT),
                                     errmsg("could not find array type for data type %s",
                            format_type_be(exprType((Node *) tent->expr)))));
                    }
                }
                else
                {
                    /* for all other sublink types, result is boolean */
                    type = BOOLOID;
                }
            }
            break;
        case T_SubPlan:
            {
                const SubPlan *subplan = (const SubPlan *) expr;

                if (subplan->subLinkType == EXPR_SUBLINK ||
                    subplan->subLinkType == ARRAY_SUBLINK)
                {
                    /* get the type of the subselect's first target column */
                    type = subplan->firstColType;
                    if (subplan->subLinkType == ARRAY_SUBLINK)
                    {
                        type = get_array_type(type);
                        if (!OidIsValid(type))
                            ereport(ERROR,
                                    (errcode(ERRCODE_UNDEFINED_OBJECT),
                                     errmsg("could not find array type for data type %s",
                                    format_type_be(subplan->firstColType))));
                    }
                }
                else
                {
                    /* for all other subplan types, result is boolean */
                    type = BOOLOID;
                }
            }
            break;
        case T_AlternativeSubPlan:
            {
                const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;

                /* subplans should all return the same thing */
                type = exprType((Node *) linitial(asplan->subplans));
            }
            break;
        case T_FieldSelect:
            type = ((const FieldSelect *) expr)->resulttype;
            break;
        case T_FieldStore:
            type = ((const FieldStore *) expr)->resulttype;
            break;
        case T_RelabelType:
            type = ((const RelabelType *) expr)->resulttype;
            break;
        case T_CoerceViaIO:
            type = ((const CoerceViaIO *) expr)->resulttype;
            break;
        case T_ArrayCoerceExpr:
            type = ((const ArrayCoerceExpr *) expr)->resulttype;
            break;
        case T_ConvertRowtypeExpr:
            type = ((const ConvertRowtypeExpr *) expr)->resulttype;
            break;
        case T_CollateExpr:
            type = exprType((Node *) ((const CollateExpr *) expr)->arg);
            break;
        case T_CaseExpr:
            type = ((const CaseExpr *) expr)->casetype;
            break;
        case T_CaseTestExpr:
            type = ((const CaseTestExpr *) expr)->typeId;
            break;
        case T_ArrayExpr:
            type = ((const ArrayExpr *) expr)->array_typeid;
            break;
        case T_RowExpr:
            type = ((const RowExpr *) expr)->row_typeid;
            break;
        case T_RowCompareExpr:
            type = BOOLOID;
            break;
        case T_CoalesceExpr:
            type = ((const CoalesceExpr *) expr)->coalescetype;
            break;
        case T_MinMaxExpr:
            type = ((const MinMaxExpr *) expr)->minmaxtype;
            break;
        case T_XmlExpr:
            if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
                type = BOOLOID;
            else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
                type = TEXTOID;
            else
                type = XMLOID;
            break;
        case T_NullTest:
            type = BOOLOID;
            break;
        case T_BooleanTest:
            type = BOOLOID;
            break;
        case T_CoerceToDomain:
            type = ((const CoerceToDomain *) expr)->resulttype;
            break;
        case T_CoerceToDomainValue:
            type = ((const CoerceToDomainValue *) expr)->typeId;
            break;
        case T_SetToDefault:
            type = ((const SetToDefault *) expr)->typeId;
            break;
        case T_CurrentOfExpr:
            type = BOOLOID;
            break;
        case T_PlaceHolderVar:
            type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
            break;
        default:
            elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
            type = InvalidOid;  /* keep compiler quiet */
            break;
    }
    return type;
}

int32 exprTypmod ( const Node expr  ) 

Definition at line 245 of file nodeFuncs.c.

References arg, MinMaxExpr::args, CoalesceExpr::args, CaseExpr::args, OpExpr::args, ARRAY_SUBLINK, ArrayExpr::array_typeid, Assert, CaseExpr::casetype, CoalesceExpr::coalescetype, CaseExpr::defresult, ArrayExpr::element_typeid, ArrayExpr::elements, elog, ERROR, EXPR_SUBLINK, exprIsLengthCoercion(), exprType(), exprTypmod(), SubPlan::firstColTypmod, for_each_cell, IsA, lfirst, linitial, list_head(), lnext, MinMaxExpr::minmaxtype, ArrayExpr::multidims, NIL, nodeTag, CaseWhen::result, SubPlan::subLinkType, SubLink::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CollateExpr, T_Const, T_FieldSelect, T_FuncExpr, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_SetToDefault, T_SubLink, T_SubPlan, T_Var, and Query::targetList.

Referenced by analyzeCTE(), analyzeCTETargetList(), assign_nestloop_param_placeholdervar(), build_subplan(), canonicalize_ec_expression(), checkRuleResultList(), coerce_type_typmod(), convert_EXISTS_to_ANY(), count_agg_clauses_walker(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_variable(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), ExpandRowReference(), expandRTE(), exprTypmod(), find_placeholder_info(), generate_append_tlist(), generate_setop_tlist(), generate_subquery_params(), get_first_col_type(), get_name_for_var_field(), get_rte_attribute_type(), interval_transform(), makeVarFromTargetEntry(), numeric_transform(), replace_outer_placeholdervar(), set_append_rel_size(), set_dummy_tlist_references(), set_rel_width(), TemporalTransform(), transformCaseExpr(), transformIndirection(), transformSetOperationTree(), transformSubLink(), varbit_transform(), and varchar_transform().

{
    if (!expr)
        return -1;

    switch (nodeTag(expr))
    {
        case T_Var:
            return ((const Var *) expr)->vartypmod;
        case T_Const:
            return ((const Const *) expr)->consttypmod;
        case T_Param:
            return ((const Param *) expr)->paramtypmod;
        case T_ArrayRef:
            /* typmod is the same for array or element */
            return ((const ArrayRef *) expr)->reftypmod;
        case T_FuncExpr:
            {
                int32       coercedTypmod;

                /* Be smart about length-coercion functions... */
                if (exprIsLengthCoercion(expr, &coercedTypmod))
                    return coercedTypmod;
            }
            break;
        case T_NamedArgExpr:
            return exprTypmod((Node *) ((const NamedArgExpr *) expr)->arg);
        case T_NullIfExpr:
            {
                /*
                 * Result is either first argument or NULL, so we can report
                 * first argument's typmod if known.
                 */
                const NullIfExpr *nexpr = (const NullIfExpr *) expr;

                return exprTypmod((Node *) linitial(nexpr->args));
            }
            break;
        case T_SubLink:
            {
                const SubLink *sublink = (const SubLink *) expr;

                if (sublink->subLinkType == EXPR_SUBLINK ||
                    sublink->subLinkType == ARRAY_SUBLINK)
                {
                    /* get the typmod of the subselect's first target column */
                    Query      *qtree = (Query *) sublink->subselect;
                    TargetEntry *tent;

                    if (!qtree || !IsA(qtree, Query))
                        elog(ERROR, "cannot get type for untransformed sublink");
                    tent = (TargetEntry *) linitial(qtree->targetList);
                    Assert(IsA(tent, TargetEntry));
                    Assert(!tent->resjunk);
                    return exprTypmod((Node *) tent->expr);
                    /* note we don't need to care if it's an array */
                }
            }
            break;
        case T_SubPlan:
            {
                const SubPlan *subplan = (const SubPlan *) expr;

                if (subplan->subLinkType == EXPR_SUBLINK ||
                    subplan->subLinkType == ARRAY_SUBLINK)
                {
                    /* get the typmod of the subselect's first target column */
                    /* note we don't need to care if it's an array */
                    return subplan->firstColTypmod;
                }
                else
                {
                    /* for all other subplan types, result is boolean */
                    return -1;
                }
            }
            break;
        case T_AlternativeSubPlan:
            {
                const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;

                /* subplans should all return the same thing */
                return exprTypmod((Node *) linitial(asplan->subplans));
            }
            break;
        case T_FieldSelect:
            return ((const FieldSelect *) expr)->resulttypmod;
        case T_RelabelType:
            return ((const RelabelType *) expr)->resulttypmod;
        case T_ArrayCoerceExpr:
            return ((const ArrayCoerceExpr *) expr)->resulttypmod;
        case T_CollateExpr:
            return exprTypmod((Node *) ((const CollateExpr *) expr)->arg);
        case T_CaseExpr:
            {
                /*
                 * If all the alternatives agree on type/typmod, return that
                 * typmod, else use -1
                 */
                const CaseExpr *cexpr = (const CaseExpr *) expr;
                Oid         casetype = cexpr->casetype;
                int32       typmod;
                ListCell   *arg;

                if (!cexpr->defresult)
                    return -1;
                if (exprType((Node *) cexpr->defresult) != casetype)
                    return -1;
                typmod = exprTypmod((Node *) cexpr->defresult);
                if (typmod < 0)
                    return -1;  /* no point in trying harder */
                foreach(arg, cexpr->args)
                {
                    CaseWhen   *w = (CaseWhen *) lfirst(arg);

                    Assert(IsA(w, CaseWhen));
                    if (exprType((Node *) w->result) != casetype)
                        return -1;
                    if (exprTypmod((Node *) w->result) != typmod)
                        return -1;
                }
                return typmod;
            }
            break;
        case T_CaseTestExpr:
            return ((const CaseTestExpr *) expr)->typeMod;
        case T_ArrayExpr:
            {
                /*
                 * If all the elements agree on type/typmod, return that
                 * typmod, else use -1
                 */
                const ArrayExpr *arrayexpr = (const ArrayExpr *) expr;
                Oid         commontype;
                int32       typmod;
                ListCell   *elem;

                if (arrayexpr->elements == NIL)
                    return -1;
                typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
                if (typmod < 0)
                    return -1;  /* no point in trying harder */
                if (arrayexpr->multidims)
                    commontype = arrayexpr->array_typeid;
                else
                    commontype = arrayexpr->element_typeid;
                foreach(elem, arrayexpr->elements)
                {
                    Node       *e = (Node *) lfirst(elem);

                    if (exprType(e) != commontype)
                        return -1;
                    if (exprTypmod(e) != typmod)
                        return -1;
                }
                return typmod;
            }
            break;
        case T_CoalesceExpr:
            {
                /*
                 * If all the alternatives agree on type/typmod, return that
                 * typmod, else use -1
                 */
                const CoalesceExpr *cexpr = (const CoalesceExpr *) expr;
                Oid         coalescetype = cexpr->coalescetype;
                int32       typmod;
                ListCell   *arg;

                if (exprType((Node *) linitial(cexpr->args)) != coalescetype)
                    return -1;
                typmod = exprTypmod((Node *) linitial(cexpr->args));
                if (typmod < 0)
                    return -1;  /* no point in trying harder */
                for_each_cell(arg, lnext(list_head(cexpr->args)))
                {
                    Node       *e = (Node *) lfirst(arg);

                    if (exprType(e) != coalescetype)
                        return -1;
                    if (exprTypmod(e) != typmod)
                        return -1;
                }
                return typmod;
            }
            break;
        case T_MinMaxExpr:
            {
                /*
                 * If all the alternatives agree on type/typmod, return that
                 * typmod, else use -1
                 */
                const MinMaxExpr *mexpr = (const MinMaxExpr *) expr;
                Oid         minmaxtype = mexpr->minmaxtype;
                int32       typmod;
                ListCell   *arg;

                if (exprType((Node *) linitial(mexpr->args)) != minmaxtype)
                    return -1;
                typmod = exprTypmod((Node *) linitial(mexpr->args));
                if (typmod < 0)
                    return -1;  /* no point in trying harder */
                for_each_cell(arg, lnext(list_head(mexpr->args)))
                {
                    Node       *e = (Node *) lfirst(arg);

                    if (exprType(e) != minmaxtype)
                        return -1;
                    if (exprTypmod(e) != typmod)
                        return -1;
                }
                return typmod;
            }
            break;
        case T_CoerceToDomain:
            return ((const CoerceToDomain *) expr)->resulttypmod;
        case T_CoerceToDomainValue:
            return ((const CoerceToDomainValue *) expr)->typeMod;
        case T_SetToDefault:
            return ((const SetToDefault *) expr)->typeMod;
        case T_PlaceHolderVar:
            return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
        default:
            break;
    }
    return -1;
}

Node* query_or_expression_tree_mutator ( Node node,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 2692 of file nodeFuncs.c.

References IsA, and query_tree_mutator().

Referenced by map_variable_attnos(), and replace_rte_variables().

{
    if (node && IsA(node, Query))
        return (Node *) query_tree_mutator((Query *) node,
                                           mutator,
                                           context,
                                           flags);
    else
        return mutator(node, context);
}

bool query_or_expression_tree_walker ( Node node,
bool(*)()  walker,
void *  context,
int  flags 
)
Query* query_tree_mutator ( Query query,
Node *(*)()  mutator,
void *  context,
int  flags 
)
bool query_tree_walker ( Query query,
bool(*)()  walker,
void *  context,
int  flags 
)

Definition at line 1863 of file nodeFuncs.c.

References Assert, Query::cteList, Query::havingQual, IsA, Query::jointree, Query::limitCount, Query::limitOffset, NULL, QTW_IGNORE_CTE_SUBQUERIES, QTW_IGNORE_RANGE_TABLE, range_table_walker(), Query::returningList, Query::rtable, Query::setOperations, and Query::targetList.

Referenced by AcquireRewriteLocks(), assign_query_collations(), attribute_used_walker(), ChangeVarNodes(), ChangeVarNodes_walker(), check_agg_arguments_walker(), check_parameter_resolution_walker(), check_ungrouped_columns_walker(), check_variable_parameters(), contain_aggs_of_level_walker(), contain_vars_of_level_walker(), extract_query_dependencies_walker(), find_expr_references_walker(), fireRIRrules(), IncrementVarSublevelsUp_walker(), isQueryUsingTempRelation_walker(), locate_agg_of_level_walker(), locate_var_of_level_walker(), OffsetVarNodes(), OffsetVarNodes_walker(), pull_varnos_walker(), pull_vars_walker(), query_contains_extern_params(), query_contains_extern_params_walker(), query_or_expression_tree_walker(), rangeTableEntry_used_walker(), ScanQueryForLocks(), setRuleCheckAsUser_Query(), and substitute_multiple_relids_walker().

{
    Assert(query != NULL && IsA(query, Query));

    if (walker((Node *) query->targetList, context))
        return true;
    if (walker((Node *) query->returningList, context))
        return true;
    if (walker((Node *) query->jointree, context))
        return true;
    if (walker(query->setOperations, context))
        return true;
    if (walker(query->havingQual, context))
        return true;
    if (walker(query->limitOffset, context))
        return true;
    if (walker(query->limitCount, context))
        return true;
    if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
    {
        if (walker((Node *) query->cteList, context))
            return true;
    }
    if (!(flags & QTW_IGNORE_RANGE_TABLE))
    {
        if (range_table_walker(query->rtable, walker, context, flags))
            return true;
    }
    return false;
}

List* range_table_mutator ( List rtable,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 2607 of file nodeFuncs.c.

References CHECKFLATCOPY, copyObject(), FLATCOPY, RangeTblEntry::funcexpr, RangeTblEntry::joinaliasvars, lappend(), lfirst, MUTATE, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_RELATION, RTE_SUBQUERY, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::subquery, and RangeTblEntry::values_lists.

Referenced by query_tree_mutator().

{
    List       *newrt = NIL;
    ListCell   *rt;

    foreach(rt, rtable)
    {
        RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
        RangeTblEntry *newrte;

        FLATCOPY(newrte, rte, RangeTblEntry);
        switch (rte->rtekind)
        {
            case RTE_RELATION:
            case RTE_CTE:
                /* we don't bother to copy eref, aliases, etc; OK? */
                break;
            case RTE_SUBQUERY:
                if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
                {
                    CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
                    MUTATE(newrte->subquery, newrte->subquery, Query *);
                }
                else
                {
                    /* else, copy RT subqueries as-is */
                    newrte->subquery = copyObject(rte->subquery);
                }
                break;
            case RTE_JOIN:
                if (!(flags & QTW_IGNORE_JOINALIASES))
                    MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
                else
                {
                    /* else, copy join aliases as-is */
                    newrte->joinaliasvars = copyObject(rte->joinaliasvars);
                }
                break;
            case RTE_FUNCTION:
                MUTATE(newrte->funcexpr, rte->funcexpr, Node *);
                break;
            case RTE_VALUES:
                MUTATE(newrte->values_lists, rte->values_lists, List *);
                break;
        }
        newrt = lappend(newrt, newrte);
    }
    return newrt;
}

bool range_table_walker ( List rtable,
bool(*)()  walker,
void *  context,
int  flags 
)

Definition at line 1903 of file nodeFuncs.c.

References RangeTblEntry::funcexpr, RangeTblEntry::joinaliasvars, lfirst, QTW_EXAMINE_RTES, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_RELATION, RTE_SUBQUERY, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::subquery, and RangeTblEntry::values_lists.

Referenced by IncrementVarSublevelsUp_rtable(), and query_tree_walker().

{
    ListCell   *rt;

    foreach(rt, rtable)
    {
        RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);

        /* For historical reasons, visiting RTEs is not the default */
        if (flags & QTW_EXAMINE_RTES)
            if (walker(rte, context))
                return true;

        switch (rte->rtekind)
        {
            case RTE_RELATION:
            case RTE_CTE:
                /* nothing to do */
                break;
            case RTE_SUBQUERY:
                if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
                    if (walker(rte->subquery, context))
                        return true;
                break;
            case RTE_JOIN:
                if (!(flags & QTW_IGNORE_JOINALIASES))
                    if (walker(rte->joinaliasvars, context))
                        return true;
                break;
            case RTE_FUNCTION:
                if (walker(rte->funcexpr, context))
                    return true;
                break;
            case RTE_VALUES:
                if (walker(rte->values_lists, context))
                    return true;
                break;
        }
    }
    return false;
}

bool raw_expression_tree_walker ( Node node,
bool(*)()  walker,
void *  context 
)

Definition at line 2721 of file nodeFuncs.c.

References FuncCall::agg_order, RangeFunction::alias, RangeSubselect::alias, JoinExpr::alias, TypeCast::arg, A_Indirection::arg, arg, CaseExpr::arg, FuncCall::args, XmlExpr::args, CaseExpr::args, TypeName::arrayBounds, Assert, check_stack_depth(), ColumnDef::collClause, InsertStmt::cols, CaseExpr::defresult, SelectStmt::distinctClause, elog, WindowDef::endOffset, ERROR, XmlSerialize::expr, CaseWhen::expr, SelectStmt::fromClause, UpdateStmt::fromClause, RangeFunction::funccallnode, SelectStmt::groupClause, SelectStmt::havingClause, ResTarget::indirection, A_Indirection::indirection, SelectStmt::intoClause, IsA, SelectStmt::larg, JoinExpr::larg, A_Expr::lexpr, lfirst, A_Indices::lidx, SelectStmt::limitCount, SelectStmt::limitOffset, SelectStmt::lockingClause, XmlExpr::named_args, nodeTag, NULL, WindowDef::orderClause, FuncCall::over, WindowDef::partitionClause, JoinExpr::quals, SelectStmt::rarg, JoinExpr::rarg, ColumnDef::raw_default, IntoClause::rel, UpdateStmt::relation, DeleteStmt::relation, InsertStmt::relation, CaseWhen::result, UpdateStmt::returningList, DeleteStmt::returningList, InsertStmt::returningList, A_Expr::rexpr, InsertStmt::selectStmt, SelectStmt::sortClause, WindowDef::startOffset, RangeSubselect::subquery, SubLink::subselect, T_A_ArrayExpr, T_A_Const, T_A_Expr, T_A_Indices, T_A_Indirection, T_A_Star, T_Alias, T_BitString, T_BooleanTest, T_CaseExpr, T_CoalesceExpr, T_CollateClause, T_ColumnDef, T_ColumnRef, T_CommonTableExpr, T_CurrentOfExpr, T_DeleteStmt, T_Float, T_FuncCall, T_InsertStmt, T_Integer, T_IntoClause, T_JoinExpr, T_List, T_LockingClause, T_MinMaxExpr, T_NamedArgExpr, T_Null, T_NullTest, T_ParamRef, T_RangeFunction, T_RangeSubselect, T_RangeVar, T_ResTarget, T_RowExpr, T_SelectStmt, T_SetToDefault, T_SortBy, T_String, T_SubLink, T_TypeCast, T_TypeName, T_UpdateStmt, T_WindowDef, T_WithClause, T_XmlExpr, T_XmlSerialize, SelectStmt::targetList, UpdateStmt::targetList, SubLink::testexpr, XmlSerialize::typeName, ColumnDef::typeName, TypeCast::typeName, TypeName::typmods, A_Indices::uidx, DeleteStmt::usingClause, ResTarget::val, SelectStmt::valuesLists, IntoClause::viewQuery, SelectStmt::whereClause, UpdateStmt::whereClause, DeleteStmt::whereClause, SelectStmt::windowClause, SelectStmt::withClause, UpdateStmt::withClause, DeleteStmt::withClause, and InsertStmt::withClause.

Referenced by checkWellFormedRecursionWalker(), checkWellFormedSelectStmt(), and makeDependencyGraphWalker().

{
    ListCell   *temp;

    /*
     * The walker has already visited the current node, and so we need only
     * recurse into any sub-nodes it has.
     */
    if (node == NULL)
        return false;

    /* Guard against stack overflow due to overly complex expressions */
    check_stack_depth();

    switch (nodeTag(node))
    {
        case T_SetToDefault:
        case T_CurrentOfExpr:
        case T_Integer:
        case T_Float:
        case T_String:
        case T_BitString:
        case T_Null:
        case T_ParamRef:
        case T_A_Const:
        case T_A_Star:
            /* primitive node types with no subnodes */
            break;
        case T_Alias:
            /* we assume the colnames list isn't interesting */
            break;
        case T_RangeVar:
            return walker(((RangeVar *) node)->alias, context);
        case T_SubLink:
            {
                SubLink    *sublink = (SubLink *) node;

                if (walker(sublink->testexpr, context))
                    return true;
                /* we assume the operName is not interesting */
                if (walker(sublink->subselect, context))
                    return true;
            }
            break;
        case T_CaseExpr:
            {
                CaseExpr   *caseexpr = (CaseExpr *) node;

                if (walker(caseexpr->arg, context))
                    return true;
                /* we assume walker doesn't care about CaseWhens, either */
                foreach(temp, caseexpr->args)
                {
                    CaseWhen   *when = (CaseWhen *) lfirst(temp);

                    Assert(IsA(when, CaseWhen));
                    if (walker(when->expr, context))
                        return true;
                    if (walker(when->result, context))
                        return true;
                }
                if (walker(caseexpr->defresult, context))
                    return true;
            }
            break;
        case T_RowExpr:
            /* Assume colnames isn't interesting */
            return walker(((RowExpr *) node)->args, context);
        case T_CoalesceExpr:
            return walker(((CoalesceExpr *) node)->args, context);
        case T_MinMaxExpr:
            return walker(((MinMaxExpr *) node)->args, context);
        case T_XmlExpr:
            {
                XmlExpr    *xexpr = (XmlExpr *) node;

                if (walker(xexpr->named_args, context))
                    return true;
                /* we assume walker doesn't care about arg_names */
                if (walker(xexpr->args, context))
                    return true;
            }
            break;
        case T_NullTest:
            return walker(((NullTest *) node)->arg, context);
        case T_BooleanTest:
            return walker(((BooleanTest *) node)->arg, context);
        case T_JoinExpr:
            {
                JoinExpr   *join = (JoinExpr *) node;

                if (walker(join->larg, context))
                    return true;
                if (walker(join->rarg, context))
                    return true;
                if (walker(join->quals, context))
                    return true;
                if (walker(join->alias, context))
                    return true;
                /* using list is deemed uninteresting */
            }
            break;
        case T_IntoClause:
            {
                IntoClause *into = (IntoClause *) node;

                if (walker(into->rel, context))
                    return true;
                /* colNames, options are deemed uninteresting */
                /* viewQuery should be null in raw parsetree, but check it */
                if (walker(into->viewQuery, context))
                    return true;
            }
            break;
        case T_List:
            foreach(temp, (List *) node)
            {
                if (walker((Node *) lfirst(temp), context))
                    return true;
            }
            break;
        case T_InsertStmt:
            {
                InsertStmt *stmt = (InsertStmt *) node;

                if (walker(stmt->relation, context))
                    return true;
                if (walker(stmt->cols, context))
                    return true;
                if (walker(stmt->selectStmt, context))
                    return true;
                if (walker(stmt->returningList, context))
                    return true;
                if (walker(stmt->withClause, context))
                    return true;
            }
            break;
        case T_DeleteStmt:
            {
                DeleteStmt *stmt = (DeleteStmt *) node;

                if (walker(stmt->relation, context))
                    return true;
                if (walker(stmt->usingClause, context))
                    return true;
                if (walker(stmt->whereClause, context))
                    return true;
                if (walker(stmt->returningList, context))
                    return true;
                if (walker(stmt->withClause, context))
                    return true;
            }
            break;
        case T_UpdateStmt:
            {
                UpdateStmt *stmt = (UpdateStmt *) node;

                if (walker(stmt->relation, context))
                    return true;
                if (walker(stmt->targetList, context))
                    return true;
                if (walker(stmt->whereClause, context))
                    return true;
                if (walker(stmt->fromClause, context))
                    return true;
                if (walker(stmt->returningList, context))
                    return true;
                if (walker(stmt->withClause, context))
                    return true;
            }
            break;
        case T_SelectStmt:
            {
                SelectStmt *stmt = (SelectStmt *) node;

                if (walker(stmt->distinctClause, context))
                    return true;
                if (walker(stmt->intoClause, context))
                    return true;
                if (walker(stmt->targetList, context))
                    return true;
                if (walker(stmt->fromClause, context))
                    return true;
                if (walker(stmt->whereClause, context))
                    return true;
                if (walker(stmt->groupClause, context))
                    return true;
                if (walker(stmt->havingClause, context))
                    return true;
                if (walker(stmt->windowClause, context))
                    return true;
                if (walker(stmt->valuesLists, context))
                    return true;
                if (walker(stmt->sortClause, context))
                    return true;
                if (walker(stmt->limitOffset, context))
                    return true;
                if (walker(stmt->limitCount, context))
                    return true;
                if (walker(stmt->lockingClause, context))
                    return true;
                if (walker(stmt->withClause, context))
                    return true;
                if (walker(stmt->larg, context))
                    return true;
                if (walker(stmt->rarg, context))
                    return true;
            }
            break;
        case T_A_Expr:
            {
                A_Expr     *expr = (A_Expr *) node;

                if (walker(expr->lexpr, context))
                    return true;
                if (walker(expr->rexpr, context))
                    return true;
                /* operator name is deemed uninteresting */
            }
            break;
        case T_ColumnRef:
            /* we assume the fields contain nothing interesting */
            break;
        case T_FuncCall:
            {
                FuncCall   *fcall = (FuncCall *) node;

                if (walker(fcall->args, context))
                    return true;
                if (walker(fcall->agg_order, context))
                    return true;
                if (walker(fcall->over, context))
                    return true;
                /* function name is deemed uninteresting */
            }
            break;
        case T_NamedArgExpr:
            return walker(((NamedArgExpr *) node)->arg, context);
        case T_A_Indices:
            {
                A_Indices  *indices = (A_Indices *) node;

                if (walker(indices->lidx, context))
                    return true;
                if (walker(indices->uidx, context))
                    return true;
            }
            break;
        case T_A_Indirection:
            {
                A_Indirection *indir = (A_Indirection *) node;

                if (walker(indir->arg, context))
                    return true;
                if (walker(indir->indirection, context))
                    return true;
            }
            break;
        case T_A_ArrayExpr:
            return walker(((A_ArrayExpr *) node)->elements, context);
        case T_ResTarget:
            {
                ResTarget  *rt = (ResTarget *) node;

                if (walker(rt->indirection, context))
                    return true;
                if (walker(rt->val, context))
                    return true;
            }
            break;
        case T_TypeCast:
            {
                TypeCast   *tc = (TypeCast *) node;

                if (walker(tc->arg, context))
                    return true;
                if (walker(tc->typeName, context))
                    return true;
            }
            break;
        case T_CollateClause:
            return walker(((CollateClause *) node)->arg, context);
        case T_SortBy:
            return walker(((SortBy *) node)->node, context);
        case T_WindowDef:
            {
                WindowDef  *wd = (WindowDef *) node;

                if (walker(wd->partitionClause, context))
                    return true;
                if (walker(wd->orderClause, context))
                    return true;
                if (walker(wd->startOffset, context))
                    return true;
                if (walker(wd->endOffset, context))
                    return true;
            }
            break;
        case T_RangeSubselect:
            {
                RangeSubselect *rs = (RangeSubselect *) node;

                if (walker(rs->subquery, context))
                    return true;
                if (walker(rs->alias, context))
                    return true;
            }
            break;
        case T_RangeFunction:
            {
                RangeFunction *rf = (RangeFunction *) node;

                if (walker(rf->funccallnode, context))
                    return true;
                if (walker(rf->alias, context))
                    return true;
            }
            break;
        case T_TypeName:
            {
                TypeName   *tn = (TypeName *) node;

                if (walker(tn->typmods, context))
                    return true;
                if (walker(tn->arrayBounds, context))
                    return true;
                /* type name itself is deemed uninteresting */
            }
            break;
        case T_ColumnDef:
            {
                ColumnDef  *coldef = (ColumnDef *) node;

                if (walker(coldef->typeName, context))
                    return true;
                if (walker(coldef->raw_default, context))
                    return true;
                if (walker(coldef->collClause, context))
                    return true;
                /* for now, constraints are ignored */
            }
            break;
        case T_LockingClause:
            return walker(((LockingClause *) node)->lockedRels, context);
        case T_XmlSerialize:
            {
                XmlSerialize *xs = (XmlSerialize *) node;

                if (walker(xs->expr, context))
                    return true;
                if (walker(xs->typeName, context))
                    return true;
            }
            break;
        case T_WithClause:
            return walker(((WithClause *) node)->ctes, context);
        case T_CommonTableExpr:
            return walker(((CommonTableExpr *) node)->ctequery, context);
        default:
            elog(ERROR, "unrecognized node type: %d",
                 (int) nodeTag(node));
            break;
    }
    return false;
}

Node* relabel_to_typmod ( Node expr,
int32  typmod 
)

Definition at line 560 of file nodeFuncs.c.

References arg, COERCE_EXPLICIT_CAST, exprCollation(), exprType(), IsA, and makeRelabelType().

Referenced by interval_transform(), numeric_transform(), TemporalTransform(), varbit_transform(), and varchar_transform().

{
    Oid         type = exprType(expr);
    Oid         coll = exprCollation(expr);

    /* Strip any existing RelabelType node(s) */
    while (expr && IsA(expr, RelabelType))
        expr = (Node *) ((RelabelType *) expr)->arg;

    /* Apply new typmod, preserving the previous exposed type and collation */
    return (Node *) makeRelabelType((Expr *) expr, type, typmod, coll,
                                    COERCE_EXPLICIT_CAST);
}