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

Commitde4026c

Browse files
committed
Use heap_modify_tuple not SPI_modifytuple in pl/python triggers.
The code here would need some change anyway given planned change inSPI_modifytuple semantics, since this executes after we've exited theSPI environment. But really it's better to just use heap_modify_tuple.While at it, normalize use of SPI_fnumber: make error messages distinguishno-such-column from can't-set-system-column, and remove test for deletedcolumn which is going to migrate into SPI_fnumber. The lack of a checkfor system column names is actually a pre-existing bug here, and mighteven qualify as a security bug except that we don't have any trustedversion of plpython.
1 parent0d44460 commitde4026c

File tree

1 file changed

+41
-45
lines changed

1 file changed

+41
-45
lines changed

‎src/pl/plpython/plpy_exec.c

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -896,31 +896,30 @@ static HeapTuple
896896
PLy_modify_tuple(PLyProcedure*proc,PyObject*pltd,TriggerData*tdata,
897897
HeapTupleotup)
898898
{
899+
HeapTuplertup;
899900
PyObject*volatileplntup;
900901
PyObject*volatileplkeys;
901902
PyObject*volatileplval;
902-
HeapTuplertup;
903-
intnatts,
904-
i,
905-
attn,
906-
atti;
907-
int*volatilemodattrs;
908903
Datum*volatilemodvalues;
909-
char*volatilemodnulls;
910-
TupleDesctupdesc;
904+
bool*volatilemodnulls;
905+
bool*volatilemodrepls;
911906
ErrorContextCallbackplerrcontext;
912907

913908
plerrcontext.callback=plpython_trigger_error_callback;
914909
plerrcontext.previous=error_context_stack;
915910
error_context_stack=&plerrcontext;
916911

917912
plntup=plkeys=plval=NULL;
918-
modattrs=NULL;
919913
modvalues=NULL;
920914
modnulls=NULL;
915+
modrepls=NULL;
921916

922917
PG_TRY();
923918
{
919+
TupleDesctupdesc;
920+
intnkeys,
921+
i;
922+
924923
if ((plntup=PyDict_GetItemString(pltd,"new"))==NULL)
925924
ereport(ERROR,
926925
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -932,18 +931,20 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
932931
errmsg("TD[\"new\"] is not a dictionary")));
933932

934933
plkeys=PyDict_Keys(plntup);
935-
natts=PyList_Size(plkeys);
936-
937-
modattrs= (int*)palloc(natts*sizeof(int));
938-
modvalues= (Datum*)palloc(natts*sizeof(Datum));
939-
modnulls= (char*)palloc(natts*sizeof(char));
934+
nkeys=PyList_Size(plkeys);
940935

941936
tupdesc=tdata->tg_relation->rd_att;
942937

943-
for (i=0;i<natts;i++)
938+
modvalues= (Datum*)palloc0(tupdesc->natts*sizeof(Datum));
939+
modnulls= (bool*)palloc0(tupdesc->natts*sizeof(bool));
940+
modrepls= (bool*)palloc0(tupdesc->natts*sizeof(bool));
941+
942+
for (i=0;i<nkeys;i++)
944943
{
945944
PyObject*platt;
946945
char*plattstr;
946+
intattn;
947+
PLyObToDatum*att;
947948

948949
platt=PyList_GetItem(plkeys,i);
949950
if (PyString_Check(platt))
@@ -963,62 +964,57 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
963964
(errcode(ERRCODE_UNDEFINED_COLUMN),
964965
errmsg("key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row",
965966
plattstr)));
966-
atti=attn-1;
967+
if (attn <=0)
968+
ereport(ERROR,
969+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
970+
errmsg("cannot set system attribute \"%s\"",
971+
plattstr)));
972+
att=&proc->result.out.r.atts[attn-1];
967973

968974
plval=PyDict_GetItem(plntup,platt);
969975
if (plval==NULL)
970976
elog(FATAL,"Python interpreter is probably corrupted");
971977

972978
Py_INCREF(plval);
973979

974-
modattrs[i]=attn;
975-
976-
if (tupdesc->attrs[atti]->attisdropped)
977-
{
978-
modvalues[i]= (Datum)0;
979-
modnulls[i]='n';
980-
}
981-
elseif (plval!=Py_None)
980+
if (plval!=Py_None)
982981
{
983-
PLyObToDatum*att=&proc->result.out.r.atts[atti];
984-
985-
modvalues[i]= (att->func) (att,
986-
tupdesc->attrs[atti]->atttypmod,
987-
plval,
988-
false);
989-
modnulls[i]=' ';
982+
modvalues[attn-1]=
983+
(att->func) (att,
984+
tupdesc->attrs[attn-1]->atttypmod,
985+
plval,
986+
false);
987+
modnulls[attn-1]= false;
990988
}
991989
else
992990
{
993-
modvalues[i]=
994-
InputFunctionCall(&proc->result.out.r.atts[atti].typfunc,
991+
modvalues[attn-1]=
992+
InputFunctionCall(&att->typfunc,
995993
NULL,
996-
proc->result.out.r.atts[atti].typioparam,
997-
tupdesc->attrs[atti]->atttypmod);
998-
modnulls[i]='n';
994+
att->typioparam,
995+
tupdesc->attrs[attn-1]->atttypmod);
996+
modnulls[attn-1]=true;
999997
}
998+
modrepls[attn-1]= true;
1000999

10011000
Py_DECREF(plval);
10021001
plval=NULL;
10031002
}
10041003

1005-
rtup=SPI_modifytuple(tdata->tg_relation,otup,natts,
1006-
modattrs,modvalues,modnulls);
1007-
if (rtup==NULL)
1008-
elog(ERROR,"SPI_modifytuple failed: error %d",SPI_result);
1004+
rtup=heap_modify_tuple(otup,tupdesc,modvalues,modnulls,modrepls);
10091005
}
10101006
PG_CATCH();
10111007
{
10121008
Py_XDECREF(plntup);
10131009
Py_XDECREF(plkeys);
10141010
Py_XDECREF(plval);
10151011

1016-
if (modnulls)
1017-
pfree(modnulls);
10181012
if (modvalues)
10191013
pfree(modvalues);
1020-
if (modattrs)
1021-
pfree(modattrs);
1014+
if (modnulls)
1015+
pfree(modnulls);
1016+
if (modrepls)
1017+
pfree(modrepls);
10221018

10231019
PG_RE_THROW();
10241020
}
@@ -1027,9 +1023,9 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
10271023
Py_DECREF(plntup);
10281024
Py_DECREF(plkeys);
10291025

1030-
pfree(modattrs);
10311026
pfree(modvalues);
10321027
pfree(modnulls);
1028+
pfree(modrepls);
10331029

10341030
error_context_stack=plerrcontext.previous;
10351031

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp