Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postgres/src/backend/utils/adt/   (Postgres Database Version 18.4©)  Datei vom 11.4.2026 mit Größe 6 kB image not shown  

Quelle  pg_lsn.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * pg_lsn.c
 *   Operations for the pg_lsn datatype.
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *   src/backend/utils/adt/pg_lsn.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "libpq/pqformat.h"
#include "utils/fmgrprotos.h"
#include "utils/numeric.h"
#include "utils/pg_lsn.h"

#define MAXPG_LSNLEN   17
#define MAXPG_LSNCOMPONENT 8

/*----------------------------------------------------------
 * Formatting and conversion routines.
 *---------------------------------------------------------*/


XLogRecPtr
pg_lsn_in_internal(const char *str, bool *have_error)
{
 int   len1,
    len2;
 uint32  id,
    off;
 XLogRecPtr result;

 Assert(have_error != NULL);
 *have_error = false;

 /* Sanity check input format. */
 len1 = strspn(str, "0123456789abcdefABCDEF");
 if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
 {
  *have_error = true;
  return InvalidXLogRecPtr;
 }
 len2 = strspn(str + len1 + 1"0123456789abcdefABCDEF");
 if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0')
 {
  *have_error = true;
  return InvalidXLogRecPtr;
 }

 /* Decode result. */
 id = (uint32) strtoul(str, NULL, 16);
 off = (uint32) strtoul(str + len1 + 1, NULL, 16);
 result = ((uint64) id << 32) | off;

 return result;
}

Datum
pg_lsn_in(PG_FUNCTION_ARGS)
{
 char    *str = PG_GETARG_CSTRING(0);
 XLogRecPtr result;
 bool  have_error = false;

 result = pg_lsn_in_internal(str, &have_error);
 if (have_error)
  ereturn(fcinfo->context, (Datum) 0,
    (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     errmsg("invalid input syntax for type %s: \"%s\"",
      "pg_lsn", str)));

 PG_RETURN_LSN(result);
}

Datum
pg_lsn_out(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn = PG_GETARG_LSN(0);
 char  buf[MAXPG_LSNLEN + 1];
 char    *result;

 snprintf(buf, sizeof buf, "%X/%X", LSN_FORMAT_ARGS(lsn));
 result = pstrdup(buf);
 PG_RETURN_CSTRING(result);
}

Datum
pg_lsn_recv(PG_FUNCTION_ARGS)
{
 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
 XLogRecPtr result;

 result = pq_getmsgint64(buf);
 PG_RETURN_LSN(result);
}

Datum
pg_lsn_send(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn = PG_GETARG_LSN(0);
 StringInfoData buf;

 pq_begintypsend(&buf);
 pq_sendint64(&buf, lsn);
 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}


/*----------------------------------------------------------
 * Operators for PostgreSQL LSNs
 *---------------------------------------------------------*/


Datum
pg_lsn_eq(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_BOOL(lsn1 == lsn2);
}

Datum
pg_lsn_ne(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_BOOL(lsn1 != lsn2);
}

Datum
pg_lsn_lt(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_BOOL(lsn1 < lsn2);
}

Datum
pg_lsn_gt(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_BOOL(lsn1 > lsn2);
}

Datum
pg_lsn_le(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_BOOL(lsn1 <= lsn2);
}

Datum
pg_lsn_ge(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_BOOL(lsn1 >= lsn2);
}

Datum
pg_lsn_larger(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_LSN((lsn1 > lsn2) ? lsn1 : lsn2);
}

Datum
pg_lsn_smaller(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);

 PG_RETURN_LSN((lsn1 < lsn2) ? lsn1 : lsn2);
}

/* btree index opclass support */
Datum
pg_lsn_cmp(PG_FUNCTION_ARGS)
{
 XLogRecPtr a = PG_GETARG_LSN(0);
 XLogRecPtr b = PG_GETARG_LSN(1);

 if (a > b)
  PG_RETURN_INT32(1);
 else if (a == b)
  PG_RETURN_INT32(0);
 else
  PG_RETURN_INT32(-1);
}

/* hash index opclass support */
Datum
pg_lsn_hash(PG_FUNCTION_ARGS)
{
 /* We can use hashint8 directly */
 return hashint8(fcinfo);
}

Datum
pg_lsn_hash_extended(PG_FUNCTION_ARGS)
{
 return hashint8extended(fcinfo);
}


/*----------------------------------------------------------
 * Arithmetic operators on PostgreSQL LSNs.
 *---------------------------------------------------------*/


Datum
pg_lsn_mi(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn1 = PG_GETARG_LSN(0);
 XLogRecPtr lsn2 = PG_GETARG_LSN(1);
 char  buf[256];
 Datum  result;

 /* Output could be as large as plus or minus 2^63 - 1. */
 if (lsn1 < lsn2)
  snprintf(buf, sizeof buf, "-" UINT64_FORMAT, lsn2 - lsn1);
 else
  snprintf(buf, sizeof buf, UINT64_FORMAT, lsn1 - lsn2);

 /* Convert to numeric. */
 result = DirectFunctionCall3(numeric_in,
         CStringGetDatum(buf),
         ObjectIdGetDatum(0),
         Int32GetDatum(-1));

 return result;
}

/*
 * Add the number of bytes to pg_lsn, giving a new pg_lsn.
 * Must handle both positive and negative numbers of bytes.
 */

Datum
pg_lsn_pli(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn = PG_GETARG_LSN(0);
 Numeric  nbytes = PG_GETARG_NUMERIC(1);
 Datum  num;
 Datum  res;
 char  buf[32];

 if (numeric_is_nan(nbytes))
  ereport(ERROR,
    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     errmsg("cannot add NaN to pg_lsn")));

 /* Convert to numeric */
 snprintf(buf, sizeof(buf), UINT64_FORMAT, lsn);
 num = DirectFunctionCall3(numeric_in,
         CStringGetDatum(buf),
         ObjectIdGetDatum(0),
         Int32GetDatum(-1));

 /* Add two numerics */
 res = DirectFunctionCall2(numeric_add,
         num,
         NumericGetDatum(nbytes));

 /* Convert to pg_lsn */
 return DirectFunctionCall1(numeric_pg_lsn, res);
}

/*
 * Subtract the number of bytes from pg_lsn, giving a new pg_lsn.
 * Must handle both positive and negative numbers of bytes.
 */

Datum
pg_lsn_mii(PG_FUNCTION_ARGS)
{
 XLogRecPtr lsn = PG_GETARG_LSN(0);
 Numeric  nbytes = PG_GETARG_NUMERIC(1);
 Datum  num;
 Datum  res;
 char  buf[32];

 if (numeric_is_nan(nbytes))
  ereport(ERROR,
    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     errmsg("cannot subtract NaN from pg_lsn")));

 /* Convert to numeric */
 snprintf(buf, sizeof(buf), UINT64_FORMAT, lsn);
 num = DirectFunctionCall3(numeric_in,
         CStringGetDatum(buf),
         ObjectIdGetDatum(0),
         Int32GetDatum(-1));

 /* Subtract two numerics */
 res = DirectFunctionCall2(numeric_sub,
         num,
         NumericGetDatum(nbytes));

 /* Convert to pg_lsn */
 return DirectFunctionCall1(numeric_pg_lsn, res);
}

Messung V0.5 in Prozent
C=94 H=94 G=93

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.