Fix use-after-free that may occur for INSERT..SELECT in prepared statements

release-7.4
Marco Slot 2018-06-14 23:21:37 +02:00 committed by velioglu
parent 0d429aff8b
commit 6514d04f01
3 changed files with 36 additions and 1 deletions

View File

@ -101,6 +101,7 @@ ExecuteSelectIntoRelation(Oid targetRelationId, List *insertTargetList,
int partitionColumnIndex = -1;
CitusCopyDestReceiver *copyDest = NULL;
Query *queryCopy = NULL;
partitionMethod = PartitionMethod(targetRelationId);
if (partitionMethod == DISTRIBUTE_BY_NONE)
@ -135,7 +136,14 @@ ExecuteSelectIntoRelation(Oid targetRelationId, List *insertTargetList,
partitionColumnIndex, executorState,
stopOnFailure);
ExecuteQueryIntoDestReceiver(selectQuery, paramListInfo, (DestReceiver *) copyDest);
/*
* Make a copy of the query, since ExecuteQueryIntoDestReceiver may scribble on it
* and we want it to be replanned every time if it is stored in a prepared
* statement.
*/
queryCopy = copyObject(selectQuery);
ExecuteQueryIntoDestReceiver(queryCopy, paramListInfo, (DestReceiver *) copyDest);
executorState->es_processed = copyDest->tuplesSent;

View File

@ -2715,6 +2715,19 @@ SELECT * FROM coerce_agg;
2 | {2,2,2}
(2 rows)
-- INSERT..SELECT + prepared statements + recursive planning
BEGIN;
PREPARE prepared_recursive_insert_select AS
INSERT INTO users_table
SELECT * FROM users_table
WHERE value_1 IN (SELECT value_2 FROM events_table OFFSET 0);
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
ROLLBACK;
-- wrap in a transaction to improve performance
BEGIN;
DROP TABLE coerce_events;

View File

@ -2082,6 +2082,20 @@ LIMIT 5;
SELECT * FROM coerce_agg;
-- INSERT..SELECT + prepared statements + recursive planning
BEGIN;
PREPARE prepared_recursive_insert_select AS
INSERT INTO users_table
SELECT * FROM users_table
WHERE value_1 IN (SELECT value_2 FROM events_table OFFSET 0);
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
EXECUTE prepared_recursive_insert_select;
ROLLBACK;
-- wrap in a transaction to improve performance
BEGIN;
DROP TABLE coerce_events;