postgres.git / summary / log / commit / refs

commit    602c91cf2ef7745bdecac2d3a644a343c7c0a17d
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Mon Jul 07 18:33:20 2025 +0000

    Restore the ability to run pl/pgsql expression queries in parallel.
    
    pl/pgsql's notion of an "expression" is very broad, encompassing
    any SQL SELECT query that returns a single column and no more than
    one row.  So there are cases, for example evaluation of an aggregate
    function, where the query involves significant work and it'd be useful
    to run it with parallel workers.  This used to be possible, but
    commits 3eea7a0c9 et al unintentionally disabled it.
    
    The simplest fix is to make exec_eval_expr() pass maxtuples = 0
    rather than 2 to exec_run_select().  This avoids the new rule that
    we will never use parallelism when a nonzero "count" limit is passed
    to ExecutorRun().  (Note that the pre-3eea7a0c9 behavior was indeed
    unsafe, so reverting that rule is not in the cards.)  The reason
    for passing 2 before was that exec_eval_expr() will throw an error
    if it gets more than one returned row, so we figured that as soon
    as we have two rows we know that will happen and we might as well
    stop running the query.  That choice was cost-free when it was made;
    but disabling parallelism is far from cost-free, so now passing 2
    amounts to optimizing a failure case at the expense of useful cases.
    An expression query that can return more than one row is certainly
    broken.  People might now need to wait a bit longer to discover such
    breakage; but hopefully few will use enormously expensive cases as
    their first test of new pl/pgsql logic.
    
    Author: Dipesh Dhameliya <dipeshdhameliya125@gmail.com>
    Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
    Discussion: https://postgr.es/m/CABgZEgdfbnq9t6xXJnmXbChNTcWFjeM_6nuig41tm327gYi2ig@mail.gmail.com
    Backpatch-through: 13


src/pl/plpgsql/src/pl_exec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 50f158a54a4..6ddf58826e9 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -5653,7 +5653,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); + rc = exec_run_select(estate, expr, 0, NULL); if (rc != SPI_OK_SELECT) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -5707,6 +5707,10 @@ exec_eval_expr(PLpgSQL_execstate *estate, /* ---------- * exec_run_select Execute a select query + * + * Note: passing maxtuples different from 0 ("return all tuples") is + * deprecated because it will prevent parallel execution of the query. + * However, we retain the parameter in case we need it someday. * ---------- */ static int [parent: ac166b19a171]