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