From 9bae7e4cde7c9786ee61dac4a3e032b346350a88 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Tue, 30 Jun 2020 23:55:07 +0900 Subject: Add +(pg_lsn,numeric) and -(pg_lsn,numeric) operators. By using these operators, the number of bytes can be added into and subtracted from LSN. Bump catalog version. Author: Fujii Masao Reviewed-by: Kyotaro Horiguchi, Michael Paquier, Asif Rehman Discussion: https://postgr.es/m/ed9f7f74-e996-67f8-554a-52ebd3779b3b@oss.nttdata.com --- src/backend/utils/adt/pg_lsn.c | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'src/backend/utils/adt/pg_lsn.c') diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c index d9754a7778c..ad0a7bd869d 100644 --- a/src/backend/utils/adt/pg_lsn.c +++ b/src/backend/utils/adt/pg_lsn.c @@ -16,6 +16,7 @@ #include "funcapi.h" #include "libpq/pqformat.h" #include "utils/builtins.h" +#include "utils/numeric.h" #include "utils/pg_lsn.h" #define MAXPG_LSNLEN 17 @@ -248,3 +249,71 @@ pg_lsn_mi(PG_FUNCTION_ARGS) 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, + NumericGetDatum(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, + NumericGetDatum(num), + NumericGetDatum(nbytes)); + + /* Convert to pg_lsn */ + return DirectFunctionCall1(numeric_pg_lsn, res); +} -- cgit v1.2.3