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-2019, 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 */
36Datum
37cstring_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 */
50Datum
51cstring_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 */
61Datum
62cstring_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 */
75Datum
76cstring_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 */
89Datum
90anyarray_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 */
104Datum
105anyarray_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 */
117Datum
118anyarray_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 */
132Datum
133anyarray_send(PG_FUNCTION_ARGS)
134{
135 return array_send(fcinfo);
136}
137
138
139/*
140 * anyenum_in - input routine for pseudo-type ANYENUM.
141 */
142Datum
143anyenum_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 */
157Datum
158anyenum_out(PG_FUNCTION_ARGS)
159{
160 return enum_out(fcinfo);
161}
162
163/*
164 * anyrange_in - input routine for pseudo-type ANYRANGE.
165 */
166Datum
167anyrange_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 */
181Datum
182anyrange_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 */
194Datum
195void_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 */
205Datum
206void_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 */
217Datum
218void_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 */
229Datum
230void_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 */
242Datum
243shell_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 */
255Datum
256shell_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 */
273Datum
274pg_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 */
293Datum
294pg_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 */
302Datum
303pg_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 */
315Datum
316pg_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 */
327Datum
328pg_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 */
345Datum
346pg_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 */
358Datum
359pg_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 */
371Datum
372pg_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\
388Datum \
389typname##_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\
398Datum \
399typname##_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\
408extern int no_such_variable
409
410PSEUDOTYPE_DUMMY_IO_FUNCS(any);
411PSEUDOTYPE_DUMMY_IO_FUNCS(trigger);
412PSEUDOTYPE_DUMMY_IO_FUNCS(event_trigger);
413PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler);
414PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler);
415PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler);
416PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler);
417PSEUDOTYPE_DUMMY_IO_FUNCS(internal);
418PSEUDOTYPE_DUMMY_IO_FUNCS(opaque);
419PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement);
420PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray);
421PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler);
422