LCOV - code coverage report
Current view: top level - src/backend/utils/adt - xid.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 82 116 70.7 %
Date: 2020-06-01 10:07:15 Functions: 18 26 69.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * xid.c
       4             :  *    POSTGRES transaction identifier and command identifier datatypes.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/utils/adt/xid.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include <limits.h>
      18             : 
      19             : #include "access/multixact.h"
      20             : #include "access/transam.h"
      21             : #include "access/xact.h"
      22             : #include "libpq/pqformat.h"
      23             : #include "utils/builtins.h"
      24             : #include "utils/xid8.h"
      25             : 
      26             : #define PG_GETARG_TRANSACTIONID(n)  DatumGetTransactionId(PG_GETARG_DATUM(n))
      27             : #define PG_RETURN_TRANSACTIONID(x)  return TransactionIdGetDatum(x)
      28             : 
      29             : #define PG_GETARG_COMMANDID(n)      DatumGetCommandId(PG_GETARG_DATUM(n))
      30             : #define PG_RETURN_COMMANDID(x)      return CommandIdGetDatum(x)
      31             : 
      32             : 
      33             : Datum
      34        6660 : xidin(PG_FUNCTION_ARGS)
      35             : {
      36        6660 :     char       *str = PG_GETARG_CSTRING(0);
      37             : 
      38        6660 :     PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0));
      39             : }
      40             : 
      41             : Datum
      42       90722 : xidout(PG_FUNCTION_ARGS)
      43             : {
      44       90722 :     TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
      45       90722 :     char       *result = (char *) palloc(16);
      46             : 
      47       90722 :     snprintf(result, 16, "%lu", (unsigned long) transactionId);
      48       90722 :     PG_RETURN_CSTRING(result);
      49             : }
      50             : 
      51             : /*
      52             :  *      xidrecv         - converts external binary format to xid
      53             :  */
      54             : Datum
      55           0 : xidrecv(PG_FUNCTION_ARGS)
      56             : {
      57           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      58             : 
      59           0 :     PG_RETURN_TRANSACTIONID((TransactionId) pq_getmsgint(buf, sizeof(TransactionId)));
      60             : }
      61             : 
      62             : /*
      63             :  *      xidsend         - converts xid to binary format
      64             :  */
      65             : Datum
      66           0 : xidsend(PG_FUNCTION_ARGS)
      67             : {
      68           0 :     TransactionId arg1 = PG_GETARG_TRANSACTIONID(0);
      69             :     StringInfoData buf;
      70             : 
      71           0 :     pq_begintypsend(&buf);
      72           0 :     pq_sendint32(&buf, arg1);
      73           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
      74             : }
      75             : 
      76             : /*
      77             :  *      xideq           - are two xids equal?
      78             :  */
      79             : Datum
      80      748848 : xideq(PG_FUNCTION_ARGS)
      81             : {
      82      748848 :     TransactionId xid1 = PG_GETARG_TRANSACTIONID(0);
      83      748848 :     TransactionId xid2 = PG_GETARG_TRANSACTIONID(1);
      84             : 
      85      748848 :     PG_RETURN_BOOL(TransactionIdEquals(xid1, xid2));
      86             : }
      87             : 
      88             : /*
      89             :  *      xidneq          - are two xids different?
      90             :  */
      91             : Datum
      92         810 : xidneq(PG_FUNCTION_ARGS)
      93             : {
      94         810 :     TransactionId xid1 = PG_GETARG_TRANSACTIONID(0);
      95         810 :     TransactionId xid2 = PG_GETARG_TRANSACTIONID(1);
      96             : 
      97         810 :     PG_RETURN_BOOL(!TransactionIdEquals(xid1, xid2));
      98             : }
      99             : 
     100             : /*
     101             :  *      xid_age         - compute age of an XID (relative to latest stable xid)
     102             :  */
     103             : Datum
     104         216 : xid_age(PG_FUNCTION_ARGS)
     105             : {
     106         216 :     TransactionId xid = PG_GETARG_TRANSACTIONID(0);
     107         216 :     TransactionId now = GetStableLatestTransactionId();
     108             : 
     109             :     /* Permanent XIDs are always infinitely old */
     110         216 :     if (!TransactionIdIsNormal(xid))
     111           0 :         PG_RETURN_INT32(INT_MAX);
     112             : 
     113         216 :     PG_RETURN_INT32((int32) (now - xid));
     114             : }
     115             : 
     116             : /*
     117             :  *      mxid_age            - compute age of a multi XID (relative to latest stable mxid)
     118             :  */
     119             : Datum
     120           2 : mxid_age(PG_FUNCTION_ARGS)
     121             : {
     122           2 :     TransactionId xid = PG_GETARG_TRANSACTIONID(0);
     123           2 :     MultiXactId now = ReadNextMultiXactId();
     124             : 
     125           2 :     if (!MultiXactIdIsValid(xid))
     126           0 :         PG_RETURN_INT32(INT_MAX);
     127             : 
     128           2 :     PG_RETURN_INT32((int32) (now - xid));
     129             : }
     130             : 
     131             : /*
     132             :  * xidComparator
     133             :  *      qsort comparison function for XIDs
     134             :  *
     135             :  * We can't use wraparound comparison for XIDs because that does not respect
     136             :  * the triangle inequality!  Any old sort order will do.
     137             :  */
     138             : int
     139       40696 : xidComparator(const void *arg1, const void *arg2)
     140             : {
     141       40696 :     TransactionId xid1 = *(const TransactionId *) arg1;
     142       40696 :     TransactionId xid2 = *(const TransactionId *) arg2;
     143             : 
     144       40696 :     if (xid1 > xid2)
     145        7632 :         return 1;
     146       33064 :     if (xid1 < xid2)
     147       27838 :         return -1;
     148        5226 :     return 0;
     149             : }
     150             : 
     151             : Datum
     152        1034 : xid8toxid(PG_FUNCTION_ARGS)
     153             : {
     154        1034 :     FullTransactionId fxid = PG_GETARG_FULLTRANSACTIONID(0);
     155             : 
     156        1034 :     PG_RETURN_TRANSACTIONID(XidFromFullTransactionId(fxid));
     157             : }
     158             : 
     159             : Datum
     160         548 : xid8in(PG_FUNCTION_ARGS)
     161             : {
     162         548 :     char       *str = PG_GETARG_CSTRING(0);
     163             : 
     164         548 :     PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(pg_strtouint64(str, NULL, 0)));
     165             : }
     166             : 
     167             : Datum
     168         490 : xid8out(PG_FUNCTION_ARGS)
     169             : {
     170         490 :     FullTransactionId fxid = PG_GETARG_FULLTRANSACTIONID(0);
     171         490 :     char       *result = (char *) palloc(21);
     172             : 
     173         490 :     snprintf(result, 21, UINT64_FORMAT, U64FromFullTransactionId(fxid));
     174         490 :     PG_RETURN_CSTRING(result);
     175             : }
     176             : 
     177             : Datum
     178           0 : xid8recv(PG_FUNCTION_ARGS)
     179             : {
     180           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     181             :     uint64      value;
     182             : 
     183           0 :     value = (uint64) pq_getmsgint64(buf);
     184           0 :     PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(value));
     185             : }
     186             : 
     187             : Datum
     188           0 : xid8send(PG_FUNCTION_ARGS)
     189             : {
     190           0 :     FullTransactionId arg1 = PG_GETARG_FULLTRANSACTIONID(0);
     191             :     StringInfoData buf;
     192             : 
     193           0 :     pq_begintypsend(&buf);
     194           0 :     pq_sendint64(&buf, (uint64) U64FromFullTransactionId(arg1));
     195           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     196             : }
     197             : 
     198             : Datum
     199          14 : xid8eq(PG_FUNCTION_ARGS)
     200             : {
     201          14 :     FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
     202          14 :     FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
     203             : 
     204          14 :     PG_RETURN_BOOL(FullTransactionIdEquals(fxid1, fxid2));
     205             : }
     206             : 
     207             : Datum
     208           6 : xid8ne(PG_FUNCTION_ARGS)
     209             : {
     210           6 :     FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
     211           6 :     FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
     212             : 
     213           6 :     PG_RETURN_BOOL(!FullTransactionIdEquals(fxid1, fxid2));
     214             : }
     215             : 
     216             : Datum
     217          12 : xid8lt(PG_FUNCTION_ARGS)
     218             : {
     219          12 :     FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
     220          12 :     FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
     221             : 
     222          12 :     PG_RETURN_BOOL(FullTransactionIdPrecedes(fxid1, fxid2));
     223             : }
     224             : 
     225             : Datum
     226          12 : xid8gt(PG_FUNCTION_ARGS)
     227             : {
     228          12 :     FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
     229          12 :     FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
     230             : 
     231          12 :     PG_RETURN_BOOL(FullTransactionIdFollows(fxid1, fxid2));
     232             : }
     233             : 
     234             : Datum
     235          12 : xid8le(PG_FUNCTION_ARGS)
     236             : {
     237          12 :     FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
     238          12 :     FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
     239             : 
     240          12 :     PG_RETURN_BOOL(FullTransactionIdPrecedesOrEquals(fxid1, fxid2));
     241             : }
     242             : 
     243             : Datum
     244          16 : xid8ge(PG_FUNCTION_ARGS)
     245             : {
     246          16 :     FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
     247          16 :     FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
     248             : 
     249          16 :     PG_RETURN_BOOL(FullTransactionIdFollowsOrEquals(fxid1, fxid2));
     250             : }
     251             : 
     252             : Datum
     253          12 : xid8cmp(PG_FUNCTION_ARGS)
     254             : {
     255          12 :     FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
     256          12 :     FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
     257             : 
     258          12 :     if (FullTransactionIdFollows(fxid1, fxid2))
     259           4 :         PG_RETURN_INT32(1);
     260           8 :     else if (FullTransactionIdEquals(fxid1, fxid2))
     261           4 :         PG_RETURN_INT32(0);
     262             :     else
     263           4 :         PG_RETURN_INT32(-1);
     264             : }
     265             : 
     266             : /*****************************************************************************
     267             :  *   COMMAND IDENTIFIER ROUTINES                                             *
     268             :  *****************************************************************************/
     269             : 
     270             : /*
     271             :  *      cidin   - converts CommandId to internal representation.
     272             :  */
     273             : Datum
     274           0 : cidin(PG_FUNCTION_ARGS)
     275             : {
     276           0 :     char       *str = PG_GETARG_CSTRING(0);
     277             : 
     278           0 :     PG_RETURN_COMMANDID((CommandId) strtoul(str, NULL, 0));
     279             : }
     280             : 
     281             : /*
     282             :  *      cidout  - converts a cid to external representation.
     283             :  */
     284             : Datum
     285         124 : cidout(PG_FUNCTION_ARGS)
     286             : {
     287         124 :     CommandId   c = PG_GETARG_COMMANDID(0);
     288         124 :     char       *result = (char *) palloc(16);
     289             : 
     290         124 :     snprintf(result, 16, "%lu", (unsigned long) c);
     291         124 :     PG_RETURN_CSTRING(result);
     292             : }
     293             : 
     294             : /*
     295             :  *      cidrecv         - converts external binary format to cid
     296             :  */
     297             : Datum
     298           0 : cidrecv(PG_FUNCTION_ARGS)
     299             : {
     300           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     301             : 
     302           0 :     PG_RETURN_COMMANDID((CommandId) pq_getmsgint(buf, sizeof(CommandId)));
     303             : }
     304             : 
     305             : /*
     306             :  *      cidsend         - converts cid to binary format
     307             :  */
     308             : Datum
     309           0 : cidsend(PG_FUNCTION_ARGS)
     310             : {
     311           0 :     CommandId   arg1 = PG_GETARG_COMMANDID(0);
     312             :     StringInfoData buf;
     313             : 
     314           0 :     pq_begintypsend(&buf);
     315           0 :     pq_sendint32(&buf, arg1);
     316           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     317             : }
     318             : 
     319             : Datum
     320           0 : cideq(PG_FUNCTION_ARGS)
     321             : {
     322           0 :     CommandId   arg1 = PG_GETARG_COMMANDID(0);
     323           0 :     CommandId   arg2 = PG_GETARG_COMMANDID(1);
     324             : 
     325           0 :     PG_RETURN_BOOL(arg1 == arg2);
     326             : }

Generated by: LCOV version 1.13