LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - pseudotypes.c (source / functions) Coverage Total Hit UNC UIC UBC GIC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 22.4 % 76 17 3 23 33 6 11 23 5 3 1
Current Date: 2023-04-08 15:15:32 Functions: 12.9 % 62 8 2 39 13 3 5 39 2 2 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  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-2023, 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 CBC           9 : cstring_in(PG_FUNCTION_ARGS)
     111                 : {
     112               9 :     char       *str = PG_GETARG_CSTRING(0);
     113                 : 
     114               9 :     PG_RETURN_CSTRING(pstrdup(str));
     115                 : }
     116                 : 
     117                 : Datum
     118             105 : cstring_out(PG_FUNCTION_ARGS)
     119                 : {
     120             105 :     char       *str = PG_GETARG_CSTRING(0);
     121                 : 
     122             105 :     PG_RETURN_CSTRING(pstrdup(str));
     123                 : }
     124                 : 
     125                 : Datum
     126 UBC           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 CBC          22 : anyarray_out(PG_FUNCTION_ARGS)
     162                 : {
     163              22 :     return array_out(fcinfo);
     164                 : }
     165                 : 
     166                 : Datum
     167 UBC           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 CBC           3 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anyrange);
     211                 : 
     212                 : Datum
     213              30 : anyrange_out(PG_FUNCTION_ARGS)
     214                 : {
     215              30 :     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 UBC           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                 :  * anymultirange
     233                 :  *
     234                 :  * We may as well allow output, since multirange_out will in fact work.
     235                 :  */
     236 UNC           0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anymultirange);
     237                 : 
     238                 : Datum
     239               0 : anymultirange_out(PG_FUNCTION_ARGS)
     240                 : {
     241               0 :     return multirange_out(fcinfo);
     242                 : }
     243                 : 
     244                 : /*
     245                 :  * anycompatiblemultirange
     246                 :  *
     247                 :  * We may as well allow output, since multirange_out will in fact work.
     248                 :  */
     249 UBC           0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(anycompatiblemultirange);
     250                 : 
     251                 : Datum
     252               0 : anycompatiblemultirange_out(PG_FUNCTION_ARGS)
     253                 : {
     254               0 :     return multirange_out(fcinfo);
     255                 : }
     256                 : 
     257 ECB             : /*
     258                 :  * void
     259                 :  *
     260                 :  * We support void_in so that PL functions can return VOID without any
     261                 :  * special hack in the PL handler.  Whatever value the PL thinks it's
     262                 :  * returning will just be ignored.  Conversely, void_out and void_send
     263                 :  * are needed so that "SELECT function_returning_void(...)" works.
     264                 :  */
     265                 : Datum
     266 GIC          14 : void_in(PG_FUNCTION_ARGS)
     267 EUB             : {
     268 GIC          14 :     PG_RETURN_VOID();           /* you were expecting something different? */
     269                 : }
     270                 : 
     271                 : Datum
     272            8620 : void_out(PG_FUNCTION_ARGS)
     273 EUB             : {
     274 GIC        8620 :     PG_RETURN_CSTRING(pstrdup(""));
     275                 : }
     276                 : 
     277 EUB             : Datum
     278 UIC           0 : void_recv(PG_FUNCTION_ARGS)
     279                 : {
     280                 :     /*
     281                 :      * Note that since we consume no bytes, an attempt to send anything but an
     282 EUB             :      * empty string will result in an "invalid message format" error.
     283                 :      */
     284 UIC           0 :     PG_RETURN_VOID();
     285                 : }
     286                 : 
     287                 : Datum
     288               0 : void_send(PG_FUNCTION_ARGS)
     289                 : {
     290                 :     StringInfoData buf;
     291                 : 
     292                 :     /* send an empty string */
     293               0 :     pq_begintypsend(&buf);
     294               0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     295 EUB             : }
     296                 : 
     297                 : /*
     298                 :  * shell
     299                 :  *
     300                 :  * shell_in and shell_out are entered in pg_type for "shell" types
     301                 :  * (those not yet filled in).  They should be unreachable, but we
     302                 :  * set them up just in case some code path tries to do I/O without
     303                 :  * having checked pg_type.typisdefined anywhere along the way.
     304                 :  */
     305                 : Datum
     306 UIC           0 : shell_in(PG_FUNCTION_ARGS)
     307 EUB             : {
     308 UIC           0 :     ereport(ERROR,
     309                 :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     310                 :              errmsg("cannot accept a value of a shell type")));
     311                 : 
     312                 :     PG_RETURN_VOID();           /* keep compiler quiet */
     313                 : }
     314                 : 
     315                 : Datum
     316               0 : shell_out(PG_FUNCTION_ARGS)
     317                 : {
     318               0 :     ereport(ERROR,
     319                 :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     320                 :              errmsg("cannot display a value of a shell type")));
     321                 : 
     322                 :     PG_RETURN_VOID();           /* keep compiler quiet */
     323                 : }
     324                 : 
     325                 : 
     326 EUB             : /*
     327                 :  * pg_node_tree
     328                 :  *
     329                 :  * pg_node_tree isn't really a pseudotype --- it's real enough to be a table
     330 ECB             :  * column --- but it presently has no operations of its own, and disallows
     331                 :  * input too, so its I/O functions seem to fit here as much as anywhere.
     332                 :  *
     333                 :  * We must disallow input of pg_node_tree values because the SQL functions
     334                 :  * that operate on the type are not secure against malformed input.
     335                 :  * We do want to allow output, though.
     336 EUB             :  */
     337 UIC           0 : PSEUDOTYPE_DUMMY_INPUT_FUNC(pg_node_tree);
     338 UBC           0 : PSEUDOTYPE_DUMMY_RECEIVE_FUNC(pg_node_tree);
     339                 : 
     340                 : Datum
     341 GIC        3344 : pg_node_tree_out(PG_FUNCTION_ARGS)
     342                 : {
     343            3344 :     return textout(fcinfo);
     344                 : }
     345                 : 
     346                 : Datum
     347 UIC           0 : pg_node_tree_send(PG_FUNCTION_ARGS)
     348                 : {
     349               0 :     return textsend(fcinfo);
     350 EUB             : }
     351                 : 
     352                 : /*
     353                 :  * pg_ddl_command
     354                 :  *
     355                 :  * Like pg_node_tree, pg_ddl_command isn't really a pseudotype; it's here
     356                 :  * for the same reasons as that one.
     357                 :  *
     358                 :  * We don't have any good way to output this type directly, so punt
     359                 :  * for output as well as input.
     360                 :  */
     361 UBC           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(pg_ddl_command);
     362               0 : PSEUDOTYPE_DUMMY_BINARY_IO_FUNCS(pg_ddl_command);
     363 EUB             : 
     364                 : 
     365                 : /*
     366                 :  * Dummy I/O functions for various other pseudotypes.
     367                 :  */
     368 UBC           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(any);
     369               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(trigger);
     370 UIC           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(event_trigger);
     371               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler);
     372               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler);
     373               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler);
     374               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler);
     375               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler);
     376               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(internal);
     377               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement);
     378               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray);
     379               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anycompatible);
     380               0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anycompatiblenonarray);
        

Generated by: LCOV version v1.16-55-g56c0a2a