diff options
Diffstat (limited to 'src/backend/executor/nodeFunctionscan.c')
-rw-r--r-- | src/backend/executor/nodeFunctionscan.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c index 4cf77dac930..be1fbb05155 100644 --- a/src/backend/executor/nodeFunctionscan.c +++ b/src/backend/executor/nodeFunctionscan.c @@ -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; } |