diff options
Diffstat (limited to 'src/backend/nodes')
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 36 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 28 | ||||
-rw-r--r-- | src/backend/nodes/makefuncs.c | 46 | ||||
-rw-r--r-- | src/backend/nodes/nodeFuncs.c | 24 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 34 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 26 |
6 files changed, 132 insertions, 62 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 1733da633a..e3edcf6f74 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -504,11 +504,7 @@ _copyFunctionScan(const FunctionScan *from) /* * copy remainder of node */ - COPY_NODE_FIELD(funcexpr); - COPY_NODE_FIELD(funccolnames); - COPY_NODE_FIELD(funccoltypes); - COPY_NODE_FIELD(funccoltypmods); - COPY_NODE_FIELD(funccolcollations); + COPY_NODE_FIELD(functions); COPY_SCALAR_FIELD(funcordinality); return newnode; @@ -1981,10 +1977,7 @@ _copyRangeTblEntry(const RangeTblEntry *from) COPY_SCALAR_FIELD(security_barrier); COPY_SCALAR_FIELD(jointype); COPY_NODE_FIELD(joinaliasvars); - COPY_NODE_FIELD(funcexpr); - COPY_NODE_FIELD(funccoltypes); - COPY_NODE_FIELD(funccoltypmods); - COPY_NODE_FIELD(funccolcollations); + COPY_NODE_FIELD(functions); COPY_SCALAR_FIELD(funcordinality); COPY_NODE_FIELD(values_lists); COPY_NODE_FIELD(values_collations); @@ -2007,6 +2000,22 @@ _copyRangeTblEntry(const RangeTblEntry *from) return newnode; } +static RangeTblFunction * +_copyRangeTblFunction(const RangeTblFunction *from) +{ + RangeTblFunction *newnode = makeNode(RangeTblFunction); + + COPY_NODE_FIELD(funcexpr); + COPY_SCALAR_FIELD(funccolcount); + COPY_NODE_FIELD(funccolnames); + COPY_NODE_FIELD(funccoltypes); + COPY_NODE_FIELD(funccoltypmods); + COPY_NODE_FIELD(funccolcollations); + COPY_BITMAPSET_FIELD(funcparams); + + return newnode; +} + static WithCheckOption * _copyWithCheckOption(const WithCheckOption *from) { @@ -2299,9 +2308,10 @@ _copyRangeFunction(const RangeFunction *from) { RangeFunction *newnode = makeNode(RangeFunction); - COPY_SCALAR_FIELD(ordinality); COPY_SCALAR_FIELD(lateral); - COPY_NODE_FIELD(funccallnode); + COPY_SCALAR_FIELD(ordinality); + COPY_SCALAR_FIELD(is_table); + COPY_NODE_FIELD(functions); COPY_NODE_FIELD(alias); COPY_NODE_FIELD(coldeflist); @@ -2366,6 +2376,7 @@ _copyColumnDef(const ColumnDef *from) COPY_SCALAR_FIELD(collOid); COPY_NODE_FIELD(constraints); COPY_NODE_FIELD(fdwoptions); + COPY_LOCATION_FIELD(location); return newnode; } @@ -4550,6 +4561,9 @@ copyObject(const void *from) case T_RangeTblEntry: retval = _copyRangeTblEntry(from); break; + case T_RangeTblFunction: + retval = _copyRangeTblFunction(from); + break; case T_WithCheckOption: retval = _copyWithCheckOption(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 7b29812b69..1f9b5d70f5 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -2140,9 +2140,10 @@ _equalRangeSubselect(const RangeSubselect *a, const RangeSubselect *b) static bool _equalRangeFunction(const RangeFunction *a, const RangeFunction *b) { - COMPARE_SCALAR_FIELD(ordinality); COMPARE_SCALAR_FIELD(lateral); - COMPARE_NODE_FIELD(funccallnode); + COMPARE_SCALAR_FIELD(ordinality); + COMPARE_SCALAR_FIELD(is_table); + COMPARE_NODE_FIELD(functions); COMPARE_NODE_FIELD(alias); COMPARE_NODE_FIELD(coldeflist); @@ -2179,6 +2180,7 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b) COMPARE_SCALAR_FIELD(collOid); COMPARE_NODE_FIELD(constraints); COMPARE_NODE_FIELD(fdwoptions); + COMPARE_LOCATION_FIELD(location); return true; } @@ -2245,10 +2247,7 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b) COMPARE_SCALAR_FIELD(security_barrier); COMPARE_SCALAR_FIELD(jointype); COMPARE_NODE_FIELD(joinaliasvars); - COMPARE_NODE_FIELD(funcexpr); - COMPARE_NODE_FIELD(funccoltypes); - COMPARE_NODE_FIELD(funccoltypmods); - COMPARE_NODE_FIELD(funccolcollations); + COMPARE_NODE_FIELD(functions); COMPARE_SCALAR_FIELD(funcordinality); COMPARE_NODE_FIELD(values_lists); COMPARE_NODE_FIELD(values_collations); @@ -2272,6 +2271,20 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b) } static bool +_equalRangeTblFunction(const RangeTblFunction *a, const RangeTblFunction *b) +{ + COMPARE_NODE_FIELD(funcexpr); + COMPARE_SCALAR_FIELD(funccolcount); + COMPARE_NODE_FIELD(funccolnames); + COMPARE_NODE_FIELD(funccoltypes); + COMPARE_NODE_FIELD(funccoltypmods); + COMPARE_NODE_FIELD(funccolcollations); + COMPARE_BITMAPSET_FIELD(funcparams); + + return true; +} + +static bool _equalWithCheckOption(const WithCheckOption *a, const WithCheckOption *b) { COMPARE_STRING_FIELD(viewname); @@ -3018,6 +3031,9 @@ equal(const void *a, const void *b) case T_RangeTblEntry: retval = _equalRangeTblEntry(a, b); break; + case T_RangeTblFunction: + retval = _equalRangeTblFunction(a, b); + break; case T_WithCheckOption: retval = _equalWithCheckOption(a, b); break; diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 4a7e793ae0..d3ed4fe98b 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -122,14 +122,10 @@ makeVarFromTargetEntry(Index varno, * a rowtype; either a named composite type, or RECORD. This function * encapsulates the logic for determining the correct rowtype OID to use. * - * If allowScalar is true, then for the case where the RTE is a function + * If allowScalar is true, then for the case where the RTE is a single function * returning a non-composite result type, we produce a normal Var referencing * the function's result directly, instead of the single-column composite * value that the whole-row notation might otherwise suggest. - * - * We also handle the specific case of function RTEs with ordinality, - * where the additional column has to be added. This forces the result - * to be composite and RECORD type. */ Var * makeWholeRowVar(RangeTblEntry *rte, @@ -139,6 +135,7 @@ makeWholeRowVar(RangeTblEntry *rte, { Var *result; Oid toid; + Node *fexpr; switch (rte->rtekind) { @@ -157,31 +154,27 @@ makeWholeRowVar(RangeTblEntry *rte, break; case RTE_FUNCTION: + /* - * RTE is a function with or without ordinality. We map the - * cases as follows: - * - * If ordinality is set, we return a composite var even if - * the function is a scalar. This var is always of RECORD type. - * - * If ordinality is not set but the function returns a row, - * we keep the function's return type. - * - * If the function is a scalar, we do what allowScalar requests. + * If there's more than one function, or ordinality is requested, + * force a RECORD result, since there's certainly more than one + * column involved and it can't be a known named type. */ - toid = exprType(rte->funcexpr); - - if (rte->funcordinality) + if (rte->funcordinality || list_length(rte->functions) != 1) { - /* ORDINALITY always produces an anonymous RECORD result */ + /* always produces an anonymous RECORD result */ result = makeVar(varno, InvalidAttrNumber, RECORDOID, -1, InvalidOid, varlevelsup); + break; } - else if (type_is_rowtype(toid)) + + fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr; + toid = exprType(fexpr); + if (type_is_rowtype(toid)) { /* func returns composite; same as relation case */ result = makeVar(varno, @@ -198,7 +191,7 @@ makeWholeRowVar(RangeTblEntry *rte, 1, toid, -1, - exprCollation(rte->funcexpr), + exprCollation(fexpr), varlevelsup); } else @@ -214,6 +207,7 @@ makeWholeRowVar(RangeTblEntry *rte, break; default: + /* * RTE is a join, subselect, or VALUES. We represent this as a * whole-row Var of RECORD type. (Note that in most cases the Var @@ -541,23 +535,21 @@ makeDefElemExtended(char *nameSpace, char *name, Node *arg, * makeFuncCall - * * Initialize a FuncCall struct with the information every caller must - * supply. Any non-default parameters have to be handled by the - * caller. - * + * supply. Any non-default parameters have to be inserted by the caller. */ - FuncCall * makeFuncCall(List *name, List *args, int location) { - FuncCall *n = makeNode(FuncCall); + FuncCall *n = makeNode(FuncCall); + n->funcname = name; n->args = args; - n->location = location; n->agg_order = NIL; n->agg_filter = NULL; n->agg_star = FALSE; n->agg_distinct = FALSE; n->func_variadic = FALSE; n->over = NULL; + n->location = location; return n; } diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 908f397d50..d7db67dc9e 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -1447,6 +1447,9 @@ exprLocation(const Node *expr) case T_TypeName: loc = ((const TypeName *) expr)->location; break; + case T_ColumnDef: + loc = ((const ColumnDef *) expr)->location; + break; case T_Constraint: loc = ((const Constraint *) expr)->location; break; @@ -1901,6 +1904,8 @@ expression_tree_walker(Node *node, break; case T_PlaceHolderInfo: return walker(((PlaceHolderInfo *) node)->ph_var, context); + case T_RangeTblFunction: + return walker(((RangeTblFunction *) node)->funcexpr, context); default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); @@ -2000,7 +2005,7 @@ range_table_walker(List *rtable, return true; break; case RTE_FUNCTION: - if (walker(rte->funcexpr, context)) + if (walker(rte->functions, context)) return true; break; case RTE_VALUES: @@ -2615,6 +2620,17 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } break; + case T_RangeTblFunction: + { + RangeTblFunction *rtfunc = (RangeTblFunction *) node; + RangeTblFunction *newnode; + + FLATCOPY(newnode, rtfunc, RangeTblFunction); + MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *); + /* Assume we need not copy the coldef info lists */ + return (Node *) newnode; + } + break; default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); @@ -2725,7 +2741,7 @@ range_table_mutator(List *rtable, } break; case RTE_FUNCTION: - MUTATE(newrte->funcexpr, rte->funcexpr, Node *); + MUTATE(newrte->functions, rte->functions, List *); break; case RTE_VALUES: MUTATE(newrte->values_lists, rte->values_lists, List *); @@ -3113,10 +3129,12 @@ raw_expression_tree_walker(Node *node, { RangeFunction *rf = (RangeFunction *) node; - if (walker(rf->funccallnode, context)) + if (walker(rf->functions, context)) return true; if (walker(rf->alias, context)) return true; + if (walker(rf->coldeflist, context)) + return true; } break; case T_TypeName: diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index b39927e025..4c7505e334 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -516,11 +516,7 @@ _outFunctionScan(StringInfo str, const FunctionScan *node) _outScanInfo(str, (const Scan *) node); - WRITE_NODE_FIELD(funcexpr); - WRITE_NODE_FIELD(funccolnames); - WRITE_NODE_FIELD(funccoltypes); - WRITE_NODE_FIELD(funccoltypmods); - WRITE_NODE_FIELD(funccolcollations); + WRITE_NODE_FIELD(functions); WRITE_BOOL_FIELD(funcordinality); } @@ -2154,6 +2150,7 @@ _outColumnDef(StringInfo str, const ColumnDef *node) WRITE_OID_FIELD(collOid); WRITE_NODE_FIELD(constraints); WRITE_NODE_FIELD(fdwoptions); + WRITE_LOCATION_FIELD(location); } static void @@ -2382,10 +2379,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) WRITE_NODE_FIELD(joinaliasvars); break; case RTE_FUNCTION: - WRITE_NODE_FIELD(funcexpr); - WRITE_NODE_FIELD(funccoltypes); - WRITE_NODE_FIELD(funccoltypmods); - WRITE_NODE_FIELD(funccolcollations); + WRITE_NODE_FIELD(functions); WRITE_BOOL_FIELD(funcordinality); break; case RTE_VALUES: @@ -2415,6 +2409,20 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) } static void +_outRangeTblFunction(StringInfo str, const RangeTblFunction *node) +{ + WRITE_NODE_TYPE("RANGETBLFUNCTION"); + + WRITE_NODE_FIELD(funcexpr); + WRITE_INT_FIELD(funccolcount); + WRITE_NODE_FIELD(funccolnames); + WRITE_NODE_FIELD(funccoltypes); + WRITE_NODE_FIELD(funccoltypmods); + WRITE_NODE_FIELD(funccolcollations); + WRITE_BITMAPSET_FIELD(funcparams); +} + +static void _outAExpr(StringInfo str, const A_Expr *node) { WRITE_NODE_TYPE("AEXPR"); @@ -2619,9 +2627,10 @@ _outRangeFunction(StringInfo str, const RangeFunction *node) { WRITE_NODE_TYPE("RANGEFUNCTION"); - WRITE_BOOL_FIELD(ordinality); WRITE_BOOL_FIELD(lateral); - WRITE_NODE_FIELD(funccallnode); + WRITE_BOOL_FIELD(ordinality); + WRITE_BOOL_FIELD(is_table); + WRITE_NODE_FIELD(functions); WRITE_NODE_FIELD(alias); WRITE_NODE_FIELD(coldeflist); } @@ -3156,6 +3165,9 @@ _outNode(StringInfo str, const void *obj) case T_RangeTblEntry: _outRangeTblEntry(str, obj); break; + case T_RangeTblFunction: + _outRangeTblFunction(str, obj); + break; case T_A_Expr: _outAExpr(str, obj); break; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index d325bb3212..2e2cfa7af6 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -1220,10 +1220,7 @@ _readRangeTblEntry(void) READ_NODE_FIELD(joinaliasvars); break; case RTE_FUNCTION: - READ_NODE_FIELD(funcexpr); - READ_NODE_FIELD(funccoltypes); - READ_NODE_FIELD(funccoltypmods); - READ_NODE_FIELD(funccolcollations); + READ_NODE_FIELD(functions); READ_BOOL_FIELD(funcordinality); break; case RTE_VALUES: @@ -1255,6 +1252,25 @@ _readRangeTblEntry(void) READ_DONE(); } +/* + * _readRangeTblFunction + */ +static RangeTblFunction * +_readRangeTblFunction(void) +{ + READ_LOCALS(RangeTblFunction); + + READ_NODE_FIELD(funcexpr); + READ_INT_FIELD(funccolcount); + READ_NODE_FIELD(funccolnames); + READ_NODE_FIELD(funccoltypes); + READ_NODE_FIELD(funccoltypmods); + READ_NODE_FIELD(funccolcollations); + READ_BITMAPSET_FIELD(funcparams); + + READ_DONE(); +} + /* * parseNodeString @@ -1378,6 +1394,8 @@ parseNodeString(void) return_value = _readFromExpr(); else if (MATCH("RTE", 3)) return_value = _readRangeTblEntry(); + else if (MATCH("RANGETBLFUNCTION", 16)) + return_value = _readRangeTblFunction(); else if (MATCH("NOTIFY", 6)) return_value = _readNotifyStmt(); else if (MATCH("DECLARECURSOR", 13)) |