LCOV - code coverage report
Current view: top level - src/backend/utils/adt - pseudotypes.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 11 71 15.5 %
Date: 2017-09-29 13:40:31 Functions: 5 48 10.4 %
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-2017, 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             :  * cstring_in       - input routine for pseudo-type CSTRING.
      33             :  *
      34             :  * We might as well allow this to support constructs like "foo_in('blah')".
      35             :  */
      36             : Datum
      37           0 : cstring_in(PG_FUNCTION_ARGS)
      38             : {
      39           0 :     char       *str = PG_GETARG_CSTRING(0);
      40             : 
      41           0 :     PG_RETURN_CSTRING(pstrdup(str));
      42             : }
      43             : 
      44             : /*
      45             :  * cstring_out      - output routine for pseudo-type CSTRING.
      46             :  *
      47             :  * We allow this mainly so that "SELECT some_output_function(...)" does
      48             :  * what the user will expect.
      49             :  */
      50             : Datum
      51           1 : cstring_out(PG_FUNCTION_ARGS)
      52             : {
      53           1 :     char       *str = PG_GETARG_CSTRING(0);
      54             : 
      55           1 :     PG_RETURN_CSTRING(pstrdup(str));
      56             : }
      57             : 
      58             : /*
      59             :  * cstring_recv     - binary input routine for pseudo-type CSTRING.
      60             :  */
      61             : Datum
      62           0 : cstring_recv(PG_FUNCTION_ARGS)
      63             : {
      64           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      65             :     char       *str;
      66             :     int         nbytes;
      67             : 
      68           0 :     str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
      69           0 :     PG_RETURN_CSTRING(str);
      70             : }
      71             : 
      72             : /*
      73             :  * cstring_send     - binary output routine for pseudo-type CSTRING.
      74             :  */
      75             : Datum
      76           0 : cstring_send(PG_FUNCTION_ARGS)
      77             : {
      78           0 :     char       *str = PG_GETARG_CSTRING(0);
      79             :     StringInfoData buf;
      80             : 
      81           0 :     pq_begintypsend(&buf);
      82           0 :     pq_sendtext(&buf, str, strlen(str));
      83           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
      84             : }
      85             : 
      86             : /*
      87             :  * anyarray_in      - input routine for pseudo-type ANYARRAY.
      88             :  */
      89             : Datum
      90           0 : anyarray_in(PG_FUNCTION_ARGS)
      91             : {
      92           0 :     ereport(ERROR,
      93             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
      94             :              errmsg("cannot accept a value of type %s", "anyarray")));
      95             : 
      96             :     PG_RETURN_VOID();           /* keep compiler quiet */
      97             : }
      98             : 
      99             : /*
     100             :  * anyarray_out     - output routine for pseudo-type ANYARRAY.
     101             :  *
     102             :  * We may as well allow this, since array_out will in fact work.
     103             :  */
     104             : Datum
     105           3 : anyarray_out(PG_FUNCTION_ARGS)
     106             : {
     107           3 :     return array_out(fcinfo);
     108             : }
     109             : 
     110             : /*
     111             :  * anyarray_recv        - binary input routine for pseudo-type ANYARRAY.
     112             :  *
     113             :  * XXX this could actually be made to work, since the incoming array
     114             :  * data will contain the element type OID.  Need to think through
     115             :  * type-safety issues before allowing it, however.
     116             :  */
     117             : Datum
     118           0 : anyarray_recv(PG_FUNCTION_ARGS)
     119             : {
     120           0 :     ereport(ERROR,
     121             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     122             :              errmsg("cannot accept a value of type %s", "anyarray")));
     123             : 
     124             :     PG_RETURN_VOID();           /* keep compiler quiet */
     125             : }
     126             : 
     127             : /*
     128             :  * anyarray_send        - binary output routine for pseudo-type ANYARRAY.
     129             :  *
     130             :  * We may as well allow this, since array_send will in fact work.
     131             :  */
     132             : Datum
     133           0 : anyarray_send(PG_FUNCTION_ARGS)
     134             : {
     135           0 :     return array_send(fcinfo);
     136             : }
     137             : 
     138             : 
     139             : /*
     140             :  * anyenum_in       - input routine for pseudo-type ANYENUM.
     141             :  */
     142             : Datum
     143           0 : anyenum_in(PG_FUNCTION_ARGS)
     144             : {
     145           0 :     ereport(ERROR,
     146             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     147             :              errmsg("cannot accept a value of type %s", "anyenum")));
     148             : 
     149             :     PG_RETURN_VOID();           /* keep compiler quiet */
     150             : }
     151             : 
     152             : /*
     153             :  * anyenum_out      - output routine for pseudo-type ANYENUM.
     154             :  *
     155             :  * We may as well allow this, since enum_out will in fact work.
     156             :  */
     157             : Datum
     158           0 : anyenum_out(PG_FUNCTION_ARGS)
     159             : {
     160           0 :     return enum_out(fcinfo);
     161             : }
     162             : 
     163             : /*
     164             :  * anyrange_in      - input routine for pseudo-type ANYRANGE.
     165             :  */
     166             : Datum
     167           0 : anyrange_in(PG_FUNCTION_ARGS)
     168             : {
     169           0 :     ereport(ERROR,
     170             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     171             :              errmsg("cannot accept a value of type %s", "anyrange")));
     172             : 
     173             :     PG_RETURN_VOID();           /* keep compiler quiet */
     174             : }
     175             : 
     176             : /*
     177             :  * anyrange_out     - output routine for pseudo-type ANYRANGE.
     178             :  *
     179             :  * We may as well allow this, since range_out will in fact work.
     180             :  */
     181             : Datum
     182           8 : anyrange_out(PG_FUNCTION_ARGS)
     183             : {
     184           8 :     return range_out(fcinfo);
     185             : }
     186             : 
     187             : /*
     188             :  * void_in      - input routine for pseudo-type VOID.
     189             :  *
     190             :  * We allow this so that PL functions can return VOID without any special
     191             :  * hack in the PL handler.  Whatever value the PL thinks it's returning
     192             :  * will just be ignored.
     193             :  */
     194             : Datum
     195           0 : void_in(PG_FUNCTION_ARGS)
     196             : {
     197           0 :     PG_RETURN_VOID();           /* you were expecting something different? */
     198             : }
     199             : 
     200             : /*
     201             :  * void_out     - output routine for pseudo-type VOID.
     202             :  *
     203             :  * We allow this so that "SELECT function_returning_void(...)" works.
     204             :  */
     205             : Datum
     206         106 : void_out(PG_FUNCTION_ARGS)
     207             : {
     208         106 :     PG_RETURN_CSTRING(pstrdup(""));
     209             : }
     210             : 
     211             : /*
     212             :  * void_recv    - binary input routine for pseudo-type VOID.
     213             :  *
     214             :  * Note that since we consume no bytes, an attempt to send anything but
     215             :  * an empty string will result in an "invalid message format" error.
     216             :  */
     217             : Datum
     218           0 : void_recv(PG_FUNCTION_ARGS)
     219             : {
     220           0 :     PG_RETURN_VOID();
     221             : }
     222             : 
     223             : /*
     224             :  * void_send    - binary output routine for pseudo-type VOID.
     225             :  *
     226             :  * We allow this so that "SELECT function_returning_void(...)" works
     227             :  * even when binary output is requested.
     228             :  */
     229             : Datum
     230           0 : void_send(PG_FUNCTION_ARGS)
     231             : {
     232             :     StringInfoData buf;
     233             : 
     234             :     /* send an empty string */
     235           0 :     pq_begintypsend(&buf);
     236           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     237             : }
     238             : 
     239             : /*
     240             :  * shell_in     - input routine for "shell" types (those not yet filled in).
     241             :  */
     242             : Datum
     243           0 : shell_in(PG_FUNCTION_ARGS)
     244             : {
     245           0 :     ereport(ERROR,
     246             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     247             :              errmsg("cannot accept a value of a shell type")));
     248             : 
     249             :     PG_RETURN_VOID();           /* keep compiler quiet */
     250             : }
     251             : 
     252             : /*
     253             :  * shell_out        - output routine for "shell" types.
     254             :  */
     255             : Datum
     256           0 : shell_out(PG_FUNCTION_ARGS)
     257             : {
     258           0 :     ereport(ERROR,
     259             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     260             :              errmsg("cannot display a value of a shell type")));
     261             : 
     262             :     PG_RETURN_VOID();           /* keep compiler quiet */
     263             : }
     264             : 
     265             : 
     266             : /*
     267             :  * pg_node_tree_in      - input routine for type PG_NODE_TREE.
     268             :  *
     269             :  * pg_node_tree isn't really a pseudotype --- it's real enough to be a table
     270             :  * column --- but it presently has no operations of its own, and disallows
     271             :  * input too, so its I/O functions seem to fit here as much as anywhere.
     272             :  */
     273             : Datum
     274           0 : pg_node_tree_in(PG_FUNCTION_ARGS)
     275             : {
     276             :     /*
     277             :      * We disallow input of pg_node_tree values because the SQL functions that
     278             :      * operate on the type are not secure against malformed input.
     279             :      */
     280           0 :     ereport(ERROR,
     281             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     282             :              errmsg("cannot accept a value of type %s", "pg_node_tree")));
     283             : 
     284             :     PG_RETURN_VOID();           /* keep compiler quiet */
     285             : }
     286             : 
     287             : 
     288             : /*
     289             :  * pg_node_tree_out     - output routine for type PG_NODE_TREE.
     290             :  *
     291             :  * The internal representation is the same as TEXT, so just pass it off.
     292             :  */
     293             : Datum
     294         524 : pg_node_tree_out(PG_FUNCTION_ARGS)
     295             : {
     296         524 :     return textout(fcinfo);
     297             : }
     298             : 
     299             : /*
     300             :  * pg_node_tree_recv        - binary input routine for type PG_NODE_TREE.
     301             :  */
     302             : Datum
     303           0 : pg_node_tree_recv(PG_FUNCTION_ARGS)
     304             : {
     305           0 :     ereport(ERROR,
     306             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     307             :              errmsg("cannot accept a value of type %s", "pg_node_tree")));
     308             : 
     309             :     PG_RETURN_VOID();           /* keep compiler quiet */
     310             : }
     311             : 
     312             : /*
     313             :  * pg_node_tree_send        - binary output routine for type PG_NODE_TREE.
     314             :  */
     315             : Datum
     316           0 : pg_node_tree_send(PG_FUNCTION_ARGS)
     317             : {
     318           0 :     return textsend(fcinfo);
     319             : }
     320             : 
     321             : /*
     322             :  * pg_ddl_command_in    - input routine for type PG_DDL_COMMAND.
     323             :  *
     324             :  * Like pg_node_tree, pg_ddl_command isn't really a pseudotype; it's here for
     325             :  * the same reasons as that one.
     326             :  */
     327             : Datum
     328           0 : pg_ddl_command_in(PG_FUNCTION_ARGS)
     329             : {
     330             :     /*
     331             :      * Disallow input of pg_ddl_command value.
     332             :      */
     333           0 :     ereport(ERROR,
     334             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     335             :              errmsg("cannot accept a value of type %s", "pg_ddl_command")));
     336             : 
     337             :     PG_RETURN_VOID();           /* keep compiler quiet */
     338             : }
     339             : 
     340             : /*
     341             :  * pg_ddl_command_out       - output routine for type PG_DDL_COMMAND.
     342             :  *
     343             :  * We don't have any good way to output this type directly, so punt.
     344             :  */
     345             : Datum
     346           0 : pg_ddl_command_out(PG_FUNCTION_ARGS)
     347             : {
     348           0 :     ereport(ERROR,
     349             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     350             :              errmsg("cannot output a value of type %s", "pg_ddl_command")));
     351             : 
     352             :     PG_RETURN_VOID();
     353             : }
     354             : 
     355             : /*
     356             :  * pg_ddl_command_recv      - binary input routine for type PG_DDL_COMMAND.
     357             :  */
     358             : Datum
     359           0 : pg_ddl_command_recv(PG_FUNCTION_ARGS)
     360             : {
     361           0 :     ereport(ERROR,
     362             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     363             :              errmsg("cannot accept a value of type %s", "pg_ddl_command")));
     364             : 
     365             :     PG_RETURN_VOID();
     366             : }
     367             : 
     368             : /*
     369             :  * pg_ddl_command_send      - binary output routine for type PG_DDL_COMMAND.
     370             :  */
     371             : Datum
     372           0 : pg_ddl_command_send(PG_FUNCTION_ARGS)
     373             : {
     374           0 :     ereport(ERROR,
     375             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     376             :              errmsg("cannot output a value of type %s", "pg_ddl_command")));
     377             : 
     378             :     PG_RETURN_VOID();
     379             : }
     380             : 
     381             : 
     382             : /*
     383             :  * Generate input and output functions for a pseudotype that will reject all
     384             :  * input and output attempts.
     385             :  */
     386             : #define PSEUDOTYPE_DUMMY_IO_FUNCS(typname) \
     387             : \
     388             : Datum \
     389             : typname##_in(PG_FUNCTION_ARGS) \
     390             : { \
     391             :     ereport(ERROR, \
     392             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
     393             :              errmsg("cannot accept a value of type %s", #typname))); \
     394             : \
     395             :     PG_RETURN_VOID();           /* keep compiler quiet */ \
     396             : } \
     397             : \
     398             : Datum \
     399             : typname##_out(PG_FUNCTION_ARGS) \
     400             : { \
     401             :     ereport(ERROR, \
     402             :             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
     403             :              errmsg("cannot display a value of type %s", #typname))); \
     404             : \
     405             :     PG_RETURN_VOID();           /* keep compiler quiet */ \
     406             : } \
     407             : \
     408             : extern int no_such_variable
     409             : 
     410           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(any);
     411           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(trigger);
     412           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(event_trigger);
     413           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(language_handler);
     414           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(fdw_handler);
     415           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(index_am_handler);
     416           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(tsm_handler);
     417           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(internal);
     418           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(opaque);
     419           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement);
     420           0 : PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray);

Generated by: LCOV version 1.11