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

Commit67120d3

Browse files
committed
Fix plpython so that it again honors typmod while assigning to tuple fields.
This was broken in 9.0 while improving plpython's conversion behavior forbytea and boolean. Per bug report from maizi.
1 parent3b6eb75 commit67120d3

File tree

3 files changed

+76
-35
lines changed

3 files changed

+76
-35
lines changed

‎src/pl/plpython/expected/plpython_trigger.out

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,3 +453,29 @@ SELECT * FROM trigger_test;
453453
0 |
454454
(1 row)
455455

456+
--
457+
-- Test that triggers honor typmod when assigning to tuple fields,
458+
-- as per an early 9.0 bug report
459+
--
460+
SET DateStyle = 'ISO';
461+
CREATE FUNCTION set_modif_time() RETURNS trigger AS $$
462+
TD['new']['modif_time'] = '2010-10-13 21:57:28.930486'
463+
return 'MODIFY'
464+
$$ LANGUAGE plpythonu;
465+
CREATE TABLE pb (a TEXT, modif_time TIMESTAMP(0) WITHOUT TIME ZONE);
466+
CREATE TRIGGER set_modif_time BEFORE UPDATE ON pb
467+
FOR EACH ROW EXECUTE PROCEDURE set_modif_time();
468+
INSERT INTO pb VALUES ('a', '2010-10-09 21:57:33.930486');
469+
SELECT * FROM pb;
470+
a | modif_time
471+
---+---------------------
472+
a | 2010-10-09 21:57:34
473+
(1 row)
474+
475+
UPDATE pb SET a = 'b';
476+
SELECT * FROM pb;
477+
a | modif_time
478+
---+---------------------
479+
b | 2010-10-13 21:57:29
480+
(1 row)
481+

‎src/pl/plpython/plpython.c

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,8 @@ typedef union PLyTypeInput
153153
*/
154154

155155
structPLyObToDatum;
156-
structPLyTypeInfo;
157-
typedefDatum (*PLyObToDatumFunc) (structPLyTypeInfo*,
158-
structPLyObToDatum*,
159-
PyObject*);
156+
typedefDatum (*PLyObToDatumFunc) (structPLyObToDatum*,int32typmod,
157+
PyObject*);
160158

