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