Line data Source code
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-2017, 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
37 0 : cstring_in(PG_FUNCTION_ARGS)
38 : {
39 0 : char *str = PG_GETARG_CSTRING(0);
40 :
41 0 : 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
51 1 : cstring_out(PG_FUNCTION_ARGS)
52 : {
53 1 : char *str = PG_GETARG_CSTRING(0);
54 :
55 1 : PG_RETURN_CSTRING(pstrdup(str));
56 : }
57 :
58 : /*
59 : * cstring_recv - binary input routine for pseudo-type CSTRING.
60 : */
61 : Datum
62 0 : cstring_recv(PG_FUNCTION_ARGS)
63 : {
64 0 : StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
65 : char *str;
66 : int nbytes;
67 :
68 0 : str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
69 0 : PG_RETURN_CSTRING(str);
70 : }
71 :
72 : /*
73 : * cstring_send - binary output routine for pseudo-type CSTRING.
74 : */
75 : Datum
76 0 : cstring_send(PG_FUNCTION_ARGS)
77 : {
78 0 : char *str = PG_GETARG_CSTRING(0);
79 : StringInfoData buf;
80 :
81 0 : pq_begintypsend(&buf);
82 0 : pq_sendtext(&buf, str, strlen(str));
83 0 : PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
84 : }
85 :
86 : /*
87 : * anyarray_in - input routine for pseudo-type ANYARRAY.
88 : */
89 : Datum
90 0 : anyarray_in(PG_FUNCTION_ARGS)
91 : {
92 0 : 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
105 3 : anyarray_out(PG_FUNCTION_ARGS)
106 : {
107 3 : 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
118 0 : anyarray_recv(PG_FUNCTION_ARGS)
119 : {
120 0 : 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
133 0 : anyarray_send(PG_FUNCTION_ARGS)
134 : {
135 0 : return array_send(fcinfo);
136 : }
137 :
138 :
139 : /*
140 : * anyenum_in - input routine for pseudo-type ANYENUM.
141 : */
142 : Datum
143 0 : anyenum_in(PG_FUNCTION_ARGS)
144 : {
145 0 : 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
158 0 : anyenum_out(PG_FUNCTION_ARGS)
159 : {
160 0 : return enum_out(fcinfo);
161 : }
162 :
163 : /*
164 : * anyrange_in - input routine for pseudo-type ANYRANGE.
165 : */
166 : Datum
167 0 : anyrange_in(PG_FUNCTION_ARGS)
168 : {
169 0 : 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
182 8 : anyrange_out(PG_FUNCTION_ARGS)
183 : {
184 8 : 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
195 0 : void_in(PG_FUNCTION_ARGS)
196 : {
197 0 : 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
206 106 : void_out(PG_FUNCTION_ARGS)
207 : {
208 106 : 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
218 0 : void_recv(PG_FUNCTION_ARGS)
219 : {
220 0 : 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
230 0 : void_send(PG_FUNCTION_ARGS)
231 : {
232 : StringInfoData buf;
233 :
234 : /* send an empty string */
235 0 : pq_begintypsend(&buf);
236 0 : 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
243 0 : shell_in(PG_FUNCTION_ARGS)
244 : {
245 0 : 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
256 0 : shell_out(PG_FUNCTION_ARGS)
257 : {
258 0 : 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
274 0 : 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 0 : 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
294 524 : pg_node_tree_out(PG_FUNCTION_ARGS)
295 : {
296 524 : return textout(fcinfo);
297 : }
298 :
299 : /*
300 : * pg_node_tree_recv - binary input routine for type PG_NODE_TREE.
301 : */
302 : Datum
303 0 : pg_node_tree_recv(PG_FUNCTION_ARGS)
304 : {
305 0 : 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
316 0 : pg_node_tree_send(PG_FUNCTION_ARGS)
317 : {
318 0 : 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
328 0 : pg_ddl_command_in(PG_FUNCTION_ARGS)
329 : {
330 : /*
331 : * Disallow input of pg_ddl_command value.
332 : */
333 0 : 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
346 0 : pg_ddl_command_out(PG_FUNCTION_ARGS)
347 : {
348 0 : 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
359 0 : pg_ddl_command_recv(PG_FUNCTION_ARGS)
360 : {
361 0 : 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
372 0 : pg_ddl_command_send(PG_FUNCTION_ARGS)
373 : {
374 0 : 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 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(any);
411 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(trigger);
412 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(event_trigger);
413 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler);
414 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler);
415 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler);
416 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler);
417 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(internal);
418 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(opaque);
419 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement);
420 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray);
|