aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/functions.c2
-rw-r--r--src/backend/executor/spi.c4
-rw-r--r--src/pl/plpgsql/src/pl_exec.c30
3 files changed, 20 insertions, 16 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 12214f8a150..65e52cca630 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -503,7 +503,7 @@ init_execution_state(List *queryTree_list,
}
else
stmt = pg_plan_query(queryTree,
- fcache->readonly_func ? CURSOR_OPT_PARALLEL_OK : 0,
+ CURSOR_OPT_PARALLEL_OK,
NULL);
/*
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 72c7b4d0689..eeaa4805e4d 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -314,7 +314,7 @@ SPI_execute(const char *src, bool read_only, long tcount)
memset(&plan, 0, sizeof(_SPI_plan));
plan.magic = _SPI_PLAN_MAGIC;
- plan.cursor_options = 0;
+ plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
_SPI_prepare_oneshot_plan(src, &plan);
@@ -458,7 +458,7 @@ SPI_execute_with_args(const char *src,
memset(&plan, 0, sizeof(_SPI_plan));
plan.magic = _SPI_PLAN_MAGIC;
- plan.cursor_options = 0;
+ plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
plan.nargs = nargs;
plan.argtypes = argtypes;
plan.parserSetup = NULL;
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 8e836a81494..664fc425143 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -264,8 +264,7 @@ static Datum exec_eval_expr(PLpgSQL_execstate *estate,
Oid *rettype,
int32 *rettypmod);
static int exec_run_select(PLpgSQL_execstate *estate,
- PLpgSQL_expr *expr, long maxtuples, Portal *portalP,
- bool parallelOK);
+ PLpgSQL_expr *expr, long maxtuples, Portal *portalP);
static int exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
Portal portal, bool prefetch_ok);
static ParamListInfo setup_param_list(PLpgSQL_execstate *estate,
@@ -1685,7 +1684,7 @@ exec_stmt_perform(PLpgSQL_execstate *estate, PLpgSQL_stmt_perform *stmt)
{
PLpgSQL_expr *expr = stmt->expr;
- (void) exec_run_select(estate, expr, 0, NULL, true);
+ (void) exec_run_select(estate, expr, 0, NULL);
exec_set_found(estate, (estate->eval_processed != 0));
exec_eval_cleanup(estate);
@@ -2238,7 +2237,7 @@ exec_stmt_fors(PLpgSQL_execstate *estate, PLpgSQL_stmt_fors *stmt)
/*
* Open the implicit cursor for the statement using exec_run_select
*/
- exec_run_select(estate, stmt->query, 0, &portal, false);
+ exec_run_select(estate, stmt->query, 0, &portal);
/*
* Execute the loop
@@ -3023,7 +3022,7 @@ exec_stmt_return_query(PLpgSQL_execstate *estate,
if (stmt->query != NULL)
{
/* static query */
- exec_run_select(estate, stmt->query, 0, &portal, false);
+ exec_run_select(estate, stmt->query, 0, &portal);
}
else
{
@@ -3627,7 +3626,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
{
ListCell *l;
- exec_prepare_plan(estate, expr, 0);
+ exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
stmt->mod_stmt = false;
foreach(l, SPI_plan_get_plan_sources(expr->plan))
{
@@ -5174,7 +5173,7 @@ exec_eval_expr(PLpgSQL_execstate *estate,
* If first time through, create a plan for this expression.
*/
if (expr->plan == NULL)
- exec_prepare_plan(estate, expr, 0);
+ exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
/*
* If this is a simple expression, bypass SPI and use the executor
@@ -5187,7 +5186,7 @@ exec_eval_expr(PLpgSQL_execstate *estate,
/*
* Else do it the hard way via exec_run_select
*/
- rc = exec_run_select(estate, expr, 2, NULL, false);
+ rc = exec_run_select(estate, expr, 2, NULL);
if (rc != SPI_OK_SELECT)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -5243,18 +5242,23 @@ exec_eval_expr(PLpgSQL_execstate *estate,
*/
static int
exec_run_select(PLpgSQL_execstate *estate,
- PLpgSQL_expr *expr, long maxtuples, Portal *portalP,
- bool parallelOK)
+ PLpgSQL_expr *expr, long maxtuples, Portal *portalP)
{
ParamListInfo paramLI;
int rc;
/*
- * On the first call for this expression generate the plan
+ * On the first call for this expression generate the plan.
+ *
+ * If we don't need to return a portal, then we're just going to execute
+ * the query once, which means it's OK to use a parallel plan, even if the
+ * number of rows being fetched is limited. If we do need to return a
+ * portal, the caller might do cursor operations, which parallel query
+ * can't support.
*/
if (expr->plan == NULL)
- exec_prepare_plan(estate, expr, parallelOK ?
- CURSOR_OPT_PARALLEL_OK : 0);
+ exec_prepare_plan(estate, expr,
+ portalP == NULL ? CURSOR_OPT_PARALLEL_OK : 0);
/*
* If a portal was requested, put the query into the portal