@@ -153,10 +153,8 @@ typedef union PLyTypeInput
153153 */
154154
155155struct PLyObToDatum ;
156- struct PLyTypeInfo ;
157- typedef Datum (* PLyObToDatumFunc ) (struct PLyTypeInfo * ,
158- struct PLyObToDatum * ,
159- PyObject * );
156+ typedef Datum (* PLyObToDatumFunc ) (struct PLyObToDatum * ,int32 typmod ,
157+ PyObject * );
160158
161159typedef struct PLyObToDatum
162160{
@@ -346,14 +344,10 @@ static PyObject *PLyList_FromArray(PLyDatumToOb *arg, Datum d);
346344
347345static PyObject * PLyDict_FromTuple (PLyTypeInfo * ,HeapTuple ,TupleDesc );
348346
349- static Datum PLyObject_ToBool (PLyTypeInfo * ,PLyObToDatum * ,
350- PyObject * );
351- static Datum PLyObject_ToBytea (PLyTypeInfo * ,PLyObToDatum * ,
352- PyObject * );
353- static Datum PLyObject_ToDatum (PLyTypeInfo * ,PLyObToDatum * ,
354- PyObject * );
355- static Datum PLySequence_ToArray (PLyTypeInfo * ,PLyObToDatum * ,
356- PyObject * );
347+ static Datum PLyObject_ToBool (PLyObToDatum * ,int32 ,PyObject * );
348+ static Datum PLyObject_ToBytea (PLyObToDatum * ,int32 ,PyObject * );
349+ static Datum PLyObject_ToDatum (PLyObToDatum * ,int32 ,PyObject * );
350+ static Datum PLySequence_ToArray (PLyObToDatum * ,int32 ,PyObject * );
357351
358352static HeapTuple PLyMapping_ToTuple (PLyTypeInfo * ,PyObject * );
359353static HeapTuple PLySequence_ToTuple (PLyTypeInfo * ,PyObject * );
@@ -421,7 +415,8 @@ static void
421415plpython_error_callback (void * arg )
422416{
423417if (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
427422static void
@@ -743,7 +738,9 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
743738{
744739PLyObToDatum * 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 );
747744modnulls [i ]= ' ' ;
748745}
749746else
@@ -1132,9 +1129,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
11321129else
11331130{
11341131fcinfo -> 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}
11401135PG_CATCH ();
@@ -2099,9 +2094,7 @@ PLyDict_FromTuple(PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
20992094 * type can parse.
21002095 */
21012096static Datum
2102- PLyObject_ToBool (PLyTypeInfo * info ,
2103- PLyObToDatum * arg ,
2104- PyObject * plrv )
2097+ PLyObject_ToBool (PLyObToDatum * arg ,int32 typmod ,PyObject * plrv )
21052098{
21062099Datum rv ;
21072100
@@ -2120,9 +2113,7 @@ PLyObject_ToBool(PLyTypeInfo *info,
21202113 * with embedded nulls. And it's faster this way.
21212114 */
21222115static Datum
2123- PLyObject_ToBytea (PLyTypeInfo * info ,
2124- PLyObToDatum * arg ,
2125- PyObject * plrv )
2116+ PLyObject_ToBytea (PLyObToDatum * arg ,int32 typmod ,PyObject * plrv )
21262117{
21272118PyObject * volatile plrv_so = NULL ;
21282119Datum rv ;
@@ -2164,9 +2155,7 @@ PLyObject_ToBytea(PLyTypeInfo *info,
21642155 * cstring into PostgreSQL type.
21652156 */
21662157static Datum
2167- PLyObject_ToDatum (PLyTypeInfo * info ,
2168- PLyObToDatum * arg ,
2169- PyObject * plrv )
2158+ PLyObject_ToDatum (PLyObToDatum * arg ,int32 typmod ,PyObject * plrv )
21702159{
21712160PyObject * volatile plrv_bo = NULL ;
21722161Datum rv ;
@@ -2202,7 +2191,10 @@ PLyObject_ToDatum(PLyTypeInfo *info,
22022191else if (slen > plen )
22032192elog (ERROR ,"could not convert Python object into cstring: Python string longer than reported length" );
22042193pg_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}
22072199PG_CATCH ();
22082200{
@@ -2217,9 +2209,7 @@ PLyObject_ToDatum(PLyTypeInfo *info,
22172209}
22182210
22192211static Datum
2220- PLySequence_ToArray (PLyTypeInfo * info ,
2221- PLyObToDatum * arg ,
2222- PyObject * plrv )
2212+ PLySequence_ToArray (PLyObToDatum * arg ,int32 typmod ,PyObject * plrv )
22232213{
22242214ArrayType * array ;
22252215int i ;
@@ -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}
22562246Py_XDECREF (obj );
22572247}
@@ -2300,7 +2290,7 @@ PLyMapping_ToTuple(PLyTypeInfo *info, PyObject *mapping)
23002290}
23012291else if (value )
23022292{
2303- values [i ]= (att -> func ) (info , att ,value );
2293+ values [i ]= (att -> func ) (att , -1 ,value );
23042294nulls [i ]= false;
23052295}
23062296else
@@ -2377,7 +2367,7 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
23772367}
23782368else if (value )
23792369{
2380- values [i ]= (att -> func ) (info , att ,value );
2370+ values [i ]= (att -> func ) (att , -1 ,value );
23812371nulls [i ]= false;
23822372}
23832373
@@ -2437,7 +2427,7 @@ PLyObject_ToTuple(PLyTypeInfo *info, PyObject *object)
24372427}
24382428else if (value )
24392429{
2440- values [i ]= (att -> func ) (info , att ,value );
2430+ values [i ]= (att -> func ) (att , -1 ,value );
24412431nulls [i ]= false;
24422432}
24432433else
@@ -3019,7 +3009,9 @@ PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit)
30193009PG_TRY ();
30203010{
30213011plan -> 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}
30243016PG_CATCH ();
30253017{