88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.71 2000/02/2021:32:10 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.72 2000/02/2023:04:06 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -292,9 +292,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
292292/* Is it a plain Relation name from the parser? */
293293if (IsA (first_arg ,Ident )&& ((Ident * )first_arg )-> isRel )
294294{
295+ Ident * ident = (Ident * )first_arg ;
295296RangeTblEntry * rte ;
296297AttrNumber attnum ;
297- Ident * ident = (Ident * )first_arg ;
298298
299299/*
300300 * first arg is a relation. This could be a projection.
@@ -479,11 +479,13 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
479479}
480480
481481/*
482- * See if this is a single argument function with the function
483- * name also a type name and the input argument and type name
484- * binary compatible. If so, we do not need to do any real
485- * conversion, but we do need to build a RelabelType node
486- * so that exprType() sees the result as being of the output type.
482+ * See if this is really a type-coercion request: single-argument
483+ * function call where the function name is a type name. If so,
484+ * and if we can do the coercion trivially, just go ahead and do it
485+ * without requiring there to be a real function for it. "Trivial"
486+ * coercions are ones that involve binary-compatible types and ones
487+ * that are coercing a previously-unknown-type literal constant
488+ * to a specific type.
487489 */
488490if (nargs == 1 )
489491{
@@ -492,16 +494,21 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
492494tp = SearchSysCacheTuple (TYPENAME ,
493495PointerGetDatum (funcname ),
4944960 ,0 ,0 );
495- if (HeapTupleIsValid (tp )&&
496- IS_BINARY_COMPATIBLE (typeTypeId (tp ),exprType (lfirst (fargs ))))
497+ if (HeapTupleIsValid (tp ))
497498{
498- RelabelType * relabel = makeNode (RelabelType );
499+ Oid targetType = typeTypeId (tp );
500+ Node * arg1 = lfirst (fargs );
501+ Oid sourceType = exprType (arg1 );
499502
500- relabel -> arg = (Node * )lfirst (fargs );
501- relabel -> resulttype = typeTypeId (tp );
502- relabel -> resulttypmod = -1 ;
503-
504- return (Node * )relabel ;
503+ if ((sourceType == UNKNOWNOID && IsA (arg1 ,Const ))||
504+ sourceType == targetType ||
505+ IS_BINARY_COMPATIBLE (sourceType ,targetType ))
506+ {
507+ /*
508+ * coerce_type can handle these cases, so why duplicate code...
509+ */
510+ return coerce_type (pstate ,arg1 ,sourceType ,targetType ,-1 );
511+ }
505512}
506513}
507514
@@ -516,17 +523,17 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
516523nargs = 0 ;
517524foreach (i ,fargs )
518525{
519- int vnum ;
520- RangeTblEntry * rte ;
521- Node * pair = lfirst (i );
526+ Node * arg = lfirst (i );
522527
523- if (nodeTag ( pair ) == T_Ident && ((Ident * )pair )-> isRel )
528+ if (IsA ( arg , Ident ) && ((Ident * )arg )-> isRel )
524529{
530+ RangeTblEntry * rte ;
531+ int vnum ;
525532
526533/*
527534 * a relation
528535 */
529- refname = ((Ident * )pair )-> name ;
536+ refname = ((Ident * )arg )-> name ;
530537
531538rte = refnameRangeTableEntry (pstate ,refname );
532539if (rte == NULL )
@@ -554,22 +561,15 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
554561 */
555562toid = typeTypeId (typenameType (relname ));
556563/* replace it in the arg list */
557- lfirst (fargs )= makeVar (vnum ,0 ,toid ,-1 ,0 );
564+ lfirst (i )= makeVar (vnum ,0 ,toid ,-1 ,0 );
558565}
559566else if (!attisset )
560- {/* set functions don't have parameters */
561-
562- /*
563- * any function args which are typed "unknown", but aren't
564- * constants, we don't know what to do with, because we can't
565- * cast them- jolly
566- */
567- if (exprType (pair )== UNKNOWNOID && !IsA (pair ,Const ))
568- elog (ERROR ,"There is no function '%s'"
569- " with argument #%d of type UNKNOWN" ,
570- funcname ,nargs + 1 );
571- else
572- toid = exprType (pair );
567+ {
568+ toid = exprType (arg );
569+ }
570+ else
571+ {
572+ /* if attisset is true, we already set toid for the single arg */
573573}
574574
575575/* Most of the rest of the parser just assumes that functions do not