LCOV - code coverage report
Current view: top level - src/backend/utils/adt - pg_lsn.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 80 89 89.9 %
Date: 2019-09-22 07:07:17 Functions: 15 17 88.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * pg_lsn.c
       4             :  *    Operations for the pg_lsn datatype.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2019, 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/pg_lsn.h"
      20             : 
      21             : #define MAXPG_LSNLEN            17
      22             : #define MAXPG_LSNCOMPONENT  8
      23             : 
      24             : /*----------------------------------------------------------
      25             :  * Formatting and conversion routines.
      26             :  *---------------------------------------------------------*/
      27             : 
      28             : XLogRecPtr
      29        2830 : pg_lsn_in_internal(const char *str, bool *have_error)
      30             : {
      31             :     int         len1,
      32             :                 len2;
      33             :     uint32      id,
      34             :                 off;
      35             :     XLogRecPtr  result;
      36             : 
      37             :     Assert(have_error != NULL);
      38        2830 :     *have_error = false;
      39             : 
      40             :     /* Sanity check input format. */
      41        2830 :     len1 = strspn(str, "0123456789abcdefABCDEF");
      42        2830 :     if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
      43             :     {
      44          16 :         *have_error = true;
      45          16 :         return InvalidXLogRecPtr;
      46             :     }
      47        2814 :     len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF");
      48        2814 :     if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0')
      49             :     {
      50           4 :         *have_error = true;
      51           4 :         return InvalidXLogRecPtr;
      52             :     }
      53             : 
      54             :     /* Decode result. */
      55        2810 :     id = (uint32) strtoul(str, NULL, 16);
      56        2810 :     off = (uint32) strtoul(str + len1 + 1, NULL, 16);
      57        2810 :     result = ((uint64) id << 32) | off;
      58             : 
      59        2810 :     return result;
      60             : }
      61             : 
      62             : Datum
      63        2828 : pg_lsn_in(PG_FUNCTION_ARGS)
      64             : {
      65        2828 :     char       *str = PG_GETARG_CSTRING(0);
      66             :     XLogRecPtr  result;
      67        2828 :     bool        have_error = false;
      68             : 
      69        2828 :     result = pg_lsn_in_internal(str, &have_error);
      70        2828 :     if (have_error)
      71          20 :         ereport(ERROR,
      72             :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
      73             :                  errmsg("invalid input syntax for type %s: \"%s\"",
      74             :                         "pg_lsn", str)));
      75             : 
      76        2808 :     PG_RETURN_LSN(result);
      77             : }
      78             : 
      79             : Datum
      80        1050 : pg_lsn_out(PG_FUNCTION_ARGS)
      81             : {
      82        1050 :     XLogRecPtr  lsn = PG_GETARG_LSN(0);
      83             :     char        buf[MAXPG_LSNLEN + 1];
      84             :     char       *result;
      85             :     uint32      id,
      86             :                 off;
      87             : 
      88             :     /* Decode ID and offset */
      89        1050 :     id = (uint32) (lsn >> 32);
      90        1050 :     off = (uint32) lsn;
      91             : 
      92        1050 :     snprintf(buf, sizeof buf, "%X/%X", id, off);
      93        1050 :     result = pstrdup(buf);
      94        1050 :     PG_RETURN_CSTRING(result);
      95             : }
      96             : 
      97             : Datum
      98           0 : pg_lsn_recv(PG_FUNCTION_ARGS)
      99             : {
     100           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     101             :     XLogRecPtr  result;
     102             : 
     103           0 :     result = pq_getmsgint64(buf);
     104           0 :     PG_RETURN_LSN(result);
     105             : }
     106             : 
     107             : Datum
     108           0 : pg_lsn_send(PG_FUNCTION_ARGS)
     109             : {
     110           0 :     XLogRecPtr  lsn = PG_GETARG_LSN(0);
     111             :     StringInfoData buf;
     112             : 
     113           0 :     pq_begintypsend(&buf);
     114           0 :     pq_sendint64(&buf, lsn);
     115           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     116             : }
     117             : 
     118             : 
     119             : /*----------------------------------------------------------
     120             :  *  Operators for PostgreSQL LSNs
     121             :  *---------------------------------------------------------*/
     122             : 
     123             : Datum
     124        6246 : pg_lsn_eq(PG_FUNCTION_ARGS)
     125             : {
     126        6246 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     127        6246 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     128             : 
     129        6246 :     PG_RETURN_BOOL(lsn1 == lsn2);
     130             : }
     131             : 
     132             : Datum
     133           6 : pg_lsn_ne(PG_FUNCTION_ARGS)
     134             : {
     135           6 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     136           6 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     137             : 
     138           6 :     PG_RETURN_BOOL(lsn1 != lsn2);
     139             : }
     140             : 
     141             : Datum
     142        2052 : pg_lsn_lt(PG_FUNCTION_ARGS)
     143             : {
     144        2052 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     145        2052 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     146             : 
     147        2052 :     PG_RETURN_BOOL(lsn1 < lsn2);
     148             : }
     149             : 
     150             : Datum
     151        2052 : pg_lsn_gt(PG_FUNCTION_ARGS)
     152             : {
     153        2052 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     154        2052 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     155             : 
     156        2052 :     PG_RETURN_BOOL(lsn1 > lsn2);
     157             : }
     158             : 
     159             : Datum
     160        1758 : pg_lsn_le(PG_FUNCTION_ARGS)
     161             : {
     162        1758 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     163        1758 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     164             : 
     165        1758 :     PG_RETURN_BOOL(lsn1 <= lsn2);
     166             : }
     167             : 
     168             : Datum
     169        1320 : pg_lsn_ge(PG_FUNCTION_ARGS)
     170             : {
     171        1320 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     172        1320 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     173             : 
     174        1320 :     PG_RETURN_BOOL(lsn1 >= lsn2);
     175             : }
     176             : 
     177             : Datum
     178           4 : pg_lsn_larger(PG_FUNCTION_ARGS)
     179             : {
     180           4 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     181           4 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     182             : 
     183           4 :     PG_RETURN_LSN((lsn1 > lsn2) ? lsn1 : lsn2);
     184             : }
     185             : 
     186             : Datum
     187           4 : pg_lsn_smaller(PG_FUNCTION_ARGS)
     188             : {
     189           4 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     190           4 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     191             : 
     192           4 :     PG_RETURN_LSN((lsn1 < lsn2) ? lsn1 : lsn2);
     193             : }
     194             : 
     195             : /* btree index opclass support */
     196             : Datum
     197        9620 : pg_lsn_cmp(PG_FUNCTION_ARGS)
     198             : {
     199        9620 :     XLogRecPtr  a = PG_GETARG_LSN(0);
     200        9620 :     XLogRecPtr  b = PG_GETARG_LSN(1);
     201             : 
     202        9620 :     if (a > b)
     203        4858 :         PG_RETURN_INT32(1);
     204        4762 :     else if (a == b)
     205          72 :         PG_RETURN_INT32(0);
     206             :     else
     207        4690 :         PG_RETURN_INT32(-1);
     208             : }
     209             : 
     210             : /* hash index opclass support */
     211             : Datum
     212        2088 : pg_lsn_hash(PG_FUNCTION_ARGS)
     213             : {
     214             :     /* We can use hashint8 directly */
     215        2088 :     return hashint8(fcinfo);
     216             : }
     217             : 
     218             : Datum
     219          40 : pg_lsn_hash_extended(PG_FUNCTION_ARGS)
     220             : {
     221          40 :     return hashint8extended(fcinfo);
     222             : }
     223             : 
     224             : 
     225             : /*----------------------------------------------------------
     226             :  *  Arithmetic operators on PostgreSQL LSNs.
     227             :  *---------------------------------------------------------*/
     228             : 
     229             : Datum
     230          40 : pg_lsn_mi(PG_FUNCTION_ARGS)
     231             : {
     232          40 :     XLogRecPtr  lsn1 = PG_GETARG_LSN(0);
     233          40 :     XLogRecPtr  lsn2 = PG_GETARG_LSN(1);
     234             :     char        buf[256];
     235             :     Datum       result;
     236             : 
     237             :     /* Output could be as large as plus or minus 2^63 - 1. */
     238          40 :     if (lsn1 < lsn2)
     239          32 :         snprintf(buf, sizeof buf, "-" UINT64_FORMAT, lsn2 - lsn1);
     240             :     else
     241           8 :         snprintf(buf, sizeof buf, UINT64_FORMAT, lsn1 - lsn2);
     242             : 
     243             :     /* Convert to numeric. */
     244          40 :     result = DirectFunctionCall3(numeric_in,
     245             :                                  CStringGetDatum(buf),
     246             :                                  ObjectIdGetDatum(0),
     247             :                                  Int32GetDatum(-1));
     248             : 
     249          40 :     return result;
     250             : }

Generated by: LCOV version 1.13