aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-01-14 13:27:47 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2017-01-14 13:27:47 -0500
commita23ea8f65e07aa56a501bbdd68068b52469d77cf (patch)
treea1dc1ecd82ec7c00fc7e63c2bbf9123c50f42866
parent7fbd3ddd1d2b76c0229cdc44d355b6238c146335 (diff)
downloadpostgresql-a23ea8f65e07aa56a501bbdd68068b52469d77cf.tar.gz
postgresql-a23ea8f65e07aa56a501bbdd68068b52469d77cf.zip
Throw suitable error for COPY TO STDOUT/FROM STDIN in a SQL function.
A client copy can't work inside a function because the FE/BE wire protocol doesn't support nesting of a COPY operation within query results. (Maybe it could, but the protocol spec doesn't suggest that clients should support this, and libpq for one certainly doesn't.) In most PLs, this prohibition is enforced by spi.c, but SQL functions don't use SPI. A comparison of _SPI_execute_plan() and init_execution_state() shows that rejecting client COPY is the only discrepancy in what they allow, so there's no other similar bugs. This is an astonishingly ancient oversight, so back-patch to all supported branches. Report: https://postgr.es/m/BY2PR05MB2309EABA3DEFA0143F50F0D593780@BY2PR05MB2309.namprd05.prod.outlook.com
-rw-r--r--src/backend/executor/functions.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index ce49c471d49..93292d6b1ca 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -498,7 +498,16 @@ init_execution_state(List *queryTree_list,
else
stmt = (Node *) pg_plan_query(queryTree, 0, NULL);
- /* Precheck all commands for validity in a function */
+ /*
+ * Precheck all commands for validity in a function. This should
+ * generally match the restrictions spi.c applies.
+ */
+ if (IsA(stmt, CopyStmt) &&
+ ((CopyStmt *) stmt)->filename == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot COPY to/from client in a SQL function")));
+
if (IsA(stmt, TransactionStmt))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),