LCOV - code coverage report
Current view: top level - src/backend/utils/adt - pseudotypes.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 17 70 24.3 %
Date: 2020-05-29 00:07:09 Functions: 8 58 13.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13