88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.113 2007/04/0203 :49:38 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.114 2007/04/0218 :49:29 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -849,9 +849,9 @@ ShutdownSQLFunction(Datum arg)
849849 * ANYELEMENT as rettype. (This means we can't check the type during function
850850 * definition of a polymorphic function.)
851851 *
852- *The return value is true if the function returns the entire tuple result
853- * of its final SELECT, and false otherwise. Note that because we allow
854- * "SELECT rowtype_expression", this may be false even when the declared
852+ *This function returns true if thesql function returns the entire tuple
853+ *result of its final SELECT, and false otherwise. Note that because we
854+ *allow "SELECT rowtype_expression", this may be false even when the declared
855855 * function return type is a rowtype.
856856 *
857857 * If junkFilter isn't NULL, then *junkFilter is set to a JunkFilter defined
@@ -864,7 +864,6 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
864864JunkFilter * * junkFilter )
865865{
866866Query * parse ;
867- bool isSelect ;
868867List * tlist ;
869868ListCell * tlistitem ;
870869int tlistlen ;
@@ -890,32 +889,30 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
890889parse = (Query * )lfirst (list_tail (queryTreeList ));
891890
892891/*
893- * Note: eventually replace this with QueryReturnsTuples? We'd need a
894- * more general method of determining the output type, though.
895- */
896- isSelect = (parse -> commandType == CMD_SELECT && parse -> into == NULL );
897-
898- /*
899- * The last query must be a SELECT if and only if return type isn't VOID.
892+ * If the last query isn't a SELECT, the return type must be VOID.
893+ *
894+ * Note: eventually replace this test with QueryReturnsTuples? We'd need
895+ * a more general method of determining the output type, though.
900896 */
901- if (rettype == VOIDOID )
897+ if (!( parse -> commandType == CMD_SELECT && parse -> into == NULL ) )
902898{
903- if (isSelect )
899+ if (rettype != VOIDOID )
904900ereport (ERROR ,
905901(errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
906902errmsg ("return type mismatch in function declared to return %s" ,
907903format_type_be (rettype )),
908- errdetail ("Function's final statement must not be a SELECT." )));
904+ errdetail ("Function's final statement must be a SELECT." )));
909905return false;
910906}
911907
912- /* by here, the function is declared to return some type */
913- if (!isSelect )
914- ereport (ERROR ,
915- (errcode (ERRCODE_INVALID_FUNCTION_DEFINITION ),
916- errmsg ("return type mismatch in function declared to return %s" ,
917- format_type_be (rettype )),
918- errdetail ("Function's final statement must be a SELECT." )));
908+ /*
909+ * OK, it's a SELECT, so it must return something matching the declared
910+ * type. (We used to insist that the declared type not be VOID in this
911+ * case, but that makes it hard to write a void function that exits
912+ * after calling another void function. Instead, we insist that the
913+ * SELECT return void ... so void is treated as if it were a scalar type
914+ * below.)
915+ */
919916
920917/*
921918 * Count the non-junk entries in the result targetlist.
@@ -927,10 +924,11 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
927924
928925if (fn_typtype == TYPTYPE_BASE ||
929926fn_typtype == TYPTYPE_DOMAIN ||
930- fn_typtype == TYPTYPE_ENUM )
927+ fn_typtype == TYPTYPE_ENUM ||
928+ rettype == VOIDOID )
931929{
932930/*
933- * Forbase -type returns, the target list should have exactly one
931+ * Forscalar -type returns, the target list should have exactly one
934932 * entry, and its type should agree with what the user declared. (As
935933 * of Postgres 7.2, we accept binary-compatible types too.)
936934 */