88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.110 2001/08/09 18:28:18 petere Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.111 2001/10/04 22:06:46 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -427,12 +427,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
427427}
428428
429429/*
430- * func_get_detail looks up the function in the catalogs, does
431- * disambiguation for polymorphic functions, handles inheritance, and
432- * returns the funcid and type and set or singleton status of the
433- * function's return value. it also returns the true argument types
434- * to the function. if func_get_detail returns true, the function
435- * exists.otherwise, there was an error.
430+ * Is it a set, or a function?
436431 */
437432if (attisset )
438433{/* we know all of these fields already */
@@ -454,61 +449,29 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
454449}
455450else
456451{
457- bool exists ;
452+ FuncDetailCode fdresult ;
458453
459- exists = func_get_detail (funcname ,nargs ,oid_array ,& funcid ,
460- & rettype ,& retset ,& true_oid_array );
461- if (!exists )
454+ /*
455+ * func_get_detail looks up the function in the catalogs, does
456+ * disambiguation for polymorphic functions, handles inheritance, and
457+ * returns the funcid and type and set or singleton status of the
458+ * function's return value. it also returns the true argument types
459+ * to the function.
460+ */
461+ fdresult = func_get_detail (funcname ,fargs ,nargs ,oid_array ,
462+ & funcid ,& rettype ,& retset ,
463+ & true_oid_array );
464+ if (fdresult == FUNCDETAIL_COERCION )
462465{
463-
464466/*
465- * If we can't find a function (or can't find a unique
466- * function), see if this is really a type-coercion request:
467- * single-argument function call where the function name is a
468- * type name. If so, and if we can do the coercion trivially,
469- * just go ahead and do it without requiring there to be a
470- * real function for it.
471- *
472- * "Trivial" coercions are ones that involve binary-compatible
473- * types and ones that are coercing a previously-unknown-type
474- * literal constant to a specific type.
475- *
476- * DO NOT try to generalize this code to nontrivial coercions,
477- * because you'll just set up an infinite recursion between
478- * this routine and coerce_type! We have already failed to
479- * find a suitable "real" coercion function, so we have to
480- * fail unless this is a coercion that coerce_type can handle
481- * by itself. Make sure this code stays in sync with what
482- * coerce_type does!
467+ * We can do it as a trivial coercion.
468+ * coerce_type can handle these cases, so why duplicate code...
483469 */
484- if (nargs == 1 )
485- {
486- Oid targetType ;
487-
488- targetType = GetSysCacheOid (TYPENAME ,
489- PointerGetDatum (funcname ),
490- 0 ,0 ,0 );
491- if (OidIsValid (targetType ))
492- {
493- Oid sourceType = oid_array [0 ];
494- Node * arg1 = lfirst (fargs );
495-
496- if ((sourceType == UNKNOWNOID && IsA (arg1 ,Const ))||
497- sourceType == targetType ||
498- IS_BINARY_COMPATIBLE (sourceType ,targetType ))
499- {
500-
501- /*
502- * Ah-hah, we can do it as a trivial coercion.
503- * coerce_type can handle these cases, so why
504- * duplicate code...
505- */
506- return coerce_type (pstate ,arg1 ,
507- sourceType ,targetType ,-1 );
508- }
509- }
510- }
511-
470+ return coerce_type (pstate ,lfirst (fargs ),
471+ oid_array [0 ],rettype ,-1 );
472+ }
473+ if (fdresult != FUNCDETAIL_NORMAL )
474+ {
512475/*
513476 * Oops. Time to die.
514477 *
@@ -1130,26 +1093,29 @@ func_select_candidate(int nargs,
11301093
11311094
11321095/* func_get_detail()
1096+ *
11331097 * Find the named function in the system catalogs.
11341098 *
11351099 * Attempt to find the named function in the system catalogs with
11361100 *arguments exactly as specified, so that the normal case
11371101 *(exact match) is as quick as possible.
11381102 *
11391103 * If an exact match isn't found:
1140- *1) get a vector of all possible input arg type arrays constructed
1104+ * 1) check for possible interpretation as a trivial type coercion
1105+ *2) get a vector of all possible input arg type arrays constructed
11411106 * from the superclasses of the original input arg types
1142- *2 ) get a list of all possible argument type arrays to the function
1107+ *3 ) get a list of all possible argument type arrays to the function
11431108 * with given name and number of arguments
1144- *3 ) for each input arg type array from vector #1:
1109+ *4 ) for each input arg type array from vector #1:
11451110 * a) find how many of the function arg type arrays from list #2
11461111 *it can be coerced to
11471112 * b) if the answer is one, we have our function
11481113 * c) if the answer is more than one, attempt to resolve the conflict
11491114 * d) if the answer is zero, try the next array from vector #1
11501115 */
1151- bool
1116+ FuncDetailCode
11521117func_get_detail (char * funcname ,
1118+ List * fargs ,
11531119int nargs ,
11541120Oid * argtypes ,
11551121Oid * funcid ,/* return value */
@@ -1158,6 +1124,7 @@ func_get_detail(char *funcname,
11581124Oid * * true_typeids )/* return value */
11591125{
11601126HeapTuple ftup ;
1127+ CandidateList function_typeids ;
11611128
11621129/* attempt to find with arguments exactly as specified... */
11631130ftup = SearchSysCache (PROCNAME ,
@@ -1173,12 +1140,59 @@ func_get_detail(char *funcname,
11731140}
11741141else
11751142{
1143+ /*
1144+ * If we didn't find an exact match, next consider the possibility
1145+ * that this is really a type-coercion request: a single-argument
1146+ * function call where the function name is a type name. If so,
1147+ * and if we can do the coercion trivially (no run-time function
1148+ * call needed), then go ahead and treat the "function call" as
1149+ * a coercion. This interpretation needs to be given higher
1150+ * priority than interpretations involving a type coercion followed
1151+ * by a function call, otherwise we can produce surprising results.
1152+ * For example, we want "text(varchar)" to be interpreted as a
1153+ * trivial coercion, not as "text(name(varchar))" which the code
1154+ * below this point is entirely capable of selecting.
1155+ *
1156+ * "Trivial" coercions are ones that involve binary-compatible
1157+ * types and ones that are coercing a previously-unknown-type
1158+ * literal constant to a specific type.
1159+ *
1160+ * NB: it's important that this code stays in sync with what
1161+ * coerce_type can do, because the caller will try to apply
1162+ * coerce_type if we return FUNCDETAIL_COERCION. If we return
1163+ * that result for something coerce_type can't handle, we'll
1164+ * cause infinite recursion between this module and coerce_type!
1165+ */
1166+ if (nargs == 1 )
1167+ {
1168+ Oid targetType ;
1169+
1170+ targetType = GetSysCacheOid (TYPENAME ,
1171+ PointerGetDatum (funcname ),
1172+ 0 ,0 ,0 );
1173+ if (OidIsValid (targetType ))
1174+ {
1175+ Oid sourceType = argtypes [0 ];
1176+ Node * arg1 = lfirst (fargs );
1177+
1178+ if ((sourceType == UNKNOWNOID && IsA (arg1 ,Const ))||
1179+ sourceType == targetType ||
1180+ IS_BINARY_COMPATIBLE (sourceType ,targetType ))
1181+ {
1182+ /* Yup, it's a type coercion */
1183+ * funcid = InvalidOid ;
1184+ * rettype = targetType ;
1185+ * retset = false;
1186+ * true_typeids = argtypes ;
1187+ return FUNCDETAIL_COERCION ;
1188+ }
1189+ }
1190+ }
11761191
11771192/*
11781193 * didn't find an exact match, so now try to match up
11791194 * candidates...
11801195 */
1181- CandidateList function_typeids ;
11821196
11831197function_typeids = func_get_candidates (funcname ,nargs );
11841198
@@ -1268,9 +1282,10 @@ func_get_detail(char *funcname,
12681282* rettype = pform -> prorettype ;
12691283* retset = pform -> proretset ;
12701284ReleaseSysCache (ftup );
1271- return true ;
1285+ return FUNCDETAIL_NORMAL ;
12721286}
1273- return false;
1287+
1288+ return FUNCDETAIL_NOTFOUND ;
12741289}/* func_get_detail() */
12751290
12761291/*