diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-10-24 23:27:08 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-10-24 23:27:08 +0000 |
commit | 048efc25e46d95f6a6dad20d65f6d9dd10c640d4 (patch) | |
tree | 62aa8e84ce59710b3317eb97926cfa86452d8bd0 /src/backend/executor/spi.c | |
parent | 8a35b07e1849c1af7acbdc8eea0bc357b5ad51e3 (diff) | |
download | postgresql-048efc25e46d95f6a6dad20d65f6d9dd10c640d4.tar.gz postgresql-048efc25e46d95f6a6dad20d65f6d9dd10c640d4.zip |
Disallow scrolling of FOR UPDATE/FOR SHARE cursors, so as to avoid problems
in corner cases such as re-fetching a just-deleted row. We may be able to
relax this someday, but let's find out how many people really care before
we invest a lot of work in it. Per report from Heikki and subsequent
discussion.
While in the neighborhood, make the combination of INSENSITIVE and FOR UPDATE
throw an error, since they are semantically incompatible. (Up to now we've
accepted but just ignored the INSENSITIVE option of DECLARE CURSOR.)
Diffstat (limited to 'src/backend/executor/spi.c')
-rw-r--r-- | src/backend/executor/spi.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 875e4da2914..6d59401d0fb 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.181 2007/09/20 17:56:31 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.182 2007/10/24 23:27:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -975,6 +975,7 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan, { if (list_length(stmt_list) == 1 && IsA((Node *) linitial(stmt_list), PlannedStmt) && + ((PlannedStmt *) linitial(stmt_list))->rowMarks == NIL && ExecSupportsBackwardScan(((PlannedStmt *) linitial(stmt_list))->planTree)) portal->cursorOptions |= CURSOR_OPT_SCROLL; else @@ -982,6 +983,22 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan, } /* + * Disallow SCROLL with SELECT FOR UPDATE. This is not redundant with + * the check in transformDeclareCursorStmt because the cursor options + * might not have come through there. + */ + if (portal->cursorOptions & CURSOR_OPT_SCROLL) + { + if (list_length(stmt_list) == 1 && + IsA((Node *) linitial(stmt_list), PlannedStmt) && + ((PlannedStmt *) linitial(stmt_list))->rowMarks != NIL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("DECLARE CURSOR SCROLL ... FOR UPDATE/SHARE is not supported"), + errdetail("Scrollable cursors must be READ ONLY."))); + } + + /* * If told to be read-only, we'd better check for read-only queries. * This can't be done earlier because we need to look at the finished, * planned queries. (In particular, we don't want to do it between |