|
3 | 3 | * procedural language |
4 | 4 | * |
5 | 5 | * IDENTIFICATION |
6 | | - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.142 2005/06/07 02:47:17 neilc Exp $ |
| 6 | + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.143 2005/06/10 16:23:11 neilc Exp $ |
7 | 7 | * |
8 | 8 | * This software is copyrighted by Jan Wieck - Hamburg. |
9 | 9 | * |
@@ -180,7 +180,7 @@ static Datum exec_simple_cast_value(Datum value, Oid valtype, |
180 | 180 | static void exec_init_tuple_store(PLpgSQL_execstate *estate); |
181 | 181 | static bool compatible_tupdesc(TupleDesc td1, TupleDesc td2); |
182 | 182 | static void exec_set_found(PLpgSQL_execstate *estate, bool state); |
183 | | - |
| 183 | +static void free_var(PLpgSQL_var *var); |
184 | 184 |
|
185 | 185 | /* ---------- |
186 | 186 | * plpgsql_exec_function Called by the call handler for |
@@ -760,12 +760,7 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) |
760 | 760 | { |
761 | 761 | PLpgSQL_var *var = (PLpgSQL_var *) (estate->datums[n]); |
762 | 762 |
|
763 | | - if (var->freeval) |
764 | | - { |
765 | | - pfree((void *) (var->value)); |
766 | | - var->freeval = false; |
767 | | - } |
768 | | - |
| 763 | + free_var(var); |
769 | 764 | if (!var->isconst || var->isnull) |
770 | 765 | { |
771 | 766 | if (var->default_val == NULL) |
@@ -864,13 +859,37 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) |
864 | 859 | SPI_restore_connection(); |
865 | 860 |
|
866 | 861 | /* Look for a matching exception handler */ |
867 | | - foreach (e, block->exceptions) |
| 862 | + foreach (e, block->exceptions->exc_list) |
868 | 863 | { |
869 | 864 | PLpgSQL_exception *exception = (PLpgSQL_exception *) lfirst(e); |
870 | 865 |
|
871 | 866 | if (exception_matches_conditions(edata, exception->conditions)) |
872 | 867 | { |
| 868 | + /* |
| 869 | + * Initialize the magic SQLSTATE and SQLERRM |
| 870 | + * variables for the exception block. We needn't |
| 871 | + * do this until we have found a matching |
| 872 | + * exception. |
| 873 | + */ |
| 874 | + PLpgSQL_var *state_var; |
| 875 | + PLpgSQL_var *errm_var; |
| 876 | + |
| 877 | + state_var = (PLpgSQL_var *) (estate->datums[block->exceptions->sqlstate_varno]); |
| 878 | + state_var->value = DirectFunctionCall1(textin, |
| 879 | + CStringGetDatum(unpack_sql_state(edata->sqlerrcode))); |
| 880 | + state_var->freeval = true; |
| 881 | + state_var->isnull = false; |
| 882 | + |
| 883 | + errm_var = (PLpgSQL_var *) (estate->datums[block->exceptions->sqlerrm_varno]); |
| 884 | + errm_var->value = DirectFunctionCall1(textin, |
| 885 | + CStringGetDatum(edata->message)); |
| 886 | + errm_var->freeval = true; |
| 887 | + errm_var->isnull = false; |
| 888 | + |
873 | 889 | rc = exec_stmts(estate, exception->action); |
| 890 | + |
| 891 | + free_var(state_var); |
| 892 | + free_var(errm_var); |
874 | 893 | break; |
875 | 894 | } |
876 | 895 | } |
@@ -2586,9 +2605,7 @@ exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt) |
2586 | 2605 | * Store the eventually assigned cursor name in the cursor variable |
2587 | 2606 | * ---------- |
2588 | 2607 | */ |
2589 | | - if (curvar->freeval) |
2590 | | - pfree((void *) (curvar->value)); |
2591 | | - |
| 2608 | + free_var(curvar); |
2592 | 2609 | curvar->value = DirectFunctionCall1(textin, CStringGetDatum(portal->name)); |
2593 | 2610 | curvar->isnull = false; |
2594 | 2611 | curvar->freeval = true; |
@@ -2684,9 +2701,7 @@ exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt) |
2684 | 2701 | * Store the eventually assigned portal name in the cursor variable |
2685 | 2702 | * ---------- |
2686 | 2703 | */ |
2687 | | - if (curvar->freeval) |
2688 | | - pfree((void *) (curvar->value)); |
2689 | | - |
| 2704 | + free_var(curvar); |
2690 | 2705 | curvar->value = DirectFunctionCall1(textin, CStringGetDatum(portal->name)); |
2691 | 2706 | curvar->isnull = false; |
2692 | 2707 | curvar->freeval = true; |
@@ -2857,11 +2872,7 @@ exec_assign_value(PLpgSQL_execstate *estate, |
2857 | 2872 | errmsg("NULL cannot be assigned to variable \"%s\" declared NOT NULL", |
2858 | 2873 | var->refname))); |
2859 | 2874 |
|
2860 | | - if (var->freeval) |
2861 | | - { |
2862 | | - pfree(DatumGetPointer(var->value)); |
2863 | | - var->freeval = false; |
2864 | | - } |
| 2875 | + free_var(var); |
2865 | 2876 |
|
2866 | 2877 | /* |
2867 | 2878 | * If type is by-reference, make sure we have a freshly |
@@ -4343,3 +4354,13 @@ plpgsql_xact_cb(XactEvent event, void *arg) |
4343 | 4354 | FreeExecutorState(simple_eval_estate); |
4344 | 4355 | simple_eval_estate = NULL; |
4345 | 4356 | } |
| 4357 | + |
| 4358 | +static void |
| 4359 | +free_var(PLpgSQL_var *var) |
| 4360 | +{ |
| 4361 | + if (var->freeval) |
| 4362 | + { |
| 4363 | + pfree(DatumGetPointer(var->value)); |
| 4364 | + var->freeval = false; |
| 4365 | + } |
| 4366 | +} |
0 commit comments