Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 61c2e1a

Browse files
committed
Improve access to parallel query from procedural languages.
In SQL, the ability to use parallel query was previous contingent on fcache->readonly_func, which is only set for non-volatile functions; but the volatility of a function has no bearing on whether queries inside it can use parallelism. Remove that condition. SPI_execute and SPI_execute_with_args always run the plan just once, though not necessarily to completion. Given the changes in commit 691b8d5, it's sensible to pass CURSOR_OPT_PARALLEL_OK here, so do that. This improves access to parallelism for any caller that uses these functions to execute queries. Such callers include plperl, plpython, pltcl, and plpgsql, though it's not the case that they all use these functions exclusively. In plpgsql, allow parallel query for plain SELECT queries (as opposed to PERFORM, which already worked) and for plain expressions (which probably won't go through the executor at all, because they will likely be simple expressions, but if they do then this helps). Rafia Sabih and Robert Haas, reviewed by Dilip Kumar and Amit Kapila Discussion: http://postgr.es/m/CAOGQiiMfJ+4SQwgG=6CVHWoisiU0+7jtXSuiyXBM3y=A=eJzmg@mail.gmail.com
1 parent 8082bea commit 61c2e1a

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

src/backend/executor/functions.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ init_execution_state(List *queryTree_list,
503503
}
504504
else
505505
stmt = pg_plan_query(queryTree,
506-
fcache->readonly_func ? CURSOR_OPT_PARALLEL_OK : 0,
506+
CURSOR_OPT_PARALLEL_OK,
507507
NULL);
508508

509509
/*

src/backend/executor/spi.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ SPI_execute(const char *src, bool read_only, long tcount)
314314

315315
memset(&plan, 0, sizeof(_SPI_plan));
316316
plan.magic = _SPI_PLAN_MAGIC;
317-
plan.cursor_options = 0;
317+
plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
318318

319319
_SPI_prepare_oneshot_plan(src, &plan);
320320

@@ -458,7 +458,7 @@ SPI_execute_with_args(const char *src,
458458

459459
memset(&plan, 0, sizeof(_SPI_plan));
460460
plan.magic = _SPI_PLAN_MAGIC;
461-
plan.cursor_options = 0;
461+
plan.cursor_options = CURSOR_OPT_PARALLEL_OK;
462462
plan.nargs = nargs;
463463
plan.argtypes = argtypes;
464464
plan.parserSetup = NULL;

src/pl/plpgsql/src/pl_exec.c

+17-13
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,7 @@ static Datum exec_eval_expr(PLpgSQL_execstate *estate,
264264
Oid *rettype,
265265
int32 *rettypmod);
266266
static int exec_run_select(PLpgSQL_execstate *estate,
267-
PLpgSQL_expr *expr, long maxtuples, Portal *portalP,
268-
bool parallelOK);
267+
PLpgSQL_expr *expr, long maxtuples, Portal *portalP);
269268
static int exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt,
270269
Portal portal, bool prefetch_ok);
271270
static ParamListInfo setup_param_list(PLpgSQL_execstate *estate,
@@ -1685,7 +1684,7 @@ exec_stmt_perform(PLpgSQL_execstate *estate, PLpgSQL_stmt_perform *stmt)
16851684
{
16861685
PLpgSQL_expr *expr = stmt->expr;
16871686

1688-
(void) exec_run_select(estate, expr, 0, NULL, true);
1687+
(void) exec_run_select(estate, expr, 0, NULL);
16891688
exec_set_found(estate, (estate->eval_processed != 0));
16901689
exec_eval_cleanup(estate);
16911690

@@ -2238,7 +2237,7 @@ exec_stmt_fors(PLpgSQL_execstate *estate, PLpgSQL_stmt_fors *stmt)
22382237
/*
22392238
* Open the implicit cursor for the statement using exec_run_select
22402239
*/
2241-
exec_run_select(estate, stmt->query, 0, &portal, false);
2240+
exec_run_select(estate, stmt->query, 0, &portal);
22422241

22432242
/*
22442243
* Execute the loop
@@ -3023,7 +3022,7 @@ exec_stmt_return_query(PLpgSQL_execstate *estate,
30233022
if (stmt->query != NULL)
30243023
{
30253024
/* static query */
3026-
exec_run_select(estate, stmt->query, 0, &portal, false);
3025+
exec_run_select(estate, stmt->query, 0, &portal);
30273026
}
30283027
else
30293028
{
@@ -3627,7 +3626,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
36273626
{
36283627
ListCell *l;
36293628

3630-
exec_prepare_plan(estate, expr, 0);
3629+
exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
36313630
stmt->mod_stmt = false;
36323631
foreach(l, SPI_plan_get_plan_sources(expr->plan))
36333632
{
@@ -5174,7 +5173,7 @@ exec_eval_expr(PLpgSQL_execstate *estate,
51745173
* If first time through, create a plan for this expression.
51755174
*/
51765175
if (expr->plan == NULL)
5177-
exec_prepare_plan(estate, expr, 0);
5176+
exec_prepare_plan(estate, expr, CURSOR_OPT_PARALLEL_OK);
51785177

51795178
/*
51805179
* If this is a simple expression, bypass SPI and use the executor
@@ -5187,7 +5186,7 @@ exec_eval_expr(PLpgSQL_execstate *estate,
51875186
/*
51885187
* Else do it the hard way via exec_run_select
51895188
*/
5190-
rc = exec_run_select(estate, expr, 2, NULL, false);
5189+
rc = exec_run_select(estate, expr, 2, NULL);
51915190
if (rc != SPI_OK_SELECT)
51925191
ereport(ERROR,
51935192
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -5243,18 +5242,23 @@ exec_eval_expr(PLpgSQL_execstate *estate,
52435242
*/
52445243
static int
52455244
exec_run_select(PLpgSQL_execstate *estate,
5246-
PLpgSQL_expr *expr, long maxtuples, Portal *portalP,
5247-
bool parallelOK)
5245+
PLpgSQL_expr *expr, long maxtuples, Portal *portalP)
52485246
{
52495247
ParamListInfo paramLI;
52505248
int rc;
52515249

52525250
/*
5253-
* On the first call for this expression generate the plan
5251+
* On the first call for this expression generate the plan.
5252+
*
5253+
* If we don't need to return a portal, then we're just going to execute
5254+
* the query once, which means it's OK to use a parallel plan, even if the
5255+
* number of rows being fetched is limited. If we do need to return a
5256+
* portal, the caller might do cursor operations, which parallel query
5257+
* can't support.
52545258
*/
52555259
if (expr->plan == NULL)
5256-
exec_prepare_plan(estate, expr, parallelOK ?
5257-
CURSOR_OPT_PARALLEL_OK : 0);
5260+
exec_prepare_plan(estate, expr,
5261+
portalP == NULL ? CURSOR_OPT_PARALLEL_OK : 0);
52585262

52595263
/*
52605264
* If a portal was requested, put the query into the portal

0 commit comments

Comments
 (0)