LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - char.c (source / functions) Coverage Total Hit UIC UBC GIC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 81.0 % 84 68 13 3 41 27 13 41
Current Date: 2023-04-08 17:13:01 Functions: 71.4 % 14 10 4 10 4 10
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 81.0 % 84 68 13 3 41 27 13 41
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 35.7 % 28 10 4 10 4 10

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * char.c
                                  4                 :  *    Functions for the built-in type "char" (not to be confused with
                                  5                 :  *    bpchar, which is the SQL CHAR(n) type).
                                  6                 :  *
                                  7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  8                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :  *
                                 10                 :  *
                                 11                 :  * IDENTIFICATION
                                 12                 :  *    src/backend/utils/adt/char.c
                                 13                 :  *
                                 14                 :  *-------------------------------------------------------------------------
                                 15                 :  */
                                 16                 : #include "postgres.h"
                                 17                 : 
                                 18                 : #include <limits.h>
                                 19                 : 
                                 20                 : #include "libpq/pqformat.h"
                                 21                 : #include "utils/builtins.h"
                                 22                 : #include "varatt.h"
                                 23                 : 
                                 24                 : #define ISOCTAL(c)   (((c) >= '0') && ((c) <= '7'))
                                 25                 : #define TOOCTAL(c)   ((c) + '0')
                                 26                 : #define FROMOCTAL(c) ((unsigned char) (c) - '0')
                                 27                 : 
                                 28                 : 
                                 29                 : /*****************************************************************************
                                 30                 :  *   USER I/O ROUTINES                                                       *
                                 31                 :  *****************************************************************************/
                                 32                 : 
                                 33                 : /*
                                 34                 :  *      charin          - converts "x" to 'x'
                                 35                 :  *
                                 36                 :  * This accepts the formats charout produces.  If we have multibyte input
                                 37                 :  * that is not in the form '\ooo', then we take its first byte as the value
                                 38                 :  * and silently discard the rest; this is a backwards-compatibility provision.
                                 39                 :  */
                                 40                 : Datum
 8343 tgl                        41 GIC     4655427 : charin(PG_FUNCTION_ARGS)
 9770 scrappy                    42 ECB             : {
 8343 tgl                        43 GIC     4655427 :     char       *ch = PG_GETARG_CSTRING(0);
 8343 tgl                        44 ECB             : 
  250 tgl                        45 GIC     4655427 :     if (strlen(ch) == 4 && ch[0] == '\\' &&
  250 tgl                        46 CBC          12 :         ISOCTAL(ch[1]) && ISOCTAL(ch[2]) && ISOCTAL(ch[3]))
                                 47              12 :         PG_RETURN_CHAR((FROMOCTAL(ch[1]) << 6) +
  250 tgl                        48 ECB             :                        (FROMOCTAL(ch[2]) << 3) +
                                 49                 :                        FROMOCTAL(ch[3]));
                                 50                 :     /* This will do the right thing for a zero-length input string */
 8343 tgl                        51 GIC     4655415 :     PG_RETURN_CHAR(ch[0]);
 9770 scrappy                    52 ECB             : }
                                 53                 : 
                                 54                 : /*
                                 55                 :  *      charout         - converts 'x' to "x"
                                 56                 :  *
                                 57                 :  * The possible output formats are:
                                 58                 :  * 1. 0x00 is represented as an empty string.
                                 59                 :  * 2. 0x01..0x7F are represented as a single ASCII byte.
                                 60                 :  * 3. 0x80..0xFF are represented as \ooo (backslash and 3 octal digits).
                                 61                 :  * Case 3 is meant to match the traditional "escape" format of bytea.
                                 62                 :  */
                                 63                 : Datum
 8343 tgl                        64 GIC      860899 : charout(PG_FUNCTION_ARGS)
 9770 scrappy                    65 ECB             : {
 8343 tgl                        66 GIC      860899 :     char        ch = PG_GETARG_CHAR(0);
  250 tgl                        67 CBC      860899 :     char       *result = (char *) palloc(5);
 9345 bruce                      68 ECB             : 
  250 tgl                        69 GIC      860899 :     if (IS_HIGHBIT_SET(ch))
  250 tgl                        70 ECB             :     {
  250 tgl                        71 GIC           6 :         result[0] = '\\';
  250 tgl                        72 CBC           6 :         result[1] = TOOCTAL(((unsigned char) ch) >> 6);
                                 73               6 :         result[2] = TOOCTAL((((unsigned char) ch) >> 3) & 07);
                                 74               6 :         result[3] = TOOCTAL(((unsigned char) ch) & 07);
                                 75               6 :         result[4] = '\0';
  250 tgl                        76 ECB             :     }
                                 77                 :     else
                                 78                 :     {
                                 79                 :         /* This produces acceptable results for 0x00 as well */
  250 tgl                        80 GIC      860893 :         result[0] = ch;
  250 tgl                        81 CBC      860893 :         result[1] = '\0';
  250 tgl                        82 ECB             :     }
 8343 tgl                        83 GIC      860899 :     PG_RETURN_CSTRING(result);
 9770 scrappy                    84 ECB             : }
                                 85                 : 
                                 86                 : /*
                                 87                 :  *      charrecv            - converts external binary format to char
                                 88                 :  *
                                 89                 :  * The external representation is one byte, with no character set
                                 90                 :  * conversion.  This is somewhat dubious, perhaps, but in many
                                 91                 :  * cases people use char for a 1-byte binary type.
                                 92                 :  */
                                 93                 : Datum
 7272 tgl                        94 UIC           0 : charrecv(PG_FUNCTION_ARGS)
 7272 tgl                        95 EUB             : {
 7272 tgl                        96 UIC           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
 7272 tgl                        97 EUB             : 
 7272 tgl                        98 UIC           0 :     PG_RETURN_CHAR(pq_getmsgbyte(buf));
 7272 tgl                        99 EUB             : }
                                100                 : 
                                101                 : /*
                                102                 :  *      charsend            - converts char to binary format
                                103                 :  */
                                104                 : Datum
 7272 tgl                       105 UIC           0 : charsend(PG_FUNCTION_ARGS)
 7272 tgl                       106 EUB             : {
 7272 tgl                       107 UIC           0 :     char        arg1 = PG_GETARG_CHAR(0);
 7272 tgl                       108 EUB             :     StringInfoData buf;
                                109                 : 
 7272 tgl                       110 UIC           0 :     pq_begintypsend(&buf);
 7272 tgl                       111 UBC           0 :     pq_sendbyte(&buf, arg1);
                                112               0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
 7272 tgl                       113 EUB             : }
                                114                 : 
                                115                 : /*****************************************************************************
                                116                 :  *   PUBLIC ROUTINES                                                         *
                                117                 :  *****************************************************************************/
                                118                 : 
                                119                 : /*
                                120                 :  * NOTE: comparisons are done as though char is unsigned (uint8).
                                121                 :  * Conversions to and from integer are done as though char is signed (int8).
                                122                 :  *
                                123                 :  * You wanted consistency?
                                124                 :  */
                                125                 : 
                                126                 : Datum
 8343 tgl                       127 GIC     2804213 : chareq(PG_FUNCTION_ARGS)
 8343 tgl                       128 ECB             : {
 8343 tgl                       129 GIC     2804213 :     char        arg1 = PG_GETARG_CHAR(0);
 8343 tgl                       130 CBC     2804213 :     char        arg2 = PG_GETARG_CHAR(1);
 9345 bruce                     131 ECB             : 
 8343 tgl                       132 GIC     2804213 :     PG_RETURN_BOOL(arg1 == arg2);
 9770 scrappy                   133 ECB             : }
                                134                 : 
                                135                 : Datum
 8343 tgl                       136 GIC     1477017 : charne(PG_FUNCTION_ARGS)
 9345 bruce                     137 ECB             : {
 8343 tgl                       138 GIC     1477017 :     char        arg1 = PG_GETARG_CHAR(0);
 8343 tgl                       139 CBC     1477017 :     char        arg2 = PG_GETARG_CHAR(1);
 9345 bruce                     140 ECB             : 
 8343 tgl                       141 GIC     1477017 :     PG_RETURN_BOOL(arg1 != arg2);
 9770 scrappy                   142 ECB             : }
                                143                 : 
                                144                 : Datum
 8343 tgl                       145 GIC        1548 : charlt(PG_FUNCTION_ARGS)
 9345 bruce                     146 ECB             : {
 8343 tgl                       147 GIC        1548 :     char        arg1 = PG_GETARG_CHAR(0);
 8343 tgl                       148 CBC        1548 :     char        arg2 = PG_GETARG_CHAR(1);
 8343 tgl                       149 ECB             : 
 8343 tgl                       150 GIC        1548 :     PG_RETURN_BOOL((uint8) arg1 < (uint8) arg2);
 9345 bruce                     151 ECB             : }
                                152                 : 
                                153                 : Datum
 8343 tgl                       154 GIC        1212 : charle(PG_FUNCTION_ARGS)
 9345 bruce                     155 ECB             : {
 8343 tgl                       156 GIC        1212 :     char        arg1 = PG_GETARG_CHAR(0);
 8343 tgl                       157 CBC        1212 :     char        arg2 = PG_GETARG_CHAR(1);
 8343 tgl                       158 ECB             : 
 8343 tgl                       159 GIC        1212 :     PG_RETURN_BOOL((uint8) arg1 <= (uint8) arg2);
 9345 bruce                     160 ECB             : }
                                161                 : 
                                162                 : Datum
 8343 tgl                       163 GIC        1521 : chargt(PG_FUNCTION_ARGS)
 9345 bruce                     164 ECB             : {
 8343 tgl                       165 GIC        1521 :     char        arg1 = PG_GETARG_CHAR(0);
 8343 tgl                       166 CBC        1521 :     char        arg2 = PG_GETARG_CHAR(1);
 8343 tgl                       167 ECB             : 
 8343 tgl                       168 GIC        1521 :     PG_RETURN_BOOL((uint8) arg1 > (uint8) arg2);
 9345 bruce                     169 ECB             : }
                                170                 : 
                                171                 : Datum
 8343 tgl                       172 GIC        1065 : charge(PG_FUNCTION_ARGS)
 9345 bruce                     173 ECB             : {
 8343 tgl                       174 GIC        1065 :     char        arg1 = PG_GETARG_CHAR(0);
 8343 tgl                       175 CBC        1065 :     char        arg2 = PG_GETARG_CHAR(1);
 8343 tgl                       176 ECB             : 
 8343 tgl                       177 GIC        1065 :     PG_RETURN_BOOL((uint8) arg1 >= (uint8) arg2);
 9345 bruce                     178 ECB             : }
                                179                 : 
                                180                 : 
                                181                 : Datum
 6761 tgl                       182 UIC           0 : chartoi4(PG_FUNCTION_ARGS)
 9345 bruce                     183 EUB             : {
 8343 tgl                       184 UIC           0 :     char        arg1 = PG_GETARG_CHAR(0);
 8343 tgl                       185 EUB             : 
 6761 tgl                       186 UIC           0 :     PG_RETURN_INT32((int32) ((int8) arg1));
 9345 bruce                     187 EUB             : }
                                188                 : 
                                189                 : Datum
 6761 tgl                       190 UIC           0 : i4tochar(PG_FUNCTION_ARGS)
 9345 bruce                     191 EUB             : {
 6761 tgl                       192 UIC           0 :     int32       arg1 = PG_GETARG_INT32(0);
 8343 tgl                       193 EUB             : 
 6761 tgl                       194 UIC           0 :     if (arg1 < SCHAR_MIN || arg1 > SCHAR_MAX)
 7196 tgl                       195 UBC           0 :         ereport(ERROR,
 6761 tgl                       196 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                197                 :                  errmsg("\"char\" out of range")));
                                198                 : 
 6761 tgl                       199 UIC           0 :     PG_RETURN_CHAR((int8) arg1);
 9345 bruce                     200 EUB             : }
                                201                 : 
                                202                 : 
                                203                 : Datum
 8343 tgl                       204 GIC       38849 : text_char(PG_FUNCTION_ARGS)
 9345 bruce                     205 ECB             : {
 2219 noah                      206 GIC       38849 :     text       *arg1 = PG_GETARG_TEXT_PP(0);
  250 tgl                       207 CBC       38849 :     char       *ch = VARDATA_ANY(arg1);
 7986 tgl                       208 ECB             :     char        result;
                                209                 : 
                                210                 :     /*
                                211                 :      * Conversion rules are the same as in charin(), but here we need to
                                212                 :      * handle the empty-string case honestly.
                                213                 :      */
  250 tgl                       214 GIC       38849 :     if (VARSIZE_ANY_EXHDR(arg1) == 4 && ch[0] == '\\' &&
  250 tgl                       215 CBC           3 :         ISOCTAL(ch[1]) && ISOCTAL(ch[2]) && ISOCTAL(ch[3]))
                                216               3 :         result = (FROMOCTAL(ch[1]) << 6) +
                                217               3 :             (FROMOCTAL(ch[2]) << 3) +
                                218               3 :             FROMOCTAL(ch[3]);
                                219           38846 :     else if (VARSIZE_ANY_EXHDR(arg1) > 0)
                                220           38843 :         result = ch[0];
 7986 tgl                       221 ECB             :     else
 7986 tgl                       222 GIC           3 :         result = '\0';
 7986 tgl                       223 ECB             : 
 7986 tgl                       224 GIC       38849 :     PG_RETURN_CHAR(result);
 9345 bruce                     225 ECB             : }
                                226                 : 
                                227                 : Datum
 8343 tgl                       228 GIC       15422 : char_text(PG_FUNCTION_ARGS)
 9345 bruce                     229 ECB             : {
 8343 tgl                       230 GIC       15422 :     char        arg1 = PG_GETARG_CHAR(0);
  250 tgl                       231 CBC       15422 :     text       *result = palloc(VARHDRSZ + 4);
 8343 tgl                       232 ECB             : 
                                233                 :     /*
                                234                 :      * Conversion rules are the same as in charout(), but here we need to be
                                235                 :      * honest about converting 0x00 to an empty string.
                                236                 :      */
  250 tgl                       237 GIC       15422 :     if (IS_HIGHBIT_SET(arg1))
  250 tgl                       238 ECB             :     {
  250 tgl                       239 GIC           3 :         SET_VARSIZE(result, VARHDRSZ + 4);
  250 tgl                       240 CBC           3 :         (VARDATA(result))[0] = '\\';
                                241               3 :         (VARDATA(result))[1] = TOOCTAL(((unsigned char) arg1) >> 6);
                                242               3 :         (VARDATA(result))[2] = TOOCTAL((((unsigned char) arg1) >> 3) & 07);
                                243               3 :         (VARDATA(result))[3] = TOOCTAL(((unsigned char) arg1) & 07);
  250 tgl                       244 ECB             :     }
  250 tgl                       245 GIC       15419 :     else if (arg1 != '\0')
 7986 tgl                       246 ECB             :     {
 5885 tgl                       247 GIC       15416 :         SET_VARSIZE(result, VARHDRSZ + 1);
 7986 tgl                       248 CBC       15416 :         *(VARDATA(result)) = arg1;
 7986 tgl                       249 ECB             :     }
                                250                 :     else
 5885 tgl                       251 GIC           3 :         SET_VARSIZE(result, VARHDRSZ);
 8343 tgl                       252 ECB             : 
 8343 tgl                       253 GIC       15422 :     PG_RETURN_TEXT_P(result);
 9345 bruce                     254 ECB             : }
        

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