diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-08-12 20:05:56 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-08-12 20:05:56 +0000 |
commit | 3f8db37c2f1eeeffd9dae3189b783a463f56fe77 (patch) | |
tree | f6520123161af6191b5f53262d67eab69b24eccf /src/backend/executor/functions.c | |
parent | 883f4b42d7292f1a7142e55046cee86f92049b5a (diff) | |
download | postgresql-3f8db37c2f1eeeffd9dae3189b783a463f56fe77.tar.gz postgresql-3f8db37c2f1eeeffd9dae3189b783a463f56fe77.zip |
Tweak SPI_cursor_open to allow INSERT/UPDATE/DELETE RETURNING; this was
merely a matter of fixing the error check, since the underlying Portal
infrastructure already handles it. This in turn allows these statements
to be used in some existing plpgsql and plperl contexts, such as a
plpgsql FOR loop. Also, do some marginal code cleanup in places that
were being sloppy about distinguishing SELECT from SELECT INTO.
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r-- | src/backend/executor/functions.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 0da2abba77c..28462ba8b8b 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.104 2006/07/14 14:52:19 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.105 2006/08/12 20:05:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -361,7 +361,9 @@ postquel_getnext(execution_state *es) * run it to completion. (If we run to completion then * ExecutorRun is guaranteed to return NULL.) */ - if (LAST_POSTQUEL_COMMAND(es) && es->qd->operation == CMD_SELECT) + if (LAST_POSTQUEL_COMMAND(es) && + es->qd->operation == CMD_SELECT && + es->qd->parsetree->into == NULL) count = 1L; else count = 0L; @@ -868,7 +870,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, JunkFilter **junkFilter) { Query *parse; - int cmd; + bool isSelect; List *tlist; ListCell *tlistitem; int tlistlen; @@ -893,15 +895,18 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, /* find the final query */ parse = (Query *) lfirst(list_tail(queryTreeList)); - cmd = parse->commandType; - tlist = parse->targetList; + /* + * Note: eventually replace this with QueryReturnsTuples? We'd need + * a more general method of determining the output type, though. + */ + isSelect = (parse->commandType == CMD_SELECT && parse->into == NULL); /* * The last query must be a SELECT if and only if return type isn't VOID. */ if (rettype == VOIDOID) { - if (cmd == CMD_SELECT) + if (isSelect) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("return type mismatch in function declared to return %s", @@ -911,7 +916,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, } /* by here, the function is declared to return some type */ - if (cmd != CMD_SELECT) + if (!isSelect) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("return type mismatch in function declared to return %s", @@ -921,6 +926,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, /* * Count the non-junk entries in the result targetlist. */ + tlist = parse->targetList; tlistlen = ExecCleanTargetListLength(tlist); fn_typtype = get_typtype(rettype); |