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