@@ -153,6 +153,8 @@ static int exec_stmt_return_query(PLpgSQL_execstate *estate,
153153 PLpgSQL_stmt_return_query * stmt );
154154static int exec_stmt_raise (PLpgSQL_execstate * estate ,
155155 PLpgSQL_stmt_raise * stmt );
156+ static int exec_stmt_assert (PLpgSQL_execstate * estate ,
157+ PLpgSQL_stmt_assert * stmt );
156158static int exec_stmt_execsql (PLpgSQL_execstate * estate ,
157159 PLpgSQL_stmt_execsql * stmt );
158160static int exec_stmt_dynexecute (PLpgSQL_execstate * estate ,
@@ -363,8 +365,8 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
363365 estate .err_text = NULL ;
364366
365367 /*
366- * Provide a more helpful message if a CONTINUE or RAISE has been used
367- * outside the context it can work in.
368+ * Provide a more helpful message if a CONTINUE has been used outside
369+ * the context it can work in.
368370 */
369371 if (rc == PLPGSQL_RC_CONTINUE )
370372 ereport (ERROR ,
@@ -730,8 +732,8 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
730732 estate .err_text = NULL ;
731733
732734 /*
733- * Provide a more helpful message if a CONTINUE or RAISE has been used
734- * outside the context it can work in.
735+ * Provide a more helpful message if a CONTINUE has been used outside
736+ * the context it can work in.
735737 */
736738 if (rc == PLPGSQL_RC_CONTINUE )
737739 ereport (ERROR ,
@@ -862,8 +864,8 @@ plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
862864 estate .err_text = NULL ;
863865
864866 /*
865- * Provide a more helpful message if a CONTINUE or RAISE has been used
866- * outside the context it can work in.
867+ * Provide a more helpful message if a CONTINUE has been used outside
868+ * the context it can work in.
867869 */
868870 if (rc == PLPGSQL_RC_CONTINUE )
869871 ereport (ERROR ,
@@ -1027,12 +1029,14 @@ exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
10271029 int sqlerrstate = cond -> sqlerrstate ;
10281030
10291031 /*
1030- * OTHERS matches everything *except* query-canceled; if you're
1031- * foolish enough, you can match that explicitly.
1032+ * OTHERS matches everything *except* query-canceled and
1033+ * assert-failure. If you're foolish enough, you can match those
1034+ * explicitly.
10321035 */
10331036 if (sqlerrstate == 0 )
10341037 {
1035- if (edata -> sqlerrcode != ERRCODE_QUERY_CANCELED )
1038+ if (edata -> sqlerrcode != ERRCODE_QUERY_CANCELED &&
1039+ edata -> sqlerrcode != ERRCODE_ASSERT_FAILURE )
10361040 return true;
10371041 }
10381042 /* Exact match? */
@@ -1471,6 +1475,10 @@ exec_stmt(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
14711475 rc = exec_stmt_raise (estate , (PLpgSQL_stmt_raise * ) stmt );
14721476 break ;
14731477
1478+ case PLPGSQL_STMT_ASSERT :
1479+ rc = exec_stmt_assert (estate , (PLpgSQL_stmt_assert * ) stmt );
1480+ break ;
1481+
14741482 case PLPGSQL_STMT_EXECSQL :
14751483 rc = exec_stmt_execsql (estate , (PLpgSQL_stmt_execsql * ) stmt );
14761484 break ;
@@ -3117,6 +3125,48 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
31173125 return PLPGSQL_RC_OK ;
31183126}
31193127
3128+ /* ----------
3129+ * exec_stmt_assert Assert statement
3130+ * ----------
3131+ */
3132+ static int
3133+ exec_stmt_assert (PLpgSQL_execstate * estate , PLpgSQL_stmt_assert * stmt )
3134+ {
3135+ bool value ;
3136+ bool isnull ;
3137+
3138+ /* do nothing when asserts are not enabled */
3139+ if (!plpgsql_check_asserts )
3140+ return PLPGSQL_RC_OK ;
3141+
3142+ value = exec_eval_boolean (estate , stmt -> cond , & isnull );
3143+ exec_eval_cleanup (estate );
3144+
3145+ if (isnull || !value )
3146+ {
3147+ char * message = NULL ;
3148+
3149+ if (stmt -> message != NULL )
3150+ {
3151+ Datum val ;
3152+ Oid typeid ;
3153+ int32 typmod ;
3154+
3155+ val = exec_eval_expr (estate , stmt -> message ,
3156+ & isnull , & typeid , & typmod );
3157+ if (!isnull )
3158+ message = convert_value_to_string (estate , val , typeid );
3159+ /* we mustn't do exec_eval_cleanup here */
3160+ }
3161+
3162+ ereport (ERROR ,
3163+ (errcode (ERRCODE_ASSERT_FAILURE ),
3164+ message ? errmsg_internal ("%s" , message ) :
3165+ errmsg ("assertion failed" )));
3166+ }
3167+
3168+ return PLPGSQL_RC_OK ;
3169+ }
31203170
31213171/* ----------
31223172 * Initialize a mostly empty execution state
0 commit comments