Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9d7c005

Browse files
committed
plpgsql's exec_assign_value() freed the old value of a variable before
copying/converting the new value, which meant that it failed badly on"var := var" if var is of pass-by-reference type. Fix this and a similarhazard in exec_move_row(); not sure that the latter can manifest before8.0, but patch it all the way back anyway. Per report from Dave Chapeskie.
1 parentb95ae32 commit9d7c005

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.144 2005/06/14 06:43:14 neilc Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.145 2005/06/20 20:44:44 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -182,6 +182,7 @@ static bool compatible_tupdesc(TupleDesc td1, TupleDesc td2);
182182
staticvoidexec_set_found(PLpgSQL_execstate*estate,boolstate);
183183
staticvoidfree_var(PLpgSQL_var*var);
184184

185+
185186
/* ----------
186187
* plpgsql_exec_functionCalled by the call handler for
187188
*function execution.
@@ -874,13 +875,15 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
874875
PLpgSQL_var*state_var;
875876
PLpgSQL_var*errm_var;
876877

877-
state_var= (PLpgSQL_var*) (estate->datums[block->exceptions->sqlstate_varno]);
878+
state_var= (PLpgSQL_var*)
879+
estate->datums[block->exceptions->sqlstate_varno];
878880
state_var->value=DirectFunctionCall1(textin,
879881
CStringGetDatum(unpack_sql_state(edata->sqlerrcode)));
880882
state_var->freeval= true;
881883
state_var->isnull= false;
882884

883-
errm_var= (PLpgSQL_var*) (estate->datums[block->exceptions->sqlerrm_varno]);
885+
errm_var= (PLpgSQL_var*)
886+
estate->datums[block->exceptions->sqlerrm_varno];
884887
errm_var->value=DirectFunctionCall1(textin,
885888
CStringGetDatum(edata->message));
886889
errm_var->freeval= true;
@@ -2862,8 +2865,6 @@ exec_assign_value(PLpgSQL_execstate *estate,
28622865
errmsg("NULL cannot be assigned to variable \"%s\" declared NOT NULL",
28632866
var->refname)));
28642867

2865-
free_var(var);
2866-
28672868
/*
28682869
* If type is by-reference, make sure we have a freshly
28692870
* palloc'd copy; the originally passed value may not live
@@ -2874,16 +2875,24 @@ exec_assign_value(PLpgSQL_execstate *estate,
28742875
if (!var->datatype->typbyval&& !*isNull)
28752876
{
28762877
if (newvalue==value)
2877-
var->value=datumCopy(newvalue,
2878-
false,
2879-
var->datatype->typlen);
2880-
else
2881-
var->value=newvalue;
2882-
var->freeval= true;
2878+
newvalue=datumCopy(newvalue,
2879+
false,
2880+
var->datatype->typlen);
28832881
}
2884-
else
2885-
var->value=newvalue;
2882+
2883+
/*
2884+
* Now free the old value. (We can't do this any earlier
2885+
* because of the possibility that we are assigning the
2886+
* var's old value to it, eg "foo := foo". We could optimize
2887+
* out the assignment altogether in such cases, but it's too
2888+
* infrequent to be worth testing for.)
2889+
*/
2890+
free_var(var);
2891+
2892+
var->value=newvalue;
28862893
var->isnull=*isNull;
2894+
if (!var->datatype->typbyval&& !*isNull)
2895+
var->freeval= true;
28872896
break;
28882897
}
28892898

@@ -3740,6 +3749,14 @@ exec_move_row(PLpgSQL_execstate *estate,
37403749
*/
37413750
if (rec!=NULL)
37423751
{
3752+
/*
3753+
* copy input first, just in case it is pointing at variable's value
3754+
*/
3755+
if (HeapTupleIsValid(tup))
3756+
tup=heap_copytuple(tup);
3757+
if (tupdesc)
3758+
tupdesc=CreateTupleDescCopy(tupdesc);
3759+
37433760
if (rec->freetup)
37443761
{
37453762
heap_freetuple(rec->tup);
@@ -3753,7 +3770,7 @@ exec_move_row(PLpgSQL_execstate *estate,
37533770

37543771
if (HeapTupleIsValid(tup))
37553772
{
3756-
rec->tup=heap_copytuple(tup);
3773+
rec->tup=tup;
37573774
rec->freetup= true;
37583775
}
37593776
elseif (tupdesc)
@@ -3774,7 +3791,7 @@ exec_move_row(PLpgSQL_execstate *estate,
37743791

37753792
if (tupdesc)
37763793
{
3777-
rec->tupdesc=CreateTupleDescCopy(tupdesc);
3794+
rec->tupdesc=tupdesc;
37783795
rec->freetupdesc= true;
37793796
}
37803797
else

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp