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