Age Owner Branch data TLA 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-2024, 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/fmgrprotos.h"
27 : :
28 : :
29 : : /*
30 : : * These macros generate input and output functions for a pseudo-type that
31 : : * will reject all input and output attempts. (But for some types, only
32 : : * the input function need be dummy.)
33 : : */
34 : : #define PSEUDOTYPE_DUMMY_INPUT_FUNC(typname) \
35 : : Datum \
36 : : typname##_in(PG_FUNCTION_ARGS) \
37 : : { \
38 : : ereport(ERROR, \
39 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
40 : : errmsg("cannot accept a value of type %s", #typname))); \
41 : : \
42 : : PG_RETURN_VOID(); /* keep compiler quiet */ \
43 : : } \
44 : : \
45 : : extern int no_such_variable
46 : :
47 : : #define PSEUDOTYPE_DUMMY_IO_FUNCS(typname) \
48 : : PSEUDOTYPE_DUMMY_INPUT_FUNC(typname); \
49 : : \
50 : : Datum \
51 : : typname##_out(PG_FUNCTION_ARGS) \
52 : : { \
53 : : ereport(ERROR, \
54 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
55 : : errmsg("cannot display a value of type %s", #typname))); \
56 : : \
57 : : PG_RETURN_VOID(); /* keep compiler quiet */ \
58 : : } \
59 : : \
60 : : extern int no_such_variable
61 : :
62 : : /*
63 : : * Likewise for binary send/receive functions. We don't bother with these
64 : : * at all for many pseudotypes, but some have them. (By convention, if
65 : : * a type has a send function it should have a receive function, even if
66 : : * that's only dummy.)
67 : : */
68 : : #define PSEUDOTYPE_DUMMY_RECEIVE_FUNC(typname) \
69 : : Datum \
70 : : typname##_recv(PG_FUNCTION_ARGS) \
71 : : { \
72 : : ereport(ERROR, \
73 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
74 : : errmsg("cannot accept a value of type %s", #typname))); \
75 : : \
76 : : PG_RETURN_VOID(); /* keep compiler quiet */ \
77 : : } \
78 : : \
79 : : extern int no_such_variable
80 : :
81 : : #define PSEUDOTYPE_DUMMY_BINARY_IO_FUNCS(typname) \
82 : : PSEUDOTYPE_DUMMY_RECEIVE_FUNC(typname); \
83 : : \
84 : : Datum \
85 : : typname##_send(PG_FUNCTION_ARGS) \
86 : : { \
87 : : ereport(ERROR, \
88 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
89 : : errmsg("cannot display a value of type %s", #typname))); \
90 : : \
91 : : PG_RETURN_VOID(); /* keep compiler quiet */ \
92 : : } \
93 : : \
94 : : extern int no_such_variable
95 : :
96 : :
97 : : /*
98 : : * cstring
99 : : *
100 : : * cstring is marked as a pseudo-type because we don't want people using it
101 : : * in tables. But it's really a perfectly functional type, so provide
102 : : * a full set of working I/O functions for it. Among other things, this
103 : : * allows manual invocation of datatype I/O functions, along the lines of
104 : : * "SELECT foo_in('blah')" or "SELECT foo_out(some-foo-value)".
105 : : */
106 : : Datum
7906 tgl@sss.pgh.pa.us 107 :CBC 9 : cstring_in(PG_FUNCTION_ARGS)
108 : : {
7904 109 : 9 : char *str = PG_GETARG_CSTRING(0);
110 : :
111 : 9 : PG_RETURN_CSTRING(pstrdup(str));
112 : : }
113 : :
114 : : Datum
7906 115 : 123 : cstring_out(PG_FUNCTION_ARGS)
116 : : {
7904 117 : 123 : char *str = PG_GETARG_CSTRING(0);
118 : :
119 : 123 : PG_RETURN_CSTRING(pstrdup(str));
120 : : }
121 : :
122 : : Datum
7642 tgl@sss.pgh.pa.us 123 :UBC 0 : cstring_recv(PG_FUNCTION_ARGS)
124 : : {
125 : 0 : StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
126 : : char *str;
127 : : int nbytes;
128 : :
129 : 0 : str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
130 : 0 : PG_RETURN_CSTRING(str);
131 : : }
132 : :
133 : : Datum
134 : 0 : cstring_send(PG_FUNCTION_ARGS)
135 : : {
136 : 0 : char *str = PG_GETARG_CSTRING(0);
137 : : StringInfoData buf;
138 : :
139 : 0 : pq_begintypsend(&buf);
140 : 0 : pq_sendtext(&buf, str, strlen(str));
141 : 0 : PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
142 : : }
143 : :
144 : : /*
145 : : * anyarray
146 : : *
147 : : * We need to allow output of anyarray so that, e.g., pg_statistic columns
148 : : * can be printed. Input has to be disallowed, however.
149 : : *
150 : : * XXX anyarray_recv could actually be made to work, since the incoming
151 : : * array data would contain the element type OID. It seems unlikely that
152 : : * it'd be sufficiently type-safe, though.
153 : : */
1492 154 [ # # ]: 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyarray);
155 [ # # ]: 0 : PSEUDOTYPE_DUMMY_RECEIVE_FUNC(anyarray);
156 : :
157 : : Datum
7906 tgl@sss.pgh.pa.us 158 :CBC 636 : anyarray_out(PG_FUNCTION_ARGS)
159 : : {
7902 160 : 636 : return array_out(fcinfo);
161 : : }
162 : :
163 : : Datum
7642 tgl@sss.pgh.pa.us 164 :UBC 0 : anyarray_send(PG_FUNCTION_ARGS)
165 : : {
166 : 0 : return array_send(fcinfo);
167 : : }
168 : :
169 : : /*
170 : : * anycompatiblearray
171 : : *
172 : : * We may as well allow output, since we do for anyarray.
173 : : */
1487 174 [ # # ]: 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anycompatiblearray);
175 [ # # ]: 0 : PSEUDOTYPE_DUMMY_RECEIVE_FUNC(anycompatiblearray);
176 : :
177 : : Datum
178 : 0 : anycompatiblearray_out(PG_FUNCTION_ARGS)
179 : : {
180 : 0 : return array_out(fcinfo);
181 : : }
182 : :
183 : : Datum
184 : 0 : anycompatiblearray_send(PG_FUNCTION_ARGS)
185 : : {
186 : 0 : return array_send(fcinfo);
187 : : }
188 : :
189 : : /*
190 : : * anyenum
191 : : *
192 : : * We may as well allow output, since enum_out will in fact work.
193 : : */
1492 194 [ # # ]: 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyenum);
195 : :
196 : : Datum
6222 197 : 0 : anyenum_out(PG_FUNCTION_ARGS)
198 : : {
199 : 0 : return enum_out(fcinfo);
200 : : }
201 : :
202 : : /*
203 : : * anyrange
204 : : *
205 : : * We may as well allow output, since range_out will in fact work.
206 : : */
1492 tgl@sss.pgh.pa.us 207 [ + - ]:CBC 3 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyrange);
208 : :
209 : : Datum
4546 heikki.linnakangas@i 210 : 64 : anyrange_out(PG_FUNCTION_ARGS)
211 : : {
212 : 64 : return range_out(fcinfo);
213 : : }
214 : :
215 : : /*
216 : : * anycompatiblerange
217 : : *
218 : : * We may as well allow output, since range_out will in fact work.
219 : : */
1487 tgl@sss.pgh.pa.us 220 [ # # ]:UBC 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anycompatiblerange);
221 : :
222 : : Datum
223 : 0 : anycompatiblerange_out(PG_FUNCTION_ARGS)
224 : : {
225 : 0 : return range_out(fcinfo);
226 : : }
227 : :
228 : : /*
229 : : * anymultirange
230 : : *
231 : : * We may as well allow output, since multirange_out will in fact work.
232 : : */
491 233 [ # # ]: 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anymultirange);
234 : :
235 : : Datum
491 tgl@sss.pgh.pa.us 236 :GBC 6 : anymultirange_out(PG_FUNCTION_ARGS)
237 : : {
1211 akorotkov@postgresql 238 : 6 : return multirange_out(fcinfo);
239 : : }
240 : :
241 : : /*
242 : : * anycompatiblemultirange
243 : : *
244 : : * We may as well allow output, since multirange_out will in fact work.
245 : : */
491 tgl@sss.pgh.pa.us 246 [ # # ]:UBC 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anycompatiblemultirange);
247 : :
248 : : Datum
249 : 0 : anycompatiblemultirange_out(PG_FUNCTION_ARGS)
250 : : {
1211 akorotkov@postgresql 251 : 0 : return multirange_out(fcinfo);
252 : : }
253 : :
254 : : /*
255 : : * void
256 : : *
257 : : * We support void_in so that PL functions can return VOID without any
258 : : * special hack in the PL handler. Whatever value the PL thinks it's
259 : : * returning will just be ignored. Conversely, void_out and void_send
260 : : * are needed so that "SELECT function_returning_void(...)" works.
261 : : */
262 : : Datum
7906 tgl@sss.pgh.pa.us 263 :CBC 14 : void_in(PG_FUNCTION_ARGS)
264 : : {
265 : 14 : PG_RETURN_VOID(); /* you were expecting something different? */
266 : : }
267 : :
268 : : Datum
269 : 9888 : void_out(PG_FUNCTION_ARGS)
270 : : {
271 : 9888 : PG_RETURN_CSTRING(pstrdup(""));
272 : : }
273 : :
274 : : Datum
4800 tgl@sss.pgh.pa.us 275 :UBC 0 : void_recv(PG_FUNCTION_ARGS)
276 : : {
277 : : /*
278 : : * Note that since we consume no bytes, an attempt to send anything but an
279 : : * empty string will result in an "invalid message format" error.
280 : : */
281 : 0 : PG_RETURN_VOID();
282 : : }
283 : :
284 : : Datum
285 : 0 : void_send(PG_FUNCTION_ARGS)
286 : : {
287 : : StringInfoData buf;
288 : :
289 : : /* send an empty string */
290 : 0 : pq_begintypsend(&buf);
291 : 0 : PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
292 : : }
293 : :
294 : : /*
295 : : * shell
296 : : *
297 : : * shell_in and shell_out are entered in pg_type for "shell" types
298 : : * (those not yet filled in). They should be unreachable, but we
299 : : * set them up just in case some code path tries to do I/O without
300 : : * having checked pg_type.typisdefined anywhere along the way.
301 : : */
302 : : Datum
6620 303 : 0 : shell_in(PG_FUNCTION_ARGS)
304 : : {
305 [ # # ]: 0 : ereport(ERROR,
306 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
307 : : errmsg("cannot accept a value of a shell type")));
308 : :
309 : : PG_RETURN_VOID(); /* keep compiler quiet */
310 : : }
311 : :
312 : : Datum
313 : 0 : shell_out(PG_FUNCTION_ARGS)
314 : : {
315 [ # # ]: 0 : ereport(ERROR,
316 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
317 : : errmsg("cannot display a value of a shell type")));
318 : :
319 : : PG_RETURN_VOID(); /* keep compiler quiet */
320 : : }
321 : :
322 : :
323 : : /*
324 : : * pg_node_tree
325 : : *
326 : : * pg_node_tree isn't really a pseudotype --- it's real enough to be a table
327 : : * column --- but it presently has no operations of its own, and disallows
328 : : * input too, so its I/O functions seem to fit here as much as anywhere.
329 : : *
330 : : * We must disallow input of pg_node_tree values because the SQL functions
331 : : * that operate on the type are not secure against malformed input.
332 : : * We do want to allow output, though.
333 : : */
1492 334 [ # # ]: 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(pg_node_tree);
335 [ # # ]: 0 : PSEUDOTYPE_DUMMY_RECEIVE_FUNC(pg_node_tree);
336 : :
337 : : Datum
4972 tgl@sss.pgh.pa.us 338 :CBC 4113 : pg_node_tree_out(PG_FUNCTION_ARGS)
339 : : {
340 : 4113 : return textout(fcinfo);
341 : : }
342 : :
343 : : Datum
4972 tgl@sss.pgh.pa.us 344 :UBC 0 : pg_node_tree_send(PG_FUNCTION_ARGS)
345 : : {
346 : 0 : return textsend(fcinfo);
347 : : }
348 : :
349 : : /*
350 : : * pg_ddl_command
351 : : *
352 : : * Like pg_node_tree, pg_ddl_command isn't really a pseudotype; it's here
353 : : * for the same reasons as that one.
354 : : *
355 : : * We don't have any good way to output this type directly, so punt
356 : : * for output as well as input.
357 : : */
1492 358 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(pg_ddl_command);
359 [ # # ]: 0 : PSEUDOTYPE_DUMMY_BINARY_IO_FUNCS(pg_ddl_command);
360 : :
361 : :
362 : : /*
363 : : * Dummy I/O functions for various other pseudotypes.
364 : : */
2726 peter_e@gmx.net 365 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(any);
366 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(trigger);
367 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(event_trigger);
368 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler);
369 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler);
1492 tgl@sss.pgh.pa.us 370 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler);
2726 peter_e@gmx.net 371 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler);
372 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler);
373 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(internal);
374 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement);
375 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray);
1487 tgl@sss.pgh.pa.us 376 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anycompatible);
377 [ # # ]: 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anycompatiblenonarray);
|