@@ -260,12 +260,12 @@ static MemoryContext get_stmt_mcontext(PLpgSQL_execstate *estate);
260
260
static void push_stmt_mcontext (PLpgSQL_execstate * estate );
261
261
static void pop_stmt_mcontext (PLpgSQL_execstate * estate );
262
262
263
+ static int exec_toplevel_block (PLpgSQL_execstate * estate ,
264
+ PLpgSQL_stmt_block * block );
263
265
static int exec_stmt_block (PLpgSQL_execstate * estate ,
264
266
PLpgSQL_stmt_block * block );
265
267
static int exec_stmts (PLpgSQL_execstate * estate ,
266
268
List * stmts );
267
- static int exec_stmt (PLpgSQL_execstate * estate ,
268
- PLpgSQL_stmt * stmt );
269
269
static int exec_stmt_assign (PLpgSQL_execstate * estate ,
270
270
PLpgSQL_stmt_assign * stmt );
271
271
static int exec_stmt_perform (PLpgSQL_execstate * estate ,
@@ -599,11 +599,9 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
599
599
* Now call the toplevel block of statements
600
600
*/
601
601
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 );
604
603
if (rc != PLPGSQL_RC_RETURN )
605
604
{
606
- estate .err_stmt = NULL ;
607
605
estate .err_text = NULL ;
608
606
ereport (ERROR ,
609
607
(errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
@@ -613,7 +611,6 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
613
611
/*
614
612
* We got a return value - process it
615
613
*/
616
- estate .err_stmt = NULL ;
617
614
estate .err_text = gettext_noop ("while casting return value to function's return type" );
618
615
619
616
fcinfo -> isnull = estate .retisnull ;
@@ -1015,18 +1012,15 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
1015
1012
* Now call the toplevel block of statements
1016
1013
*/
1017
1014
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 );
1020
1016
if (rc != PLPGSQL_RC_RETURN )
1021
1017
{
1022
- estate .err_stmt = NULL ;
1023
1018
estate .err_text = NULL ;
1024
1019
ereport (ERROR ,
1025
1020
(errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
1026
1021
errmsg ("control reached end of trigger procedure without RETURN" )));
1027
1022
}
1028
1023
1029
- estate .err_stmt = NULL ;
1030
1024
estate .err_text = gettext_noop ("during function exit" );
1031
1025
1032
1026
if (estate .retisset )
@@ -1176,18 +1170,15 @@ plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
1176
1170
* Now call the toplevel block of statements
1177
1171
*/
1178
1172
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 );
1181
1174
if (rc != PLPGSQL_RC_RETURN )
1182
1175
{
1183
- estate .err_stmt = NULL ;
1184
1176
estate .err_text = NULL ;
1185
1177
ereport (ERROR ,
1186
1178
(errcode (ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT ),
1187
1179
errmsg ("control reached end of trigger procedure without RETURN" )));
1188
1180
}
1189
1181
1190
- estate .err_stmt = NULL ;
1191
1182
estate .err_text = gettext_noop ("during function exit" );
1192
1183
1193
1184
/*
@@ -1584,6 +1575,40 @@ exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
1584
1575
}
1585
1576
1586
1577
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
+
1587
1612
/* ----------
1588
1613
* exec_stmt_block Execute a block of statements
1589
1614
* ----------
@@ -1917,6 +1942,7 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
1917
1942
static int
1918
1943
exec_stmts (PLpgSQL_execstate * estate , List * stmts )
1919
1944
{
1945
+ PLpgSQL_stmt * save_estmt = estate -> err_stmt ;
1920
1946
ListCell * s ;
1921
1947
1922
1948
if (stmts == NIL )
@@ -1933,162 +1959,150 @@ exec_stmts(PLpgSQL_execstate *estate, List *stmts)
1933
1959
foreach (s , stmts )
1934
1960
{
1935
1961
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 ;
1941
1963
1942
- return PLPGSQL_RC_OK ;
1943
- }
1964
+ estate -> err_stmt = stmt ;
1944
1965
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 );
1945
1969
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 ();
1959
1971
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 ;
1963
1977
1964
- CHECK_FOR_INTERRUPTS ();
1978
+ case PLPGSQL_STMT_ASSIGN :
1979
+ rc = exec_stmt_assign (estate , (PLpgSQL_stmt_assign * ) stmt );
1980
+ break ;
1965
1981
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 ;
1971
1985
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 ;
1975
1989
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 ;
1979
1993
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 ;
1983
1997
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 ;
1987
2001
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 ;
1991
2005
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 ;
1995
2009
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 ;
1999
2013
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 ;
2003
2017
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 ;
2007
2021
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 ;
2011
2025
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 ;
2015
2029
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 ;
2019
2033
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 ;
2023
2037
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 ;
2027
2041
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 ;
2031
2045
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 ;
2035
2049
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 ;
2039
2053
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 ;
2043
2057
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 ;
2047
2061
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 ;
2051
2065
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 ;
2055
2069
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 ;
2059
2073
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 ;
2063
2077
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 ;
2067
2081
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 ;
2071
2085
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
+ }
2075
2092
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 ) ;
2079
2096
2080
- default :
2097
+ if (rc != PLPGSQL_RC_OK )
2098
+ {
2081
2099
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 */
2088
2103
2089
2104
estate -> err_stmt = save_estmt ;
2090
-
2091
- return rc ;
2105
+ return PLPGSQL_RC_OK ;
2092
2106
}
2093
2107
2094
2108
0 commit comments