1 /*-------------------------------------------------------------------------
2  *
3  * pseudotypes.c
4  *	  Functions for the system pseudo-types.
5  *
6  * A pseudo-type isn't really a type and never has any operations, but
7  * we do need to supply input and output functions to satisfy the links
8  * in the pseudo-type's entry in pg_type.  In most cases the functions
9  * just throw an error if invoked.  (XXX the error messages here cover
10  * the most common case, but might be confusing in some contexts.  Can
11  * we do better?)
12  *
13  *
14  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
15  * Portions Copyright (c) 1994, Regents of the University of California
16  *
17  *
18  * IDENTIFICATION
19  *	  src/backend/utils/adt/pseudotypes.c
20  *
21  *-------------------------------------------------------------------------
22  */
23 #include "postgres.h"
24 
25 #include "libpq/pqformat.h"
26 #include "utils/array.h"
27 #include "utils/builtins.h"
28 #include "utils/rangetypes.h"
29 
30 
31 /*
32  * cstring_in		- input routine for pseudo-type CSTRING.
33  *
34  * We might as well allow this to support constructs like "foo_in('blah')".
35  */
36 Datum
cstring_in(PG_FUNCTION_ARGS)37 cstring_in(PG_FUNCTION_ARGS)
38 {
39 	char	   *str = PG_GETARG_CSTRING(0);
40 
41 	PG_RETURN_CSTRING(pstrdup(str));
42 }
43 
44 /*
45  * cstring_out		- output routine for pseudo-type CSTRING.
46  *
47  * We allow this mainly so that "SELECT some_output_function(...)" does
48  * what the user will expect.
49  */
50 Datum
cstring_out(PG_FUNCTION_ARGS)51 cstring_out(PG_FUNCTION_ARGS)
52 {
53 	char	   *str = PG_GETARG_CSTRING(0);
54 
55 	PG_RETURN_CSTRING(pstrdup(str));
56 }
57 
58 /*
59  * cstring_recv		- binary input routine for pseudo-type CSTRING.
60  */
61 Datum
cstring_recv(PG_FUNCTION_ARGS)62 cstring_recv(PG_FUNCTION_ARGS)
63 {
64 	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
65 	char	   *str;
66 	int			nbytes;
67 
68 	str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
69 	PG_RETURN_CSTRING(str);
70 }
71 
72 /*
73  * cstring_send		- binary output routine for pseudo-type CSTRING.
74  */
75 Datum
cstring_send(PG_FUNCTION_ARGS)76 cstring_send(PG_FUNCTION_ARGS)
77 {
78 	char	   *str = PG_GETARG_CSTRING(0);
79 	StringInfoData buf;
80 
81 	pq_begintypsend(&buf);
82 	pq_sendtext(&buf, str, strlen(str));
83 	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
84 }
85 
86 /*
87  * anyarray_in		- input routine for pseudo-type ANYARRAY.
88  */
89 Datum
anyarray_in(PG_FUNCTION_ARGS)90 anyarray_in(PG_FUNCTION_ARGS)
91 {
92 	ereport(ERROR,
93 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
94 			 errmsg("cannot accept a value of type %s", "anyarray")));
95 
96 	PG_RETURN_VOID();			/* keep compiler quiet */
97 }
98 
99 /*
100  * anyarray_out		- output routine for pseudo-type ANYARRAY.
101  *
102  * We may as well allow this, since array_out will in fact work.
103  */
104 Datum
anyarray_out(PG_FUNCTION_ARGS)105 anyarray_out(PG_FUNCTION_ARGS)
106 {
107 	return array_out(fcinfo);
108 }
109 
110 /*
111  * anyarray_recv		- binary input routine for pseudo-type ANYARRAY.
112  *
113  * XXX this could actually be made to work, since the incoming array
114  * data will contain the element type OID.  Need to think through
115  * type-safety issues before allowing it, however.
116  */
117 Datum
anyarray_recv(PG_FUNCTION_ARGS)118 anyarray_recv(PG_FUNCTION_ARGS)
119 {
120 	ereport(ERROR,
121 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
122 			 errmsg("cannot accept a value of type %s", "anyarray")));
123 
124 	PG_RETURN_VOID();			/* keep compiler quiet */
125 }
126 
127 /*
128  * anyarray_send		- binary output routine for pseudo-type ANYARRAY.
129  *
130  * We may as well allow this, since array_send will in fact work.
131  */
132 Datum
anyarray_send(PG_FUNCTION_ARGS)133 anyarray_send(PG_FUNCTION_ARGS)
134 {
135 	return array_send(fcinfo);
136 }
137 
138 
139 /*
140  * anyenum_in		- input routine for pseudo-type ANYENUM.
141  */
142 Datum
anyenum_in(PG_FUNCTION_ARGS)143 anyenum_in(PG_FUNCTION_ARGS)
144 {
145 	ereport(ERROR,
146 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
147 			 errmsg("cannot accept a value of type %s", "anyenum")));
148 
149 	PG_RETURN_VOID();			/* keep compiler quiet */
150 }
151 
152 /*
153  * anyenum_out		- output routine for pseudo-type ANYENUM.
154  *
155  * We may as well allow this, since enum_out will in fact work.
156  */
157 Datum
anyenum_out(PG_FUNCTION_ARGS)158 anyenum_out(PG_FUNCTION_ARGS)
159 {
160 	return enum_out(fcinfo);
161 }
162 
163 /*
164  * anyrange_in		- input routine for pseudo-type ANYRANGE.
165  */
166 Datum
anyrange_in(PG_FUNCTION_ARGS)167 anyrange_in(PG_FUNCTION_ARGS)
168 {
169 	ereport(ERROR,
170 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
171 			 errmsg("cannot accept a value of type %s", "anyrange")));
172 
173 	PG_RETURN_VOID();			/* keep compiler quiet */
174 }
175 
176 /*
177  * anyrange_out		- output routine for pseudo-type ANYRANGE.
178  *
179  * We may as well allow this, since range_out will in fact work.
180  */
181 Datum
anyrange_out(PG_FUNCTION_ARGS)182 anyrange_out(PG_FUNCTION_ARGS)
183 {
184 	return range_out(fcinfo);
185 }
186 
187 /*
188  * void_in		- input routine for pseudo-type VOID.
189  *
190  * We allow this so that PL functions can return VOID without any special
191  * hack in the PL handler.  Whatever value the PL thinks it's returning
192  * will just be ignored.
193  */
194 Datum
void_in(PG_FUNCTION_ARGS)195 void_in(PG_FUNCTION_ARGS)
196 {
197 	PG_RETURN_VOID();			/* you were expecting something different? */
198 }
199 
200 /*
201  * void_out		- output routine for pseudo-type VOID.
202  *
203  * We allow this so that "SELECT function_returning_void(...)" works.
204  */
205 Datum
void_out(PG_FUNCTION_ARGS)206 void_out(PG_FUNCTION_ARGS)
207 {
208 	PG_RETURN_CSTRING(pstrdup(""));
209 }
210 
211 /*
212  * void_recv	- binary input routine for pseudo-type VOID.
213  *
214  * Note that since we consume no bytes, an attempt to send anything but
215  * an empty string will result in an "invalid message format" error.
216  */
217 Datum
void_recv(PG_FUNCTION_ARGS)218 void_recv(PG_FUNCTION_ARGS)
219 {
220 	PG_RETURN_VOID();
221 }
222 
223 /*
224  * void_send	- binary output routine for pseudo-type VOID.
225  *
226  * We allow this so that "SELECT function_returning_void(...)" works
227  * even when binary output is requested.
228  */
229 Datum
void_send(PG_FUNCTION_ARGS)230 void_send(PG_FUNCTION_ARGS)
231 {
232 	StringInfoData buf;
233 
234 	/* send an empty string */
235 	pq_begintypsend(&buf);
236 	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
237 }
238 
239 /*
240  * shell_in		- input routine for "shell" types (those not yet filled in).
241  */
242 Datum
shell_in(PG_FUNCTION_ARGS)243 shell_in(PG_FUNCTION_ARGS)
244 {
245 	ereport(ERROR,
246 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
247 			 errmsg("cannot accept a value of a shell type")));
248 
249 	PG_RETURN_VOID();			/* keep compiler quiet */
250 }
251 
252 /*
253  * shell_out		- output routine for "shell" types.
254  */
255 Datum
shell_out(PG_FUNCTION_ARGS)256 shell_out(PG_FUNCTION_ARGS)
257 {
258 	ereport(ERROR,
259 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
260 			 errmsg("cannot display a value of a shell type")));
261 
262 	PG_RETURN_VOID();			/* keep compiler quiet */
263 }
264 
265 
266 /*
267  * pg_node_tree_in		- input routine for type PG_NODE_TREE.
268  *
269  * pg_node_tree isn't really a pseudotype --- it's real enough to be a table
270  * column --- but it presently has no operations of its own, and disallows
271  * input too, so its I/O functions seem to fit here as much as anywhere.
272  */
273 Datum
pg_node_tree_in(PG_FUNCTION_ARGS)274 pg_node_tree_in(PG_FUNCTION_ARGS)
275 {
276 	/*
277 	 * We disallow input of pg_node_tree values because the SQL functions that
278 	 * operate on the type are not secure against malformed input.
279 	 */
280 	ereport(ERROR,
281 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
282 			 errmsg("cannot accept a value of type %s", "pg_node_tree")));
283 
284 	PG_RETURN_VOID();			/* keep compiler quiet */
285 }
286 
287 
288 /*
289  * pg_node_tree_out		- output routine for type PG_NODE_TREE.
290  *
291  * The internal representation is the same as TEXT, so just pass it off.
292  */
293 Datum
pg_node_tree_out(PG_FUNCTION_ARGS)294 pg_node_tree_out(PG_FUNCTION_ARGS)
295 {
296 	return textout(fcinfo);
297 }
298 
299 /*
300  * pg_node_tree_recv		- binary input routine for type PG_NODE_TREE.
301  */
302 Datum
pg_node_tree_recv(PG_FUNCTION_ARGS)303 pg_node_tree_recv(PG_FUNCTION_ARGS)
304 {
305 	ereport(ERROR,
306 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
307 			 errmsg("cannot accept a value of type %s", "pg_node_tree")));
308 
309 	PG_RETURN_VOID();			/* keep compiler quiet */
310 }
311 
312 /*
313  * pg_node_tree_send		- binary output routine for type PG_NODE_TREE.
314  */
315 Datum
pg_node_tree_send(PG_FUNCTION_ARGS)316 pg_node_tree_send(PG_FUNCTION_ARGS)
317 {
318 	return textsend(fcinfo);
319 }
320 
321 /*
322  * pg_ddl_command_in	- input routine for type PG_DDL_COMMAND.
323  *
324  * Like pg_node_tree, pg_ddl_command isn't really a pseudotype; it's here for
325  * the same reasons as that one.
326  */
327 Datum
pg_ddl_command_in(PG_FUNCTION_ARGS)328 pg_ddl_command_in(PG_FUNCTION_ARGS)
329 {
330 	/*
331 	 * Disallow input of pg_ddl_command value.
332 	 */
333 	ereport(ERROR,
334 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
335 			 errmsg("cannot accept a value of type %s", "pg_ddl_command")));
336 
337 	PG_RETURN_VOID();			/* keep compiler quiet */
338 }
339 
340 /*
341  * pg_ddl_command_out		- output routine for type PG_DDL_COMMAND.
342  *
343  * We don't have any good way to output this type directly, so punt.
344  */
345 Datum
pg_ddl_command_out(PG_FUNCTION_ARGS)346 pg_ddl_command_out(PG_FUNCTION_ARGS)
347 {
348 	ereport(ERROR,
349 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
350 			 errmsg("cannot output a value of type %s", "pg_ddl_command")));
351 
352 	PG_RETURN_VOID();
353 }
354 
355 /*
356  * pg_ddl_command_recv		- binary input routine for type PG_DDL_COMMAND.
357  */
358 Datum
pg_ddl_command_recv(PG_FUNCTION_ARGS)359 pg_ddl_command_recv(PG_FUNCTION_ARGS)
360 {
361 	ereport(ERROR,
362 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
363 			 errmsg("cannot accept a value of type %s", "pg_ddl_command")));
364 
365 	PG_RETURN_VOID();
366 }
367 
368 /*
369  * pg_ddl_command_send		- binary output routine for type PG_DDL_COMMAND.
370  */
371 Datum
pg_ddl_command_send(PG_FUNCTION_ARGS)372 pg_ddl_command_send(PG_FUNCTION_ARGS)
373 {
374 	ereport(ERROR,
375 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
376 			 errmsg("cannot output a value of type %s", "pg_ddl_command")));
377 
378 	PG_RETURN_VOID();
379 }
380 
381 
382 /*
383  * Generate input and output functions for a pseudotype that will reject all
384  * input and output attempts.
385  */
386 #define PSEUDOTYPE_DUMMY_IO_FUNCS(typname) \
387 \
388 Datum \
389 typname##_in(PG_FUNCTION_ARGS) \
390 { \
391 	ereport(ERROR, \
392 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
393 			 errmsg("cannot accept a value of type %s", #typname))); \
394 \
395 	PG_RETURN_VOID();			/* keep compiler quiet */ \
396 } \
397 \
398 Datum \
399 typname##_out(PG_FUNCTION_ARGS) \
400 { \
401 	ereport(ERROR, \
402 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
403 			 errmsg("cannot display a value of type %s", #typname))); \
404 \
405 	PG_RETURN_VOID();			/* keep compiler quiet */ \
406 } \
407 \
408 extern int no_such_variable
409 
410 PSEUDOTYPE_DUMMY_IO_FUNCS(any);
411 PSEUDOTYPE_DUMMY_IO_FUNCS(trigger);
412 PSEUDOTYPE_DUMMY_IO_FUNCS(event_trigger);
413 PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler);
414 PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler);
415 PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler);
416 PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler);
417 PSEUDOTYPE_DUMMY_IO_FUNCS(internal);
418 PSEUDOTYPE_DUMMY_IO_FUNCS(opaque);
419 PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement);
420 PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray);
421