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

Generated by: LCOV version 1.14