aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_agg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_agg.c')
-rw-r--r--src/backend/parser/parse_agg.c136
1 files changed, 64 insertions, 72 deletions
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index b9ca066698e..481a4ddc484 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -71,6 +71,8 @@ static bool finalize_grouping_exprs_walker(Node *node,
check_ungrouped_columns_context *context);
static void check_agglevels_and_constraints(ParseState *pstate, Node *expr);
static List *expand_groupingset_node(GroupingSet *gs);
+static Node *make_agg_arg(Oid argtype, Oid argcollation);
+
/*
* transformAggregateCall -
@@ -1863,37 +1865,19 @@ build_aggregate_transfn_expr(Oid *agg_input_types,
Expr **transfnexpr,
Expr **invtransfnexpr)
{
- Param *argp;
List *args;
FuncExpr *fexpr;
int i;
/*
- * Build arg list to use in the transfn FuncExpr node. We really only care
- * that transfn can discover the actual argument types at runtime using
- * get_fn_expr_argtype(), so it's okay to use Param nodes that don't
- * correspond to any real Param.
+ * Build arg list to use in the transfn FuncExpr node.
*/
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_state_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
-
- args = list_make1(argp);
+ args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));
for (i = agg_num_direct_inputs; i < agg_num_inputs; i++)
{
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_input_types[i];
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
- args = lappend(args, argp);
+ args = lappend(args,
+ make_agg_arg(agg_input_types[i], agg_input_collation));
}
fexpr = makeFuncExpr(transfn_oid,
@@ -1936,20 +1920,13 @@ build_aggregate_combinefn_expr(Oid agg_state_type,
Oid combinefn_oid,
Expr **combinefnexpr)
{
- Param *argp;
+ Node *argp;
List *args;
FuncExpr *fexpr;
- /* Build arg list to use in the combinefn FuncExpr node. */
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_state_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
+ /* combinefn takes two arguments of the aggregate state type */
+ argp = make_agg_arg(agg_state_type, agg_input_collation);
- /* transition state type is arg 1 and 2 */
args = list_make2(argp, argp);
fexpr = makeFuncExpr(combinefn_oid,
@@ -1958,51 +1935,59 @@ build_aggregate_combinefn_expr(Oid agg_state_type,
InvalidOid,
agg_input_collation,
COERCE_EXPLICIT_CALL);
- fexpr->funcvariadic = false;
+ /* combinefn is currently never treated as variadic */
*combinefnexpr = (Expr *) fexpr;
}
/*
* Like build_aggregate_transfn_expr, but creates an expression tree for the
- * serialization or deserialization function of an aggregate, rather than the
- * transition function. This may be used for either the serialization or
- * deserialization function by swapping the first two parameters over.
+ * serialization function of an aggregate.
*/
void
-build_aggregate_serialfn_expr(Oid agg_input_type,
- Oid agg_output_type,
- Oid agg_input_collation,
- Oid serialfn_oid,
+build_aggregate_serialfn_expr(Oid serialfn_oid,
Expr **serialfnexpr)
{
- Param *argp;
List *args;
FuncExpr *fexpr;
- /* Build arg list to use in the FuncExpr node. */
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_input_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
-
- /* takes a single arg of the agg_input_type */
- args = list_make1(argp);
+ /* serialfn always takes INTERNAL and returns BYTEA */
+ args = list_make1(make_agg_arg(INTERNALOID, InvalidOid));
fexpr = makeFuncExpr(serialfn_oid,
- agg_output_type,
+ BYTEAOID,
args,
InvalidOid,
- agg_input_collation,
+ InvalidOid,
COERCE_EXPLICIT_CALL);
- fexpr->funcvariadic = false;
*serialfnexpr = (Expr *) fexpr;
}
/*
* Like build_aggregate_transfn_expr, but creates an expression tree for the
+ * deserialization function of an aggregate.
+ */
+void
+build_aggregate_deserialfn_expr(Oid deserialfn_oid,
+ Expr **deserialfnexpr)
+{
+ List *args;
+ FuncExpr *fexpr;
+
+ /* deserialfn always takes BYTEA, INTERNAL and returns INTERNAL */
+ args = list_make2(make_agg_arg(BYTEAOID, InvalidOid),
+ make_agg_arg(INTERNALOID, InvalidOid));
+
+ fexpr = makeFuncExpr(deserialfn_oid,
+ INTERNALOID,
+ args,
+ InvalidOid,
+ InvalidOid,
+ COERCE_EXPLICIT_CALL);
+ *deserialfnexpr = (Expr *) fexpr;
+}
+
+/*
+ * Like build_aggregate_transfn_expr, but creates an expression tree for the
* final function of an aggregate, rather than the transition function.
*/
void
@@ -2014,33 +1999,19 @@ build_aggregate_finalfn_expr(Oid *agg_input_types,
Oid finalfn_oid,
Expr **finalfnexpr)
{
- Param *argp;
List *args;
int i;
/*
* Build expr tree for final function
*/
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_state_type;
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
- args = list_make1(argp);
+ args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));
/* finalfn may take additional args, which match agg's input types */
for (i = 0; i < num_finalfn_inputs - 1; i++)
{
- argp = makeNode(Param);
- argp->paramkind = PARAM_EXEC;
- argp->paramid = -1;
- argp->paramtype = agg_input_types[i];
- argp->paramtypmod = -1;
- argp->paramcollid = agg_input_collation;
- argp->location = -1;
- args = lappend(args, argp);
+ args = lappend(args,
+ make_agg_arg(agg_input_types[i], agg_input_collation));
}
*finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,
@@ -2051,3 +2022,24 @@ build_aggregate_finalfn_expr(Oid *agg_input_types,
COERCE_EXPLICIT_CALL);
/* finalfn is currently never treated as variadic */
}
+
+/*
+ * Convenience function to build dummy argument expressions for aggregates.
+ *
+ * We really only care that an aggregate support function can discover its
+ * actual argument types at runtime using get_fn_expr_argtype(), so it's okay
+ * to use Param nodes that don't correspond to any real Param.
+ */
+static Node *
+make_agg_arg(Oid argtype, Oid argcollation)
+{
+ Param *argp = makeNode(Param);
+
+ argp->paramkind = PARAM_EXEC;
+ argp->paramid = -1;
+ argp->paramtype = argtype;
+ argp->paramtypmod = -1;
+ argp->paramcollid = argcollation;
+ argp->location = -1;
+ return (Node *) argp;
+}