88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.71 2000/02/20 21:32:10 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.72 2000/02/20 23: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? */
293293 if (IsA (first_arg , Ident ) && ((Ident * ) first_arg )-> isRel )
294294 {
295+ Ident * ident = (Ident * ) first_arg ;
295296 RangeTblEntry * rte ;
296297 AttrNumber 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 */
488490 if (nargs == 1 )
489491 {
@@ -492,16 +494,21 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
492494 tp = SearchSysCacheTuple (TYPENAME ,
493495 PointerGetDatum (funcname ),
494496 0 , 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,
516523 nargs = 0 ;
517524 foreach (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
531538 rte = refnameRangeTableEntry (pstate , refname );
532539 if (rte == NULL )
@@ -554,22 +561,15 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
554561 */
555562 toid = 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 }
559566 else 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
0 commit comments