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

Generated by: LCOV version 1.13