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
107 18 : cstring_in(PG_FUNCTION_ARGS)
108 : {
109 18 : char *str = PG_GETARG_CSTRING(0);
110 :
111 18 : PG_RETURN_CSTRING(pstrdup(str));
112 : }
113 :
114 : Datum
115 246 : cstring_out(PG_FUNCTION_ARGS)
116 : {
117 246 : char *str = PG_GETARG_CSTRING(0);
118 :
119 246 : PG_RETURN_CSTRING(pstrdup(str));
120 : }
121 :
122 : Datum
123 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 : */
154 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyarray);
155 0 : PSEUDOTYPE_DUMMY_RECEIVE_FUNC(anyarray);
156 :
157 : Datum
158 6076 : anyarray_out(PG_FUNCTION_ARGS)
159 : {
160 6076 : return array_out(fcinfo);
161 : }
162 :
163 : Datum
164 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 : */
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 : */
194 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyenum);
195 :
196 : Datum
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 : */
207 6 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyrange);
208 :
209 : Datum
210 320 : anyrange_out(PG_FUNCTION_ARGS)
211 : {
212 320 : 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 : */
220 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 : */
233 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anymultirange);
234 :
235 : Datum
236 84 : anymultirange_out(PG_FUNCTION_ARGS)
237 : {
238 84 : 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 : */
246 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anycompatiblemultirange);
247 :
248 : Datum
249 0 : anycompatiblemultirange_out(PG_FUNCTION_ARGS)
250 : {
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
263 28 : void_in(PG_FUNCTION_ARGS)
264 : {
265 28 : PG_RETURN_VOID(); /* you were expecting something different? */
266 : }
267 :
268 : Datum
269 20870 : void_out(PG_FUNCTION_ARGS)
270 : {
271 20870 : PG_RETURN_CSTRING(pstrdup(""));
272 : }
273 :
274 : Datum
275 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
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 : */
334 0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(pg_node_tree);
335 0 : PSEUDOTYPE_DUMMY_RECEIVE_FUNC(pg_node_tree);
336 :
337 : Datum
338 12688 : pg_node_tree_out(PG_FUNCTION_ARGS)
339 : {
340 12688 : return textout(fcinfo);
341 : }
342 :
343 : Datum
344 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 : */
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 : */
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);
370 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler);
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);
376 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anycompatible);
377 0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anycompatiblenonarray);
|