diff --git a/src/backend/distributed/executor/insert_select_executor.c b/src/backend/distributed/executor/insert_select_executor.c index 9e55680e4..6aab2c74b 100644 --- a/src/backend/distributed/executor/insert_select_executor.c +++ b/src/backend/distributed/executor/insert_select_executor.c @@ -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; diff --git a/src/test/regress/expected/multi_insert_select.out b/src/test/regress/expected/multi_insert_select.out index 7e1955dcb..452146cba 100644 --- a/src/test/regress/expected/multi_insert_select.out +++ b/src/test/regress/expected/multi_insert_select.out @@ -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; diff --git a/src/test/regress/sql/multi_insert_select.sql b/src/test/regress/sql/multi_insert_select.sql index a05d79318..a7a802cef 100644 --- a/src/test/regress/sql/multi_insert_select.sql +++ b/src/test/regress/sql/multi_insert_select.sql @@ -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;