Header And Logo

PostgreSQL
| The world's most advanced open source database.

xid.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * xid.c
00004  *    POSTGRES transaction identifier and command identifier datatypes.
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  *
00010  * IDENTIFICATION
00011  *    src/backend/utils/adt/xid.c
00012  *
00013  *-------------------------------------------------------------------------
00014  */
00015 #include "postgres.h"
00016 
00017 #include <limits.h>
00018 
00019 #include "access/transam.h"
00020 #include "access/xact.h"
00021 #include "libpq/pqformat.h"
00022 #include "utils/builtins.h"
00023 
00024 #define PG_GETARG_TRANSACTIONID(n)  DatumGetTransactionId(PG_GETARG_DATUM(n))
00025 #define PG_RETURN_TRANSACTIONID(x)  return TransactionIdGetDatum(x)
00026 
00027 #define PG_GETARG_COMMANDID(n)      DatumGetCommandId(PG_GETARG_DATUM(n))
00028 #define PG_RETURN_COMMANDID(x)      return CommandIdGetDatum(x)
00029 
00030 
00031 Datum
00032 xidin(PG_FUNCTION_ARGS)
00033 {
00034     char       *str = PG_GETARG_CSTRING(0);
00035 
00036     PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0));
00037 }
00038 
00039 Datum
00040 xidout(PG_FUNCTION_ARGS)
00041 {
00042     TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
00043 
00044     /* maximum 32 bit unsigned integer representation takes 10 chars */
00045     char       *str = palloc(11);
00046 
00047     snprintf(str, 11, "%lu", (unsigned long) transactionId);
00048 
00049     PG_RETURN_CSTRING(str);
00050 }
00051 
00052 /*
00053  *      xidrecv         - converts external binary format to xid
00054  */
00055 Datum
00056 xidrecv(PG_FUNCTION_ARGS)
00057 {
00058     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
00059 
00060     PG_RETURN_TRANSACTIONID((TransactionId) pq_getmsgint(buf, sizeof(TransactionId)));
00061 }
00062 
00063 /*
00064  *      xidsend         - converts xid to binary format
00065  */
00066 Datum
00067 xidsend(PG_FUNCTION_ARGS)
00068 {
00069     TransactionId arg1 = PG_GETARG_TRANSACTIONID(0);
00070     StringInfoData buf;
00071 
00072     pq_begintypsend(&buf);
00073     pq_sendint(&buf, arg1, sizeof(arg1));
00074     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00075 }
00076 
00077 /*
00078  *      xideq           - are two xids equal?
00079  */
00080 Datum
00081 xideq(PG_FUNCTION_ARGS)
00082 {
00083     TransactionId xid1 = PG_GETARG_TRANSACTIONID(0);
00084     TransactionId xid2 = PG_GETARG_TRANSACTIONID(1);
00085 
00086     PG_RETURN_BOOL(TransactionIdEquals(xid1, xid2));
00087 }
00088 
00089 /*
00090  *      xid_age         - compute age of an XID (relative to latest stable xid)
00091  */
00092 Datum
00093 xid_age(PG_FUNCTION_ARGS)
00094 {
00095     TransactionId xid = PG_GETARG_TRANSACTIONID(0);
00096     TransactionId now = GetStableLatestTransactionId();
00097 
00098     /* Permanent XIDs are always infinitely old */
00099     if (!TransactionIdIsNormal(xid))
00100         PG_RETURN_INT32(INT_MAX);
00101 
00102     PG_RETURN_INT32((int32) (now - xid));
00103 }
00104 
00105 /*
00106  * xidComparator
00107  *      qsort comparison function for XIDs
00108  *
00109  * We can't use wraparound comparison for XIDs because that does not respect
00110  * the triangle inequality!  Any old sort order will do.
00111  */
00112 int
00113 xidComparator(const void *arg1, const void *arg2)
00114 {
00115     TransactionId xid1 = *(const TransactionId *) arg1;
00116     TransactionId xid2 = *(const TransactionId *) arg2;
00117 
00118     if (xid1 > xid2)
00119         return 1;
00120     if (xid1 < xid2)
00121         return -1;
00122     return 0;
00123 }
00124 
00125 /*****************************************************************************
00126  *   COMMAND IDENTIFIER ROUTINES                                             *
00127  *****************************************************************************/
00128 
00129 /*
00130  *      cidin   - converts CommandId to internal representation.
00131  */
00132 Datum
00133 cidin(PG_FUNCTION_ARGS)
00134 {
00135     char       *s = PG_GETARG_CSTRING(0);
00136     CommandId   c;
00137 
00138     c = atoi(s);
00139 
00140     PG_RETURN_COMMANDID(c);
00141 }
00142 
00143 /*
00144  *      cidout  - converts a cid to external representation.
00145  */
00146 Datum
00147 cidout(PG_FUNCTION_ARGS)
00148 {
00149     CommandId   c = PG_GETARG_COMMANDID(0);
00150     char       *result = (char *) palloc(16);
00151 
00152     snprintf(result, 16, "%u", (unsigned int) c);
00153     PG_RETURN_CSTRING(result);
00154 }
00155 
00156 /*
00157  *      cidrecv         - converts external binary format to cid
00158  */
00159 Datum
00160 cidrecv(PG_FUNCTION_ARGS)
00161 {
00162     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
00163 
00164     PG_RETURN_COMMANDID((CommandId) pq_getmsgint(buf, sizeof(CommandId)));
00165 }
00166 
00167 /*
00168  *      cidsend         - converts cid to binary format
00169  */
00170 Datum
00171 cidsend(PG_FUNCTION_ARGS)
00172 {
00173     CommandId   arg1 = PG_GETARG_COMMANDID(0);
00174     StringInfoData buf;
00175 
00176     pq_begintypsend(&buf);
00177     pq_sendint(&buf, arg1, sizeof(arg1));
00178     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00179 }
00180 
00181 Datum
00182 cideq(PG_FUNCTION_ARGS)
00183 {
00184     CommandId   arg1 = PG_GETARG_COMMANDID(0);
00185     CommandId   arg2 = PG_GETARG_COMMANDID(1);
00186 
00187     PG_RETURN_BOOL(arg1 == arg2);
00188 }