diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-03-17 03:15:38 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-03-17 03:15:38 +0000 |
commit | cdf8b56d5463815244467ea8f5ec6e72b6c65a6c (patch) | |
tree | e3d810e8d1d00bc7fffecb67aa2b59c02c97b5ef /src/backend/executor/spi.c | |
parent | e88a7ad77486db0926d33b31962d274bc9fd08ae (diff) | |
download | postgresql-cdf8b56d5463815244467ea8f5ec6e72b6c65a6c.tar.gz postgresql-cdf8b56d5463815244467ea8f5ec6e72b6c65a6c.zip |
SPI_cursor_open failed to enforce that only read-only queries could be
executed in read_only mode. This could lead to various relatively-subtle
failures, such as an allegedly stable function returning non-stable results.
Bug goes all the way back to the introduction of read-only mode in 8.0.
Per report from Gaetano Mendola.
Diffstat (limited to 'src/backend/executor/spi.c')
-rw-r--r-- | src/backend/executor/spi.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 7a34add7105..e0856a3d8f2 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.172 2007/03/15 23:12:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.173 2007/03/17 03:15:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -965,6 +965,30 @@ SPI_cursor_open(const char *name, SPIPlanPtr plan, portal->cursorOptions |= CURSOR_OPT_NO_SCROLL; /* + * 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 + * RevalidateCachedPlan and PortalDefineQuery, because throwing an error + * between those steps would result in leaking our plancache refcount.) + */ + if (read_only) + { + ListCell *lc; + + foreach(lc, stmt_list) + { + Node *pstmt = (Node *) lfirst(lc); + + if (!CommandIsReadOnly(pstmt)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + /* translator: %s is a SQL statement name */ + errmsg("%s is not allowed in a non-volatile function", + CreateCommandTag(pstmt)))); + } + } + + /* * Set up the snapshot to use. (PortalStart will do CopySnapshot, so we * skip that here.) */ |