@@ -260,12 +260,12 @@ static MemoryContext get_stmt_mcontext(PLpgSQL_execstate *estate);
260260static void push_stmt_mcontext (PLpgSQL_execstate * estate );
261261static void pop_stmt_mcontext (PLpgSQL_execstate * estate );
262262
263+ static int exec_toplevel_block (PLpgSQL_execstate * estate ,
264+ PLpgSQL_stmt_block * block );
263265static int exec_stmt_block (PLpgSQL_execstate * estate ,
264266 PLpgSQL_stmt_block * block );
265267static int exec_stmts (PLpgSQL_execstate * estate ,
266268 List * stmts );
267- static int exec_stmt (PLpgSQL_execstate * estate ,
268- PLpgSQL_stmt * stmt );
269269static int exec_stmt_assign (PLpgSQL_execstate * estate ,
270270 PLpgSQL_stmt_assign * stmt );
271271static int exec_stmt_perform (PLpgSQL_execstate * estate ,
@@ -599,11 +599,9 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
599599 * Now call the toplevel block of statements
600600 */
601601 estate .err_text = NULL ;
602- estate .err_stmt = (PLpgSQL_stmt * ) (func -> action );
603- rc = exec_stmt (& estate , (PLpgSQL_stmt * ) func -> action );
602+ rc = exec_toplevel_block (& estate , func -> action );
604603 if (rc != PLPGSQL_RC_RETURN )
605604 {
606- estate .err_stmt = NULL ;
607605 estate .err_text = NULL ;
608606 ereport (ERROR ,
609607 (errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
@@ -613,7 +611,6 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
613611 /*
614612 * We got a return value - process it
615613 */
616- estate .err_stmt = NULL ;
617614 estate .err_text = gettext_noop ("while casting return value to function's return type" );
618615
619616 fcinfo -> isnull = estate .retisnull ;
@@ -1015,18 +1012,15 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
10151012 * Now call the toplevel block of statements
10161013 */
10171014 estate .err_text = NULL ;
1018- estate .err_stmt = (PLpgSQL_stmt * ) (func -> action );
1019- rc = exec_stmt (& estate , (PLpgSQL_stmt * ) func -> action );
1015+ rc = exec_toplevel_block (& estate , func -> action );
10201016 if (rc != PLPGSQL_RC_RETURN )
10211017 {
1022- estate .err_stmt = NULL ;
10231018 estate .err_text = NULL ;
10241019 ereport (ERROR ,
10251020 (errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
10261021 errmsg ("control reached end of trigger procedure without RETURN" )));
10271022 }
10281023
1029- estate .err_stmt = NULL ;
10301024 estate .err_text = gettext_noop ("during function exit" );
10311025
10321026 if (estate .retisset )
@@ -1176,18 +1170,15 @@ plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
11761170 * Now call the toplevel block of statements
11771171 */
11781172 estate .err_text = NULL ;
1179- estate .err_stmt = (PLpgSQL_stmt * ) (func -> action );
1180- rc = exec_stmt (& estate , (PLpgSQL_stmt * ) func -> action );
1173+ rc = exec_toplevel_block (& estate , func -> action );
11811174 if (rc != PLPGSQL_RC_RETURN )
11821175 {
1183- estate .err_stmt = NULL ;
11841176 estate .err_text = NULL ;
11851177 ereport (ERROR ,
11861178 (errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
11871179 errmsg ("control reached end of trigger procedure without RETURN" )));
11881180 }
11891181
1190- estate .err_stmt = NULL ;
11911182 estate .err_text = gettext_noop ("during function exit" );
11921183
11931184 /*
@@ -1584,6 +1575,40 @@ exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
15841575}
15851576
15861577
1578+ /* ----------
1579+ * exec_toplevel_block Execute the toplevel block
1580+ *
1581+ * This is intentionally equivalent to executing exec_stmts() with a
1582+ * list consisting of the one statement. One tiny difference is that
1583+ * we do not bother to save the entry value of estate->err_stmt;
1584+ * that's assumed to be NULL.
1585+ * ----------
1586+ */
1587+ static int
1588+ exec_toplevel_block (PLpgSQL_execstate * estate , PLpgSQL_stmt_block * block )
1589+ {
1590+ int rc ;
1591+
1592+ estate -> err_stmt = (PLpgSQL_stmt * ) block ;
1593+
1594+ /* Let the plugin know that we are about to execute this statement */
1595+ if (* plpgsql_plugin_ptr && (* plpgsql_plugin_ptr )-> stmt_beg )
1596+ ((* plpgsql_plugin_ptr )-> stmt_beg ) (estate , (PLpgSQL_stmt * ) block );
1597+
1598+ CHECK_FOR_INTERRUPTS ();
1599+
1600+ rc = exec_stmt_block (estate , block );
1601+
1602+ /* Let the plugin know that we have finished executing this statement */
1603+ if (* plpgsql_plugin_ptr && (* plpgsql_plugin_ptr )-> stmt_end )
1604+ ((* plpgsql_plugin_ptr )-> stmt_end ) (estate , (PLpgSQL_stmt * ) block );
1605+
1606+ estate -> err_stmt = NULL ;
1607+
1608+ return rc ;
1609+ }
1610+
1611+
15871612/* ----------
15881613 * exec_stmt_block Execute a block of statements
15891614 * ----------
@@ -1917,6 +1942,7 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
19171942static int
19181943exec_stmts (PLpgSQL_execstate * estate , List * stmts )
19191944{
1945+ PLpgSQL_stmt * save_estmt = estate -> err_stmt ;
19201946 ListCell * s ;
19211947
19221948 if (stmts == NIL )
@@ -1933,162 +1959,150 @@ exec_stmts(PLpgSQL_execstate *estate, List *stmts)
19331959 foreach (s , stmts )
19341960 {
19351961 PLpgSQL_stmt * stmt = (PLpgSQL_stmt * ) lfirst (s );
1936- int rc = exec_stmt (estate , stmt );
1937-
1938- if (rc != PLPGSQL_RC_OK )
1939- return rc ;
1940- }
1962+ int rc ;
19411963
1942- return PLPGSQL_RC_OK ;
1943- }
1964+ estate -> err_stmt = stmt ;
19441965
1966+ /* Let the plugin know that we are about to execute this statement */
1967+ if (* plpgsql_plugin_ptr && (* plpgsql_plugin_ptr )-> stmt_beg )
1968+ ((* plpgsql_plugin_ptr )-> stmt_beg ) (estate , stmt );
19451969
1946- /* ----------
1947- * exec_stmt Distribute one statement to the statements
1948- * type specific execution function.
1949- * ----------
1950- */
1951- static int
1952- exec_stmt (PLpgSQL_execstate * estate , PLpgSQL_stmt * stmt )
1953- {
1954- PLpgSQL_stmt * save_estmt ;
1955- int rc = -1 ;
1956-
1957- save_estmt = estate -> err_stmt ;
1958- estate -> err_stmt = stmt ;
1970+ CHECK_FOR_INTERRUPTS ();
19591971
1960- /* Let the plugin know that we are about to execute this statement */
1961- if (* plpgsql_plugin_ptr && (* plpgsql_plugin_ptr )-> stmt_beg )
1962- ((* plpgsql_plugin_ptr )-> stmt_beg ) (estate , stmt );
1972+ switch (stmt -> cmd_type )
1973+ {
1974+ case PLPGSQL_STMT_BLOCK :
1975+ rc = exec_stmt_block (estate , (PLpgSQL_stmt_block * ) stmt );
1976+ break ;
19631977
1964- CHECK_FOR_INTERRUPTS ();
1978+ case PLPGSQL_STMT_ASSIGN :
1979+ rc = exec_stmt_assign (estate , (PLpgSQL_stmt_assign * ) stmt );
1980+ break ;
19651981
1966- switch (stmt -> cmd_type )
1967- {
1968- case PLPGSQL_STMT_BLOCK :
1969- rc = exec_stmt_block (estate , (PLpgSQL_stmt_block * ) stmt );
1970- break ;
1982+ case PLPGSQL_STMT_PERFORM :
1983+ rc = exec_stmt_perform (estate , (PLpgSQL_stmt_perform * ) stmt );
1984+ break ;
19711985
1972- case PLPGSQL_STMT_ASSIGN :
1973- rc = exec_stmt_assign (estate , (PLpgSQL_stmt_assign * ) stmt );
1974- break ;
1986+ case PLPGSQL_STMT_CALL :
1987+ rc = exec_stmt_call (estate , (PLpgSQL_stmt_call * ) stmt );
1988+ break ;
19751989
1976- case PLPGSQL_STMT_PERFORM :
1977- rc = exec_stmt_perform (estate , (PLpgSQL_stmt_perform * ) stmt );
1978- break ;
1990+ case PLPGSQL_STMT_GETDIAG :
1991+ rc = exec_stmt_getdiag (estate , (PLpgSQL_stmt_getdiag * ) stmt );
1992+ break ;
19791993
1980- case PLPGSQL_STMT_CALL :
1981- rc = exec_stmt_call (estate , (PLpgSQL_stmt_call * ) stmt );
1982- break ;
1994+ case PLPGSQL_STMT_IF :
1995+ rc = exec_stmt_if (estate , (PLpgSQL_stmt_if * ) stmt );
1996+ break ;
19831997
1984- case PLPGSQL_STMT_GETDIAG :
1985- rc = exec_stmt_getdiag (estate , (PLpgSQL_stmt_getdiag * ) stmt );
1986- break ;
1998+ case PLPGSQL_STMT_CASE :
1999+ rc = exec_stmt_case (estate , (PLpgSQL_stmt_case * ) stmt );
2000+ break ;
19872001
1988- case PLPGSQL_STMT_IF :
1989- rc = exec_stmt_if (estate , (PLpgSQL_stmt_if * ) stmt );
1990- break ;
2002+ case PLPGSQL_STMT_LOOP :
2003+ rc = exec_stmt_loop (estate , (PLpgSQL_stmt_loop * ) stmt );
2004+ break ;
19912005
1992- case PLPGSQL_STMT_CASE :
1993- rc = exec_stmt_case (estate , (PLpgSQL_stmt_case * ) stmt );
1994- break ;
2006+ case PLPGSQL_STMT_WHILE :
2007+ rc = exec_stmt_while (estate , (PLpgSQL_stmt_while * ) stmt );
2008+ break ;
19952009
1996- case PLPGSQL_STMT_LOOP :
1997- rc = exec_stmt_loop (estate , (PLpgSQL_stmt_loop * ) stmt );
1998- break ;
2010+ case PLPGSQL_STMT_FORI :
2011+ rc = exec_stmt_fori (estate , (PLpgSQL_stmt_fori * ) stmt );
2012+ break ;
19992013
2000- case PLPGSQL_STMT_WHILE :
2001- rc = exec_stmt_while (estate , (PLpgSQL_stmt_while * ) stmt );
2002- break ;
2014+ case PLPGSQL_STMT_FORS :
2015+ rc = exec_stmt_fors (estate , (PLpgSQL_stmt_fors * ) stmt );
2016+ break ;
20032017
2004- case PLPGSQL_STMT_FORI :
2005- rc = exec_stmt_fori (estate , (PLpgSQL_stmt_fori * ) stmt );
2006- break ;
2018+ case PLPGSQL_STMT_FORC :
2019+ rc = exec_stmt_forc (estate , (PLpgSQL_stmt_forc * ) stmt );
2020+ break ;
20072021
2008- case PLPGSQL_STMT_FORS :
2009- rc = exec_stmt_fors (estate , (PLpgSQL_stmt_fors * ) stmt );
2010- break ;
2022+ case PLPGSQL_STMT_FOREACH_A :
2023+ rc = exec_stmt_foreach_a (estate , (PLpgSQL_stmt_foreach_a * ) stmt );
2024+ break ;
20112025
2012- case PLPGSQL_STMT_FORC :
2013- rc = exec_stmt_forc (estate , (PLpgSQL_stmt_forc * ) stmt );
2014- break ;
2026+ case PLPGSQL_STMT_EXIT :
2027+ rc = exec_stmt_exit (estate , (PLpgSQL_stmt_exit * ) stmt );
2028+ break ;
20152029
2016- case PLPGSQL_STMT_FOREACH_A :
2017- rc = exec_stmt_foreach_a (estate , (PLpgSQL_stmt_foreach_a * ) stmt );
2018- break ;
2030+ case PLPGSQL_STMT_RETURN :
2031+ rc = exec_stmt_return (estate , (PLpgSQL_stmt_return * ) stmt );
2032+ break ;
20192033
2020- case PLPGSQL_STMT_EXIT :
2021- rc = exec_stmt_exit (estate , (PLpgSQL_stmt_exit * ) stmt );
2022- break ;
2034+ case PLPGSQL_STMT_RETURN_NEXT :
2035+ rc = exec_stmt_return_next (estate , (PLpgSQL_stmt_return_next * ) stmt );
2036+ break ;
20232037
2024- case PLPGSQL_STMT_RETURN :
2025- rc = exec_stmt_return (estate , (PLpgSQL_stmt_return * ) stmt );
2026- break ;
2038+ case PLPGSQL_STMT_RETURN_QUERY :
2039+ rc = exec_stmt_return_query (estate , (PLpgSQL_stmt_return_query * ) stmt );
2040+ break ;
20272041
2028- case PLPGSQL_STMT_RETURN_NEXT :
2029- rc = exec_stmt_return_next (estate , (PLpgSQL_stmt_return_next * ) stmt );
2030- break ;
2042+ case PLPGSQL_STMT_RAISE :
2043+ rc = exec_stmt_raise (estate , (PLpgSQL_stmt_raise * ) stmt );
2044+ break ;
20312045
2032- case PLPGSQL_STMT_RETURN_QUERY :
2033- rc = exec_stmt_return_query (estate , (PLpgSQL_stmt_return_query * ) stmt );
2034- break ;
2046+ case PLPGSQL_STMT_ASSERT :
2047+ rc = exec_stmt_assert (estate , (PLpgSQL_stmt_assert * ) stmt );
2048+ break ;
20352049
2036- case PLPGSQL_STMT_RAISE :
2037- rc = exec_stmt_raise (estate , (PLpgSQL_stmt_raise * ) stmt );
2038- break ;
2050+ case PLPGSQL_STMT_EXECSQL :
2051+ rc = exec_stmt_execsql (estate , (PLpgSQL_stmt_execsql * ) stmt );
2052+ break ;
20392053
2040- case PLPGSQL_STMT_ASSERT :
2041- rc = exec_stmt_assert (estate , (PLpgSQL_stmt_assert * ) stmt );
2042- break ;
2054+ case PLPGSQL_STMT_DYNEXECUTE :
2055+ rc = exec_stmt_dynexecute (estate , (PLpgSQL_stmt_dynexecute * ) stmt );
2056+ break ;
20432057
2044- case PLPGSQL_STMT_EXECSQL :
2045- rc = exec_stmt_execsql (estate , (PLpgSQL_stmt_execsql * ) stmt );
2046- break ;
2058+ case PLPGSQL_STMT_DYNFORS :
2059+ rc = exec_stmt_dynfors (estate , (PLpgSQL_stmt_dynfors * ) stmt );
2060+ break ;
20472061
2048- case PLPGSQL_STMT_DYNEXECUTE :
2049- rc = exec_stmt_dynexecute (estate , (PLpgSQL_stmt_dynexecute * ) stmt );
2050- break ;
2062+ case PLPGSQL_STMT_OPEN :
2063+ rc = exec_stmt_open (estate , (PLpgSQL_stmt_open * ) stmt );
2064+ break ;
20512065
2052- case PLPGSQL_STMT_DYNFORS :
2053- rc = exec_stmt_dynfors (estate , (PLpgSQL_stmt_dynfors * ) stmt );
2054- break ;
2066+ case PLPGSQL_STMT_FETCH :
2067+ rc = exec_stmt_fetch (estate , (PLpgSQL_stmt_fetch * ) stmt );
2068+ break ;
20552069
2056- case PLPGSQL_STMT_OPEN :
2057- rc = exec_stmt_open (estate , (PLpgSQL_stmt_open * ) stmt );
2058- break ;
2070+ case PLPGSQL_STMT_CLOSE :
2071+ rc = exec_stmt_close (estate , (PLpgSQL_stmt_close * ) stmt );
2072+ break ;
20592073
2060- case PLPGSQL_STMT_FETCH :
2061- rc = exec_stmt_fetch (estate , (PLpgSQL_stmt_fetch * ) stmt );
2062- break ;
2074+ case PLPGSQL_STMT_COMMIT :
2075+ rc = exec_stmt_commit (estate , (PLpgSQL_stmt_commit * ) stmt );
2076+ break ;
20632077
2064- case PLPGSQL_STMT_CLOSE :
2065- rc = exec_stmt_close (estate , (PLpgSQL_stmt_close * ) stmt );
2066- break ;
2078+ case PLPGSQL_STMT_ROLLBACK :
2079+ rc = exec_stmt_rollback (estate , (PLpgSQL_stmt_rollback * ) stmt );
2080+ break ;
20672081
2068- case PLPGSQL_STMT_COMMIT :
2069- rc = exec_stmt_commit (estate , (PLpgSQL_stmt_commit * ) stmt );
2070- break ;
2082+ case PLPGSQL_STMT_SET :
2083+ rc = exec_stmt_set (estate , (PLpgSQL_stmt_set * ) stmt );
2084+ break ;
20712085
2072- case PLPGSQL_STMT_ROLLBACK :
2073- rc = exec_stmt_rollback (estate , (PLpgSQL_stmt_rollback * ) stmt );
2074- break ;
2086+ default :
2087+ /* point err_stmt to parent, since this one seems corrupt */
2088+ estate -> err_stmt = save_estmt ;
2089+ elog (ERROR , "unrecognized cmd_type: %d" , stmt -> cmd_type );
2090+ rc = -1 ; /* keep compiler quiet */
2091+ }
20752092
2076- case PLPGSQL_STMT_SET :
2077- rc = exec_stmt_set ( estate , ( PLpgSQL_stmt_set * ) stmt );
2078- break ;
2093+ /* Let the plugin know that we have finished executing this statement */
2094+ if ( * plpgsql_plugin_ptr && ( * plpgsql_plugin_ptr ) -> stmt_end )
2095+ (( * plpgsql_plugin_ptr ) -> stmt_end ) ( estate , stmt ) ;
20792096
2080- default :
2097+ if (rc != PLPGSQL_RC_OK )
2098+ {
20812099 estate -> err_stmt = save_estmt ;
2082- elog (ERROR , "unrecognized cmd_type: %d" , stmt -> cmd_type );
2083- }
2084-
2085- /* Let the plugin know that we have finished executing this statement */
2086- if (* plpgsql_plugin_ptr && (* plpgsql_plugin_ptr )-> stmt_end )
2087- ((* plpgsql_plugin_ptr )-> stmt_end ) (estate , stmt );
2100+ return rc ;
2101+ }
2102+ } /* end of loop over statements */
20882103
20892104 estate -> err_stmt = save_estmt ;
2090-
2091- return rc ;
2105+ return PLPGSQL_RC_OK ;
20922106}
20932107
20942108
0 commit comments