diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/pseudotypes.c | 348 |
1 files changed, 123 insertions, 225 deletions
diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c index 4653fc33e6d..9eee03c143a 100644 --- a/src/backend/utils/adt/pseudotypes.c +++ b/src/backend/utils/adt/pseudotypes.c @@ -29,9 +29,81 @@ /* - * cstring_in - input routine for pseudo-type CSTRING. + * These macros generate input and output functions for a pseudo-type that + * will reject all input and output attempts. (But for some types, only + * the input function need be dummy.) + */ +#define PSEUDOTYPE_DUMMY_INPUT_FUNC(typname) \ +Datum \ +typname##_in(PG_FUNCTION_ARGS) \ +{ \ + ereport(ERROR, \ + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ + errmsg("cannot accept a value of type %s", #typname))); \ +\ + PG_RETURN_VOID(); /* keep compiler quiet */ \ +} \ +\ +extern int no_such_variable + +#define PSEUDOTYPE_DUMMY_IO_FUNCS(typname) \ +PSEUDOTYPE_DUMMY_INPUT_FUNC(typname); \ +\ +Datum \ +typname##_out(PG_FUNCTION_ARGS) \ +{ \ + ereport(ERROR, \ + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ + errmsg("cannot display a value of type %s", #typname))); \ +\ + PG_RETURN_VOID(); /* keep compiler quiet */ \ +} \ +\ +extern int no_such_variable + +/* + * Likewise for binary send/receive functions. We don't bother with these + * at all for many pseudotypes, but some have them. (By convention, if + * a type has a send function it should have a receive function, even if + * that's only dummy.) + */ +#define PSEUDOTYPE_DUMMY_RECEIVE_FUNC(typname) \ +Datum \ +typname##_recv(PG_FUNCTION_ARGS) \ +{ \ + ereport(ERROR, \ + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ + errmsg("cannot accept a value of type %s", #typname))); \ +\ + PG_RETURN_VOID(); /* keep compiler quiet */ \ +} \ +\ +extern int no_such_variable + +#define PSEUDOTYPE_DUMMY_BINARY_IO_FUNCS(typname) \ +PSEUDOTYPE_DUMMY_RECEIVE_FUNC(typname); \ +\ +Datum \ +typname##_send(PG_FUNCTION_ARGS) \ +{ \ + ereport(ERROR, \ + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ + errmsg("cannot display a value of type %s", #typname))); \ +\ + PG_RETURN_VOID(); /* keep compiler quiet */ \ +} \ +\ +extern int no_such_variable + + +/* + * cstring * - * We might as well allow this to support constructs like "foo_in('blah')". + * cstring is marked as a pseudo-type because we don't want people using it + * in tables. But it's really a perfectly functional type, so provide + * a full set of working I/O functions for it. Among other things, this + * allows manual invocation of datatype I/O functions, along the lines of + * "SELECT foo_in('blah')" or "SELECT foo_out(some-foo-value)". */ Datum cstring_in(PG_FUNCTION_ARGS) @@ -41,12 +113,6 @@ cstring_in(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(pstrdup(str)); } -/* - * cstring_out - output routine for pseudo-type CSTRING. - * - * We allow this mainly so that "SELECT some_output_function(...)" does - * what the user will expect. - */ Datum cstring_out(PG_FUNCTION_ARGS) { @@ -55,9 +121,6 @@ cstring_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(pstrdup(str)); } -/* - * cstring_recv - binary input routine for pseudo-type CSTRING. - */ Datum cstring_recv(PG_FUNCTION_ARGS) { @@ -69,9 +132,6 @@ cstring_recv(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(str); } -/* - * cstring_send - binary output routine for pseudo-type CSTRING. - */ Datum cstring_send(PG_FUNCTION_ARGS) { @@ -84,76 +144,37 @@ cstring_send(PG_FUNCTION_ARGS) } /* - * anyarray_in - input routine for pseudo-type ANYARRAY. - */ -Datum -anyarray_in(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "anyarray"))); - - PG_RETURN_VOID(); /* keep compiler quiet */ -} - -/* - * anyarray_out - output routine for pseudo-type ANYARRAY. + * anyarray + * + * We need to allow output of anyarray so that, e.g., pg_statistic columns + * can be printed. Input has to be disallowed, however. * - * We may as well allow this, since array_out will in fact work. + * XXX anyarray_recv could actually be made to work, since the incoming + * array data would contain the element type OID. It seems unlikely that + * it'd be sufficiently type-safe, though. */ +PSEUDOTYPE_DUMMY_INPUT_FUNC(anyarray); +PSEUDOTYPE_DUMMY_RECEIVE_FUNC(anyarray); + Datum anyarray_out(PG_FUNCTION_ARGS) { return array_out(fcinfo); } -/* - * anyarray_recv - binary input routine for pseudo-type ANYARRAY. - * - * XXX this could actually be made to work, since the incoming array - * data will contain the element type OID. Need to think through - * type-safety issues before allowing it, however. - */ -Datum -anyarray_recv(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "anyarray"))); - - PG_RETURN_VOID(); /* keep compiler quiet */ -} - -/* - * anyarray_send - binary output routine for pseudo-type ANYARRAY. - * - * We may as well allow this, since array_send will in fact work. - */ Datum anyarray_send(PG_FUNCTION_ARGS) { return array_send(fcinfo); } - /* - * anyenum_in - input routine for pseudo-type ANYENUM. - */ -Datum -anyenum_in(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "anyenum"))); - - PG_RETURN_VOID(); /* keep compiler quiet */ -} - -/* - * anyenum_out - output routine for pseudo-type ANYENUM. + * anyenum * - * We may as well allow this, since enum_out will in fact work. + * We may as well allow output, since enum_out will in fact work. */ +PSEUDOTYPE_DUMMY_INPUT_FUNC(anyenum); + Datum anyenum_out(PG_FUNCTION_ARGS) { @@ -161,23 +182,12 @@ anyenum_out(PG_FUNCTION_ARGS) } /* - * anyrange_in - input routine for pseudo-type ANYRANGE. - */ -Datum -anyrange_in(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "anyrange"))); - - PG_RETURN_VOID(); /* keep compiler quiet */ -} - -/* - * anyrange_out - output routine for pseudo-type ANYRANGE. + * anyrange * - * We may as well allow this, since range_out will in fact work. + * We may as well allow output, since range_out will in fact work. */ +PSEUDOTYPE_DUMMY_INPUT_FUNC(anyrange); + Datum anyrange_out(PG_FUNCTION_ARGS) { @@ -185,11 +195,12 @@ anyrange_out(PG_FUNCTION_ARGS) } /* - * void_in - input routine for pseudo-type VOID. + * void * - * We allow this so that PL functions can return VOID without any special - * hack in the PL handler. Whatever value the PL thinks it's returning - * will just be ignored. + * We support void_in so that PL functions can return VOID without any + * special hack in the PL handler. Whatever value the PL thinks it's + * returning will just be ignored. Conversely, void_out and void_send + * are needed so that "SELECT function_returning_void(...)" works. */ Datum void_in(PG_FUNCTION_ARGS) @@ -197,35 +208,22 @@ void_in(PG_FUNCTION_ARGS) PG_RETURN_VOID(); /* you were expecting something different? */ } -/* - * void_out - output routine for pseudo-type VOID. - * - * We allow this so that "SELECT function_returning_void(...)" works. - */ Datum void_out(PG_FUNCTION_ARGS) { PG_RETURN_CSTRING(pstrdup("")); } -/* - * void_recv - binary input routine for pseudo-type VOID. - * - * Note that since we consume no bytes, an attempt to send anything but - * an empty string will result in an "invalid message format" error. - */ Datum void_recv(PG_FUNCTION_ARGS) { + /* + * Note that since we consume no bytes, an attempt to send anything but an + * empty string will result in an "invalid message format" error. + */ PG_RETURN_VOID(); } -/* - * void_send - binary output routine for pseudo-type VOID. - * - * We allow this so that "SELECT function_returning_void(...)" works - * even when binary output is requested. - */ Datum void_send(PG_FUNCTION_ARGS) { @@ -237,7 +235,12 @@ void_send(PG_FUNCTION_ARGS) } /* - * shell_in - input routine for "shell" types (those not yet filled in). + * shell + * + * shell_in and shell_out are entered in pg_type for "shell" types + * (those not yet filled in). They should be unreachable, but we + * set them up just in case some code path tries to do I/O without + * having checked pg_type.typisdefined anywhere along the way. */ Datum shell_in(PG_FUNCTION_ARGS) @@ -249,9 +252,6 @@ shell_in(PG_FUNCTION_ARGS) PG_RETURN_VOID(); /* keep compiler quiet */ } -/* - * shell_out - output routine for "shell" types. - */ Datum shell_out(PG_FUNCTION_ARGS) { @@ -264,54 +264,25 @@ shell_out(PG_FUNCTION_ARGS) /* - * pg_node_tree_in - input routine for type PG_NODE_TREE. + * pg_node_tree * * pg_node_tree isn't really a pseudotype --- it's real enough to be a table * column --- but it presently has no operations of its own, and disallows * input too, so its I/O functions seem to fit here as much as anywhere. - */ -Datum -pg_node_tree_in(PG_FUNCTION_ARGS) -{ - /* - * We disallow input of pg_node_tree values because the SQL functions that - * operate on the type are not secure against malformed input. - */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "pg_node_tree"))); - - PG_RETURN_VOID(); /* keep compiler quiet */ -} - - -/* - * pg_node_tree_out - output routine for type PG_NODE_TREE. * - * The internal representation is the same as TEXT, so just pass it off. + * We must disallow input of pg_node_tree values because the SQL functions + * that operate on the type are not secure against malformed input. + * We do want to allow output, though. */ +PSEUDOTYPE_DUMMY_INPUT_FUNC(pg_node_tree); +PSEUDOTYPE_DUMMY_RECEIVE_FUNC(pg_node_tree); + Datum pg_node_tree_out(PG_FUNCTION_ARGS) { return textout(fcinfo); } -/* - * pg_node_tree_recv - binary input routine for type PG_NODE_TREE. - */ -Datum -pg_node_tree_recv(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "pg_node_tree"))); - - PG_RETURN_VOID(); /* keep compiler quiet */ -} - -/* - * pg_node_tree_send - binary output routine for type PG_NODE_TREE. - */ Datum pg_node_tree_send(PG_FUNCTION_ARGS) { @@ -319,102 +290,29 @@ pg_node_tree_send(PG_FUNCTION_ARGS) } /* - * pg_ddl_command_in - input routine for type PG_DDL_COMMAND. + * pg_ddl_command * - * Like pg_node_tree, pg_ddl_command isn't really a pseudotype; it's here for - * the same reasons as that one. - */ -Datum -pg_ddl_command_in(PG_FUNCTION_ARGS) -{ - /* - * Disallow input of pg_ddl_command value. - */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "pg_ddl_command"))); - - PG_RETURN_VOID(); /* keep compiler quiet */ -} - -/* - * pg_ddl_command_out - output routine for type PG_DDL_COMMAND. + * Like pg_node_tree, pg_ddl_command isn't really a pseudotype; it's here + * for the same reasons as that one. * - * We don't have any good way to output this type directly, so punt. + * We don't have any good way to output this type directly, so punt + * for output as well as input. */ -Datum -pg_ddl_command_out(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot output a value of type %s", "pg_ddl_command"))); - - PG_RETURN_VOID(); -} - -/* - * pg_ddl_command_recv - binary input routine for type PG_DDL_COMMAND. - */ -Datum -pg_ddl_command_recv(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot accept a value of type %s", "pg_ddl_command"))); - - PG_RETURN_VOID(); -} - -/* - * pg_ddl_command_send - binary output routine for type PG_DDL_COMMAND. - */ -Datum -pg_ddl_command_send(PG_FUNCTION_ARGS) -{ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot output a value of type %s", "pg_ddl_command"))); - - PG_RETURN_VOID(); -} +PSEUDOTYPE_DUMMY_IO_FUNCS(pg_ddl_command); +PSEUDOTYPE_DUMMY_BINARY_IO_FUNCS(pg_ddl_command); /* - * Generate input and output functions for a pseudotype that will reject all - * input and output attempts. + * Dummy I/O functions for various other pseudotypes. */ -#define PSEUDOTYPE_DUMMY_IO_FUNCS(typname) \ -\ -Datum \ -typname##_in(PG_FUNCTION_ARGS) \ -{ \ - ereport(ERROR, \ - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ - errmsg("cannot accept a value of type %s", #typname))); \ -\ - PG_RETURN_VOID(); /* keep compiler quiet */ \ -} \ -\ -Datum \ -typname##_out(PG_FUNCTION_ARGS) \ -{ \ - ereport(ERROR, \ - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ - errmsg("cannot display a value of type %s", #typname))); \ -\ - PG_RETURN_VOID(); /* keep compiler quiet */ \ -} \ -\ -extern int no_such_variable - PSEUDOTYPE_DUMMY_IO_FUNCS(any); PSEUDOTYPE_DUMMY_IO_FUNCS(trigger); PSEUDOTYPE_DUMMY_IO_FUNCS(event_trigger); PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler); PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler); +PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler); PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler); PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler); PSEUDOTYPE_DUMMY_IO_FUNCS(internal); PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement); PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray); -PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler); |