|
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 | staticvoidexec_init_tuple_store(PLpgSQL_execstate*estate);
|
181 | 181 | staticboolcompatible_tupdesc(TupleDesctd1,TupleDesctd2);
|
182 | 182 | staticvoidexec_set_found(PLpgSQL_execstate*estate,boolstate);
|
183 |
| - |
| 183 | +staticvoidfree_var(PLpgSQL_var*var); |
184 | 184 |
|
185 | 185 | /* ----------
|
186 | 186 | * plpgsql_exec_functionCalled 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 | +staticvoid |
| 4359 | +free_var(PLpgSQL_var*var) |
| 4360 | +{ |
| 4361 | +if (var->freeval) |
| 4362 | +{ |
| 4363 | +pfree(DatumGetPointer(var->value)); |
| 4364 | +var->freeval= false; |
| 4365 | +} |
| 4366 | +} |