]> granicus.if.org Git - postgresql/blob - src/backend/parser/parse_func.c
Move some system includes into c.h, and remove duplicates.
[postgresql] / src / backend / parser / parse_func.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_func.c
4  *              handle function calls in parser
5  *
6  * Copyright (c) 1994, Regents of the University of California
7  *
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.50 1999/07/17 20:17:24 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14
15 #include "postgres.h"
16
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"
38
39 static Node *ParseComplexProjection(ParseState *pstate,
40                                            char *funcname,
41                                            Node *first_arg,
42                                            bool *attisset);
43 static Oid **argtype_inherit(int nargs, Oid *oid_array);
44
45 static int      find_inheritors(Oid relid, Oid **supervec);
46 static CandidateList func_get_candidates(char *funcname, int nargs);
47 static bool
48 func_get_detail(char *funcname,
49                                 int nargs,
50                                 Oid *oid_array,
51                                 Oid *funcid,    /* return value */
52                                 Oid *rettype,   /* return value */
53                                 bool *retset,   /* return value */
54                                 Oid **true_typeids);
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,
58                            int nargs,
59                            List *fargs,
60                            Oid *input_typeids,
61                            Oid *function_typeids);
62 static int match_argtypes(int nargs,
63                            Oid *input_typeids,
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);
72
73 #define ISCOMPLEX(type) (typeidTypeRelid(type) ? true : false)
74
75 typedef struct _SuperQE
76 {
77         Oid                     sqe_relid;
78 } SuperQE;
79
80 /*
81  ** ParseNestedFuncOrColumn
82  **    Given a nested dot expression (i.e. (relation func ... attr), build up
83  ** a tree with of Iter and Func nodes.
84  */
85 Node *
86 ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr, int *curr_resno, int precedence)
87 {
88         List       *mutator_iter;
89         Node       *retval = NULL;
90
91         if (attr->paramNo != NULL)
92         {
93                 Param      *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
94
95                 retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
96                                                                    lcons(param, NIL),
97                                                                    curr_resno,
98                                                                    precedence);
99         }
100         else
101         {
102                 Ident      *ident = makeNode(Ident);
103
104                 ident->name = attr->relname;
105                 ident->isRel = TRUE;
106                 retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
107                                                                    lcons(ident, NIL),
108                                                                    curr_resno,
109                                                                    precedence);
110         }
111
112         /* Do more attributes follow this one? */
113         foreach(mutator_iter, lnext(attr->attrs))
114         {
115                 retval = ParseFuncOrColumn(pstate, strVal(lfirst(mutator_iter)),
116                                                                    lcons(retval, NIL),
117                                                                    curr_resno,
118                                                                    precedence);
119         }
120
121         return retval;
122 }
123
124 static int
125 agg_get_candidates(char *aggname,
126                                    Oid typeId,
127                                    CandidateList *candidates)
128 {
129         CandidateList current_candidate;
130         Relation        pg_aggregate_desc;
131         HeapScanDesc pg_aggregate_scan;
132         HeapTuple       tup;
133         Form_pg_aggregate agg;
134         int                     ncandidates = 0;
135
136         static ScanKeyData aggKey[1] = {
137         {0, Anum_pg_aggregate_aggname, F_NAMEEQ}};
138
139         *candidates = NULL;
140
141         fmgr_info(F_NAMEEQ, (FmgrInfo *) &aggKey[0].sk_func);
142         aggKey[0].sk_argument = NameGetDatum(aggname);
143
144         pg_aggregate_desc = heap_openr(AggregateRelationName);
145         pg_aggregate_scan = heap_beginscan(pg_aggregate_desc,
146                                                                            0,
147                                                                            SnapshotSelf,        /* ??? */
148                                                                            1,
149                                                                            aggKey);
150
151         while (HeapTupleIsValid(tup = heap_getnext(pg_aggregate_scan, 0)))
152         {
153                 current_candidate = (CandidateList) palloc(sizeof(struct _CandidateList));
154                 current_candidate->args = (Oid *) palloc(sizeof(Oid));
155
156                 agg = (Form_pg_aggregate) GETSTRUCT(tup);
157                 current_candidate->args[0] = agg->aggbasetype;
158                 current_candidate->next = *candidates;
159                 *candidates = current_candidate;
160                 ncandidates++;
161         }
162
163         heap_endscan(pg_aggregate_scan);
164         heap_close(pg_aggregate_desc);
165
166         return ncandidates;
167 }       /* agg_get_candidates() */
168
169 /* agg_select_candidate()
170  * Try to choose only one candidate aggregate function from a list of possibles.
171  */
172 static Oid
173 agg_select_candidate(Oid typeid, CandidateList candidates)
174 {
175         CandidateList current_candidate;
176         CandidateList last_candidate;
177         Oid                     current_typeid;
178         int                     ncandidates;
179         CATEGORY        category,
180                                 current_category;
181
182 /*
183  * Look for candidates which allow coersion and have a preferred type.
184  * Keep all candidates if none match.
185  */
186         category = TypeCategory(typeid);
187         ncandidates = 0;
188         last_candidate = NULL;
189         for (current_candidate = candidates;
190                  current_candidate != NULL;
191                  current_candidate = current_candidate->next)
192         {
193                 current_typeid = current_candidate->args[0];
194                 current_category = TypeCategory(current_typeid);
195
196                 if ((current_category == category)
197                         && IsPreferredType(current_category, current_typeid)
198                         && can_coerce_type(1, &typeid, &current_typeid))
199                 {
200                         /* only one so far? then keep it... */
201                         if (last_candidate == NULL)
202                         {
203                                 candidates = current_candidate;
204                                 last_candidate = current_candidate;
205                                 ncandidates = 1;
206                         }
207                         /* otherwise, keep this one too... */
208                         else
209                         {
210                                 last_candidate->next = current_candidate;
211                                 last_candidate = current_candidate;
212                                 ncandidates++;
213                         }
214                 }
215                 /* otherwise, don't bother keeping this one around... */
216                 else if (last_candidate != NULL)
217                         last_candidate->next = NULL;
218         }
219
220         return ((ncandidates == 1) ? candidates->args[0] : 0);
221 }       /* agg_select_candidate() */
222
223
224 /*
225  * parse function
226  */
227 Node *
228 ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
229                                   int *curr_resno, int precedence)
230 {
231         Oid                     rettype = InvalidOid;
232         Oid                     argrelid = InvalidOid;
233         Oid                     funcid = InvalidOid;
234         List       *i = NIL;
235         Node       *first_arg = NULL;
236         char       *relname = NULL;
237         char       *refname = NULL;
238         Relation        rd;
239         Oid                     relid;
240         int                     nargs;
241         Func       *funcnode;
242         Oid                     oid_array[MAXFARGS];
243         Oid                *true_oid_array;
244         Node       *retval;
245         bool            retset;
246         bool            attisset = false;
247         Oid                     toid = InvalidOid;
248         Expr       *expr;
249
250         if (fargs)
251         {
252                 first_arg = lfirst(fargs);
253                 if (first_arg == NULL)
254                         elog(ERROR, "Function '%s' does not allow NULL input", funcname);
255         }
256
257         /*
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.
261          */
262         /* We only have one parameter */
263         if (length(fargs) == 1)
264         {
265                 /* Is is a plain Relation name from the parser? */
266                 if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
267                 {
268                         RangeTblEntry *rte;
269                         Ident      *ident = (Ident *) first_arg;
270
271                         /*
272                          * first arg is a relation. This could be a projection.
273                          */
274                         refname = ident->name;
275
276                         rte = refnameRangeTableEntry(pstate, refname);
277                         if (rte == NULL)
278                                 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE);
279
280                         relname = rte->relname;
281                         relid = rte->relid;
282
283                         /*
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.
286                          */
287                         if (get_attnum(relid, funcname) != InvalidAttrNumber)
288                         {
289                                 return (Node *) make_var(pstate,
290                                                                                  relid,
291                                                                                  refname,
292                                                                                  funcname);
293                         }
294                         else
295                         {
296                                 /* drop through - attr is a set */
297                                 ;
298                         }
299                 }
300                 else if (ISCOMPLEX(exprType(first_arg)))
301                 {
302
303                         /*
304                          * Attempt to handle projection of a complex argument. If
305                          * ParseComplexProjection can't handle the projection, we have
306                          * to keep going.
307                          */
308                         retval = ParseComplexProjection(pstate,
309                                                                                         funcname,
310                                                                                         first_arg,
311                                                                                         &attisset);
312                         if (attisset)
313                         {
314                                 toid = exprType(first_arg);
315                                 rd = heap_openr(typeidTypeName(toid));
316                                 if (RelationIsValid(rd))
317                                 {
318                                         relname = RelationGetRelationName(rd)->data;
319                                         heap_close(rd);
320                                 }
321                                 else
322                                         elog(ERROR, "Type '%s' is not a relation type",
323                                                  typeidTypeName(toid));
324                                 argrelid = typeidTypeRelid(toid);
325
326                                 /*
327                                  * A projection contains either an attribute name or the
328                                  * "*".
329                                  */
330                                 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
331                                         && strcmp(funcname, "*"))
332                                         elog(ERROR, "Functions on sets are not yet supported");
333                         }
334
335                         if (retval)
336                                 return retval;
337                 }
338                 else
339                 {
340
341                         /*
342                          * Parsing aggregates.
343                          */
344                         Type            tp;
345                         Oid                     basetype;
346                         int                     ncandidates;
347                         CandidateList candidates;
348
349                         /*
350                          * the aggregate COUNT is a special case, ignore its base
351                          * type.  Treat it as zero
352                          */
353                         if (strcmp(funcname, "count") == 0)
354                                 basetype = 0;
355                         else
356                                 basetype = exprType(lfirst(fargs));
357
358                         /* try for exact match first... */
359                         if (SearchSysCacheTuple(AGGNAME,
360                                                                         PointerGetDatum(funcname),
361                                                                         ObjectIdGetDatum(basetype),
362                                                                         0, 0))
363                                 return (Node *) ParseAgg(pstate, funcname, basetype,
364                                                                                  fargs, precedence);
365
366                         /*
367                          * No exact match yet, so see if there is another entry in the
368                          * aggregate table which is compatible. - thomas 1998-12-05
369                          */
370                         ncandidates = agg_get_candidates(funcname, basetype, &candidates);
371                         if (ncandidates > 0)
372                         {
373                                 Oid                     type;
374
375                                 type = agg_select_candidate(basetype, candidates);
376                                 if (OidIsValid(type))
377                                 {
378                                         lfirst(fargs) = coerce_type(pstate, lfirst(fargs),
379                                                                                                 basetype, type, -1);
380                                         basetype = type;
381
382                                         return (Node *) ParseAgg(pstate, funcname, basetype,
383                                                                                          fargs, precedence);
384                                 }
385                                 else
386                                 {
387                                         elog(ERROR, "Unable to select an aggregate function %s(%s)",
388                                                  funcname, typeidTypeName(basetype));
389                                 }
390                         }
391
392                         /*
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)
399                          */
400                         if ((HeapTupleIsValid(tp = SearchSysCacheTuple(TYPNAME,
401                                                                                            PointerGetDatum(funcname),
402                                                                                                                    0, 0, 0)))
403                                 && IS_BINARY_COMPATIBLE(typeTypeId(tp), basetype))
404                                 return ((Node *) lfirst(fargs));
405                 }
406         }
407
408
409         /*
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
413          * form.
414          */
415         MemSet(oid_array, 0, MAXFARGS * sizeof(Oid));
416
417         nargs = 0;
418         foreach(i, fargs)
419         {
420                 int                     vnum;
421                 RangeTblEntry *rte;
422                 Node       *pair = lfirst(i);
423
424                 if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
425                 {
426
427                         /*
428                          * a relation
429                          */
430                         refname = ((Ident *) pair)->name;
431
432                         rte = refnameRangeTableEntry(pstate, refname);
433                         if (rte == NULL)
434                                 rte = addRangeTableEntry(pstate, refname, refname,
435                                                                                  FALSE, FALSE);
436                         relname = rte->relname;
437
438                         vnum = refnameRangeTablePosn(pstate, rte->refname, NULL);
439
440                         /*
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
445                          * argument.
446                          */
447                         toid = typeTypeId(typenameType(relname));
448                         /* replace it in the arg list */
449                         lfirst(fargs) = makeVar(vnum, 0, toid, -1, 0, vnum, 0);
450                 }
451                 else if (!attisset)
452                 {                                               /* set functions don't have parameters */
453
454                         /*
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
457                          * cast them    - jolly
458                          */
459                         if (exprType(pair) == UNKNOWNOID && !IsA(pair, Const))
460                                 elog(ERROR, "There is no function '%s'"
461                                          " with argument #%d of type UNKNOWN",
462                                          funcname, nargs);
463                         else
464                                 toid = exprType(pair);
465                 }
466
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.
470                  */
471                 if (nargs >= MAXFARGS)
472                         elog(ERROR, "Cannot pass more than %d arguments to a function",
473                                  MAXFARGS);
474
475                 oid_array[nargs++] = toid;
476         }
477
478         /*
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.
485          */
486         if (attisset)
487         {                                                       /* we know all of these fields already */
488
489                 /*
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.
498                  */
499                 funcid = F_SETEVAL;
500                 rettype = toid;
501                 retset = true;
502                 true_oid_array = oid_array;
503         }
504         else
505         {
506                 bool            exists;
507
508                 exists = func_get_detail(funcname, nargs, oid_array, &funcid,
509                                                                  &rettype, &retset, &true_oid_array);
510                 if (!exists)
511                         elog(ERROR, "No such function '%s' with the specified attributes",
512                                  funcname);
513
514         }
515
516         /* got it */
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;
525
526         /* perform the necessary typecasting */
527         make_arguments(pstate, nargs, fargs, oid_array, true_oid_array);
528
529         /*
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
533          * functions.
534          */
535
536         if (typeidTypeRelid(rettype) == InvalidOid)
537                 funcnode->func_tlist = setup_base_tlist(rettype);
538
539         /*
540          * For sets, we want to make a targetlist to project out this
541          * attribute of the set tuples.
542          */
543         if (attisset)
544         {
545                 if (!strcmp(funcname, "*"))
546                         funcnode->func_tlist = expandAll(pstate, relname, refname, curr_resno);
547                 else
548                 {
549                         funcnode->func_tlist = setup_tlist(funcname, argrelid);
550                         rettype = get_atttype(argrelid, get_attnum(argrelid, funcname));
551                 }
552         }
553
554         /*
555          * Sequence handling.
556          */
557         if (funcid == F_NEXTVAL ||
558                 funcid == F_CURRVAL ||
559                 funcid == F_SETVAL)
560         {
561                 Const      *seq;
562                 char       *seqrel;
563                 text       *seqname;
564                 int32           aclcheck_result = -1;
565
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);
570
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] == '\"')
575                 {
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);
581                 }
582                 else
583                 {
584                         pfree(seqrel);
585                         seqname = lower((text *) DatumGetPointer(seq->constvalue));
586                         pfree(DatumGetPointer(seq->constvalue));
587                         seq->constvalue = PointerGetDatum(seqname);
588                         seqrel = textout(seqname);
589                 }
590
591                 if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
592                                            (((funcid == F_NEXTVAL) || (funcid == F_SETVAL)) ?
593                                                 ACL_WR : ACL_RD)))
594                         != ACLCHECK_OK)
595                         elog(ERROR, "%s.%s: %s",
596                           seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
597
598                 pfree(seqrel);
599
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");
604         }
605
606         expr = makeNode(Expr);
607         expr->typeOid = rettype;
608         expr->opType = FUNC_EXPR;
609         expr->oper = (Node *) funcnode;
610         expr->args = fargs;
611         retval = (Node *) expr;
612
613         /*
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
617          * node.
618          */
619
620         if (retset)
621         {
622                 Iter       *iter = makeNode(Iter);
623
624                 iter->itertype = rettype;
625                 iter->iterexpr = retval;
626                 retval = (Node *) iter;
627         }
628
629         return retval;
630 }
631
632 static Oid
633 funcid_get_rettype(Oid funcid)
634 {
635         HeapTuple       func_tuple = NULL;
636         Oid                     funcrettype = InvalidOid;
637
638         func_tuple = SearchSysCacheTuple(PROOID,
639                                                                          ObjectIdGetDatum(funcid),
640                                                                          0, 0, 0);
641
642         if (!HeapTupleIsValid(func_tuple))
643                 elog(ERROR, "Function OID %u does not exist", funcid);
644
645         funcrettype = (Oid)
646                 ((Form_pg_proc) GETSTRUCT(func_tuple))->prorettype;
647
648         return funcrettype;
649 }
650
651
652 /* func_get_candidates()
653  * get a list of all argument type vectors for which a function named
654  * funcname taking nargs arguments exists
655  */
656 static CandidateList
657 func_get_candidates(char *funcname, int nargs)
658 {
659         Relation        heapRelation;
660         Relation        idesc;
661         ScanKeyData skey;
662         HeapTupleData tuple;
663         IndexScanDesc sd;
664         RetrieveIndexResult indexRes;
665         Form_pg_proc pgProcP;
666         CandidateList candidates = NULL;
667         CandidateList current_candidate;
668         int                     i;
669
670         heapRelation = heap_openr(ProcedureRelationName);
671         ScanKeyEntryInitialize(&skey,
672                                                    (bits16) 0x0,
673                                                    (AttrNumber) 1,
674                                                    (RegProcedure) F_NAMEEQ,
675                                                    (Datum) funcname);
676
677         idesc = index_openr(ProcedureNameIndex);
678
679         sd = index_beginscan(idesc, false, 1, &skey);
680
681         do
682         {
683                 indexRes = index_getnext(sd, ForwardScanDirection);
684                 if (indexRes)
685                 {
686                         Buffer          buffer;
687
688                         tuple.t_self = indexRes->heap_iptr;
689                         heap_fetch(heapRelation, SnapshotNow, &tuple, &buffer);
690                         pfree(indexRes);
691                         if (tuple.t_data != NULL)
692                         {
693                                 pgProcP = (Form_pg_proc) GETSTRUCT(&tuple);
694                                 if (pgProcP->pronargs == nargs)
695                                 {
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];
703
704                                         current_candidate->next = candidates;
705                                         candidates = current_candidate;
706                                 }
707                                 ReleaseBuffer(buffer);
708                         }
709                 }
710         } while (indexRes);
711
712         index_endscan(sd);
713         index_close(idesc);
714         heap_close(heapRelation);
715
716         return candidates;
717 }
718
719
720 /* match_argtypes()
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
725  */
726 static int
727 match_argtypes(int nargs,
728                            Oid *input_typeids,
729                            CandidateList function_typeids,
730                            CandidateList *candidates)           /* return value */
731 {
732         CandidateList current_candidate;
733         CandidateList matching_candidate;
734         Oid                *current_typeids;
735         int                     ncandidates = 0;
736
737         *candidates = NULL;
738
739         for (current_candidate = function_typeids;
740                  current_candidate != NULL;
741                  current_candidate = current_candidate->next)
742         {
743                 current_typeids = current_candidate->args;
744                 if (can_coerce_type(nargs, input_typeids, current_typeids))
745                 {
746                         matching_candidate = (CandidateList)
747                                 palloc(sizeof(struct _CandidateList));
748                         matching_candidate->args = current_typeids;
749                         matching_candidate->next = *candidates;
750                         *candidates = matching_candidate;
751                         ncandidates++;
752                 }
753         }
754
755         return ncandidates;
756 }       /* match_argtypes() */
757
758
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.
764  *
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
769  */
770 static Oid *
771 func_select_candidate(int nargs,
772                                           Oid *input_typeids,
773                                           CandidateList candidates)
774 {
775         CandidateList current_candidate;
776         CandidateList last_candidate;
777         Oid                *current_typeids;
778         int                     i;
779
780         int                     ncandidates;
781         int                     nbestMatch,
782                                 nmatch,
783                                 nident;
784
785         CATEGORY        slot_category,
786                                 current_category;
787         Oid                     slot_type,
788                                 current_type;
789
790 /*
791  * Run through all candidates and keep those with the most matches
792  *      on explicit types. Keep all candidates if none match.
793  */
794         ncandidates = 0;
795         nbestMatch = 0;
796         last_candidate = NULL;
797         for (current_candidate = candidates;
798                  current_candidate != NULL;
799                  current_candidate = current_candidate->next)
800         {
801                 current_typeids = current_candidate->args;
802                 nmatch = 0;
803                 nident = 0;
804                 for (i = 0; i < nargs; i++)
805                 {
806                         if ((input_typeids[i] != UNKNOWNOID)
807                                 && (current_typeids[i] == input_typeids[i]))
808                                 nmatch++;
809                         else if (IS_BINARY_COMPATIBLE(current_typeids[i], input_typeids[i]))
810                                 nident++;
811                 }
812
813                 if ((nmatch + nident) == nargs)
814                         return current_candidate->args;
815
816                 if ((nmatch > nbestMatch) || (last_candidate == NULL))
817                 {
818                         nbestMatch = nmatch;
819                         candidates = current_candidate;
820                         last_candidate = current_candidate;
821                         ncandidates = 1;
822                 }
823                 else if (nmatch == nbestMatch)
824                 {
825                         last_candidate->next = current_candidate;
826                         last_candidate = current_candidate;
827                         ncandidates++;
828                 }
829                 else
830                         last_candidate->next = NULL;
831         }
832
833         if (ncandidates == 1)
834                 return candidates->args;
835
836 /*
837  * Still too many candidates?
838  * Try assigning types for the unknown columns.
839  */
840         for (i = 0; i < nargs; i++)
841         {
842                 if (input_typeids[i] == UNKNOWNOID)
843                 {
844                         slot_category = INVALID_TYPE;
845                         slot_type = InvalidOid;
846                         for (current_candidate = candidates;
847                                  current_candidate != NULL;
848                                  current_candidate = current_candidate->next)
849                         {
850                                 current_typeids = current_candidate->args;
851                                 current_type = current_typeids[i];
852                                 current_category = TypeCategory(current_typeids[i]);
853
854                                 if (slot_category == InvalidOid)
855                                 {
856                                         slot_category = current_category;
857                                         slot_type = current_type;
858                                 }
859                                 else if ((current_category != slot_category)
860                                                  && IS_BUILTIN_TYPE(current_type))
861                                         return NULL;
862                                 else if (current_type != slot_type)
863                                 {
864                                         if (IsPreferredType(slot_category, current_type))
865                                         {
866                                                 slot_type = current_type;
867                                                 candidates = current_candidate;
868                                         }
869                                         else if (IsPreferredType(slot_category, slot_type))
870                                                 candidates->next = current_candidate->next;
871                                 }
872                         }
873
874                         if (slot_type != InvalidOid)
875                                 input_typeids[i] = slot_type;
876                 }
877                 else
878                 {
879                 }
880         }
881
882         ncandidates = 0;
883         for (current_candidate = candidates;
884                  current_candidate != NULL;
885                  current_candidate = current_candidate->next)
886                 ncandidates++;
887
888         if (ncandidates == 1)
889                 return candidates->args;
890
891         return NULL;
892 }       /* func_select_candidate() */
893
894
895 /* func_get_detail()
896  * Find the named function in the system catalogs.
897  *
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.
901  *
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
913  */
914 static bool
915 func_get_detail(char *funcname,
916                                 int nargs,
917                                 Oid *oid_array,
918                                 Oid *funcid,    /* return value */
919                                 Oid *rettype,   /* return value */
920                                 bool *retset,   /* return value */
921                                 Oid **true_typeids)             /* return value */
922 {
923         Oid               **input_typeid_vector;
924         Oid                *current_input_typeids;
925         CandidateList function_typeids;
926         CandidateList current_function_typeids;
927         HeapTuple       ftup;
928         Form_pg_proc pform;
929
930         /* attempt to find with arguments exactly as specified... */
931         ftup = SearchSysCacheTuple(PRONAME,
932                                                            PointerGetDatum(funcname),
933                                                            Int32GetDatum(nargs),
934                                                            PointerGetDatum(oid_array),
935                                                            0);
936         *true_typeids = oid_array;
937
938         /* didn't find an exact match, so now try to match up candidates... */
939         if (!HeapTupleIsValid(ftup))
940         {
941                 function_typeids = func_get_candidates(funcname, nargs);
942
943                 /* found something, so let's look through them... */
944                 if (function_typeids != NULL)
945                 {
946                         int                     ncandidates;
947
948                         input_typeid_vector = argtype_inherit(nargs, oid_array);
949                         current_input_typeids = oid_array;
950
951                         do
952                         {
953                                 ncandidates = match_argtypes(nargs, current_input_typeids,
954                                                                                          function_typeids,
955                                                                                          &current_function_typeids);
956
957                                 /* one match only? then run with it... */
958                                 if (ncandidates == 1)
959                                 {
960                                         *true_typeids = current_function_typeids->args;
961                                         ftup = SearchSysCacheTuple(PRONAME,
962                                                                                            PointerGetDatum(funcname),
963                                                                                            Int32GetDatum(nargs),
964                                                                                   PointerGetDatum(*true_typeids),
965                                                                                            0);
966                                         Assert(HeapTupleIsValid(ftup));
967                                 }
968
969                                 /*
970                                  * multiple candidates? then better decide or throw an
971                                  * error...
972                                  */
973                                 else if (ncandidates > 1)
974                                 {
975                                         *true_typeids = func_select_candidate(nargs,
976                                                                                                    current_input_typeids,
977                                                                                            current_function_typeids);
978
979                                         /* couldn't decide, so quit */
980                                         if (*true_typeids == NULL)
981                                         {
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");
985                                         }
986
987                                         /* found something, so use the first one... */
988                                         else
989                                         {
990                                                 ftup = SearchSysCacheTuple(PRONAME,
991                                                                                            PointerGetDatum(funcname),
992                                                                                                    Int32GetDatum(nargs),
993                                                                                   PointerGetDatum(*true_typeids),
994                                                                                                    0);
995                                                 Assert(HeapTupleIsValid(ftup));
996                                         }
997                                 }
998                                 current_input_typeids = *input_typeid_vector++;
999                         }
1000                         while (current_input_typeids != InvalidOid && ncandidates == 0);
1001                 }
1002         }
1003
1004         if (!HeapTupleIsValid(ftup))
1005         {
1006                 Type            tp;
1007
1008                 if (nargs == 1)
1009                 {
1010                         tp = typeidType(oid_array[0]);
1011                         if (typeTypeFlag(tp) == 'c')
1012                                 elog(ERROR, "No such attribute or function '%s'", funcname);
1013                 }
1014         }
1015         else
1016         {
1017                 pform = (Form_pg_proc) GETSTRUCT(ftup);
1018                 *funcid = ftup->t_data->t_oid;
1019                 *rettype = pform->prorettype;
1020                 *retset = pform->proretset;
1021
1022                 return true;
1023         }
1024
1025         /* shouldn't reach here */
1026         return false;
1027 }       /* func_get_detail() */
1028
1029 /*
1030  *      argtype_inherit() -- Construct an argtype vector reflecting the
1031  *                                               inheritance properties of the supplied argv.
1032  *
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.
1040  *
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
1049  *              catalogs.
1050  */
1051 static Oid **
1052 argtype_inherit(int nargs, Oid *oid_array)
1053 {
1054         Oid                     relid;
1055         int                     i;
1056         InhPaths        arginh[MAXFARGS];
1057
1058         for (i = 0; i < MAXFARGS; i++)
1059         {
1060                 if (i < nargs)
1061                 {
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));
1065                         else
1066                         {
1067                                 arginh[i].nsupers = 0;
1068                                 arginh[i].supervec = (Oid *) NULL;
1069                         }
1070                 }
1071                 else
1072                 {
1073                         arginh[i].self = InvalidOid;
1074                         arginh[i].nsupers = 0;
1075                         arginh[i].supervec = (Oid *) NULL;
1076                 }
1077         }
1078
1079         /* return an ordered cross-product of the classes involved */
1080         return gen_cross_product(arginh, nargs);
1081 }
1082
1083 static int
1084 find_inheritors(Oid relid, Oid **supervec)
1085 {
1086         Oid                *relidvec;
1087         Relation        inhrel;
1088         HeapScanDesc inhscan;
1089         ScanKeyData skey;
1090         HeapTuple       inhtup;
1091         TupleDesc       inhtupdesc;
1092         int                     nvisited;
1093         SuperQE    *qentry,
1094                            *vnode;
1095         Dllist     *visited,
1096                            *queue;
1097         Dlelem     *qe,
1098                            *elt;
1099
1100         Relation        rd;
1101         Datum           d;
1102         bool            newrelid;
1103         char            isNull;
1104
1105         nvisited = 0;
1106         queue = DLNewList();
1107         visited = DLNewList();
1108
1109
1110         inhrel = heap_openr(InheritsRelationName);
1111         inhtupdesc = RelationGetDescr(inhrel);
1112
1113         /*
1114          * Use queue to do a breadth-first traversal of the inheritance graph
1115          * from the relid supplied up to the root.
1116          */
1117         do
1118         {
1119                 ScanKeyEntryInitialize(&skey, 0x0, Anum_pg_inherits_inhrel,
1120                                                            F_OIDEQ,
1121                                                            ObjectIdGetDatum(relid));
1122
1123                 inhscan = heap_beginscan(inhrel, 0, SnapshotNow, 1, &skey);
1124
1125                 while (HeapTupleIsValid(inhtup = heap_getnext(inhscan, 0)))
1126                 {
1127                         qentry = (SuperQE *) palloc(sizeof(SuperQE));
1128
1129                         d = fastgetattr(inhtup, Anum_pg_inherits_inhparent,
1130                                                         inhtupdesc, &isNull);
1131                         qentry->sqe_relid = DatumGetObjectId(d);
1132
1133                         /* put this one on the queue */
1134                         DLAddTail(queue, DLNewElem(qentry));
1135                 }
1136
1137                 heap_endscan(inhscan);
1138
1139                 /* pull next unvisited relid off the queue */
1140                 do
1141                 {
1142                         qe = DLRemHead(queue);
1143                         qentry = qe ? (SuperQE *) DLE_VAL(qe) : NULL;
1144
1145                         if (qentry == (SuperQE *) NULL)
1146                                 break;
1147
1148                         relid = qentry->sqe_relid;
1149                         newrelid = true;
1150
1151                         for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
1152                         {
1153                                 vnode = (SuperQE *) DLE_VAL(elt);
1154                                 if (vnode && (qentry->sqe_relid == vnode->sqe_relid))
1155                                 {
1156                                         newrelid = false;
1157                                         break;
1158                                 }
1159                         }
1160                 } while (!newrelid);
1161
1162                 if (qentry != (SuperQE *) NULL)
1163                 {
1164
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));
1169                         heap_close(rd);
1170
1171                         DLAddTail(visited, qe);
1172
1173                         nvisited++;
1174                 }
1175         } while (qentry != (SuperQE *) NULL);
1176
1177         heap_close(inhrel);
1178
1179         if (nvisited > 0)
1180         {
1181                 relidvec = (Oid *) palloc(nvisited * sizeof(Oid));
1182                 *supervec = relidvec;
1183
1184                 for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
1185                 {
1186                         vnode = (SuperQE *) DLE_VAL(elt);
1187                         *relidvec++ = vnode->sqe_relid;
1188                 }
1189
1190         }
1191         else
1192                 *supervec = (Oid *) NULL;
1193
1194         return nvisited;
1195 }
1196
1197 static Oid **
1198 gen_cross_product(InhPaths *arginh, int nargs)
1199 {
1200         int                     nanswers;
1201         Oid               **result,
1202                           **iter;
1203         Oid                *oneres;
1204         int                     i,
1205                                 j;
1206         int                     cur[MAXFARGS];
1207
1208         nanswers = 1;
1209         for (i = 0; i < nargs; i++)
1210         {
1211                 nanswers *= (arginh[i].nsupers + 2);
1212                 cur[i] = 0;
1213         }
1214
1215         iter = result = (Oid **) palloc(sizeof(Oid *) * nanswers);
1216
1217         /* compute the cross product from right to left */
1218         for (;;)
1219         {
1220                 oneres = (Oid *) palloc(MAXFARGS * sizeof(Oid));
1221                 MemSet(oneres, 0, MAXFARGS * sizeof(Oid));
1222
1223                 for (i = nargs - 1; i >= 0 && cur[i] > arginh[i].nsupers; i--)
1224                         continue;
1225
1226                 /* if we're done, terminate with NULL pointer */
1227                 if (i < 0)
1228                 {
1229                         *iter = NULL;
1230                         return result;
1231                 }
1232
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--)
1236                         cur[j] = 0;
1237
1238                 for (i = 0; i < nargs; i++)
1239                 {
1240                         if (cur[i] == 0)
1241                                 oneres[i] = arginh[i].self;
1242                         else if (cur[i] > arginh[i].nsupers)
1243                                 oneres[i] = 0;  /* wild card */
1244                         else
1245                                 oneres[i] = arginh[i].supervec[cur[i] - 1];
1246                 }
1247
1248                 *iter++ = oneres;
1249         }
1250 }
1251
1252
1253 /* make_arguments()
1254  * Given the number and types of arguments to a function, and the
1255  *      actual arguments and argument types, do the necessary typecasting.
1256  *
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.
1261  *
1262  * func_get_detail() now can find coersions for function arguments which
1263  *      will make this function executable. So, we need to recover these
1264  *      results here too.
1265  * - thomas 1998-03-25
1266  */
1267 static void
1268 make_arguments(ParseState *pstate,
1269                            int nargs,
1270                            List *fargs,
1271                            Oid *input_typeids,
1272                            Oid *function_typeids)
1273 {
1274         List       *current_fargs;
1275         int                     i;
1276
1277         for (i = 0, current_fargs = fargs;
1278                  i < nargs;
1279                  i++, current_fargs = lnext(current_fargs))
1280         {
1281
1282                 /*
1283                  * unspecified type for string constant? then use heuristics for
1284                  * conversion...
1285                  */
1286                 if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
1287                 {
1288                         lfirst(current_fargs) = parser_typecast2(lfirst(current_fargs),
1289                                                                                                          input_typeids[i],
1290                                                                                  typeidType(function_typeids[i]),
1291                                                                                                          -1);
1292                 }
1293
1294                 /* types don't match? then force coersion using a function call... */
1295                 else if (input_typeids[i] != function_typeids[i])
1296                 {
1297                         lfirst(current_fargs) = coerce_type(pstate,
1298                                                                                                 lfirst(current_fargs),
1299                                                                                                 input_typeids[i],
1300                                                                                                 function_typeids[i], -1);
1301                 }
1302         }
1303 }
1304
1305 /*
1306  ** setup_tlist
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.
1311  */
1312 static List *
1313 setup_tlist(char *attname, Oid relid)
1314 {
1315         TargetEntry *tle;
1316         Resdom     *resnode;
1317         Var                *varnode;
1318         Oid                     typeid;
1319         int32           type_mod;
1320         int                     attno;
1321
1322         attno = get_attnum(relid, attname);
1323         if (attno < 0)
1324                 elog(ERROR, "Cannot reference attribute '%s'"
1325                          " of tuple params/return values for functions", attname);
1326
1327         typeid = get_atttype(relid, attno);
1328         type_mod = get_atttypmod(relid, attno);
1329
1330         resnode = makeResdom(1,
1331                                                  typeid,
1332                                                  type_mod,
1333                                                  get_attname(relid, attno),
1334                                                  0,
1335                                                  InvalidOid,
1336                                                  false);
1337         varnode = makeVar(-1, attno, typeid, type_mod, 0, -1, attno);
1338
1339         tle = makeTargetEntry(resnode, (Node *) varnode);
1340         return lcons(tle, NIL);
1341 }
1342
1343 /*
1344  ** setup_base_tlist
1345  **             Build a tlist that extracts a base type from the tuple
1346  **             returned by the executor.
1347  */
1348 static List *
1349 setup_base_tlist(Oid typeid)
1350 {
1351         TargetEntry *tle;
1352         Resdom     *resnode;
1353         Var                *varnode;
1354
1355         resnode = makeResdom(1,
1356                                                  typeid,
1357                                                  -1,
1358                                                  "<noname>",
1359                                                  0,
1360                                                  InvalidOid,
1361                                                  false);
1362         varnode = makeVar(-1, 1, typeid, -1, 0, -1, 1);
1363         tle = makeTargetEntry(resnode, (Node *) varnode);
1364
1365         return lcons(tle, NIL);
1366 }
1367
1368 /*
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).
1372  */
1373 static Node *
1374 ParseComplexProjection(ParseState *pstate,
1375                                            char *funcname,
1376                                            Node *first_arg,
1377                                            bool *attisset)
1378 {
1379         Oid                     argtype;
1380         Oid                     argrelid;
1381         Relation        rd;
1382         Oid                     relid;
1383         int                     attnum;
1384
1385         switch (nodeTag(first_arg))
1386         {
1387                 case T_Iter:
1388                         {
1389                                 Func       *func;
1390                                 Iter       *iter;
1391
1392                                 iter = (Iter *) first_arg;
1393                                 func = (Func *) ((Expr *) iter->iterexpr)->oper;
1394                                 argtype = funcid_get_rettype(func->funcid);
1395                                 argrelid = typeidTypeRelid(argtype);
1396                                 if (argrelid &&
1397                                         ((attnum = get_attnum(argrelid, funcname))
1398                                          != InvalidAttrNumber))
1399                                 {
1400
1401                                         /*
1402                                          * the argument is a function returning a tuple, so
1403                                          * funcname may be a projection
1404                                          */
1405
1406                                         /* add a tlist to the func node and return the Iter */
1407                                         rd = heap_openr(typeidTypeName(argtype));
1408                                         if (RelationIsValid(rd))
1409                                         {
1410                                                 relid = RelationGetRelid(rd);
1411                                                 heap_close(rd);
1412                                         }
1413                                         if (RelationIsValid(rd))
1414                                         {
1415                                                 func->func_tlist = setup_tlist(funcname, argrelid);
1416                                                 iter->itertype = attnumTypeId(rd, attnum);
1417                                                 return (Node *) iter;
1418                                         }
1419                                         else
1420                                         {
1421                                                 elog(ERROR, "Function '%s' has bad return type %d",
1422                                                          funcname, argtype);
1423                                         }
1424                                 }
1425                                 else
1426                                 {
1427                                         /* drop through */
1428                                         ;
1429                                 }
1430                                 break;
1431                         }
1432                 case T_Var:
1433                         {
1434
1435                                 /*
1436                                  * The argument is a set, so this is either a projection
1437                                  * or a function call on this set.
1438                                  */
1439                                 *attisset = true;
1440                                 break;
1441                         }
1442                 case T_Expr:
1443                         {
1444                                 Expr       *expr = (Expr *) first_arg;
1445                                 Func       *funcnode;
1446
1447                                 if (expr->opType != FUNC_EXPR)
1448                                         break;
1449
1450                                 funcnode = (Func *) expr->oper;
1451                                 argtype = funcid_get_rettype(funcnode->funcid);
1452                                 argrelid = typeidTypeRelid(argtype);
1453
1454                                 /*
1455                                  * the argument is a function returning a tuple, so
1456                                  * funcname may be a projection
1457                                  */
1458                                 if (argrelid &&
1459                                         (attnum = get_attnum(argrelid, funcname))
1460                                         != InvalidAttrNumber)
1461                                 {
1462
1463                                         /* add a tlist to the func node */
1464                                         rd = heap_openr(typeidTypeName(argtype));
1465                                         if (RelationIsValid(rd))
1466                                         {
1467                                                 relid = RelationGetRelid(rd);
1468                                                 heap_close(rd);
1469                                         }
1470                                         if (RelationIsValid(rd))
1471                                         {
1472                                                 Expr       *newexpr;
1473
1474                                                 funcnode->func_tlist = setup_tlist(funcname, argrelid);
1475                                                 funcnode->functype = attnumTypeId(rd, attnum);
1476
1477                                                 newexpr = makeNode(Expr);
1478                                                 newexpr->typeOid = funcnode->functype;
1479                                                 newexpr->opType = FUNC_EXPR;
1480                                                 newexpr->oper = (Node *) funcnode;
1481                                                 newexpr->args = expr->args;
1482
1483                                                 return (Node *) newexpr;
1484                                         }
1485
1486                                 }
1487
1488                                 break;
1489                         }
1490                 case T_Param:
1491                         {
1492                                 Param      *param = (Param *) first_arg;
1493
1494                                 /*
1495                                  * If the Param is a complex type, this could be a
1496                                  * projection
1497                                  */
1498                                 rd = heap_openr(typeidTypeName(param->paramtype));
1499                                 if (RelationIsValid(rd))
1500                                 {
1501                                         relid = RelationGetRelid(rd);
1502                                         heap_close(rd);
1503                                         if ((attnum = get_attnum(relid, funcname))
1504                                                 != InvalidAttrNumber)
1505                                         {
1506                                                 param->paramtype = attnumTypeId(rd, attnum);
1507                                                 param->param_tlist = setup_tlist(funcname, relid);
1508                                                 return (Node *) param;
1509                                         }
1510                                 }
1511                                 break;
1512                         }
1513                 default:
1514                         break;
1515         }
1516
1517         return NULL;
1518 }
1519
1520 /*
1521  * Error message when function lookup fails that gives details of the
1522  * argument types
1523  */
1524 void
1525 func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg)
1526 {
1527         char            p[(NAMEDATALEN + 2) * MAXFMGRARGS],
1528                            *ptr;
1529         int                     i;
1530
1531         ptr = p;
1532         *ptr = '\0';
1533         for (i = 0; i < nargs; i++)
1534         {
1535                 if (i)
1536                 {
1537                         *ptr++ = ',';
1538                         *ptr++ = ' ';
1539                 }
1540                 if (argtypes[i] != 0)
1541                 {
1542                         strcpy(ptr, typeidTypeName(argtypes[i]));
1543                         *(ptr + NAMEDATALEN) = '\0';
1544                 }
1545                 else
1546                         strcpy(ptr, "opaque");
1547                 ptr += strlen(ptr);
1548         }
1549
1550         if (caller == NULL)
1551         {
1552                 elog(ERROR, "Function '%s(%s)' does not exist%s%s",
1553                          funcname, p, ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));
1554         }
1555         else
1556         {
1557                 elog(ERROR, "%s: function '%s(%s)' does not exist%s%s",
1558                          caller, funcname, p, ((msg != NULL) ? "\n\t" : ""), ((msg != NULL) ? msg : ""));
1559         }
1560 }