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)
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