161159
typedefstructPLyObToDatum
162160
{
@@ -346,14 +344,10 @@ static PyObject *PLyList_FromArray(PLyDatumToOb *arg, Datum d);
346344

347345
staticPyObject*PLyDict_FromTuple(PLyTypeInfo*,HeapTuple,TupleDesc);
348346

349-
staticDatumPLyObject_ToBool(PLyTypeInfo*,PLyObToDatum*,
350-
PyObject*);
351-
staticDatumPLyObject_ToBytea(PLyTypeInfo*,PLyObToDatum*,
352-
PyObject*);
353-
staticDatumPLyObject_ToDatum(PLyTypeInfo*,PLyObToDatum*,
354-
PyObject*);
355-
staticDatumPLySequence_ToArray(PLyTypeInfo*,PLyObToDatum*,
356-
PyObject*);
347+
staticDatumPLyObject_ToBool(PLyObToDatum*,int32,PyObject*);
348+
staticDatumPLyObject_ToBytea(PLyObToDatum*,int32,PyObject*);
349+
staticDatumPLyObject_ToDatum(PLyObToDatum*,int32,PyObject*);
350+
staticDatumPLySequence_ToArray(PLyObToDatum*,int32,PyObject*);
357351

358352
staticHeapTuplePLyMapping_ToTuple(PLyTypeInfo*,PyObject*);
359353
staticHeapTuplePLySequence_ToTuple(PLyTypeInfo*,PyObject*);
@@ -421,7 +415,8 @@ static void
421415
plpython_error_callback(void*arg)
422416
{
423417
if (PLy_curr_procedure)
424-
errcontext("PL/Python function \"%s\"",PLy_procedure_name(PLy_curr_procedure));
418+
errcontext("PL/Python function \"%s\"",
419+
PLy_procedure_name(PLy_curr_procedure));
425420
}
426421

427422
staticvoid
@@ -743,7 +738,9 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
743738
{
744739
PLyObToDatum*att=&proc->result.out.r.atts[atti];
745740

746-
modvalues[i]= (att->func) (&proc->result,att,plval);
741+
modvalues[i]= (att->func) (att,
742+
tupdesc->attrs[atti]->atttypmod,
743+
plval);
747744
modnulls[i]=' ';
748745
}
749746
else
@@ -1131,9 +1128,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
11311128
else
11321129
{
11331130
fcinfo->isnull= false;
1134-
rv= (proc->result.out.d.func) (&proc->result,
1135-
&proc->result.out.d,
1136-
plrv);
1131+
rv= (proc->result.out.d.func) (&proc->result.out.d,-1,plrv);
11371132
}
11381133
}
11391134
PG_CATCH();
@@ -2098,9 +2093,7 @@ PLyDict_FromTuple(PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
20982093
* type can parse.
20992094
*/
21002095
staticDatum
2101-
PLyObject_ToBool(PLyTypeInfo*info,
2102-
PLyObToDatum*arg,
2103-
PyObject*plrv)
2096+
PLyObject_ToBool(PLyObToDatum*arg,int32typmod,PyObject*plrv)
21042097
{
21052098
Datumrv;
21062099

@@ -2119,9 +2112,7 @@ PLyObject_ToBool(PLyTypeInfo *info,
21192112
* with embedded nulls. And it's faster this way.
21202113
*/
21212114
staticDatum
2122-
PLyObject_ToBytea(PLyTypeInfo*info,
2123-
PLyObToDatum*arg,
2124-
PyObject*plrv)
2115+
PLyObject_ToBytea(PLyObToDatum*arg,int32typmod,PyObject*plrv)
21252116
{
21262117
PyObject*volatileplrv_so=NULL;
21272118
Datumrv;
@@ -2163,9 +2154,7 @@ PLyObject_ToBytea(PLyTypeInfo *info,
21632154
* cstring into PostgreSQL type.
21642155
*/
21652156
staticDatum
2166-
PLyObject_ToDatum(PLyTypeInfo*info,
2167-
PLyObToDatum*arg,
2168-
PyObject*plrv)
2157+
PLyObject_ToDatum(PLyObToDatum*arg,int32typmod,PyObject*plrv)
21692158
{
21702159
PyObject*volatileplrv_bo=NULL;
21712160
Datumrv;
@@ -2201,7 +2190,10 @@ PLyObject_ToDatum(PLyTypeInfo *info,
22012190
elseif (slen>plen)
22022191
elog(ERROR,"could not convert Python object into cstring: Python string longer than reported length");
22032192
pg_verifymbstr(plrv_sc,slen, false);
2204-
rv=InputFunctionCall(&arg->typfunc,plrv_sc,arg->typioparam,-1);
2193+
rv=InputFunctionCall(&arg->typfunc,
2194+
plrv_sc,
2195+
arg->typioparam,
2196+
typmod);
22052197
}
22062198
PG_CATCH();
22072199
{
@@ -2216,9 +2208,7 @@ PLyObject_ToDatum(PLyTypeInfo *info,
22162208
}
22172209

22182210
staticDatum
2219-
PLySequence_ToArray(PLyTypeInfo*info,
2220-
PLyObToDatum*arg,
2221-
PyObject*plrv)
2211+
PLySequence_ToArray(PLyObToDatum*arg,int32typmod,PyObject*plrv)
22222212
{
22232213
ArrayType*array;
22242214
inti;
@@ -2250,7 +2240,7 @@ PLySequence_ToArray(PLyTypeInfo *info,
22502240
* We don't support arrays of row types yet, so the first argument
22512241
* can be NULL.
22522242
*/
2253-
elems[i]=arg->elm->func(NULL,arg->elm,obj);
2243+
elems[i]=arg->elm->func(arg->elm,-1,obj);
22542244
}
22552245
Py_XDECREF(obj);
22562246
}
@@ -2299,7 +2289,7 @@ PLyMapping_ToTuple(PLyTypeInfo *info, PyObject *mapping)
22992289
}
23002290
elseif (value)
23012291
{
2302-
values[i]= (att->func) (info,att,value);
2292+
values[i]= (att->func) (att,-1,value);
23032293
nulls[i]= false;
23042294
}
23052295
else
@@ -2376,7 +2366,7 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
23762366
}
23772367
elseif (value)
23782368
{
2379-
values[i]= (att->func) (info,att,value);
2369+
values[i]= (att->func) (att,-1,value);
23802370
nulls[i]= false;
23812371
}
23822372

@@ -2436,7 +2426,7 @@ PLyObject_ToTuple(PLyTypeInfo *info, PyObject *object)
24362426
}
24372427
elseif (value)
24382428
{
2439-
values[i]= (att->func) (info,att,value);
2429+
values[i]= (att->func) (att,-1,value);
24402430
nulls[i]= false;
24412431
}
24422432
else
@@ -3018,7 +3008,9 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit)
30183008
PG_TRY();
30193009
{
30203010
plan->values[j]=
3021-
plan->args[j].out.d.func(NULL,&(plan->args[j].out.d),elem);
3011+
plan->args[j].out.d.func(&(plan->args[j].out.d),
3012+
-1,
3013+
elem);
30223014
}
30233015
PG_CATCH();
30243016
{

‎src/pl/plpython/sql/plpython_trigger.sql

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,26 @@ UPDATE trigger_test SET v = 'null' WHERE i = 0;
286286
DROPTRIGGER test_null_triggerON trigger_test;
287287

288288
SELECT*FROM trigger_test;
289+
290+
291+
--
292+
-- Test that triggers honor typmod when assigning to tuple fields,
293+
-- as per an early 9.0 bug report
294+
--
295+
296+
SET DateStyle='ISO';
297+
298+
CREATEFUNCTIONset_modif_time() RETURNS triggerAS $$
299+
TD['new']['modif_time']='2010-10-13 21:57:28.930486'
300+
return'MODIFY'
301+
$$ LANGUAGE plpythonu;
302+
303+
CREATETABLEpb (aTEXT, modif_timeTIMESTAMP(0) WITHOUT TIME ZONE);
304+
305+
CREATETRIGGERset_modif_time BEFOREUPDATEON pb
306+
FOR EACH ROW EXECUTE PROCEDURE set_modif_time();
307+
308+
INSERT INTO pbVALUES ('a','2010-10-09 21:57:33.930486');
309+
SELECT*FROM pb;
310+
UPDATE pbSET a='b';
311+
SELECT*FROM pb;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp