1 /* 2 * src/pl/plpython/plpy_typeio.h 3 */ 4 5 #ifndef PLPY_TYPEIO_H 6 #define PLPY_TYPEIO_H 7 8 #include "access/htup.h" 9 #include "fmgr.h" 10 #include "plpython.h" 11 #include "utils/typcache.h" 12 13 struct PLyProcedure; /* avoid requiring plpy_procedure.h here */ 14 15 16 /* 17 * "Input" conversion from PostgreSQL Datum to a Python object. 18 * 19 * arg is the previously-set-up conversion data, val is the value to convert. 20 * val mustn't be NULL. 21 * 22 * Note: the conversion data structs should be regarded as private to 23 * plpy_typeio.c. We declare them here only so that other modules can 24 * define structs containing them. 25 */ 26 typedef struct PLyDatumToOb PLyDatumToOb; /* forward reference */ 27 28 typedef PyObject *(*PLyDatumToObFunc) (PLyDatumToOb *arg, Datum val); 29 30 typedef struct PLyScalarToOb 31 { 32 FmgrInfo typfunc; /* lookup info for type's output function */ 33 } PLyScalarToOb; 34 35 typedef struct PLyArrayToOb 36 { 37 PLyDatumToOb *elm; /* conversion info for array's element type */ 38 } PLyArrayToOb; 39 40 typedef struct PLyTupleToOb 41 { 42 /* If we're dealing with a RECORD type, actual descriptor is here: */ 43 TupleDesc recdesc; 44 /* If we're dealing with a named composite type, these fields are set: */ 45 TypeCacheEntry *typentry; /* typcache entry for type */ 46 uint64 tupdescid; /* last tupdesc identifier seen in typcache */ 47 /* These fields are NULL/0 if not yet set: */ 48 PLyDatumToOb *atts; /* array of per-column conversion info */ 49 int natts; /* length of array */ 50 } PLyTupleToOb; 51 52 typedef struct PLyTransformToOb 53 { 54 FmgrInfo typtransform; /* lookup info for from-SQL transform func */ 55 } PLyTransformToOb; 56 57 struct PLyDatumToOb 58 { 59 PLyDatumToObFunc func; /* conversion control function */ 60 Oid typoid; /* OID of the source type */ 61 int32 typmod; /* typmod of the source type */ 62 bool typbyval; /* its physical representation details */ 63 int16 typlen; 64 char typalign; 65 MemoryContext mcxt; /* context this info is stored in */ 66 union /* conversion-type-specific data */ 67 { 68 PLyScalarToOb scalar; 69 PLyArrayToOb array; 70 PLyTupleToOb tuple; 71 PLyTransformToOb transform; 72 } u; 73 }; 74 75 /* 76 * "Output" conversion from Python object to a PostgreSQL Datum. 77 * 78 * arg is the previously-set-up conversion data, val is the value to convert. 79 * 80 * *isnull is set to true if val is Py_None, false otherwise. 81 * (The conversion function *must* be called even for Py_None, 82 * so that domain constraints can be checked.) 83 * 84 * inarray is true if the converted value was in an array (Python list). 85 * It is used to give a better error message in some cases. 86 */ 87 typedef struct PLyObToDatum PLyObToDatum; /* forward reference */ 88 89 typedef Datum (*PLyObToDatumFunc) (PLyObToDatum *arg, PyObject *val, 90 bool *isnull, 91 bool inarray); 92 93 typedef struct PLyObToScalar 94 { 95 FmgrInfo typfunc; /* lookup info for type's input function */ 96 Oid typioparam; /* argument to pass to it */ 97 } PLyObToScalar; 98 99 typedef struct PLyObToArray 100 { 101 PLyObToDatum *elm; /* conversion info for array's element type */ 102 Oid elmbasetype; /* element base type */ 103 } PLyObToArray; 104 105 typedef struct PLyObToTuple 106 { 107 /* If we're dealing with a RECORD type, actual descriptor is here: */ 108 TupleDesc recdesc; 109 /* If we're dealing with a named composite type, these fields are set: */ 110 TypeCacheEntry *typentry; /* typcache entry for type */ 111 uint64 tupdescid; /* last tupdesc identifier seen in typcache */ 112 /* These fields are NULL/0 if not yet set: */ 113 PLyObToDatum *atts; /* array of per-column conversion info */ 114 int natts; /* length of array */ 115 /* We might need to convert using record_in(); if so, cache info here */ 116 FmgrInfo recinfunc; /* lookup info for record_in */ 117 } PLyObToTuple; 118 119 typedef struct PLyObToDomain 120 { 121 PLyObToDatum *base; /* conversion info for domain's base type */ 122 void *domain_info; /* cache space for domain_check() */ 123 } PLyObToDomain; 124 125 typedef struct PLyObToTransform 126 { 127 FmgrInfo typtransform; /* lookup info for to-SQL transform function */ 128 } PLyObToTransform; 129 130 struct PLyObToDatum 131 { 132 PLyObToDatumFunc func; /* conversion control function */ 133 Oid typoid; /* OID of the target type */ 134 int32 typmod; /* typmod of the target type */ 135 bool typbyval; /* its physical representation details */ 136 int16 typlen; 137 char typalign; 138 MemoryContext mcxt; /* context this info is stored in */ 139 union /* conversion-type-specific data */ 140 { 141 PLyObToScalar scalar; 142 PLyObToArray array; 143 PLyObToTuple tuple; 144 PLyObToDomain domain; 145 PLyObToTransform transform; 146 } u; 147 }; 148 149 150 extern PyObject *PLy_input_convert(PLyDatumToOb *arg, Datum val); 151 extern Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, 152 bool *isnull); 153 154 extern PyObject *PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, 155 TupleDesc desc, bool include_generated); 156 157 extern void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, 158 Oid typeOid, int32 typmod, 159 struct PLyProcedure *proc); 160 extern void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, 161 Oid typeOid, int32 typmod, 162 struct PLyProcedure *proc); 163 164 extern void PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, 165 struct PLyProcedure *proc); 166 extern void PLy_output_setup_tuple(PLyObToDatum *arg, TupleDesc desc, 167 struct PLyProcedure *proc); 168 169 extern void PLy_output_setup_record(PLyObToDatum *arg, TupleDesc desc, 170 struct PLyProcedure *proc); 171 172 /* conversion from Python objects to C strings --- exported for transforms */ 173 extern char *PLyObject_AsString(PyObject *plrv); 174 175 #endif /* PLPY_TYPEIO_H */ 176