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