88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.184 2007/01/2816:15:49 tgl Exp $
11+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.185 2007/01/2817:58:13 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -267,6 +267,8 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
267267}
268268}
269269
270+ estate .err_text = gettext_noop ("during function entry" );
271+
270272/*
271273 * Set the magic variable FOUND to false
272274 */
@@ -414,6 +416,8 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
414416}
415417}
416418
419+ estate .err_text = gettext_noop ("during function exit" );
420+
417421/*
418422 * Let the instrumentation plugin peek at this function
419423 */
@@ -608,6 +612,8 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
608612CStringGetDatum (trigdata -> tg_trigger -> tgargs [i ]));
609613}
610614
615+ estate .err_text = gettext_noop ("during function entry" );
616+
611617/*
612618 * Set the magic variable FOUND to false
613619 */
@@ -644,6 +650,9 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
644650errmsg ("control reached end of trigger procedure without RETURN" )));
645651}
646652
653+ estate .err_stmt = NULL ;
654+ estate .err_text = gettext_noop ("during function exit" );
655+
647656if (estate .retisset )
648657ereport (ERROR ,
649658(errcode (ERRCODE_DATATYPE_MISMATCH ),
@@ -711,30 +720,48 @@ plpgsql_exec_error_callback(void *arg)
711720if (estate -> err_text == raise_skip_msg )
712721return ;
713722
714- if (estate -> err_stmt != NULL )
715- {
716- /* translator: last %s is a plpgsql statement type name */
717- errcontext ("PL/pgSQL function \"%s\" line %d at %s" ,
718- estate -> err_func -> fn_name ,
719- estate -> err_stmt -> lineno ,
720- plpgsql_stmt_typename (estate -> err_stmt ));
721- }
722- else if (estate -> err_text != NULL )
723+ if (estate -> err_text != NULL )
723724{
724725/*
725726 * We don't expend the cycles to run gettext() on err_text unless we
726727 * actually need it. Therefore, places that set up err_text should
727728 * use gettext_noop() to ensure the strings get recorded in the
728729 * message dictionary.
730+ *
731+ * If both err_text and err_stmt are set, use the err_text as
732+ * description, but report the err_stmt's line number. When
733+ * err_stmt is not set, we're in function entry/exit, or some such
734+ * place not attached to a specific line number.
729735 */
730-
731- /*
732- * translator: last %s is a phrase such as "while storing call
733- * arguments into local variables"
734- */
735- errcontext ("PL/pgSQL function \"%s\" %s" ,
736+ if (estate -> err_stmt != NULL )
737+ {
738+ /*
739+ * translator: last %s is a phrase such as "during statement
740+ * block local variable initialization"
741+ */
742+ errcontext ("PL/pgSQL function \"%s\" line %d %s" ,
743+ estate -> err_func -> fn_name ,
744+ estate -> err_stmt -> lineno ,
745+ gettext (estate -> err_text ));
746+ }
747+ else
748+ {
749+ /*
750+ * translator: last %s is a phrase such as "while storing call
751+ * arguments into local variables"
752+ */
753+ errcontext ("PL/pgSQL function \"%s\" %s" ,
754+ estate -> err_func -> fn_name ,
755+ gettext (estate -> err_text ));
756+ }
757+ }
758+ else if (estate -> err_stmt != NULL )
759+ {
760+ /* translator: last %s is a plpgsql statement type name */
761+ errcontext ("PL/pgSQL function \"%s\" line %d at %s" ,
736762estate -> err_func -> fn_name ,
737- gettext (estate -> err_text ));
763+ estate -> err_stmt -> lineno ,
764+ plpgsql_stmt_typename (estate -> err_stmt ));
738765}
739766else
740767errcontext ("PL/pgSQL function \"%s\"" ,
@@ -846,6 +873,8 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
846873/*
847874 * First initialize all variables declared in this block
848875 */
876+ estate -> err_text = gettext_noop ("during statement block local variable initialization" );
877+
849878for (i = 0 ;i < block -> n_initvars ;i ++ )
850879{
851880n = block -> initvarnos [i ];
@@ -915,6 +944,8 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
915944EState * old_eval_estate = estate -> eval_estate ;
916945longint old_eval_estate_simple_id = estate -> eval_estate_simple_id ;
917946
947+ estate -> err_text = gettext_noop ("during statement block entry" );
948+
918949BeginInternalSubTransaction (NULL );
919950/* Want to run statements inside function's memory context */
920951MemoryContextSwitchTo (oldcontext );
@@ -929,9 +960,13 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
929960 */
930961plpgsql_create_econtext (estate );
931962
963+ estate -> err_text = NULL ;
964+
932965/* Run the block's statements */
933966rc = exec_stmts (estate ,block -> body );
934967
968+ estate -> err_text = gettext_noop ("during statement block exit" );
969+
935970/* Commit the inner transaction, return to outer xact context */
936971ReleaseCurrentSubTransaction ();
937972MemoryContextSwitchTo (oldcontext );
@@ -953,6 +988,8 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
953988ErrorData * edata ;
954989ListCell * e ;
955990
991+ estate -> err_text = gettext_noop ("during exception cleanup" );
992+
956993/* Save error info */
957994MemoryContextSwitchTo (oldcontext );
958995edata = CopyErrorData ();
@@ -1004,6 +1041,8 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
10041041errm_var -> freeval = true;
10051042errm_var -> isnull = false;
10061043
1044+ estate -> err_text = NULL ;
1045+
10071046rc = exec_stmts (estate ,exception -> action );
10081047
10091048free_var (state_var );
@@ -1025,9 +1064,13 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
10251064/*
10261065 * Just execute the statements in the block's body
10271066 */
1067+ estate -> err_text = NULL ;
1068+
10281069rc = exec_stmts (estate ,block -> body );
10291070}
10301071
1072+ estate -> err_text = NULL ;
1073+
10311074/*
10321075 * Handle the return code.
10331076 */