LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - pg_lsn.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 91.5 % 106 97 9 1 96 1
Current Date: 2023-04-08 15:15:32 Functions: 89.5 % 19 17 2 1 16
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * pg_lsn.c
       4                 :  *    Operations for the pg_lsn datatype.
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       7                 :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :  *
       9                 :  * IDENTIFICATION
      10                 :  *    src/backend/utils/adt/pg_lsn.c
      11                 :  *
      12                 :  *-------------------------------------------------------------------------
      13                 :  */
      14                 : #include "postgres.h"
      15                 : 
      16                 : #include "funcapi.h"
      17                 : #include "libpq/pqformat.h"
      18                 : #include "utils/builtins.h"
      19                 : #include "utils/numeric.h"
      20                 : #include "utils/pg_lsn.h"
      21                 : 
      22                 : #define MAXPG_LSNLEN            17
      23                 : #define MAXPG_LSNCOMPONENT  8
      24                 : 
      25                 : /*----------------------------------------------------------
      26                 :  * Formatting and conversion routines.
      27                 :  *---------------------------------------------------------*/
      28                 : 
      29                 : XLogRecPtr
      30 CBC        3532 : pg_lsn_in_internal(const char *str, bool *have_error)
      31                 : {
      32                 :     int         len1,
      33                 :                 len2;
      34                 :     uint32      id,
      35                 :                 off;
      36                 :     XLogRecPtr  result;
      37                 : 
      38            3532 :     Assert(have_error != NULL);
      39            3532 :     *have_error = false;
      40                 : 
      41                 :     /* Sanity check input format. */
      42            3532 :     len1 = strspn(str, "0123456789abcdefABCDEF");
      43            3532 :     if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
      44                 :     {
      45              18 :         *have_error = true;
      46              18 :         return InvalidXLogRecPtr;
      47                 :     }
      48            3514 :     len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF");
      49            3514 :     if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0')
      50                 :     {
      51               3 :         *have_error = true;
      52               3 :         return InvalidXLogRecPtr;
      53                 :     }
      54                 : 
      55                 :     /* Decode result. */
      56            3511 :     id = (uint32) strtoul(str, NULL, 16);
      57            3511 :     off = (uint32) strtoul(str + len1 + 1, NULL, 16);
      58            3511 :     result = ((uint64) id << 32) | off;
      59                 : 
      60            3511 :     return result;
      61                 : }
      62                 : 
      63                 : Datum
      64            3531 : pg_lsn_in(PG_FUNCTION_ARGS)
      65                 : {
      66            3531 :     char       *str = PG_GETARG_CSTRING(0);
      67                 :     XLogRecPtr  result;
      68            3531 :     bool        have_error = false;
      69                 : 
      70            3531 :     result = pg_lsn_in_internal(str, &have_error);
      71            3531 :     if (have_error)
      72 GNC          21 :         ereturn(fcinfo->context, (Datum) 0,
      73                 :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
      74                 :                  errmsg("invalid input syntax for type %s: \"%s\"",
      75                 :                         "pg_lsn", str)));
      76                 : 
      77 CBC        3510 :     PG_RETURN_LSN(result);
      78                 : }
      79                 : 
      80                 : Datum
      81            2417 : pg_lsn_out(PG_FUNCTION_ARGS)
      82                 : {
      83            2417 :     XLogRecPtr  lsn = PG_GETARG_LSN(0);
      84                 :     char        buf[MAXPG_LSNLEN + 1];
      85                 :     char       *result;
      86                 : 
      87            2417 :     snprintf(buf, sizeof buf, "%X/%X", LSN_FORMAT_ARGS(lsn));
      88            2417 :     result = pstrdup(buf);
      89            2417 :     PG_RETURN_CSTRING(result);
      90                 : }
      91                 : 
      92                 : Datum
      93 UBC           0 : pg_lsn_recv(PG_FUNCTION_ARGS)
      94                 : {
      95               0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      96                 :     XLogRecPtr  result;
      97                 : 
      98               0 :     result = pq_getmsgint64(buf);
      99               0 :     PG_RETURN_LSN(result);
     100                 : }
     101                 : 
     102                 : Datum
     103               0 : pg_lsn_send(PG_FUNCTION_ARGS)
     104                 : {
     105               0 :     XLogRecPtr  lsn = PG_GETARG_LSN(0);
     106                 :     StringInfoData buf;
     107                 : 
     108               0 :     pq_begintypsend(&buf);
     109               0 :     pq_sendint64(&buf, lsn);
     110               0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     111                 : }
     112                 : 
     113                 : 
     114                 : /*----------------------------------------------------------
     115                 :  *  Operators for PostgreSQL LSNs
     116                 :  *---------------------------------------------------------*/
     117                 : 
     118                 : Datum
     119 CBC       22538 : pg_lsn_eq(PG_FUNCTION_ARGS)
     120                 : {
     121           22538 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     122           22538 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     123                 : 
     124           22538 :     PG_RETURN_BOOL(lsn1 == lsn2);
     125                 : }
     126                 : 
     127                 : Datum
     128               6 : pg_lsn_ne(PG_FUNCTION_ARGS)
     129                 : {
     130               6 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     131               6 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     132                 : 
     133               6 :     PG_RETURN_BOOL(lsn1 != lsn2);
     134                 : }
     135                 : 
     136                 : Datum
     137           67423 : pg_lsn_lt(PG_FUNCTION_ARGS)
     138                 : {
     139           67423 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     140           67423 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     141                 : 
     142           67423 :     PG_RETURN_BOOL(lsn1 < lsn2);
     143                 : }
     144                 : 
     145                 : Datum
     146            2233 : pg_lsn_gt(PG_FUNCTION_ARGS)
     147                 : {
     148            2233 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     149            2233 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     150                 : 
     151            2233 :     PG_RETURN_BOOL(lsn1 > lsn2);
     152                 : }
     153                 : 
     154                 : Datum
     155            2403 : pg_lsn_le(PG_FUNCTION_ARGS)
     156                 : {
     157            2403 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     158            2403 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     159                 : 
     160            2403 :     PG_RETURN_BOOL(lsn1 <= lsn2);
     161                 : }
     162                 : 
     163                 : Datum
     164            1689 : pg_lsn_ge(PG_FUNCTION_ARGS)
     165                 : {
     166            1689 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     167            1689 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     168                 : 
     169            1689 :     PG_RETURN_BOOL(lsn1 >= lsn2);
     170                 : }
     171                 : 
     172                 : Datum
     173               3 : pg_lsn_larger(PG_FUNCTION_ARGS)
     174                 : {
     175               3 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     176               3 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     177                 : 
     178               3 :     PG_RETURN_LSN((lsn1 > lsn2) ? lsn1 : lsn2);
     179                 : }
     180                 : 
     181                 : Datum
     182               3 : pg_lsn_smaller(PG_FUNCTION_ARGS)
     183                 : {
     184               3 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     185               3 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     186                 : 
     187               3 :     PG_RETURN_LSN((lsn1 < lsn2) ? lsn1 : lsn2);
     188                 : }
     189                 : 
     190                 : /* btree index opclass support */
     191                 : Datum
     192            1968 : pg_lsn_cmp(PG_FUNCTION_ARGS)
     193                 : {
     194            1968 :     XLogRecPtr  a = PG_GETARG_LSN(0);
     195            1968 :     XLogRecPtr  b = PG_GETARG_LSN(1);
     196                 : 
     197            1968 :     if (a > b)
     198            1091 :         PG_RETURN_INT32(1);
     199             877 :     else if (a == b)
     200               7 :         PG_RETURN_INT32(0);
     201                 :     else
     202             870 :         PG_RETURN_INT32(-1);
     203                 : }
     204                 : 
     205                 : /* hash index opclass support */
     206                 : Datum
     207            2655 : pg_lsn_hash(PG_FUNCTION_ARGS)
     208                 : {
     209                 :     /* We can use hashint8 directly */
     210            2655 :     return hashint8(fcinfo);
     211                 : }
     212                 : 
     213                 : Datum
     214              30 : pg_lsn_hash_extended(PG_FUNCTION_ARGS)
     215                 : {
     216              30 :     return hashint8extended(fcinfo);
     217                 : }
     218                 : 
     219                 : 
     220                 : /*----------------------------------------------------------
     221                 :  *  Arithmetic operators on PostgreSQL LSNs.
     222                 :  *---------------------------------------------------------*/
     223                 : 
     224                 : Datum
     225            1081 : pg_lsn_mi(PG_FUNCTION_ARGS)
     226                 : {
     227            1081 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     228            1081 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     229                 :     char        buf[256];
     230                 :     Datum       result;
     231                 : 
     232                 :     /* Output could be as large as plus or minus 2^63 - 1. */
     233            1081 :     if (lsn1 < lsn2)
     234              12 :         snprintf(buf, sizeof buf, "-" UINT64_FORMAT, lsn2 - lsn1);
     235                 :     else
     236            1069 :         snprintf(buf, sizeof buf, UINT64_FORMAT, lsn1 - lsn2);
     237                 : 
     238                 :     /* Convert to numeric. */
     239            1081 :     result = DirectFunctionCall3(numeric_in,
     240                 :                                  CStringGetDatum(buf),
     241                 :                                  ObjectIdGetDatum(0),
     242                 :                                  Int32GetDatum(-1));
     243                 : 
     244            1081 :     return result;
     245                 : }
     246                 : 
     247                 : /*
     248                 :  * Add the number of bytes to pg_lsn, giving a new pg_lsn.
     249                 :  * Must handle both positive and negative numbers of bytes.
     250                 :  */
     251                 : Datum
     252              18 : pg_lsn_pli(PG_FUNCTION_ARGS)
     253                 : {
     254              18 :     XLogRecPtr  lsn = PG_GETARG_LSN(0);
     255              18 :     Numeric     nbytes = PG_GETARG_NUMERIC(1);
     256                 :     Datum       num;
     257                 :     Datum       res;
     258                 :     char        buf[32];
     259                 : 
     260              18 :     if (numeric_is_nan(nbytes))
     261               3 :         ereport(ERROR,
     262                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     263                 :                  errmsg("cannot add NaN to pg_lsn")));
     264                 : 
     265                 :     /* Convert to numeric */
     266              15 :     snprintf(buf, sizeof(buf), UINT64_FORMAT, lsn);
     267              15 :     num = DirectFunctionCall3(numeric_in,
     268                 :                               CStringGetDatum(buf),
     269                 :                               ObjectIdGetDatum(0),
     270                 :                               Int32GetDatum(-1));
     271                 : 
     272                 :     /* Add two numerics */
     273              15 :     res = DirectFunctionCall2(numeric_add,
     274                 :                               num,
     275                 :                               NumericGetDatum(nbytes));
     276                 : 
     277                 :     /* Convert to pg_lsn */
     278              15 :     return DirectFunctionCall1(numeric_pg_lsn, res);
     279                 : }
     280                 : 
     281                 : /*
     282                 :  * Subtract the number of bytes from pg_lsn, giving a new pg_lsn.
     283                 :  * Must handle both positive and negative numbers of bytes.
     284                 :  */
     285                 : Datum
     286              15 : pg_lsn_mii(PG_FUNCTION_ARGS)
     287                 : {
     288              15 :     XLogRecPtr  lsn = PG_GETARG_LSN(0);
     289              15 :     Numeric     nbytes = PG_GETARG_NUMERIC(1);
     290                 :     Datum       num;
     291                 :     Datum       res;
     292                 :     char        buf[32];
     293                 : 
     294              15 :     if (numeric_is_nan(nbytes))
     295               3 :         ereport(ERROR,
     296                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     297                 :                  errmsg("cannot subtract NaN from pg_lsn")));
     298                 : 
     299                 :     /* Convert to numeric */
     300              12 :     snprintf(buf, sizeof(buf), UINT64_FORMAT, lsn);
     301              12 :     num = DirectFunctionCall3(numeric_in,
     302                 :                               CStringGetDatum(buf),
     303                 :                               ObjectIdGetDatum(0),
     304                 :                               Int32GetDatum(-1));
     305                 : 
     306                 :     /* Subtract two numerics */
     307              12 :     res = DirectFunctionCall2(numeric_sub,
     308                 :                               num,
     309                 :                               NumericGetDatum(nbytes));
     310                 : 
     311                 :     /* Convert to pg_lsn */
     312              12 :     return DirectFunctionCall1(numeric_pg_lsn, res);
     313                 : }
        

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