Skip to content

Commit ffaaf27

Browse files
author
Neil Conway
committed
Provide a more descriptive error message when the return type of an SRF
does not match what the query expected. From Brendan Jurd, minor editorializing by Neil Conway.
1 parent f07b968 commit ffaaf27

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

src/backend/executor/nodeFunctionscan.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.29 2004/12/31 21:59:45 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.30 2005/01/27 06:36:42 neilc Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -31,12 +31,13 @@
3131
#include "parser/parsetree.h"
3232
#include "parser/parse_expr.h"
3333
#include "parser/parse_type.h"
34+
#include "utils/builtins.h"
3435
#include "utils/lsyscache.h"
3536
#include "utils/typcache.h"
3637

3738

3839
static TupleTableSlot *FunctionNext(FunctionScanState *node);
39-
static bool tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
40+
static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
4041

4142
/* ----------------------------------------------------------------
4243
* Scan Support
@@ -87,10 +88,8 @@ FunctionNext(FunctionScanState *node)
8788
* need to do this for functions returning RECORD, but might as
8889
* well do it always.
8990
*/
90-
if (funcTupdesc && !tupledesc_match(node->tupdesc, funcTupdesc))
91-
ereport(ERROR,
92-
(errcode(ERRCODE_DATATYPE_MISMATCH),
93-
errmsg("query-specified return row and actual function return row do not match")));
91+
if (funcTupdesc)
92+
tupledesc_match(node->tupdesc, funcTupdesc);
9493
}
9594

9695
/*
@@ -349,21 +348,26 @@ ExecFunctionReScan(FunctionScanState *node, ExprContext *exprCtxt)
349348
}
350349

351350
/*
352-
* Check that function result tuple type (src_tupdesc) matches or can be
353-
* considered to match what the query expects (dst_tupdesc).
351+
* Check that function result tuple type (src_tupdesc) matches or can
352+
* be considered to match what the query expects (dst_tupdesc). If
353+
* they don't match, ereport.
354354
*
355355
* We really only care about number of attributes and data type.
356356
* Also, we can ignore type mismatch on columns that are dropped in the
357357
* destination type, so long as the physical storage matches. This is
358358
* helpful in some cases involving out-of-date cached plans.
359359
*/
360-
static bool
360+
static void
361361
tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
362362
{
363363
int i;
364364

365365
if (dst_tupdesc->natts != src_tupdesc->natts)
366-
return false;
366+
ereport(ERROR,
367+
(errcode(ERRCODE_DATATYPE_MISMATCH),
368+
errmsg("function return row and query-specified return row do not match"),
369+
errdetail("Returned row contains %d attributes, but query expects %d.",
370+
src_tupdesc->natts, dst_tupdesc->natts)));
367371

368372
for (i = 0; i < dst_tupdesc->natts; i++)
369373
{
@@ -373,11 +377,20 @@ tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
373377
if (dattr->atttypid == sattr->atttypid)
374378
continue; /* no worries */
375379
if (!dattr->attisdropped)
376-
return false;
380+
ereport(ERROR,
381+
(errcode(ERRCODE_DATATYPE_MISMATCH),
382+
errmsg("function return row and query-specified return row do not match"),
383+
errdetail("Returned type %s at ordinal position %d, but query expects %s.",
384+
format_type_be(sattr->atttypid),
385+
i + 1,
386+
format_type_be(dattr->atttypid))));
387+
377388
if (dattr->attlen != sattr->attlen ||
378389
dattr->attalign != sattr->attalign)
379-
return false;
390+
ereport(ERROR,
391+
(errcode(ERRCODE_DATATYPE_MISMATCH),
392+
errmsg("function return row and query-specified return row do not match"),
393+
errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
394+
i + 1)));
380395
}
381-
382-
return true;
383396
}

0 commit comments

Comments
 (0)