@@ -410,10 +410,11 @@ static Datum PLyObject_ToComposite(PLyObToDatum *, int32, PyObject *);
410
410
static Datum PLyObject_ToDatum (PLyObToDatum * , int32 , PyObject * );
411
411
static Datum PLySequence_ToArray (PLyObToDatum * , int32 , PyObject * );
412
412
413
- static HeapTuple PLyObject_ToTuple (PLyTypeInfo * , TupleDesc , PyObject * );
414
- static HeapTuple PLyMapping_ToTuple (PLyTypeInfo * , TupleDesc , PyObject * );
415
- static HeapTuple PLySequence_ToTuple (PLyTypeInfo * , TupleDesc , PyObject * );
416
- static HeapTuple PLyGenericObject_ToTuple (PLyTypeInfo * , TupleDesc , PyObject * );
413
+ static Datum PLyObject_ToCompositeDatum (PLyTypeInfo * , TupleDesc , PyObject * );
414
+ static Datum PLyString_ToComposite (PLyTypeInfo * , TupleDesc , PyObject * );
415
+ static Datum PLyMapping_ToComposite (PLyTypeInfo * , TupleDesc , PyObject * );
416
+ static Datum PLySequence_ToComposite (PLyTypeInfo * , TupleDesc , PyObject * );
417
+ static Datum PLyGenericObject_ToComposite (PLyTypeInfo * , TupleDesc , PyObject * );
417
418
418
419
/*
419
420
* Currently active plpython function
@@ -1213,7 +1214,6 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
1213
1214
else if (proc -> result .is_rowtype >= 1 )
1214
1215
{
1215
1216
TupleDesc desc ;
1216
- HeapTuple tuple = NULL ;
1217
1217
1218
1218
/* make sure it's not an unnamed record */
1219
1219
Assert ((proc -> result .out .d .typoid == RECORDOID &&
@@ -1224,18 +1224,8 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
1224
1224
desc = lookup_rowtype_tupdesc (proc -> result .out .d .typoid ,
1225
1225
proc -> result .out .d .typmod );
1226
1226
1227
- tuple = PLyObject_ToTuple (& proc -> result , desc , plrv );
1228
-
1229
- if (tuple != NULL )
1230
- {
1231
- fcinfo -> isnull = false;
1232
- rv = HeapTupleGetDatum (tuple );
1233
- }
1234
- else
1235
- {
1236
- fcinfo -> isnull = true;
1237
- rv = (Datum ) NULL ;
1238
- }
1227
+ rv = PLyObject_ToCompositeDatum (& proc -> result , desc , plrv );
1228
+ fcinfo -> isnull = (rv == (Datum ) NULL );
1239
1229
}
1240
1230
else
1241
1231
{
@@ -2419,26 +2409,28 @@ PLyDict_FromTuple(PLyTypeInfo *info, HeapTuple tuple, TupleDesc desc)
2419
2409
}
2420
2410
2421
2411
/*
2422
- * Convert a Python object to a PostgreSQL tuple , using all supported
2423
- * conversion methods: tuple as a sequence , as a mapping or as an object that
2424
- * has __getattr__ support.
2412
+ * Convert a Python object to a composite Datum , using all supported
2413
+ * conversion methods: composite as a string , as a sequence, as a mapping or
2414
+ * as an object that has __getattr__ support.
2425
2415
*/
2426
- static HeapTuple
2427
- PLyObject_ToTuple (PLyTypeInfo * info , TupleDesc desc , PyObject * plrv )
2416
+ static Datum
2417
+ PLyObject_ToCompositeDatum (PLyTypeInfo * info , TupleDesc desc , PyObject * plrv )
2428
2418
{
2429
- HeapTuple tuple ;
2419
+ Datum datum ;
2430
2420
2431
- if (PySequence_Check (plrv ))
2421
+ if (PyString_Check (plrv ) || PyUnicode_Check (plrv ))
2422
+ datum = PLyString_ToComposite (info , desc , plrv );
2423
+ else if (PySequence_Check (plrv ))
2432
2424
/* composite type as sequence (tuple, list etc) */
2433
- tuple = PLySequence_ToTuple (info , desc , plrv );
2425
+ datum = PLySequence_ToComposite (info , desc , plrv );
2434
2426
else if (PyMapping_Check (plrv ))
2435
2427
/* composite type as mapping (currently only dict) */
2436
- tuple = PLyMapping_ToTuple (info , desc , plrv );
2428
+ datum = PLyMapping_ToComposite (info , desc , plrv );
2437
2429
else
2438
2430
/* returned as smth, must provide method __getattr__(name) */
2439
- tuple = PLyGenericObject_ToTuple (info , desc , plrv );
2431
+ datum = PLyGenericObject_ToComposite (info , desc , plrv );
2440
2432
2441
- return tuple ;
2433
+ return datum ;
2442
2434
}
2443
2435
2444
2436
/*
@@ -2513,7 +2505,6 @@ PLyObject_ToBytea(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
2513
2505
static Datum
2514
2506
PLyObject_ToComposite (PLyObToDatum * arg , int32 typmod , PyObject * plrv )
2515
2507
{
2516
- HeapTuple tuple = NULL ;
2517
2508
Datum rv ;
2518
2509
PLyTypeInfo info ;
2519
2510
TupleDesc desc ;
@@ -2535,15 +2526,10 @@ PLyObject_ToComposite(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
2535
2526
* that info instead of looking it up every time a tuple is returned from
2536
2527
* the function.
2537
2528
*/
2538
- tuple = PLyObject_ToTuple (& info , desc , plrv );
2529
+ rv = PLyObject_ToCompositeDatum (& info , desc , plrv );
2539
2530
2540
2531
PLy_typeinfo_dealloc (& info );
2541
2532
2542
- if (tuple != NULL )
2543
- rv = HeapTupleGetDatum (tuple );
2544
- else
2545
- rv = (Datum ) NULL ;
2546
-
2547
2533
return rv ;
2548
2534
}
2549
2535
@@ -2650,8 +2636,28 @@ PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
2650
2636
return PointerGetDatum (array );
2651
2637
}
2652
2638
2653
- static HeapTuple
2654
- PLyMapping_ToTuple (PLyTypeInfo * info , TupleDesc desc , PyObject * mapping )
2639
+
2640
+ static Datum
2641
+ PLyString_ToComposite (PLyTypeInfo * info , TupleDesc desc , PyObject * string )
2642
+ {
2643
+ HeapTuple typeTup ;
2644
+
2645
+ typeTup = SearchSysCache1 (TYPEOID , ObjectIdGetDatum (desc -> tdtypeid ));
2646
+ if (!HeapTupleIsValid (typeTup ))
2647
+ elog (ERROR , "cache lookup failed for type %u" , desc -> tdtypeid );
2648
+
2649
+ PLy_output_datum_func2 (& info -> out .d , typeTup );
2650
+
2651
+ ReleaseSysCache (typeTup );
2652
+ ReleaseTupleDesc (desc );
2653
+
2654
+ return PLyObject_ToDatum (& info -> out .d , info -> out .d .typmod , string );
2655
+ }
2656
+
2657
+
2658
+
2659
+ static Datum
2660
+ PLyMapping_ToComposite (PLyTypeInfo * info , TupleDesc desc , PyObject * mapping )
2655
2661
{
2656
2662
HeapTuple tuple ;
2657
2663
Datum * values ;
@@ -2719,12 +2725,12 @@ PLyMapping_ToTuple(PLyTypeInfo *info, TupleDesc desc, PyObject *mapping)
2719
2725
pfree (values );
2720
2726
pfree (nulls );
2721
2727
2722
- return tuple ;
2728
+ return HeapTupleGetDatum ( tuple ) ;
2723
2729
}
2724
2730
2725
2731
2726
- static HeapTuple
2727
- PLySequence_ToTuple (PLyTypeInfo * info , TupleDesc desc , PyObject * sequence )
2732
+ static Datum
2733
+ PLySequence_ToComposite (PLyTypeInfo * info , TupleDesc desc , PyObject * sequence )
2728
2734
{
2729
2735
HeapTuple tuple ;
2730
2736
Datum * values ;
@@ -2805,12 +2811,12 @@ PLySequence_ToTuple(PLyTypeInfo *info, TupleDesc desc, PyObject *sequence)
2805
2811
pfree (values );
2806
2812
pfree (nulls );
2807
2813
2808
- return tuple ;
2814
+ return HeapTupleGetDatum ( tuple ) ;
2809
2815
}
2810
2816
2811
2817
2812
- static HeapTuple
2813
- PLyGenericObject_ToTuple (PLyTypeInfo * info , TupleDesc desc , PyObject * object )
2818
+ static Datum
2819
+ PLyGenericObject_ToComposite (PLyTypeInfo * info , TupleDesc desc , PyObject * object )
2814
2820
{
2815
2821
HeapTuple tuple ;
2816
2822
Datum * values ;
@@ -2877,7 +2883,7 @@ PLyGenericObject_ToTuple(PLyTypeInfo *info, TupleDesc desc, PyObject *object)
2877
2883
pfree (values );
2878
2884
pfree (nulls );
2879
2885
2880
- return tuple ;
2886
+ return HeapTupleGetDatum ( tuple ) ;
2881
2887
}
2882
2888
2883
2889
0 commit comments