1 /*-------------------------------------------------------------------------
4 * handle function calls in parser
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.50 1999/07/17 20:17:24 momjian Exp $
12 *-------------------------------------------------------------------------
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "catalog/catname.h"
20 #include "catalog/indexing.h"
21 #include "catalog/pg_aggregate.h"
22 #include "catalog/pg_inherits.h"
23 #include "catalog/pg_proc.h"
24 #include "lib/dllist.h"
25 #include "miscadmin.h"
26 #include "nodes/makefuncs.h"
27 #include "nodes/relation.h"
28 #include "parser/parse_agg.h"
29 #include "parser/parse_coerce.h"
30 #include "parser/parse_expr.h"
31 #include "parser/parse_func.h"
32 #include "parser/parse_relation.h"
33 #include "parser/parse_target.h"
34 #include "utils/acl.h"
35 #include "utils/builtins.h"
36 #include "utils/lsyscache.h"
37 #include "utils/syscache.h"
39 static Node *ParseComplexProjection(ParseState *pstate,
43 static Oid **argtype_inherit(int nargs, Oid *oid_array);
45 static int find_inheritors(Oid relid, Oid **supervec);
46 static CandidateList func_get_candidates(char *funcname, int nargs);
48 func_get_detail(char *funcname,
51 Oid *funcid, /* return value */
52 Oid *rettype, /* return value */
53 bool *retset, /* return value */
55 static Oid funcid_get_rettype(Oid funcid);
56 static Oid **gen_cross_product(InhPaths *arginh, int nargs);
57 static void make_arguments(ParseState *pstate,
61 Oid *function_typeids);
62 static int match_argtypes(int nargs,
64 CandidateList function_typeids,
65 CandidateList *candidates);
66 static List *setup_tlist(char *attname, Oid relid);
67 static List *setup_base_tlist(Oid typeid);
68 static Oid *func_select_candidate(int nargs, Oid *input_typeids,
69 CandidateList candidates);
70 static int agg_get_candidates(char *aggname, Oid typeId, CandidateList *candidates);
71 static Oid agg_select_candidate(Oid typeid, CandidateList candidates);
73 #define ISCOMPLEX(type) (typeidTypeRelid(type) ? true : false)
75 typedef struct _SuperQE
81 ** ParseNestedFuncOrColumn
82 ** Given a nested dot expression (i.e. (relation func ... attr), build up
83 ** a tree with of Iter and Func nodes.
86 ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr, int *curr_resno, int precedence)
91 if (attr->paramNo != NULL)
93 Param *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
95 retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
102 Ident *ident = makeNode(Ident);
104 ident->name = attr->relname;
106 retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
112 /* Do more attributes follow this one? */
113 foreach(mutator_iter, lnext(attr->attrs))
115 retval = ParseFuncOrColumn(pstate, strVal(lfirst(mutator_iter)),
125 agg_get_candidates(char *aggname,
127 CandidateList *candidates)
129 CandidateList current_candidate;
130 Relation pg_aggregate_desc;
131 HeapScanDesc pg_aggregate_scan;
133 Form_pg_aggregate agg;
136 static ScanKeyData aggKey[1] = {
137 {0, Anum_pg_aggregate_aggname, F_NAMEEQ}};
141 fmgr_info(F_NAMEEQ, (FmgrInfo *) &aggKey[0].sk_func);
142 aggKey[0].sk_argument = NameGetDatum(aggname);
144 pg_aggregate_desc = heap_openr(AggregateRelationName);
145 pg_aggregate_scan = heap_beginscan(pg_aggregate_desc,
147 SnapshotSelf, /* ??? */
151 while (HeapTupleIsValid(tup = heap_getnext(pg_aggregate_scan, 0)))
153 current_candidate = (CandidateList) palloc(sizeof(struct _CandidateList));
154 current_candidate->args = (Oid *) palloc(sizeof(Oid));
156 agg = (Form_pg_aggregate) GETSTRUCT(tup);
157 current_candidate->args[0] = agg->aggbasetype;
158 current_candidate->next = *candidates;
159 *candidates = current_candidate;
163 heap_endscan(pg_aggregate_scan);
164 heap_close(pg_aggregate_desc);
167 } /* agg_get_candidates() */
169 /* agg_select_candidate()
170 * Try to choose only one candidate aggregate function from a list of possibles.
173 agg_select_candidate(Oid typeid, CandidateList candidates)
175 CandidateList current_candidate;
176 CandidateList last_candidate;
183 * Look for candidates which allow coersion and have a preferred type.
184 * Keep all candidates if none match.
186 category = TypeCategory(typeid);
188 last_candidate = NULL;
189 for (current_candidate = candidates;
190 current_candidate != NULL;
191 current_candidate = current_candidate->next)
193 current_typeid = current_candidate->args[0];
194 current_category = TypeCategory(current_typeid);
196 if ((current_category == category)
197 && IsPreferredType(current_category, current_typeid)
198 && can_coerce_type(1, &typeid, ¤t_typeid))
200 /* only one so far? then keep it... */
201 if (last_candidate == NULL)
203 candidates = current_candidate;
204 last_candidate = current_candidate;
207 /* otherwise, keep this one too... */
210 last_candidate->next = current_candidate;
211 last_candidate = current_candidate;
215 /* otherwise, don't bother keeping this one around... */
216 else if (last_candidate != NULL)
217 last_candidate->next = NULL;
220 return ((ncandidates == 1) ? candidates->args[0] : 0);
221 } /* agg_select_candidate() */
228 ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
229 int *curr_resno, int precedence)
231 Oid rettype = InvalidOid;
232 Oid argrelid = InvalidOid;
233 Oid funcid = InvalidOid;
235 Node *first_arg = NULL;
236 char *relname = NULL;
237 char *refname = NULL;
242 Oid oid_array[MAXFARGS];
246 bool attisset = false;
247 Oid toid = InvalidOid;
252 first_arg = lfirst(fargs);
253 if (first_arg == NULL)
254 elog(ERROR, "Function '%s' does not allow NULL input", funcname);
258 * check for projection methods: if function takes one argument, and
259 * that argument is a relation, param, or PQ function returning a
260 * complex * type, then the function could be a projection.
262 /* We only have one parameter */
263 if (length(fargs) == 1)
265 /* Is is a plain Relation name from the parser? */
266 if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
269 Ident *ident = (Ident *) first_arg;
272 * first arg is a relation. This could be a projection.
274 refname = ident->name;
276 rte = refnameRangeTableEntry(pstate, refname);
278 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE);
280 relname = rte->relname;
284 * If the attr isn't a set, just make a var for it. If it is
285 * a set, treat it like a function and drop through.
287 if (get_attnum(relid, funcname) != InvalidAttrNumber)
289 return (Node *) make_var(pstate,
296 /* drop through - attr is a set */
300 else if (ISCOMPLEX(exprType(first_arg)))
304 * Attempt to handle projection of a complex argument. If
305 * ParseComplexProjection can't handle the projection, we have
308 retval = ParseComplexProjection(pstate,
314 toid = exprType(first_arg);
315 rd = heap_openr(typeidTypeName(toid));
316 if (RelationIsValid(rd))
318 relname = RelationGetRelationName(rd)->data;
322 elog(ERROR, "Type '%s' is not a relation type",
323 typeidTypeName(toid));
324 argrelid = typeidTypeRelid(toid);
327 * A projection contains either an attribute name or the
330 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
331 && strcmp(funcname, "*"))
332 elog(ERROR, "Functions on sets are not yet supported");
342 * Parsing aggregates.
347 CandidateList candidates;
350 * the aggregate COUNT is a special case, ignore its base
351 * type. Treat it as zero
353 if (strcmp(funcname, "count") == 0)
356 basetype = exprType(lfirst(fargs));
358 /* try for exact match first... */
359 if (SearchSysCacheTuple(AGGNAME,
360 PointerGetDatum(funcname),
361 ObjectIdGetDatum(basetype),
363 return (Node *) ParseAgg(pstate, funcname, basetype,
367 * No exact match yet, so see if there is another entry in the
368 * aggregate table which is compatible. - thomas 1998-12-05
370 ncandidates = agg_get_candidates(funcname, basetype, &candidates);
375 type = agg_select_candidate(basetype, candidates);
376 if (OidIsValid(type))
378 lfirst(fargs) = coerce_type(pstate, lfirst(fargs),
382 return (Node *) ParseAgg(pstate, funcname, basetype,
387 elog(ERROR, "Unable to select an aggregate function %s(%s)",
388 funcname, typeidTypeName(basetype));
393 * See if this is a single argument function with the function
394 * name also a type name and the input argument and type name
395 * binary compatible... This means that you are trying for a
396 * type conversion which does not need to take place, so we'll
397 * just pass through the argument itself. (make this clearer
398 * with some extra brackets - thomas 1998-12-05)
400 if ((HeapTupleIsValid(tp = SearchSysCacheTuple(TYPNAME,
401 PointerGetDatum(funcname),
403 && IS_BINARY_COMPATIBLE(typeTypeId(tp), basetype))
404 return ((Node *) lfirst(fargs));
410 * If we dropped through to here it's really a function (or a set,
411 * which is implemented as a function). Extract arg type info and
412 * transform relation name arguments into varnodes of the appropriate
415 MemSet(oid_array, 0, MAXFARGS * sizeof(Oid));
422 Node *pair = lfirst(i);
424 if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
430 refname = ((Ident *) pair)->name;
432 rte = refnameRangeTableEntry(pstate, refname);
434 rte = addRangeTableEntry(pstate, refname, refname,
436 relname = rte->relname;
438 vnum = refnameRangeTablePosn(pstate, rte->refname, NULL);
441 * for func(relname), the param to the function is the tuple
442 * under consideration. we build a special VarNode to reflect
443 * this -- it has varno set to the correct range table entry,
444 * but has varattno == 0 to signal that the whole tuple is the
447 toid = typeTypeId(typenameType(relname));
448 /* replace it in the arg list */
449 lfirst(fargs) = makeVar(vnum, 0, toid, -1, 0, vnum, 0);
452 { /* set functions don't have parameters */
455 * any functiona args which are typed "unknown", but aren't
456 * constants, we don't know what to do with, because we can't
459 if (exprType(pair) == UNKNOWNOID && !IsA(pair, Const))
460 elog(ERROR, "There is no function '%s'"
461 " with argument #%d of type UNKNOWN",
464 toid = exprType(pair);
467 /* Most of the rest of the parser just assumes that functions do not
468 * have more than MAXFARGS parameters. We have to test here to protect
469 * against array overruns, etc.
471 if (nargs >= MAXFARGS)
472 elog(ERROR, "Cannot pass more than %d arguments to a function",
475 oid_array[nargs++] = toid;
479 * func_get_detail looks up the function in the catalogs, does
480 * disambiguation for polymorphic functions, handles inheritance, and
481 * returns the funcid and type and set or singleton status of the
482 * function's return value. it also returns the true argument types
483 * to the function. if func_get_detail returns true, the function
484 * exists. otherwise, there was an error.
487 { /* we know all of these fields already */
490 * We create a funcnode with a placeholder function SetEval.
491 * SetEval() never actually gets executed. When the function
492 * evaluation routines see it, they use the funcid projected out
493 * from the relation as the actual function to call. Example:
494 * retrieve (emp.mgr.name) The plan for this will scan the emp
495 * relation, projecting out the mgr attribute, which is a funcid.
496 * This function is then called (instead of SetEval) and "name" is
497 * projected from its result.
502 true_oid_array = oid_array;
508 exists = func_get_detail(funcname, nargs, oid_array, &funcid,
509 &rettype, &retset, &true_oid_array);
511 elog(ERROR, "No such function '%s' with the specified attributes",
517 funcnode = makeNode(Func);
518 funcnode->funcid = funcid;
519 funcnode->functype = rettype;
520 funcnode->funcisindex = false;
521 funcnode->funcsize = 0;
522 funcnode->func_fcache = NULL;
523 funcnode->func_tlist = NIL;
524 funcnode->func_planlist = NIL;
526 /* perform the necessary typecasting */
527 make_arguments(pstate, nargs, fargs, oid_array, true_oid_array);
530 * for functions returning base types, we want to project out the
531 * return value. set up a target list to do that. the executor will
532 * ignore these for c functions, and do the right thing for postquel
536 if (typeidTypeRelid(rettype) == InvalidOid)
537 funcnode->func_tlist = setup_base_tlist(rettype);
540 * For sets, we want to make a targetlist to project out this
541 * attribute of the set tuples.
545 if (!strcmp(funcname, "*"))
546 funcnode->func_tlist = expandAll(pstate, relname, refname, curr_resno);
549 funcnode->func_tlist = setup_tlist(funcname, argrelid);
550 rettype = get_atttype(argrelid, get_attnum(argrelid, funcname));
557 if (funcid == F_NEXTVAL ||
558 funcid == F_CURRVAL ||
564 int32 aclcheck_result = -1;
566 Assert(length(fargs) == ((funcid == F_SETVAL) ? 2 : 1));
567 seq = (Const *) lfirst(fargs);
568 if (!IsA((Node *) seq, Const))
569 elog(ERROR, "Only constant sequence names are acceptable for function '%s'", funcname);
571 seqrel = textout((text *) DatumGetPointer(seq->constvalue));
572 /* Do we have nextval('"Aa"')? */
573 if (strlen(seqrel) >= 2 &&
574 seqrel[0] == '\"' && seqrel[strlen(seqrel) - 1] == '\"')
576 /* strip off quotes, keep case */
577 seqrel = pstrdup(seqrel + 1);
578 seqrel[strlen(seqrel) - 1] = '\0';
579 pfree(DatumGetPointer(seq->constvalue));
580 seq->constvalue = (Datum) textin(seqrel);
585 seqname = lower((text *) DatumGetPointer(seq->constvalue));
586 pfree(DatumGetPointer(seq->constvalue));
587 seq->constvalue = PointerGetDatum(seqname);
588 seqrel = textout(seqname);
591 if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
592 (((funcid == F_NEXTVAL) || (funcid == F_SETVAL)) ?
595 elog(ERROR, "%s.%s: %s",
596 seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
600 if (funcid == F_NEXTVAL && pstate->p_in_where_clause)
601 elog(ERROR, "Sequence function nextval is not allowed in WHERE clauses");
602 if (funcid == F_SETVAL && pstate->p_in_where_clause)
603 elog(ERROR, "Sequence function setval is not allowed in WHERE clauses");
606 expr = makeNode(Expr);
607 expr->typeOid = rettype;
608 expr->opType = FUNC_EXPR;
609 expr->oper = (Node *) funcnode;
611 retval = (Node *) expr;
614 * if the function returns a set of values, then we need to iterate
615 * over all the returned values in the executor, so we stick an iter
616 * node here. if it returns a singleton, then we don't need the iter
622 Iter *iter = makeNode(Iter);
624 iter->itertype = rettype;
625 iter->iterexpr = retval;
626 retval = (Node *) iter;
633 funcid_get_rettype(Oid funcid)
635 HeapTuple func_tuple = NULL;
636 Oid funcrettype = InvalidOid;
638 func_tuple = SearchSysCacheTuple(PROOID,
639 ObjectIdGetDatum(funcid),
642 if (!HeapTupleIsValid(func_tuple))
643 elog(ERROR, "Function OID %u does not exist", funcid);
646 ((Form_pg_proc) GETSTRUCT(func_tuple))->prorettype;
652 /* func_get_candidates()
653 * get a list of all argument type vectors for which a function named
654 * funcname taking nargs arguments exists
657 func_get_candidates(char *funcname, int nargs)
659 Relation heapRelation;
664 RetrieveIndexResult indexRes;
665 Form_pg_proc pgProcP;
666 CandidateList candidates = NULL;
667 CandidateList current_candidate;
670 heapRelation = heap_openr(ProcedureRelationName);
671 ScanKeyEntryInitialize(&skey,
674 (RegProcedure) F_NAMEEQ,
677 idesc = index_openr(ProcedureNameIndex);
679 sd = index_beginscan(idesc, false, 1, &skey);
683 indexRes = index_getnext(sd, ForwardScanDirection);
688 tuple.t_self = indexRes->heap_iptr;
689 heap_fetch(heapRelation, SnapshotNow, &tuple, &buffer);
691 if (tuple.t_data != NULL)
693 pgProcP = (Form_pg_proc) GETSTRUCT(&tuple);
694 if (pgProcP->pronargs == nargs)
696 current_candidate = (CandidateList)
697 palloc(sizeof(struct _CandidateList));
698 current_candidate->args = (Oid *)
699 palloc(MAXFARGS * sizeof(Oid));
700 MemSet(current_candidate->args, 0, MAXFARGS * sizeof(Oid));
701 for (i = 0; i < nargs; i++)
702 current_candidate->args[i] = pgProcP->proargtypes[i];
704 current_candidate->next = candidates;
705 candidates = current_candidate;
707 ReleaseBuffer(buffer);
714 heap_close(heapRelation);
721 * Given a list of possible typeid arrays to a function and an array of
722 * input typeids, produce a shortlist of those function typeid arrays
723 * that match the input typeids (either exactly or by coercion), and
724 * return the number of such arrays
727 match_argtypes(int nargs,
729 CandidateList function_typeids,
730 CandidateList *candidates) /* return value */
732 CandidateList current_candidate;
733 CandidateList matching_candidate;
734 Oid *current_typeids;
739 for (current_candidate = function_typeids;
740 current_candidate != NULL;
741 current_candidate = current_candidate->next)
743 current_typeids = current_candidate->args;
744 if (can_coerce_type(nargs, input_typeids, current_typeids))
746 matching_candidate = (CandidateList)
747 palloc(sizeof(struct _CandidateList));
748 matching_candidate->args = current_typeids;
749 matching_candidate->next = *candidates;
750 *candidates = matching_candidate;
756 } /* match_argtypes() */
759 /* func_select_candidate()
760 * Given the input argtype array and more than one candidate
761 * for the function argtype array, attempt to resolve the conflict.
762 * returns the selected argtype array if the conflict can be resolved,
763 * otherwise returns NULL.
765 * If all input Oids are UNKNOWNOID, then try matching with TEXTOID.
766 * Otherwise, could return first function arguments on list of candidates.
767 * But for now, return NULL and make the user give a better hint.
768 * - thomas 1998-03-17
771 func_select_candidate(int nargs,
773 CandidateList candidates)
775 CandidateList current_candidate;
776 CandidateList last_candidate;
777 Oid *current_typeids;
785 CATEGORY slot_category,
791 * Run through all candidates and keep those with the most matches
792 * on explicit types. Keep all candidates if none match.
796 last_candidate = NULL;
797 for (current_candidate = candidates;
798 current_candidate != NULL;
799 current_candidate = current_candidate->next)
801 current_typeids = current_candidate->args;
804 for (i = 0; i < nargs; i++)
806 if ((input_typeids[i] != UNKNOWNOID)
807 && (current_typeids[i] == input_typeids[i]))
809 else if (IS_BINARY_COMPATIBLE(current_typeids[i], input_typeids[i]))
813 if ((nmatch + nident) == nargs)
814 return current_candidate->args;
816 if ((nmatch > nbestMatch) || (last_candidate == NULL))
819 candidates = current_candidate;
820 last_candidate = current_candidate;
823 else if (nmatch == nbestMatch)
825 last_candidate->next = current_candidate;
826 last_candidate = current_candidate;
830 last_candidate->next = NULL;
833 if (ncandidates == 1)
834 return candidates->args;
837 * Still too many candidates?
838 * Try assigning types for the unknown columns.
840 for (i = 0; i < nargs; i++)
842 if (input_typeids[i] == UNKNOWNOID)
844 slot_category = INVALID_TYPE;
845 slot_type = InvalidOid;
846 for (current_candidate = candidates;
847 current_candidate != NULL;
848 current_candidate = current_candidate->next)
850 current_typeids = current_candidate->args;
851 current_type = current_typeids[i];
852 current_category = TypeCategory(current_typeids[i]);
854 if (slot_category == InvalidOid)
856 slot_category = current_category;
857 slot_type = current_type;
859 else if ((current_category != slot_category)
860 && IS_BUILTIN_TYPE(current_type))
862 else if (current_type != slot_type)
864 if (IsPreferredType(slot_category, current_type))
866 slot_type = current_type;
867 candidates = current_candidate;
869 else if (IsPreferredType(slot_category, slot_type))
870 candidates->next = current_candidate->next;
874 if (slot_type != InvalidOid)
875 input_typeids[i] = slot_type;
883 for (current_candidate = candidates;
884 current_candidate != NULL;
885 current_candidate = current_candidate->next)
888 if (ncandidates == 1)
889 return candidates->args;
892 } /* func_select_candidate() */
896 * Find the named function in the system catalogs.
898 * Attempt to find the named function in the system catalogs with
899 * arguments exactly as specified, so that the normal case
900 * (exact match) is as quick as possible.
902 * If an exact match isn't found:
903 * 1) get a vector of all possible input arg type arrays constructed
904 * from the superclasses of the original input arg types
905 * 2) get a list of all possible argument type arrays to the function
906 * with given name and number of arguments
907 * 3) for each input arg type array from vector #1:
908 * a) find how many of the function arg type arrays from list #2
909 * it can be coerced to
910 * b) if the answer is one, we have our function
911 * c) if the answer is more than one, attempt to resolve the conflict
912 * d) if the answer is zero, try the next array from vector #1
915 func_get_detail(char *funcname,
918 Oid *funcid, /* return value */
919 Oid *rettype, /* return value */
920 bool *retset, /* return value */
921 Oid **true_typeids) /* return value */
923 Oid **input_typeid_vector;
924 Oid *current_input_typeids;
925 CandidateList function_typeids;
926 CandidateList current_function_typeids;
930 /* attempt to find with arguments exactly as specified... */
931 ftup = SearchSysCacheTuple(PRONAME,
932 PointerGetDatum(funcname),
933 Int32GetDatum(nargs),
934 PointerGetDatum(oid_array),
936 *true_typeids = oid_array;
938 /* didn't find an exact match, so now try to match up candidates... */
939 if (!HeapTupleIsValid(ftup))
941 function_typeids = func_get_candidates(funcname, nargs);
943 /* found something, so let's look through them... */
944 if (function_typeids != NULL)
948 input_typeid_vector = argtype_inherit(nargs, oid_array);
949 current_input_typeids = oid_array;
953 ncandidates = match_argtypes(nargs, current_input_typeids,
955 ¤t_function_typeids);
957 /* one match only? then run with it... */
958 if (ncandidates == 1)
960 *true_typeids = current_function_typeids->args;
961 ftup = SearchSysCacheTuple(PRONAME,
962 PointerGetDatum(funcname),
963 Int32GetDatum(nargs),
964 PointerGetDatum(*true_typeids),
966 Assert(HeapTupleIsValid(ftup));
970 * multiple candidates? then better decide or throw an
973 else if (ncandidates > 1)
975 *true_typeids = func_select_candidate(nargs,
976 current_input_typeids,
977 current_function_typeids);
979 /* couldn't decide, so quit */
980 if (*true_typeids == NULL)
982 func_error(NULL, funcname, nargs, oid_array,
983 "Unable to identify a function which satisfies the given argument types"
984 "\n\tYou will have to retype your query using explicit typecasts");
987 /* found something, so use the first one... */
990 ftup = SearchSysCacheTuple(PRONAME,
991 PointerGetDatum(funcname),
992 Int32GetDatum(nargs),
993 PointerGetDatum(*true_typeids),
995 Assert(HeapTupleIsValid(ftup));
998 current_input_typeids = *input_typeid_vector++;
1000 while (current_input_typeids != InvalidOid && ncandidates == 0);
1004 if (!HeapTupleIsValid(ftup))
1010 tp = typeidType(oid_array[0]);
1011 if (typeTypeFlag(tp) == 'c')
1012 elog(ERROR, "No such attribute or function '%s'", funcname);
1017 pform = (Form_pg_proc) GETSTRUCT(ftup);
1018 *funcid = ftup->t_data->t_oid;
1019 *rettype = pform->prorettype;
1020 *retset = pform->proretset;
1025 /* shouldn't reach here */
1027 } /* func_get_detail() */
1030 * argtype_inherit() -- Construct an argtype vector reflecting the
1031 * inheritance properties of the supplied argv.
1033 * This function is used to disambiguate among functions with the
1034 * same name but different signatures. It takes an array of eight
1035 * type ids. For each type id in the array that's a complex type
1036 * (a class), it walks up the inheritance tree, finding all
1037 * superclasses of that type. A vector of new Oid type arrays
1038 * is returned to the caller, reflecting the structure of the
1039 * inheritance tree above the supplied arguments.
1041 * The order of this vector is as follows: all superclasses of the
1042 * rightmost complex class are explored first. The exploration
1043 * continues from right to left. This policy means that we favor
1044 * keeping the leftmost argument type as low in the inheritance tree
1045 * as possible. This is intentional; it is exactly what we need to
1046 * do for method dispatch. The last type array we return is all
1047 * zeroes. This will match any functions for which return types are
1048 * not defined. There are lots of these (mostly builtins) in the
1052 argtype_inherit(int nargs, Oid *oid_array)
1056 InhPaths arginh[MAXFARGS];
1058 for (i = 0; i < MAXFARGS; i++)
1062 arginh[i].self = oid_array[i];
1063 if ((relid = typeidTypeRelid(oid_array[i])) != InvalidOid)
1064 arginh[i].nsupers = find_inheritors(relid, &(arginh[i].supervec));
1067 arginh[i].nsupers = 0;
1068 arginh[i].supervec = (Oid *) NULL;
1073 arginh[i].self = InvalidOid;
1074 arginh[i].nsupers = 0;
1075 arginh[i].supervec = (Oid *) NULL;
1079 /* return an ordered cross-product of the classes involved */
1080 return gen_cross_product(arginh, nargs);
1084 find_inheritors(Oid relid, Oid **supervec)
1088 HeapScanDesc inhscan;
1091 TupleDesc inhtupdesc;
1106 queue = DLNewList();
1107 visited = DLNewList();
1110 inhrel = heap_openr(InheritsRelationName);
1111 inhtupdesc = RelationGetDescr(inhrel);
1114 * Use queue to do a breadth-first traversal of the inheritance graph
1115 * from the relid supplied up to the root.
1119 ScanKeyEntryInitialize(&skey, 0x0, Anum_pg_inherits_inhrel,
1121 ObjectIdGetDatum(relid));
1123 inhscan = heap_beginscan(inhrel, 0, SnapshotNow, 1, &skey);
1125 while (HeapTupleIsValid(inhtup = heap_getnext(inhscan, 0)))
1127 qentry = (SuperQE *) palloc(sizeof(SuperQE));
1129 d = fastgetattr(inhtup, Anum_pg_inherits_inhparent,
1130 inhtupdesc, &isNull);
1131 qentry->sqe_relid = DatumGetObjectId(d);
1133 /* put this one on the queue */
1134 DLAddTail(queue, DLNewElem(qentry));
1137 heap_endscan(inhscan);
1139 /* pull next unvisited relid off the queue */
1142 qe = DLRemHead(queue);
1143 qentry = qe ? (SuperQE *) DLE_VAL(qe) : NULL;
1145 if (qentry == (SuperQE *) NULL)
1148 relid = qentry->sqe_relid;
1151 for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
1153 vnode = (SuperQE *) DLE_VAL(elt);
1154 if (vnode && (qentry->sqe_relid == vnode->sqe_relid))
1160 } while (!newrelid);
1162 if (qentry != (SuperQE *) NULL)
1165 /* save the type id, rather than the relation id */
1166 if ((rd = heap_open(qentry->sqe_relid)) == (Relation) NULL)
1167 elog(ERROR, "Relid %u does not exist", qentry->sqe_relid);
1168 qentry->sqe_relid = typeTypeId(typenameType(RelationGetRelationName(rd)->data));
1171 DLAddTail(visited, qe);
1175 } while (qentry != (SuperQE *) NULL);
1181 relidvec = (Oid *) palloc(nvisited * sizeof(Oid));
1182 *supervec = relidvec;
1184 for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
1186 vnode = (SuperQE *) DLE_VAL(elt);
1187 *relidvec++ = vnode->sqe_relid;
1192 *supervec = (Oid *) NULL;
1198 gen_cross_product(InhPaths *arginh, int nargs)
1209 for (i = 0; i < nargs; i++)
1211 nanswers *= (arginh[i].nsupers + 2);
1215 iter = result = (Oid **) palloc(sizeof(Oid *) * nanswers);
1217 /* compute the cross product from right to left */
1220 oneres = (Oid *) palloc(MAXFARGS * sizeof(Oid));
1221 MemSet(oneres, 0, MAXFARGS * sizeof(Oid));
1223 for (i = nargs - 1; i >= 0 && cur[i] > arginh[i].nsupers; i--)
1226 /* if we're done, terminate with NULL pointer */
1233 /* no, increment this column and zero the ones after it */
1234 cur[i] = cur[i] + 1;
1235 for (j = nargs - 1; j > i; j--)
1238 for (i = 0; i < nargs; i++)
1241 oneres[i] = arginh[i].self;
1242 else if (cur[i] > arginh[i].nsupers)
1243 oneres[i] = 0; /* wild card */
1245 oneres[i] = arginh[i].supervec[cur[i] - 1];
1254 * Given the number and types of arguments to a function, and the
1255 * actual arguments and argument types, do the necessary typecasting.
1257 * There are two ways an input typeid can differ from a function typeid:
1258 * 1) the input type inherits the function type, so no typecasting required
1259 * 2) the input type can be typecast into the function type
1260 * Right now, we only typecast unknowns, and that is all we check for.
1262 * func_get_detail() now can find coersions for function arguments which
1263 * will make this function executable. So, we need to recover these
1265 * - thomas 1998-03-25
1268 make_arguments(ParseState *pstate,
1272 Oid *function_typeids)
1274 List *current_fargs;
1277 for (i = 0, current_fargs = fargs;
1279 i++, current_fargs = lnext(current_fargs))
1283 * unspecified type for string constant? then use heuristics for
1286 if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
1288 lfirst(current_fargs) = parser_typecast2(lfirst(current_fargs),
1290 typeidType(function_typeids[i]),
1294 /* types don't match? then force coersion using a function call... */
1295 else if (input_typeids[i] != function_typeids[i])
1297 lfirst(current_fargs) = coerce_type(pstate,
1298 lfirst(current_fargs),
1300 function_typeids[i], -1);
1307 ** Build a tlist that says which attribute to project to.
1308 ** This routine is called by ParseFuncOrColumn() to set up a target list
1309 ** on a tuple parameter or return value. Due to a bug in 4.0,
1310 ** it's not possible to refer to system attributes in this case.
1313 setup_tlist(char *attname, Oid relid)
1322 attno = get_attnum(relid, attname);
1324 elog(ERROR, "Cannot reference attribute '%s'"
1325 " of tuple params/return values for functions", attname);
1327 typeid = get_atttype(relid, attno);
1328 type_mod = get_atttypmod(relid, attno);
1330 resnode = makeResdom(1,
1333 get_attname(relid, attno),
1337 varnode = makeVar(-1, attno, typeid, type_mod, 0, -1, attno);
1339 tle = makeTargetEntry(resnode, (Node *) varnode);
1340 return lcons(tle, NIL);
1345 ** Build a tlist that extracts a base type from the tuple
1346 ** returned by the executor.
1349 setup_base_tlist(Oid typeid)
1355 resnode = makeResdom(1,
1362 varnode = makeVar(-1, 1, typeid, -1, 0, -1, 1);
1363 tle = makeTargetEntry(resnode, (Node *) varnode);
1365 return lcons(tle, NIL);
1369 * ParseComplexProjection -
1370 * handles function calls with a single argument that is of complex type.
1371 * This routine returns NULL if it can't handle the projection (eg. sets).
1374 ParseComplexProjection(ParseState *pstate,
1385 switch (nodeTag(first_arg))
1392 iter = (Iter *) first_arg;
1393 func = (Func *) ((Expr *) iter->iterexpr)->oper;
1394 argtype = funcid_get_rettype(func->funcid);
1395 argrelid = typeidTypeRelid(argtype);
1397 ((attnum = get_attnum(argrelid, funcname))
1398 != InvalidAttrNumber))
1402 * the argument is a function returning a tuple, so
1403 * funcname may be a projection
1406 /* add a tlist to the func node and return the Iter */
1407 rd = heap_openr(typeidTypeName(argtype));
1408 if (RelationIsValid(rd))
1410 relid = RelationGetRelid(rd);
1413 if (RelationIsValid(rd))
1415 func->func_tlist = setup_tlist(funcname, argrelid);
1416 iter->itertype = attnumTypeId(rd, attnum);
1417 return (Node *) iter;
1421 elog(ERROR, "Function '%s' has bad return type %d",
1436 * The argument is a set, so this is either a projection
1437 * or a function call on this set.
1444 Expr *expr = (Expr *) first_arg;
1447 if (expr->opType != FUNC_EXPR)
1450 funcnode = (Func *) expr->oper;
1451 argtype = funcid_get_rettype(funcnode->funcid);
1452 argrelid = typeidTypeRelid(argtype);
1455 * the argument is a function returning a tuple, so
1456 * funcname may be a projection
1459 (attnum = get_attnum(argrelid, funcname))
1460 != InvalidAttrNumber)
1463 /* add a tlist to the func node */
1464 rd = heap_openr(typeidTypeName(argtype));
1465 if (RelationIsValid(rd))
1467 relid = RelationGetRelid(rd);
1470 if (RelationIsValid(rd))
1474 funcnode->func_tlist = setup_tlist(funcname, argrelid);
1475 funcnode->functype = attnumTypeId(rd, attnum);
1477 newexpr = makeNode(Expr);
1478 newexpr->typeOid = funcnode->functype;
1479 newexpr->opType = FUNC_EXPR;
1480 newexpr->oper = (Node *) funcnode;
1481 newexpr->args = expr->args;
1483 return (Node *) newexpr;
1492 Param *param = (Param *) first_arg;
1495 * If the Param is a complex type, this could be a
1498 rd = heap_openr(typeidTypeName(param->paramtype));
1499 if (RelationIsValid(rd))
1501 relid = RelationGetRelid(rd);
1503 if ((attnum = get_attnum(relid, funcname))
1504 != InvalidAttrNumber)
1506 param->paramtype = attnumTypeId(rd, attnum);
1507 param->param_tlist = setup_tlist(funcname, relid);
1508 return (Node *) param;
1521 * Error message when function lookup fails that gives details of the
1525 func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg)
1527 char p[(NAMEDATALEN + 2) * MAXFMGRARGS],
1533 for (i = 0; i < nargs; i++)
1540 if (argtypes[i] != 0)
1542 strcpy(ptr, typeidTypeName(argtypes[i]));
1543 *(ptr + NAMEDATALEN) = '\0';
1546 strcpy(ptr, "opaque");
1552 elog(ERROR, "Function '%s(%s)' does not exist%s%s",
1553 funcname, p, ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));
1557 elog(ERROR, "%s: function '%s(%s)' does not exist%s%s",
1558 caller, funcname, p, ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));