diff options
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 65 |
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; |