*** pgsql/src/backend/utils/adt/ruleutils.c 2008/12/04 17:51:27 1.288 --- pgsql/src/backend/utils/adt/ruleutils.c 2008/12/18 18:20:34 1.289 *************** *** 9,15 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.287 2008/10/06 20:29:38 tgl Exp $ * *------------------------------------------------------------------------- */ --- 9,15 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.288 2008/12/04 17:51:27 petere Exp $ * *------------------------------------------------------------------------- */ *************** static char *pg_get_constraintdef_worker *** 141,148 **** static char *pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags); static int print_function_arguments(StringInfo buf, HeapTuple proctup, ! bool print_table_args, ! bool full); static void print_function_rettype(StringInfo buf, HeapTuple proctup); static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags); --- 141,147 ---- static char *pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags); static int print_function_arguments(StringInfo buf, HeapTuple proctup, ! bool print_table_args, bool print_defaults); static void print_function_rettype(StringInfo buf, HeapTuple proctup); static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags); *************** pg_get_function_arguments(PG_FUNCTION_AR *** 1610,1616 **** * pg_get_function_identity_arguments * Get a formatted list of arguments for a function. * This is everything that would go between the parentheses in ! * ALTER FUNCTION, etc. skip names and defaults/ */ Datum pg_get_function_identity_arguments(PG_FUNCTION_ARGS) --- 1609,1615 ---- * pg_get_function_identity_arguments * Get a formatted list of arguments for a function. * This is everything that would go between the parentheses in ! * ALTER FUNCTION, etc. In particular, don't print defaults. */ Datum pg_get_function_identity_arguments(PG_FUNCTION_ARGS) *************** pg_get_function_identity_arguments(PG_FU *** 1634,1641 **** PG_RETURN_TEXT_P(string_to_text(buf.data)); } - - /* * pg_get_function_result * Get a nicely-formatted version of the result type of a function. --- 1633,1638 ---- *************** print_function_rettype(StringInfo buf, H *** 1680,1686 **** { /* It might be a table function; try to print the arguments */ appendStringInfoString(&rbuf, "TABLE("); ! ntabargs = print_function_arguments(&rbuf, proctup, true, true); if (ntabargs > 0) appendStringInfoString(&rbuf, ")"); else --- 1677,1683 ---- { /* It might be a table function; try to print the arguments */ appendStringInfoString(&rbuf, "TABLE("); ! ntabargs = print_function_arguments(&rbuf, proctup, true, false); if (ntabargs > 0) appendStringInfoString(&rbuf, ")"); else *************** print_function_rettype(StringInfo buf, H *** 1702,1801 **** * Common code for pg_get_function_arguments and pg_get_function_result: * append the desired subset of arguments to buf. We print only TABLE * arguments when print_table_args is true, and all the others when it's false. * Function return value is the number of arguments printed. - * When full is false, then don't print argument names and argument defaults. */ static int print_function_arguments(StringInfo buf, HeapTuple proctup, ! bool print_table_args, ! bool full) { int numargs; Oid *argtypes; char **argnames; char *argmodes; int argsprinted; int i; - Datum proargdefaults; - List *argdefaults; - int nargdefaults; - bool isnull; - List *dcontext = NIL; numargs = get_func_arg_info(proctup, &argtypes, &argnames, &argmodes); ! proargdefaults = SysCacheGetAttr(PROCOID, proctup, ! Anum_pg_proc_proargdefaults, &isnull); ! if (!isnull) { ! char *str; ! str = TextDatumGetCString(proargdefaults); ! argdefaults = (List *) stringToNode(str); ! Assert(IsA(argdefaults, List)); ! nargdefaults = list_length(argdefaults); ! ! /* we will need deparse context */ ! //dcontext = deparse_context_for("", InvalidOid); ! dcontext = NULL; ! pfree(str); ! } ! else ! { ! argdefaults = NIL; ! nargdefaults = 0; } argsprinted = 0; for (i = 0; i < numargs; i++) { Oid argtype = argtypes[i]; char *argname = argnames ? argnames[i] : NULL; char argmode = argmodes ? argmodes[i] : PROARGMODE_IN; const char *modename; ! ! if (print_table_args != (argmode == PROARGMODE_TABLE)) ! continue; switch (argmode) { case PROARGMODE_IN: modename = ""; break; case PROARGMODE_INOUT: modename = "INOUT "; break; case PROARGMODE_OUT: modename = "OUT "; break; case PROARGMODE_VARIADIC: modename = "VARIADIC "; break; case PROARGMODE_TABLE: modename = ""; break; default: elog(ERROR, "invalid parameter mode '%c'", argmode); modename = NULL; /* keep compiler quiet */ break; } if (argsprinted) appendStringInfoString(buf, ", "); appendStringInfoString(buf, modename); ! if (argname && argname[0] && full) appendStringInfo(buf, "%s ", argname); appendStringInfoString(buf, format_type_be(argtype)); ! ! /* search given default expression, expect less numargs */ ! if (nargdefaults > 0 && i >= (numargs - nargdefaults) && full) { Node *expr; ! expr = (Node *) list_nth(argdefaults, i - (numargs - nargdefaults)); ! appendStringInfo(buf, " DEFAULT %s", deparse_expression(expr, dcontext, false, false)); ! } argsprinted++; } --- 1699,1810 ---- * Common code for pg_get_function_arguments and pg_get_function_result: * append the desired subset of arguments to buf. We print only TABLE * arguments when print_table_args is true, and all the others when it's false. + * We print argument defaults only if print_defaults is true. * Function return value is the number of arguments printed. */ static int print_function_arguments(StringInfo buf, HeapTuple proctup, ! bool print_table_args, bool print_defaults) { + Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(proctup); int numargs; Oid *argtypes; char **argnames; char *argmodes; int argsprinted; + int inputargno; + int nlackdefaults; + ListCell *nextargdefault = NULL; int i; numargs = get_func_arg_info(proctup, &argtypes, &argnames, &argmodes); ! nlackdefaults = numargs; ! if (print_defaults && proc->pronargdefaults > 0) { ! Datum proargdefaults; ! bool isnull; ! proargdefaults = SysCacheGetAttr(PROCOID, proctup, ! Anum_pg_proc_proargdefaults, ! &isnull); ! if (!isnull) ! { ! char *str; ! List *argdefaults; ! ! str = TextDatumGetCString(proargdefaults); ! argdefaults = (List *) stringToNode(str); ! Assert(IsA(argdefaults, List)); ! pfree(str); ! nextargdefault = list_head(argdefaults); ! /* nlackdefaults counts only *input* arguments lacking defaults */ ! nlackdefaults = proc->pronargs - list_length(argdefaults); ! } } argsprinted = 0; + inputargno = 0; for (i = 0; i < numargs; i++) { Oid argtype = argtypes[i]; char *argname = argnames ? argnames[i] : NULL; char argmode = argmodes ? argmodes[i] : PROARGMODE_IN; const char *modename; ! bool isinput; switch (argmode) { case PROARGMODE_IN: modename = ""; + isinput = true; break; case PROARGMODE_INOUT: modename = "INOUT "; + isinput = true; break; case PROARGMODE_OUT: modename = "OUT "; + isinput = false; break; case PROARGMODE_VARIADIC: modename = "VARIADIC "; + isinput = true; break; case PROARGMODE_TABLE: modename = ""; + isinput = false; break; default: elog(ERROR, "invalid parameter mode '%c'", argmode); modename = NULL; /* keep compiler quiet */ + isinput = false; break; } + if (isinput) + inputargno++; /* this is a 1-based counter */ + + if (print_table_args != (argmode == PROARGMODE_TABLE)) + continue; + if (argsprinted) appendStringInfoString(buf, ", "); appendStringInfoString(buf, modename); ! if (argname && argname[0]) appendStringInfo(buf, "%s ", argname); appendStringInfoString(buf, format_type_be(argtype)); ! if (print_defaults && isinput && inputargno > nlackdefaults) { Node *expr; ! Assert(nextargdefault != NULL); ! expr = (Node *) lfirst(nextargdefault); ! nextargdefault = lnext(nextargdefault); + appendStringInfo(buf, " DEFAULT %s", + deparse_expression(expr, NIL, false, false)); + } argsprinted++; } *************** generate_function_name(Oid funcid, int n *** 6062,6068 **** elog(ERROR, "cache lookup failed for function %u", funcid); procform = (Form_pg_proc) GETSTRUCT(proctup); proname = NameStr(procform->proname); - Assert(nargs >= procform->pronargs); /* * The idea here is to schema-qualify only if the parser would fail to --- 6071,6076 ---- *************** generate_function_name(Oid funcid, int n *** 6070,6076 **** * specified argtypes. */ p_result = func_get_detail(list_make1(makeString(proname)), ! NIL, nargs, argtypes, false, &p_funcid, &p_rettype, &p_retset, &p_nvargs, &p_true_typeids, NULL); if ((p_result == FUNCDETAIL_NORMAL || p_result == FUNCDETAIL_AGGREGATE) && --- 6078,6084 ---- * specified argtypes. */ p_result = func_get_detail(list_make1(makeString(proname)), ! NIL, nargs, argtypes, false, true, &p_funcid, &p_rettype, &p_retset, &p_nvargs, &p_true_typeids, NULL); if ((p_result == FUNCDETAIL_NORMAL || p_result == FUNCDETAIL_AGGREGATE) &&