LCOV - code coverage report
Current view: top level - src/backend/utils/adt - pseudotypes.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 21.8 % 87 19
Test Date: 2026-01-26 10:56:24 Functions: 12.9 % 62 8
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 1.2 % 172 2

             Branch data     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-2026, 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                 :           3 : cstring_in(PG_FUNCTION_ARGS)
     108                 :             : {
     109                 :           3 :         char       *str = PG_GETARG_CSTRING(0);
     110                 :             : 
     111                 :           6 :         PG_RETURN_CSTRING(pstrdup(str));
     112                 :           3 : }
     113                 :             : 
     114                 :             : Datum
     115                 :          11 : cstring_out(PG_FUNCTION_ARGS)
     116                 :             : {
     117                 :          11 :         char       *str = PG_GETARG_CSTRING(0);
     118                 :             : 
     119                 :          22 :         PG_RETURN_CSTRING(pstrdup(str));
     120                 :          11 : }
     121                 :             : 
     122                 :             : Datum
     123                 :           0 : cstring_recv(PG_FUNCTION_ARGS)
     124                 :             : {
     125                 :           0 :         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
     126                 :           0 :         char       *str;
     127                 :           0 :         int                     nbytes;
     128                 :             : 
     129                 :           0 :         str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
     130                 :           0 :         PG_RETURN_CSTRING(str);
     131                 :           0 : }
     132                 :             : 
     133                 :             : Datum
     134                 :           0 : cstring_send(PG_FUNCTION_ARGS)
     135                 :             : {
     136                 :           0 :         char       *str = PG_GETARG_CSTRING(0);
     137                 :           0 :         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                 :           0 : }
     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                 :          66 : anyarray_out(PG_FUNCTION_ARGS)
     159                 :             : {
     160                 :          66 :         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   [ +  -  +  - ]:           1 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyrange);
     208                 :             : 
     209                 :             : Datum
     210                 :          52 : anyrange_out(PG_FUNCTION_ARGS)
     211                 :             : {
     212                 :          52 :         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                 :          14 : anymultirange_out(PG_FUNCTION_ARGS)
     237                 :             : {
     238                 :          14 :         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                 :           0 : void_in(PG_FUNCTION_ARGS)
     264                 :             : {
     265                 :           0 :         PG_RETURN_VOID();                       /* you were expecting something different? */
     266                 :             : }
     267                 :             : 
     268                 :             : Datum
     269                 :         214 : void_out(PG_FUNCTION_ARGS)
     270                 :             : {
     271                 :         214 :         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                 :           0 :         StringInfoData buf;
     288                 :             : 
     289                 :             :         /* send an empty string */
     290                 :           0 :         pq_begintypsend(&buf);
     291                 :           0 :         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     292                 :           0 : }
     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                 :           0 :         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                 :           0 :         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                 :         642 : pg_node_tree_out(PG_FUNCTION_ARGS)
     339                 :             : {
     340                 :         642 :         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);
             #  #  #  # ]
        

Generated by: LCOV version 2.3.2-1