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

Commit09130e5

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 parent4016bde commit09130e5

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
@@ -523,3 +523,29 @@ SELECT * FROM trigger_test;
523523
0 |
524524
(1 row)
525525

526+
--
527+
-- Test that triggers honor typmod when assigning to tuple fields,
528+
-- as per an early 9.0 bug report
529+
--
530+
SET DateStyle = 'ISO';
531+
CREATE FUNCTION set_modif_time() RETURNS trigger AS $$
532+
TD['new']['modif_time'] = '2010-10-13 21:57:28.930486'
533+
return 'MODIFY'
534+
$$ LANGUAGE plpythonu;
535+
CREATE TABLE pb (a TEXT, modif_time TIMESTAMP(0) WITHOUT TIME ZONE);
536+
CREATE TRIGGER set_modif_time BEFORE UPDATE ON pb
537+
FOR EACH ROW EXECUTE PROCEDURE set_modif_time();
538+
INSERT INTO pb VALUES ('a', '2010-10-09 21:57:33.930486');
539+
SELECT * FROM pb;
540+
a | modif_time
541+
---+---------------------
542+
a | 2010-10-09 21:57:34
543+
(1 row)
544+
545+
UPDATE pb SET a = 'b';
546+
SELECT * FROM pb;
547+
a | modif_time
548+
---+---------------------
549+
b | 2010-10-13 21:57:29
550+
(1 row)
551+

‎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
@@ -1132,9 +1129,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
11321129
else
11331130
{
11341131
fcinfo->isnull= false;
1135-
rv= (proc->result.out.d.func) (&proc->result,
1136-
&proc->result.out.d,
1137-
plrv);
1132+
rv= (proc->result.out.d.func) (&proc->result.out.d,-1,plrv);
11381133
}
11391134
}
11401135
PG_CATCH();
@@ -2099,9 +2094,7 @@ PLyDict_FromTuple(PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
20992094
* type can parse.
21002095
*/
21012096
staticDatum
2102-
PLyObject_ToBool(PLyTypeInfo*info,
2103-
PLyObToDatum*arg,
2104-
PyObject*plrv)
2097+
PLyObject_ToBool(PLyObToDatum*arg,int32typmod,PyObject*plrv)
21052098
{
21062099
Datumrv;
21072100

@@ -2120,9 +2113,7 @@ PLyObject_ToBool(PLyTypeInfo *info,
21202113
* with embedded nulls. And it's faster this way.
21212114
*/
21222115
staticDatum
2123-
PLyObject_ToBytea(PLyTypeInfo*info,
2124-
PLyObToDatum*arg,
2125-
PyObject*plrv)
2116+
PLyObject_ToBytea(PLyObToDatum*arg,int32typmod,PyObject*plrv)
21262117
{
21272118
PyObject*volatileplrv_so=NULL;
21282119
Datumrv;
@@ -2164,9 +2155,7 @@ PLyObject_ToBytea(PLyTypeInfo *info,
21642155
* cstring into PostgreSQL type.
21652156
*/
21662157
staticDatum
2167-
PLyObject_ToDatum(PLyTypeInfo*info,
2168-
PLyObToDatum*arg,
2169-
PyObject*plrv)
2158+
PLyObject_ToDatum(PLyObToDatum*arg,int32typmod,PyObject*plrv)
21702159
{
21712160
PyObject*volatileplrv_bo=NULL;
21722161
Datumrv;
@@ -2202,7 +2191,10 @@ PLyObject_ToDatum(PLyTypeInfo *info,
22022191
elseif (slen>plen)
22032192
elog(ERROR,"could not convert Python object into cstring: Python string longer than reported length");
22042193
pg_verifymbstr(plrv_sc,slen, false);
2205-
rv=InputFunctionCall(&arg->typfunc,plrv_sc,arg->typioparam,-1);
2194+
rv=InputFunctionCall(&arg->typfunc,
2195+
plrv_sc,
2196+
arg->typioparam,
2197+
typmod);
22062198
}
22072199
PG_CATCH();
22082200
{
@@ -2217,9 +2209,7 @@ PLyObject_ToDatum(PLyTypeInfo *info,
22172209
}
22182210

22192211
staticDatum
2220-
PLySequence_ToArray(PLyTypeInfo*info,
2221-
PLyObToDatum*arg,
2222-
PyObject*plrv)
2212+
PLySequence_ToArray(PLyObToDatum*arg,int32typmod,PyObject*plrv)
22232213
{
22242214
ArrayType*array;
22252215
inti;
@@ -2251,7 +2241,7 @@ PLySequence_ToArray(PLyTypeInfo *info,
22512241
* We don't support arrays of row types yet, so the first argument
22522242
* can be NULL.
22532243
*/
2254-
elems[i]=arg->elm->func(NULL,arg->elm,obj);
2244+
elems[i]=arg->elm->func(arg->elm,-1,obj);
22552245
}
22562246
Py_XDECREF(obj);
22572247
}
@@ -2300,7 +2290,7 @@ PLyMapping_ToTuple(PLyTypeInfo *info, PyObject *mapping)
23002290
}
23012291
elseif (value)
23022292
{
2303-
values[i]= (att->func) (info,att,value);
2293+
values[i]= (att->func) (att,-1,value);
23042294
nulls[i]= false;
23052295
}
23062296
else
@@ -2377,7 +2367,7 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
23772367
}
23782368
elseif (value)
23792369
{
2380-
values[i]= (att->func) (info,att,value);
2370+
values[i]= (att->func) (att,-1,value);
23812371
nulls[i]= false;
23822372
}
23832373

@@ -2437,7 +2427,7 @@ PLyObject_ToTuple(PLyTypeInfo *info, PyObject *object)
24372427
}
24382428
elseif (value)
24392429
{
2440-
values[i]= (att->func) (info,att,value);
2430+
values[i]= (att->func) (att,-1,value);
24412431
nulls[i]= false;
24422432
}
24432433
else
@@ -3019,7 +3009,9 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit)
30193009
PG_TRY();
30203010
{
30213011
plan->values[j]=
3022-
plan->args[j].out.d.func(NULL,&(plan->args[j].out.d),elem);
3012+
plan->args[j].out.d.func(&(plan->args[j].out.d),
3013+
-1,
3014+
elem);
30233015
}
30243016
PG_CATCH();
30253017
{

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

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

305305
SELECT*FROM trigger_test;
306+
307+
308+
--
309+
-- Test that triggers honor typmod when assigning to tuple fields,
310+
-- as per an early 9.0 bug report
311+
--
312+
313+
SET DateStyle='ISO';
314+
315+
CREATEFUNCTIONset_modif_time() RETURNS triggerAS $$
316+
TD['new']['modif_time']='2010-10-13 21:57:28.930486'
317+
return'MODIFY'
318+
$$ LANGUAGE plpythonu;
319+
320+
CREATETABLEpb (aTEXT, modif_timeTIMESTAMP(0) WITHOUT TIME ZONE);
321+
322+
CREATETRIGGERset_modif_time BEFOREUPDATEON pb
323+
FOR EACH ROW EXECUTE PROCEDURE set_modif_time();
324+
325+
INSERT INTO pbVALUES ('a','2010-10-09 21:57:33.930486');
326+
SELECT*FROM pb;
327+
UPDATE pbSET a='b';
328+
SELECT*FROM pb;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp