diff --git a/CHANGELOG.carto.md b/CHANGELOG.carto.md
index ad8079e94a526..13f3c0e42d64f 100644
--- a/CHANGELOG.carto.md
+++ b/CHANGELOG.carto.md
@@ -1,5 +1,12 @@
# Changelog
+## 10.1.2+carto-1
+
+**Release data**: 2018-XX-XX
+
+Changes
+ - Revert [#10](https://github.com/CartoDB/postgres/pull/10) as the patch was incomplete and causing crashes
+
## 10.1.1+carto-1
**Release date**: 2017-12-05
diff --git a/doc/src/sgml/parallel.sgml b/doc/src/sgml/parallel.sgml
index 1f5efd9e6d9fc..2a25f21eb4b8d 100644
--- a/doc/src/sgml/parallel.sgml
+++ b/doc/src/sgml/parallel.sgml
@@ -151,10 +151,9 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
The query writes any data or locks any database rows. If a query
contains a data-modifying operation either at the top level or within
- a CTE, no parallel plans for that query will be generated. As an
- exception, the commands CREATE TABLE>, SELECT
- INTO>, and CREATE MATERIALIZED VIEW> which create a new
- table and populate it can use a parallel plan.
+ a CTE, no parallel plans for that query will be generated. This is a
+ limitation of the current implementation which could be lifted in a
+ future release.
@@ -242,6 +241,15 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
+
+
+ A prepared statement is executed using a CREATE TABLE .. AS
+ EXECUTE .. statement. This construct converts what otherwise
+ would have been a read-only operation into a read-write operation,
+ making it ineligible for parallel query.
+
+
+
The transaction isolation level is serializable. This situation
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index f73894676ed27..2d321171fad54 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2581,17 +2581,15 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
CommandId cid, int options)
{
/*
- * Parallel operations are required to be strictly read-only in a parallel
- * worker. Parallel inserts are not safe even in the leader in the
- * general case, because group locking means that heavyweight locks for
- * relation extension or GIN page locks will not conflict between members
- * of a lock group, but we don't prohibit that case here because there are
- * useful special cases that we can safely allow, such as CREATE TABLE AS.
- */
- if (IsParallelWorker())
+ * For now, parallel operations are required to be strictly read-only.
+ * Unlike heap_update() and heap_delete(), an insert should never create a
+ * combo CID, so it might be possible to relax this restriction, but not
+ * without more thought and testing.
+ */
+ if (IsInParallelMode())
ereport(ERROR,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
- errmsg("cannot insert tuples in a parallel worker")));
+ errmsg("cannot insert tuples during a parallel operation")));
if (relation->rd_rel->relhasoids)
{
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 17cbce0bdbdd2..97f9c55d6e764 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -326,8 +326,8 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
query = linitial_node(Query, rewritten);
Assert(query->commandType == CMD_SELECT);
- /* plan the query */
- plan = pg_plan_query(query, CURSOR_OPT_PARALLEL_OK, params);
+ /* plan the query --- note we disallow parallelism */
+ plan = pg_plan_query(query, 0, params);
/*
* Use a snapshot with an updated command ID to ensure this query sees
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index fa1b716530791..953e74d73cae3 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -400,6 +400,8 @@ ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es,
* We have to rewrite the contained SELECT and then pass it back to
* ExplainOneQuery. It's probably not really necessary to copy the
* contained parsetree another time, but let's be safe.
+ *
+ * Like ExecCreateTableAs, disallow parallelism in the plan.
*/
CreateTableAsStmt *ctas = (CreateTableAsStmt *) utilityStmt;
List *rewritten;
@@ -407,7 +409,7 @@ ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es,
rewritten = QueryRewrite(castNode(Query, copyObject(ctas->query)));
Assert(list_length(rewritten) == 1);
ExplainOneQuery(linitial_node(Query, rewritten),
- CURSOR_OPT_PARALLEL_OK, ctas->into, es,
+ 0, ctas->into, es,
queryString, params, queryEnv);
}
else if (IsA(utilityStmt, DeclareCursorStmt))
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 76147d9d65b82..53dd2f0fc0cb0 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1697,9 +1697,11 @@ ExecutePlan(EState *estate,
/*
* If the plan might potentially be executed multiple times, we must force
- * it to run without parallelism, because we might exit early.
+ * it to run without parallelism, because we might exit early. Also
+ * disable parallelism when writing into a relation, because no database
+ * changes are allowed in parallel mode.
*/
- if (!execute_once)
+ if (!execute_once || dest->mydest == DestIntoRel)
use_parallel_mode = false;
estate->es_use_parallel_mode = use_parallel_mode;
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 34f6267c78505..cc3d7af42f62f 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -257,16 +257,6 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
* to values that don't permit parallelism, or if parallel-unsafe
* functions are present in the query tree.
*
- * (Note that we do allow CREATE TABLE AS, SELECT INTO, and CREATE
- * MATERIALIZED VIEW to use parallel plans, but this is safe only because
- * the command is writing into a completely new table which workers won't
- * be able to see. If the workers could see the table, the fact that
- * group locking would cause them to ignore the leader's heavyweight
- * relation extension lock and GIN page locks would make this unsafe.
- * We'll have to fix that somehow if we want to allow parallel inserts in
- * general; updates and deletes have additional problems especially around
- * combo CIDs.)
- *
* For now, we don't try to use parallel mode if we're running inside a
* parallel worker. We might eventually be able to relax this
* restriction, but for now it seems best not to have parallel workers
diff --git a/src/test/regress/expected/write_parallel.out b/src/test/regress/expected/write_parallel.out
deleted file mode 100644
index 0c4da2591a0fc..0000000000000
--- a/src/test/regress/expected/write_parallel.out
+++ /dev/null
@@ -1,79 +0,0 @@
---
--- PARALLEL
---
--- Serializable isolation would disable parallel query, so explicitly use an
--- arbitrary other level.
-begin isolation level repeatable read;
--- encourage use of parallel plans
-set parallel_setup_cost=0;
-set parallel_tuple_cost=0;
-set min_parallel_table_scan_size=0;
-set max_parallel_workers_per_gather=4;
---
--- Test write operations that has an underlying query that is eligble
--- for parallel plans
---
-explain (costs off) create table parallel_write as
- select length(stringu1) from tenk1 group by length(stringu1);
- QUERY PLAN
----------------------------------------------------
- Finalize HashAggregate
- Group Key: (length((stringu1)::text))
- -> Gather
- Workers Planned: 4
- -> Partial HashAggregate
- Group Key: length((stringu1)::text)
- -> Parallel Seq Scan on tenk1
-(7 rows)
-
-create table parallel_write as
- select length(stringu1) from tenk1 group by length(stringu1);
-drop table parallel_write;
-explain (costs off) select length(stringu1) into parallel_write
- from tenk1 group by length(stringu1);
- QUERY PLAN
----------------------------------------------------
- Finalize HashAggregate
- Group Key: (length((stringu1)::text))
- -> Gather
- Workers Planned: 4
- -> Partial HashAggregate
- Group Key: length((stringu1)::text)
- -> Parallel Seq Scan on tenk1
-(7 rows)
-
-select length(stringu1) into parallel_write
- from tenk1 group by length(stringu1);
-drop table parallel_write;
-explain (costs off) create materialized view parallel_mat_view as
- select length(stringu1) from tenk1 group by length(stringu1);
- QUERY PLAN
----------------------------------------------------
- Finalize HashAggregate
- Group Key: (length((stringu1)::text))
- -> Gather
- Workers Planned: 4
- -> Partial HashAggregate
- Group Key: length((stringu1)::text)
- -> Parallel Seq Scan on tenk1
-(7 rows)
-
-create materialized view parallel_mat_view as
- select length(stringu1) from tenk1 group by length(stringu1);
-drop materialized view parallel_mat_view;
-prepare prep_stmt as select length(stringu1) from tenk1 group by length(stringu1);
-explain (costs off) create table parallel_write as execute prep_stmt;
- QUERY PLAN
----------------------------------------------------
- Finalize HashAggregate
- Group Key: (length((stringu1)::text))
- -> Gather
- Workers Planned: 4
- -> Partial HashAggregate
- Group Key: length((stringu1)::text)
- -> Parallel Seq Scan on tenk1
-(7 rows)
-
-create table parallel_write as execute prep_stmt;
-drop table parallel_write;
-rollback;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index a114ac92c17ad..eefdeeacaef6f 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -96,7 +96,6 @@ test: rules psql_crosstab amutils
# run by itself so it can run parallel workers
test: select_parallel
-test: write_parallel
# no relation related tests can be put in this group
test: publication subscription
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index ef275d0d9a2b5..76b0de30a7a51 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -134,7 +134,6 @@ test: stats_ext
test: rules
test: psql_crosstab
test: select_parallel
-test: write_parallel
test: publication
test: subscription
test: amutils
diff --git a/src/test/regress/sql/write_parallel.sql b/src/test/regress/sql/write_parallel.sql
deleted file mode 100644
index 78b479cedf4b6..0000000000000
--- a/src/test/regress/sql/write_parallel.sql
+++ /dev/null
@@ -1,42 +0,0 @@
---
--- PARALLEL
---
-
--- Serializable isolation would disable parallel query, so explicitly use an
--- arbitrary other level.
-begin isolation level repeatable read;
-
--- encourage use of parallel plans
-set parallel_setup_cost=0;
-set parallel_tuple_cost=0;
-set min_parallel_table_scan_size=0;
-set max_parallel_workers_per_gather=4;
-
---
--- Test write operations that has an underlying query that is eligble
--- for parallel plans
---
-explain (costs off) create table parallel_write as
- select length(stringu1) from tenk1 group by length(stringu1);
-create table parallel_write as
- select length(stringu1) from tenk1 group by length(stringu1);
-drop table parallel_write;
-
-explain (costs off) select length(stringu1) into parallel_write
- from tenk1 group by length(stringu1);
-select length(stringu1) into parallel_write
- from tenk1 group by length(stringu1);
-drop table parallel_write;
-
-explain (costs off) create materialized view parallel_mat_view as
- select length(stringu1) from tenk1 group by length(stringu1);
-create materialized view parallel_mat_view as
- select length(stringu1) from tenk1 group by length(stringu1);
-drop materialized view parallel_mat_view;
-
-prepare prep_stmt as select length(stringu1) from tenk1 group by length(stringu1);
-explain (costs off) create table parallel_write as execute prep_stmt;
-create table parallel_write as execute prep_stmt;
-drop table parallel_write;
-
-rollback;