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