---------- * exec_stmt_raise Build a message and throw it with elog() * ---------- */
| 3672 | * ---------- |
| 3673 | */ |
| 3674 | static int |
| 3675 | exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt) |
| 3676 | { |
| 3677 | int err_code = 0; |
| 3678 | char *condname = NULL; |
| 3679 | char *err_message = NULL; |
| 3680 | char *err_detail = NULL; |
| 3681 | char *err_hint = NULL; |
| 3682 | char *err_column = NULL; |
| 3683 | char *err_constraint = NULL; |
| 3684 | char *err_datatype = NULL; |
| 3685 | char *err_table = NULL; |
| 3686 | char *err_schema = NULL; |
| 3687 | MemoryContext stmt_mcontext; |
| 3688 | ListCell *lc; |
| 3689 | |
| 3690 | /* RAISE with no parameters: re-throw current exception */ |
| 3691 | if (stmt->condname == NULL && stmt->message == NULL && |
| 3692 | stmt->options == NIL) |
| 3693 | { |
| 3694 | if (estate->cur_error != NULL) |
| 3695 | ReThrowError(estate->cur_error); |
| 3696 | /* oops, we're not inside a handler */ |
| 3697 | ereport(ERROR, |
| 3698 | (errcode(ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER), |
| 3699 | errmsg("RAISE without parameters cannot be used outside an exception handler"))); |
| 3700 | } |
| 3701 | |
| 3702 | /* We'll need to accumulate the various strings in stmt_mcontext */ |
| 3703 | stmt_mcontext = get_stmt_mcontext(estate); |
| 3704 | |
| 3705 | if (stmt->condname) |
| 3706 | { |
| 3707 | err_code = plpgsql_recognize_err_condition(stmt->condname, true); |
| 3708 | condname = MemoryContextStrdup(stmt_mcontext, stmt->condname); |
| 3709 | } |
| 3710 | |
| 3711 | if (stmt->message) |
| 3712 | { |
| 3713 | StringInfoData ds; |
| 3714 | ListCell *current_param; |
| 3715 | char *cp; |
| 3716 | MemoryContext oldcontext; |
| 3717 | |
| 3718 | /* build string in stmt_mcontext */ |
| 3719 | oldcontext = MemoryContextSwitchTo(stmt_mcontext); |
| 3720 | initStringInfo(&ds); |
| 3721 | MemoryContextSwitchTo(oldcontext); |
| 3722 | |
| 3723 | current_param = list_head(stmt->params); |
| 3724 | |
| 3725 | for (cp = stmt->message; *cp; cp++) |
| 3726 | { |
| 3727 | /* |
| 3728 | * Occurrences of a single % are replaced by the next parameter's |
| 3729 | * external representation. Double %'s are converted to one %. |
| 3730 | */ |
| 3731 | if (cp[0] == '%') |
no test coverage detected