Skip to content

Commit 5b2208a

Browse files
committed
Allow the return value of an SQL function to be binary-compatible with
the declared result type, rather than requiring exact type match as before. Per pghackers discusssion of 14-Aug.
1 parent 627c0d4 commit 5b2208a

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

src/backend/catalog/pg_proc.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.57 2001/08/10 15:49:39 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.58 2001/08/23 00:49:46 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -22,6 +22,7 @@
2222
#include "catalog/pg_type.h"
2323
#include "executor/executor.h"
2424
#include "miscadmin.h"
25+
#include "parser/parse_coerce.h"
2526
#include "parser/parse_expr.h"
2627
#include "parser/parse_type.h"
2728
#include "tcop/tcopprot.h"
@@ -332,7 +333,7 @@ checkretval(Oid rettype, List *queryTreeList)
332333
List *tlistitem;
333334
int tlistlen;
334335
Oid typerelid;
335-
Resdom *resnode;
336+
Oid restype;
336337
Relation reln;
337338
Oid relid;
338339
int relnatts;
@@ -377,6 +378,7 @@ checkretval(Oid rettype, List *queryTreeList)
377378
/*
378379
* For base-type returns, the target list should have exactly one
379380
* entry, and its type should agree with what the user declared.
381+
* (As of Postgres 7.2, we accept binary-compatible types too.)
380382
*/
381383
typerelid = typeidTypeRelid(rettype);
382384
if (typerelid == InvalidOid)
@@ -385,25 +387,25 @@ checkretval(Oid rettype, List *queryTreeList)
385387
elog(ERROR, "function declared to return %s returns multiple columns in final SELECT",
386388
format_type_be(rettype));
387389

388-
resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom;
389-
if (resnode->restype != rettype)
390+
restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
391+
if (restype != rettype && !IS_BINARY_COMPATIBLE(restype, rettype))
390392
elog(ERROR, "return type mismatch in function: declared to return %s, returns %s",
391-
format_type_be(rettype), format_type_be(resnode->restype));
393+
format_type_be(rettype), format_type_be(restype));
392394

393395
return;
394396
}
395397

396398
/*
397399
* If the target list is of length 1, and the type of the varnode in
398-
* the target list is the same as the declared return type, this is
399-
* okay. This can happen, for example, where the body of the function
400-
* is 'SELECT (x = func2())', where func2 has the same return type as
400+
* the target list matches the declared return type, this is okay.
401+
* This can happen, for example, where the body of the function
402+
* is 'SELECT func2()', where func2 has the same return type as
401403
* the function that's calling it.
402404
*/
403405
if (tlistlen == 1)
404406
{
405-
resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom;
406-
if (resnode->restype == rettype)
407+
restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
408+
if (restype == rettype || IS_BINARY_COMPATIBLE(restype, rettype))
407409
return;
408410
}
409411

@@ -427,15 +429,17 @@ checkretval(Oid rettype, List *queryTreeList)
427429
{
428430
TargetEntry *tle = (TargetEntry *) lfirst(tlistitem);
429431
Oid tletype;
432+
Oid atttype;
430433

431434
if (tle->resdom->resjunk)
432435
continue;
433436
tletype = exprType(tle->expr);
434-
if (tletype != reln->rd_att->attrs[i]->atttypid)
437+
atttype = reln->rd_att->attrs[i]->atttypid;
438+
if (tletype != atttype && !IS_BINARY_COMPATIBLE(tletype, atttype))
435439
elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
436440
format_type_be(rettype),
437441
format_type_be(tletype),
438-
format_type_be(reln->rd_att->attrs[i]->atttypid),
442+
format_type_be(atttype),
439443
i + 1);
440444
i++;
441445
}

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