diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index d4a3d58daa..ccbddd4d7a 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -5997,6 +5997,12 @@ exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt, */ PinPortal(portal); + /* + * Disable prefetch if procedure contains COMMIT or ROLLBACK statements + */ + if (prefetch_ok && estate->func->fn_xactctrl) + prefetch_ok = false; + /* * Fetch the initial tuple(s). If prefetching is allowed then we grab a * few more rows to avoid multiple trips through executor startup diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y index 5a7e1a4444..5b27311b95 100644 --- a/src/pl/plpgsql/src/pl_gram.y +++ b/src/pl/plpgsql/src/pl_gram.y @@ -2215,6 +2215,8 @@ stmt_commit : K_COMMIT opt_transaction_chain ';' new->stmtid = ++plpgsql_curr_compile->nstatements; new->chain = $2; + plpgsql_curr_compile->fn_xactctrl = true; + $$ = (PLpgSQL_stmt *)new; } ; @@ -2229,6 +2231,8 @@ stmt_rollback : K_ROLLBACK opt_transaction_chain ';' new->stmtid = ++plpgsql_curr_compile->nstatements; new->chain = $2; + plpgsql_curr_compile->fn_xactctrl = true; + $$ = (PLpgSQL_stmt *)new; } ; diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index 0c3d30fb13..e9b9b0d335 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -1006,6 +1006,7 @@ typedef struct PLpgSQL_function bool fn_retisdomain; bool fn_retset; bool fn_readonly; + bool fn_xactctrl; char fn_prokind; int fn_nargs;