提交 ffaaf27e 编写于 作者: N Neil Conway

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.
上级 f07b9689
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.29 2004/12/31 21:59:45 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.30 2005/01/27 06:36:42 neilc Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -31,12 +31,13 @@
#include "parser/parsetree.h"
#include "parser/parse_expr.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
static TupleTableSlot *FunctionNext(FunctionScanState *node);
static bool tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc);
/* ----------------------------------------------------------------
* Scan Support
......@@ -87,10 +88,8 @@ FunctionNext(FunctionScanState *node)
* need to do this for functions returning RECORD, but might as
* well do it always.
*/
if (funcTupdesc && !tupledesc_match(node->tupdesc, funcTupdesc))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("query-specified return row and actual function return row do not match")));
if (funcTupdesc)
tupledesc_match(node->tupdesc, funcTupdesc);
}
/*
......@@ -349,21 +348,26 @@ ExecFunctionReScan(FunctionScanState *node, ExprContext *exprCtxt)
}
/*
* Check that function result tuple type (src_tupdesc) matches or can be
* considered to match what the query expects (dst_tupdesc).
* Check that function result tuple type (src_tupdesc) matches or can
* be considered to match what the query expects (dst_tupdesc). If
* they don't match, ereport.
*
* We really only care about number of attributes and data type.
* Also, we can ignore type mismatch on columns that are dropped in the
* destination type, so long as the physical storage matches. This is
* helpful in some cases involving out-of-date cached plans.
*/
static bool
static void
tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
{
int i;
if (dst_tupdesc->natts != src_tupdesc->natts)
return false;
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("function return row and query-specified return row do not match"),
errdetail("Returned row contains %d attributes, but query expects %d.",
src_tupdesc->natts, dst_tupdesc->natts)));
for (i = 0; i < dst_tupdesc->natts; i++)
{
......@@ -373,11 +377,20 @@ tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc)
if (dattr->atttypid == sattr->atttypid)
continue; /* no worries */
if (!dattr->attisdropped)
return false;
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("function return row and query-specified return row do not match"),
errdetail("Returned type %s at ordinal position %d, but query expects %s.",
format_type_be(sattr->atttypid),
i + 1,
format_type_be(dattr->atttypid))));
if (dattr->attlen != sattr->attlen ||
dattr->attalign != sattr->attalign)
return false;
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("function return row and query-specified return row do not match"),
errdetail("Physical storage mismatch on dropped attribute at ordinal position %d.",
i + 1)));
}
return true;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册