@@ -153,6 +153,8 @@ static int exec_stmt_return_query(PLpgSQL_execstate *estate,
153
153
PLpgSQL_stmt_return_query * stmt );
154
154
static int exec_stmt_raise (PLpgSQL_execstate * estate ,
155
155
PLpgSQL_stmt_raise * stmt );
156
+ static int exec_stmt_assert (PLpgSQL_execstate * estate ,
157
+ PLpgSQL_stmt_assert * stmt );
156
158
static int exec_stmt_execsql (PLpgSQL_execstate * estate ,
157
159
PLpgSQL_stmt_execsql * stmt );
158
160
static int exec_stmt_dynexecute (PLpgSQL_execstate * estate ,
@@ -363,8 +365,8 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo,
363
365
estate .err_text = NULL ;
364
366
365
367
/*
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.
368
370
*/
369
371
if (rc == PLPGSQL_RC_CONTINUE )
370
372
ereport (ERROR ,
@@ -730,8 +732,8 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
730
732
estate .err_text = NULL ;
731
733
732
734
/*
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.
735
737
*/
736
738
if (rc == PLPGSQL_RC_CONTINUE )
737
739
ereport (ERROR ,
@@ -862,8 +864,8 @@ plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata)
862
864
estate .err_text = NULL ;
863
865
864
866
/*
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.
867
869
*/
868
870
if (rc == PLPGSQL_RC_CONTINUE )
869
871
ereport (ERROR ,
@@ -1027,12 +1029,14 @@ exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
1027
1029
int sqlerrstate = cond -> sqlerrstate ;
1028
1030
1029
1031
/*
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.
1032
1035
*/
1033
1036
if (sqlerrstate == 0 )
1034
1037
{
1035
- if (edata -> sqlerrcode != ERRCODE_QUERY_CANCELED )
1038
+ if (edata -> sqlerrcode != ERRCODE_QUERY_CANCELED &&
1039
+ edata -> sqlerrcode != ERRCODE_ASSERT_FAILURE )
1036
1040
return true;
1037
1041
}
1038
1042
/* Exact match? */
@@ -1471,6 +1475,10 @@ exec_stmt(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
1471
1475
rc = exec_stmt_raise (estate , (PLpgSQL_stmt_raise * ) stmt );
1472
1476
break ;
1473
1477
1478
+ case PLPGSQL_STMT_ASSERT :
1479
+ rc = exec_stmt_assert (estate , (PLpgSQL_stmt_assert * ) stmt );
1480
+ break ;
1481
+
1474
1482
case PLPGSQL_STMT_EXECSQL :
1475
1483
rc = exec_stmt_execsql (estate , (PLpgSQL_stmt_execsql * ) stmt );
1476
1484
break ;
@@ -3117,6 +3125,48 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt)
3117
3125
return PLPGSQL_RC_OK ;
3118
3126
}
3119
3127
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
+ }
3120
3170
3121
3171
/* ----------
3122
3172
* Initialize a mostly empty execution state
0 commit comments