* pg_get_functiondef * Returns the complete "CREATE OR REPLACE FUNCTION ..." statement for * the specified function. * * Note: if you change the output format of this function, be careful not * to break psql's rules (in \ef and \sf) for identifying the start of the * function body. To wit: the function body starts on a line that begins * with "AS ", and no preceding line will look like t
| 2799 | * with "AS ", and no preceding line will look like that. |
| 2800 | */ |
| 2801 | Datum |
| 2802 | pg_get_functiondef(PG_FUNCTION_ARGS) |
| 2803 | { |
| 2804 | Oid funcid = PG_GETARG_OID(0); |
| 2805 | StringInfoData buf; |
| 2806 | StringInfoData dq; |
| 2807 | HeapTuple proctup; |
| 2808 | Form_pg_proc proc; |
| 2809 | bool isfunction; |
| 2810 | Datum tmp; |
| 2811 | bool isnull; |
| 2812 | const char *prosrc; |
| 2813 | const char *name; |
| 2814 | const char *nsp; |
| 2815 | float4 procost; |
| 2816 | int oldlen; |
| 2817 | |
| 2818 | initStringInfo(&buf); |
| 2819 | |
| 2820 | /* Look up the function */ |
| 2821 | proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); |
| 2822 | if (!HeapTupleIsValid(proctup)) |
| 2823 | PG_RETURN_NULL(); |
| 2824 | |
| 2825 | proc = (Form_pg_proc) GETSTRUCT(proctup); |
| 2826 | name = NameStr(proc->proname); |
| 2827 | |
| 2828 | if (proc->prokind == PROKIND_AGGREGATE) |
| 2829 | ereport(ERROR, |
| 2830 | (errcode(ERRCODE_WRONG_OBJECT_TYPE), |
| 2831 | errmsg("\"%s\" is an aggregate function", name))); |
| 2832 | |
| 2833 | isfunction = (proc->prokind != PROKIND_PROCEDURE); |
| 2834 | |
| 2835 | /* |
| 2836 | * We always qualify the function name, to ensure the right function gets |
| 2837 | * replaced. |
| 2838 | */ |
| 2839 | nsp = get_namespace_name(proc->pronamespace); |
| 2840 | appendStringInfo(&buf, "CREATE OR REPLACE %s %s(", |
| 2841 | isfunction ? "FUNCTION" : "PROCEDURE", |
| 2842 | quote_qualified_identifier(nsp, name)); |
| 2843 | (void) print_function_arguments(&buf, proctup, false, true); |
| 2844 | appendStringInfoString(&buf, ")\n"); |
| 2845 | if (isfunction) |
| 2846 | { |
| 2847 | appendStringInfoString(&buf, " RETURNS "); |
| 2848 | print_function_rettype(&buf, proctup); |
| 2849 | appendStringInfoChar(&buf, '\n'); |
| 2850 | } |
| 2851 | |
| 2852 | print_function_trftypes(&buf, proctup); |
| 2853 | |
| 2854 | appendStringInfo(&buf, " LANGUAGE %s\n", |
| 2855 | quote_identifier(get_language_name(proc->prolang, false))); |
| 2856 | |
| 2857 | /* Emit some miscellaneous options on one line */ |
| 2858 | oldlen = buf.len; |
nothing calls this directly
no test coverage detected