summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ruleutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r--src/backend/utils/adt/ruleutils.c65
1 files changed, 54 insertions, 11 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 3754b4981e..dc4a6cc4a8 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.275 2008/06/06 17:59:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.276 2008/07/16 01:30:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -193,7 +193,8 @@ static Node *processIndirection(Node *node, deparse_context *context,
bool printit);
static void printSubscripts(ArrayRef *aref, deparse_context *context);
static char *generate_relation_name(Oid relid);
-static char *generate_function_name(Oid funcid, int nargs, Oid *argtypes);
+static char *generate_function_name(Oid funcid, int nargs, Oid *argtypes,
+ bool *is_variadic);
static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2);
static text *string_to_text(char *str);
static char *flatten_reloptions(Oid relid);
@@ -531,7 +532,7 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, "FOR EACH STATEMENT ");
appendStringInfo(&buf, "EXECUTE PROCEDURE %s(",
- generate_function_name(trigrec->tgfoid, 0, NULL));
+ generate_function_name(trigrec->tgfoid, 0, NULL, NULL));
if (trigrec->tgnargs > 0)
{
@@ -4293,6 +4294,7 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
Oid funcoid = expr->funcid;
Oid argtypes[FUNC_MAX_ARGS];
int nargs;
+ bool is_variadic;
ListCell *l;
/*
@@ -4343,8 +4345,17 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
}
appendStringInfo(buf, "%s(",
- generate_function_name(funcoid, nargs, argtypes));
- get_rule_expr((Node *) expr->args, context, true);
+ generate_function_name(funcoid, nargs, argtypes,
+ &is_variadic));
+ nargs = 0;
+ foreach(l, expr->args)
+ {
+ if (nargs++ > 0)
+ appendStringInfoString(buf, ", ");
+ if (is_variadic && lnext(l) == NULL)
+ appendStringInfoString(buf, "VARIADIC ");
+ get_rule_expr((Node *) lfirst(l), context, true);
+ }
appendStringInfoChar(buf, ')');
}
@@ -4371,7 +4382,8 @@ get_agg_expr(Aggref *aggref, deparse_context *context)
}
appendStringInfo(buf, "%s(%s",
- generate_function_name(aggref->aggfnoid, nargs, argtypes),
+ generate_function_name(aggref->aggfnoid,
+ nargs, argtypes, NULL),
aggref->aggdistinct ? "DISTINCT " : "");
/* aggstar can be set only in zero-argument aggregates */
if (aggref->aggstar)
@@ -5329,10 +5341,12 @@ generate_relation_name(Oid relid)
* given that it is being called with the specified actual arg types.
* (Arg types matter because of ambiguous-function resolution rules.)
*
- * The result includes all necessary quoting and schema-prefixing.
+ * The result includes all necessary quoting and schema-prefixing. We can
+ * also pass back an indication of whether the function is variadic.
*/
static char *
-generate_function_name(Oid funcid, int nargs, Oid *argtypes)
+generate_function_name(Oid funcid, int nargs, Oid *argtypes,
+ bool *is_variadic)
{
HeapTuple proctup;
Form_pg_proc procform;
@@ -5343,6 +5357,7 @@ generate_function_name(Oid funcid, int nargs, Oid *argtypes)
Oid p_funcid;
Oid p_rettype;
bool p_retset;
+ int p_nvargs;
Oid *p_true_typeids;
proctup = SearchSysCache(PROCOID,
@@ -5352,7 +5367,7 @@ generate_function_name(Oid funcid, int nargs, Oid *argtypes)
elog(ERROR, "cache lookup failed for function %u", funcid);
procform = (Form_pg_proc) GETSTRUCT(proctup);
proname = NameStr(procform->proname);
- Assert(nargs == procform->pronargs);
+ Assert(nargs >= procform->pronargs);
/*
* The idea here is to schema-qualify only if the parser would fail to
@@ -5360,9 +5375,9 @@ generate_function_name(Oid funcid, int nargs, Oid *argtypes)
* specified argtypes.
*/
p_result = func_get_detail(list_make1(makeString(proname)),
- NIL, nargs, argtypes,
+ NIL, nargs, argtypes, false,
&p_funcid, &p_rettype,
- &p_retset, &p_true_typeids);
+ &p_retset, &p_nvargs, &p_true_typeids);
if ((p_result == FUNCDETAIL_NORMAL || p_result == FUNCDETAIL_AGGREGATE) &&
p_funcid == funcid)
nspname = NULL;
@@ -5371,6 +5386,34 @@ generate_function_name(Oid funcid, int nargs, Oid *argtypes)
result = quote_qualified_identifier(nspname, proname);
+ /* Check variadic-ness if caller cares */
+ if (is_variadic)
+ {
+ /* XXX change this if we simplify code in FuncnameGetCandidates */
+ Datum proargmodes;
+ bool isnull;
+
+ *is_variadic = false;
+
+ proargmodes = SysCacheGetAttr(PROCOID, proctup,
+ Anum_pg_proc_proargmodes, &isnull);
+ if (!isnull)
+ {
+ ArrayType *ar = DatumGetArrayTypeP(proargmodes);
+ char *argmodes;
+ int j;
+
+ argmodes = ARR_DATA_PTR(ar);
+ j = ARR_DIMS(ar)[0] - 1;
+ if (j >= 0 && argmodes[j] == PROARGMODE_VARIADIC)
+ {
+ /* "any" variadics are not treated as variadics for listing */
+ if (procform->proargtypes.values[j] != ANYOID)
+ *is_variadic = true;
+ }
+ }
+ }
+
ReleaseSysCache(proctup);
return result;