Skip to content

Commit 07c495f

Browse files
committed
Further cleanups for type coercion: treat the locution typename(argument)
as representing a type coercion request in more cases than we did before. It will work now whenever no underlying function is required, ie if the coercion is binary-compatible or if the argument is a previously untyped string constant. Otherwise, you still need a real function to exist.
1 parent 57b30e8 commit 07c495f

File tree

1 file changed

+34
-34
lines changed

1 file changed

+34
-34
lines changed

src/backend/parser/parse_func.c

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy