Hello this patch carry support for named and mixed notation - more detailed described at http://archive.adaic.com/standards/83rat/html/ratl-08-03.html.
This use ADA syntax - name => value, that is conntroversal and problematic - so I expect change of syntax. Regards Pavel Stehule
*** ./src/backend/catalog/namespace.c.orig 2008-12-10 12:36:42.000000000 +0100 --- ./src/backend/catalog/namespace.c 2008-12-11 23:33:04.000000000 +0100 *************** *** 38,43 **** --- 38,44 ---- #include "commands/dbcommands.h" #include "miscadmin.h" #include "nodes/makefuncs.h" + #include "nodes/parsenodes.h" #include "parser/parse_func.h" #include "storage/backendid.h" #include "storage/ipc.h" *************** *** 49,54 **** --- 50,56 ---- #include "utils/memutils.h" #include "utils/rel.h" #include "utils/syscache.h" + #include "funcapi.h" /* *************** *** 584,590 **** * functions to mask variadic ones if the expanded argument list is the same. */ FuncCandidateList ! FuncnameGetCandidates(List *names, int nargs, bool expand_variadic) { FuncCandidateList resultList = NULL; bool any_variadic = false; --- 586,593 ---- * functions to mask variadic ones if the expanded argument list is the same. */ FuncCandidateList ! FuncnameGetCandidates(List *names, int nargs, bool expand_variadic, ! Notation notation, List *argnames) { FuncCandidateList resultList = NULL; bool any_variadic = false; *************** *** 628,643 **** Oid va_elem_type; List *defaults = NIL; FuncCandidateList newResult; /* * Check if function has some parameter defaults if some * parameters are missing. */ ! if (pronargs > nargs && expand_variadic) { bool isnull; Datum proargdefaults; char *str; /* skip when not enough default expressions */ if (nargs + procform->pronargdefaults < pronargs) --- 631,795 ---- Oid va_elem_type; List *defaults = NIL; FuncCandidateList newResult; + char *rparam_type = NULL; + short int *map_args = NULL; + short int *map_defaults = NULL; + + /* + * Check named params if are used. + */ + if (notation != POSITIONAL_NOTATION) + { + ListCell *lc; + int i; + Oid *p_argtypes; + char **p_argnames; + char *p_argmodes; + int pronallargs; + bool found_all; + bool any_default; + Notation actual_notation; + int j; + + Assert(argnames != NIL); + + pronallargs = get_func_arg_info(proctup, &p_argtypes, &p_argnames, &p_argmodes); + if (!p_argnames) + continue; + + rparam_type = palloc(pronargs * sizeof(char)); + map_args = palloc(pronargs * sizeof(short int)); + map_defaults = palloc(pronargs * sizeof(short int)); + + /* now we know nothing about params */ + for (j = 0; j < pronargs; j++) + { + rparam_type[j] = 'u'; + map_args[j] = map_defaults[j] = -1; + } + + defaults = NIL; + any_default = false; + + /* if MIXED notation is used, then I have to copy positional arguments */ + i = 0; + actual_notation = POSITIONAL_NOTATION; + found_all = true; + + foreach(lc, argnames) + { + Node *strnode = lfirst(lc); + + if (strnode == NULL && actual_notation == POSITIONAL_NOTATION) + { + rparam_type[i] = 'p'; + map_args[i] = i; + } + /* found end of positional notation */ + if (strnode != NULL && actual_notation == POSITIONAL_NOTATION) + actual_notation = NAMED_NOTATION; + + Assert(actual_notation == POSITIONAL_NOTATION || strnode != NULL); + + if (actual_notation == NAMED_NOTATION) + { + char *cargname = strVal(strnode); + int j; + bool found = false; + int k = 0; + + for (j = 0; j < pronallargs; j++) + { + /* skip all OUT arguments */ + if (p_argmodes && (p_argmodes[j] != FUNC_PARAM_IN && p_argmodes[j] != FUNC_PARAM_INOUT)) + continue; + + if (p_argnames[j] && strcmp(cargname, p_argnames[j]) == 0) + { + found = true; + break; + } + + k += 1; + } + + if (!found) + { + found_all = false; + break; + } + else + { + rparam_type[k] = 'n'; + map_args[k] = i; + } + } + + i += 1; + } + + if (!found_all) + continue; + + /* try to fill unknown params with defaults */ + if (procform->pronargdefaults > 0) + { + bool isnull; + Datum proargdefaults; + char *str; + int pronargdefaults = procform->pronargdefaults; + + proargdefaults = SysCacheGetAttr(PROCOID, proctup, + Anum_pg_proc_proargdefaults, &isnull); + Assert(!isnull); + str = TextDatumGetCString(proargdefaults); + defaults = (List *) stringToNode(str); + + for (i = 0; i < pronargdefaults; i++) + { + + + if (rparam_type[pronargs - pronargdefaults + i] == 'u') + { + rparam_type[pronargs - pronargdefaults + i] = 'd'; + map_defaults[pronargs - pronargdefaults + i] = i; + any_default = true; + } + } + /* + * When we don't use defaults, then don't carry defaults/ + */ + if (!any_default) + defaults = NIL; + } + + + + /* check if we know all params */ + for (i = 0; i < pronargs; i++) + if (rparam_type[i] == 'u') + { + found_all = false; + break; + } + + if (!found_all) + break; + + } + /* * Check if function has some parameter defaults if some * parameters are missing. */ ! if (pronargs > nargs && expand_variadic && notation == POSITIONAL_NOTATION) { bool isnull; Datum proargdefaults; char *str; + ListCell *lc; + bool dirty_defaults = false; /* skip when not enough default expressions */ if (nargs + procform->pronargdefaults < pronargs) *************** *** 657,662 **** --- 809,827 ---- */ defaults = list_copy_tail(defaults, procform->pronargdefaults - pronargs + nargs); + /* For POSITIONAL_NOTATION all defaults have to not null */ + foreach(lc, (List *) defaults) + if (lfirst(lc) == NULL) + { + dirty_defaults = true; + break; + } + if (dirty_defaults) + { + /* pfree ToDo */ + continue; + } + pfree(str); } *************** *** 664,670 **** * Check if function is variadic, and get variadic element type if so. * If expand_variadic is false, we should just ignore variadic-ness. */ ! if (pronargs <= nargs && expand_variadic) { va_elem_type = procform->provariadic; variadic = OidIsValid(va_elem_type); --- 829,835 ---- * Check if function is variadic, and get variadic element type if so. * If expand_variadic is false, we should just ignore variadic-ness. */ ! if (pronargs <= nargs && expand_variadic && notation == POSITIONAL_NOTATION) { va_elem_type = procform->provariadic; variadic = OidIsValid(va_elem_type); *************** *** 724,729 **** --- 889,896 ---- newResult->oid = HeapTupleGetOid(proctup); newResult->nargs = effective_nargs; newResult->argdefaults = defaults; + newResult->map_args = map_args; + newResult->map_defaults = map_defaults; memcpy(newResult->args, procform->proargtypes.values, pronargs * sizeof(Oid)); if (variadic) *************** *** 857,862 **** --- 1024,1031 ---- prevResult->oid = newResult->oid; prevResult->nvargs = newResult->nvargs; prevResult->argdefaults = newResult->argdefaults; + prevResult->map_args = newResult->map_args; + prevResult->map_defaults = newResult->map_defaults; pfree(newResult); continue; /* args are same, of course */ } *************** *** 922,928 **** visible = false; clist = FuncnameGetCandidates(list_make1(makeString(proname)), ! nargs, false); for (; clist; clist = clist->next) { --- 1091,1097 ---- visible = false; clist = FuncnameGetCandidates(list_make1(makeString(proname)), ! nargs, false, POSITIONAL_NOTATION, NIL); for (; clist; clist = clist->next) { *** ./src/backend/catalog/pg_aggregate.c.orig 2008-12-10 12:17:49.000000000 +0100 --- ./src/backend/catalog/pg_aggregate.c 2008-12-11 13:47:20.000000000 +0100 *************** *** 320,328 **** * function's return value. it also returns the true argument types to * the function. */ ! fdresult = func_get_detail(fnName, NIL, nargs, input_types, false, &fnOid, rettype, &retset, &nvargs, ! &true_oid_array, NULL); /* only valid case is a normal function not returning a set */ if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid)) --- 320,328 ---- * function's return value. it also returns the true argument types to * the function. */ ! fdresult = func_get_detail(fnName, NIL, nargs, input_types, false, POSITIONAL_NOTATION, NIL, &fnOid, rettype, &retset, &nvargs, ! &true_oid_array, NULL, NULL, NULL, NULL); /* only valid case is a normal function not returning a set */ if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid)) *** ./src/backend/commands/functioncmds.c.orig 2008-12-08 23:46:06.000000000 +0100 --- ./src/backend/commands/functioncmds.c 2008-12-11 15:44:45.000000000 +0100 *************** *** 301,312 **** have_defaults = true; } else ! { ! if (have_defaults) ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), ! errmsg("parameter without default value specified after parameter with default value"))); ! } i++; } --- 301,309 ---- have_defaults = true; } else ! /* add default only when some default exists, defaults list doesn't start with nulls */ ! if (have_defaults && (fp->mode == FUNC_PARAM_IN && fp->mode == FUNC_PARAM_INOUT)) ! *parameterDefaults = lappend(*parameterDefaults, NIL); i++; } *** ./src/backend/parser/parse_expr.c.orig 2008-12-08 23:07:12.000000000 +0100 --- ./src/backend/parser/parse_expr.c 2008-12-11 23:32:17.000000000 +0100 *************** *** 361,367 **** list_make1(n), list_make1(result), false, false, false, ! true, -1); } } /* process trailing subscripts, if any */ --- 361,368 ---- list_make1(n), list_make1(result), false, false, false, ! true, -1, ! POSITIONAL_NOTATION, NIL); } } /* process trailing subscripts, if any */ *************** *** 505,511 **** list_make1(makeString(name2)), list_make1(node), false, false, false, ! true, cref->location); } break; } --- 506,513 ---- list_make1(makeString(name2)), list_make1(node), false, false, false, ! true, cref->location, ! POSITIONAL_NOTATION, NIL); } break; } *************** *** 546,552 **** list_make1(makeString(name3)), list_make1(node), false, false, false, ! true, cref->location); } break; } --- 548,555 ---- list_make1(makeString(name3)), list_make1(node), false, false, false, ! true, cref->location, ! POSITIONAL_NOTATION, NIL); } break; } *************** *** 601,607 **** list_make1(makeString(name4)), list_make1(node), false, false, false, ! true, cref->location); } break; } --- 604,611 ---- list_make1(makeString(name4)), list_make1(node), false, false, false, ! true, cref->location, ! POSITIONAL_NOTATION, NIL); } break; } *************** *** 1092,1105 **** --- 1096,1178 ---- { List *targs; ListCell *args; + List *names; + int i; + Notation notation; /* Transform the list of arguments ... */ targs = NIL; + names = NIL; + i = 0; + + notation = POSITIONAL_NOTATION; foreach(args, fn->args) { + i = i + 1; + + /* + * this feature will be prohibited until hstorage will be supported, or + * be controlled by GUC. There is one problem - supported operator + * text => text, should colidate wit named notation syntax. + */ + if (IsA((Node *) lfirst(args), A_Expr) && true) + { + A_Expr *expr = (A_Expr *) lfirst(args); + + if (expr->kind == AEXPR_OP) + { + Node *name = linitial(expr->name); + + if (IsA(name, String) && strcmp(strVal(name), "=>") == 0) + { + Node *lexpr = expr->lexpr; + Node *param_name; + + if (!IsA(lexpr, ColumnRef)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("expected parameter name"), + parser_errposition(pstate, exprLocation(lexpr)))); + + param_name = linitial(((ColumnRef *) lexpr)->fields); + if (!IsA(param_name, String)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("expected parameter name"), + parser_errposition(pstate, exprLocation(lexpr)))); + + if (notation == POSITIONAL_NOTATION) + notation = (i == 1) ? NAMED_NOTATION : MIXED_NOTATION; + + Assert(list_length(expr->name) == 1); + targs = lappend(targs, transformExpr(pstate, + expr->rexpr)); + + if (list_member(names, param_name)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("ambiguous parameter value"), + errhint("You specify some parameter more time."), + parser_errposition(pstate, exprLocation(lexpr)))); + + names = lappend(names, param_name); + continue; + } + } + } + + if (notation != POSITIONAL_NOTATION) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("expected named notation"), + errhint("You can't put positionals arguments behind the named arguments."), + parser_errposition(pstate, exprLocation(lfirst(args))))); + + targs = lappend(targs, transformExpr(pstate, (Node *) lfirst(args))); + names = lappend(names, NULL); } /* ... and hand off to ParseFuncOrColumn */ *************** *** 1110,1116 **** fn->agg_distinct, fn->func_variadic, false, ! fn->location); } static Node * --- 1183,1191 ---- fn->agg_distinct, fn->func_variadic, false, ! fn->location, ! notation, ! notation == POSITIONAL_NOTATION ? NULL : names); } static Node * *** ./src/backend/parser/parse_func.c.orig 2008-12-10 11:51:49.000000000 +0100 --- ./src/backend/parser/parse_func.c 2008-12-11 23:31:29.000000000 +0100 *************** *** 63,69 **** Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool agg_star, bool agg_distinct, bool func_variadic, ! bool is_column, int location) { Oid rettype; Oid funcid; --- 63,70 ---- Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool agg_star, bool agg_distinct, bool func_variadic, ! bool is_column, int location, ! Notation notation, List *names) { Oid rettype; Oid funcid; *************** *** 78,83 **** --- 79,87 ---- int nvargs; FuncDetailCode fdresult; List *argdefaults; + int pronargs; + short int *map_args; + short int *map_defaults; /* * Most of the rest of the parser just assumes that functions do not have *************** *** 131,137 **** * wasn't any aggregate or variadic decoration. */ if (nargs == 1 && !agg_star && !agg_distinct && !func_variadic && ! list_length(funcname) == 1) { Oid argtype = actual_arg_types[0]; --- 135,141 ---- * wasn't any aggregate or variadic decoration. */ if (nargs == 1 && !agg_star && !agg_distinct && !func_variadic && ! list_length(funcname) == 1 && notation == POSITIONAL_NOTATION) { Oid argtype = actual_arg_types[0]; *************** *** 164,171 **** */ fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types, !func_variadic, &funcid, &rettype, &retset, &nvargs, ! &declared_arg_types, &argdefaults); if (fdresult == FUNCDETAIL_COERCION) { /* --- 168,177 ---- */ fdresult = func_get_detail(funcname, fargs, nargs, actual_arg_types, !func_variadic, + notation, names, &funcid, &rettype, &retset, &nvargs, ! &declared_arg_types, &argdefaults, ! &pronargs, &map_args, &map_defaults); if (fdresult == FUNCDETAIL_COERCION) { /* *************** *** 235,242 **** parser_errposition(pstate, location))); } /* add stored expressions as called values for arguments with defaults */ ! if (argdefaults) { ListCell *lc; --- 241,275 ---- parser_errposition(pstate, location))); } + /* do some magii with mapping arguments (when named or mixed notation is used */ + if (map_args != NULL) + { + List *reordered_fargs = NIL; + int i; + + nargs = 0; + for (i = 0; i < pronargs; i++) + { + Node *expr; + + if (map_args[i] != -1) + expr = list_nth(fargs, map_args[i]); + else + { + Assert(map_defaults != NULL); + Assert(map_defaults[i] != -1); + + expr = list_nth(argdefaults, map_defaults[i]); + } + reordered_fargs = lappend(reordered_fargs, expr); + actual_arg_types[nargs++] = exprType(expr); + } + + fargs = reordered_fargs; + } + /* add stored expressions as called values for arguments with defaults */ ! if (argdefaults && (map_args == NULL && map_defaults == NULL)) { ListCell *lc; *************** *** 741,758 **** int nargs, Oid *argtypes, bool expand_variadic, Oid *funcid, /* return value */ Oid *rettype, /* return value */ bool *retset, /* return value */ int *nvargs, /* return value */ Oid **true_typeids, /* return value */ ! List **argdefaults) /* return value */ { FuncCandidateList raw_candidates; FuncCandidateList best_candidate; /* Get list of possible candidates from namespace search */ ! raw_candidates = FuncnameGetCandidates(funcname, nargs, expand_variadic); /* * Quickly check if there is an exact match to the input datatypes (there --- 774,797 ---- int nargs, Oid *argtypes, bool expand_variadic, + Notation notation, + List *names, Oid *funcid, /* return value */ Oid *rettype, /* return value */ bool *retset, /* return value */ int *nvargs, /* return value */ Oid **true_typeids, /* return value */ ! List **argdefaults, /* return value */ ! int *pronargs, /* return value */ ! short int **map_args, /* return value */ ! short int **map_defaults) /* return value */ { FuncCandidateList raw_candidates; FuncCandidateList best_candidate; /* Get list of possible candidates from namespace search */ ! raw_candidates = FuncnameGetCandidates(funcname, nargs, expand_variadic, ! notation, names); /* * Quickly check if there is an exact match to the input datatypes (there *************** *** 889,895 **** *true_typeids = best_candidate->args; if (argdefaults) *argdefaults = best_candidate->argdefaults; ! ftup = SearchSysCache(PROCOID, ObjectIdGetDatum(best_candidate->oid), 0, 0, 0); --- 928,941 ---- *true_typeids = best_candidate->args; if (argdefaults) *argdefaults = best_candidate->argdefaults; ! if (map_args) ! { ! Assert(pronargs != NULL); ! *map_args = best_candidate->map_args; ! *pronargs = best_candidate->nargs; ! } ! if (map_defaults) ! *map_defaults = best_candidate->map_defaults; ftup = SearchSysCache(PROCOID, ObjectIdGetDatum(best_candidate->oid), 0, 0, 0); *************** *** 1243,1249 **** { FuncCandidateList clist; ! clist = FuncnameGetCandidates(funcname, nargs, false); while (clist) { --- 1289,1295 ---- { FuncCandidateList clist; ! clist = FuncnameGetCandidates(funcname, nargs, false, POSITIONAL_NOTATION, NIL); while (clist) { *** ./src/backend/utils/adt/regproc.c.orig 2008-12-10 12:40:55.000000000 +0100 --- ./src/backend/utils/adt/regproc.c 2008-12-10 12:42:20.000000000 +0100 *************** *** 131,137 **** * pg_proc entries in the current search path. */ names = stringToQualifiedNameList(pro_name_or_oid); ! clist = FuncnameGetCandidates(names, -1, false); if (clist == NULL) ereport(ERROR, --- 131,137 ---- * pg_proc entries in the current search path. */ names = stringToQualifiedNameList(pro_name_or_oid); ! clist = FuncnameGetCandidates(names, -1, false, POSITIONAL_NOTATION, NIL); if (clist == NULL) ereport(ERROR, *************** *** 190,196 **** * qualify it. */ clist = FuncnameGetCandidates(list_make1(makeString(proname)), ! -1, false); if (clist != NULL && clist->next == NULL && clist->oid == proid) nspname = NULL; --- 190,196 ---- * qualify it. */ clist = FuncnameGetCandidates(list_make1(makeString(proname)), ! -1, false, POSITIONAL_NOTATION, NIL); if (clist != NULL && clist->next == NULL && clist->oid == proid) nspname = NULL; *************** *** 277,283 **** */ parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes); ! clist = FuncnameGetCandidates(names, nargs, false); for (; clist; clist = clist->next) { --- 277,283 ---- */ parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes); ! clist = FuncnameGetCandidates(names, nargs, false, POSITIONAL_NOTATION, NIL); for (; clist; clist = clist->next) { *** ./src/backend/utils/adt/ruleutils.c.orig 2008-12-08 23:52:45.000000000 +0100 --- ./src/backend/utils/adt/ruleutils.c 2008-12-11 13:47:41.000000000 +0100 *************** *** 1793,1799 **** Node *expr; expr = (Node *) list_nth(argdefaults, i - (numargs - nargdefaults)); ! appendStringInfo(buf, " DEFAULT %s", deparse_expression(expr, dcontext, false, false)); } argsprinted++; --- 1793,1800 ---- Node *expr; expr = (Node *) list_nth(argdefaults, i - (numargs - nargdefaults)); ! if (expr != NULL) ! appendStringInfo(buf, " DEFAULT %s", deparse_expression(expr, dcontext, false, false)); } argsprinted++; *************** *** 6071,6078 **** */ 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) && p_funcid == funcid) nspname = NULL; --- 6072,6081 ---- */ p_result = func_get_detail(list_make1(makeString(proname)), NIL, nargs, argtypes, false, + POSITIONAL_NOTATION, NIL, &p_funcid, &p_rettype, ! &p_retset, &p_nvargs, &p_true_typeids, ! NULL, NULL, NULL, NULL); if ((p_result == FUNCDETAIL_NORMAL || p_result == FUNCDETAIL_AGGREGATE) && p_funcid == funcid) nspname = NULL; *** ./src/include/catalog/namespace.h.orig 2008-12-10 12:32:58.000000000 +0100 --- ./src/include/catalog/namespace.h 2008-12-11 12:16:45.000000000 +0100 *************** *** 14,19 **** --- 14,20 ---- #ifndef NAMESPACE_H #define NAMESPACE_H + #include "nodes/parsenodes.h" #include "nodes/primnodes.h" *************** *** 31,36 **** --- 32,39 ---- int nargs; /* number of arg types returned */ int nvargs; /* number of args to become variadic array */ List *argdefaults; /* list of parameter defaults */ + short int *map_args; + short int *map_defaults; Oid args[1]; /* arg types --- VARIABLE LENGTH ARRAY */ } *FuncCandidateList; /* VARIABLE LENGTH STRUCT */ *************** *** 54,60 **** extern bool TypeIsVisible(Oid typid); extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs, ! bool expand_variadic); extern bool FunctionIsVisible(Oid funcid); extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright); --- 57,63 ---- extern bool TypeIsVisible(Oid typid); extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs, ! bool expand_variadic, Notation notation, List *argnames); extern bool FunctionIsVisible(Oid funcid); extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright); *** ./src/include/nodes/parsenodes.h.orig 2008-12-10 11:06:16.000000000 +0100 --- ./src/include/nodes/parsenodes.h 2008-12-10 11:12:07.000000000 +0100 *************** *** 49,54 **** --- 49,64 ---- SORTBY_NULLS_LAST } SortByNulls; + /* notation used for Func call params */ + typedef enum Notation + { + POSITIONAL_NOTATION, + MIXED_NOTATION, + NAMED_NOTATION + } Notation; + + + /* * Grantable rights are encoded so that we can OR them together in a bitmask. *** ./src/include/parser/parse_func.h.orig 2008-12-10 11:27:33.000000000 +0100 --- ./src/include/parser/parse_func.h 2008-12-11 13:44:27.000000000 +0100 *************** *** 44,56 **** extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool agg_star, bool agg_distinct, bool func_variadic, ! bool is_column, int location); extern FuncDetailCode func_get_detail(List *funcname, List *fargs, int nargs, Oid *argtypes, bool expand_variadic, Oid *funcid, Oid *rettype, bool *retset, int *nvargs, Oid **true_typeids, ! List **argdefaults); extern int func_match_argtypes(int nargs, Oid *input_typeids, --- 44,59 ---- extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool agg_star, bool agg_distinct, bool func_variadic, ! bool is_column, int location, ! Notation notation, List *names); extern FuncDetailCode func_get_detail(List *funcname, List *fargs, int nargs, Oid *argtypes, bool expand_variadic, + Notation notation, List *names, Oid *funcid, Oid *rettype, bool *retset, int *nvargs, Oid **true_typeids, ! List **argdefaults, ! int *pronargs, short int **map_args, short int **map_defaults); extern int func_match_argtypes(int nargs, Oid *input_typeids,
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers