diff options
author | Robert Haas <rhaas@postgresql.org> | 2014-02-19 11:13:44 -0500 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2014-02-19 11:37:43 -0500 |
commit | 6f289c2b7d00f07f13f679092f7c71f78950e9da (patch) | |
tree | e90efb09103b8306a659a03a2b8fbcb55ab92c92 /src/backend/access/transam/xlogfuncs.c | |
parent | 694e3d139a9d090c58494428bebfadad216419da (diff) | |
download | postgresql-6f289c2b7d00f07f13f679092f7c71f78950e9da.tar.gz postgresql-6f289c2b7d00f07f13f679092f7c71f78950e9da.zip |
Switch various builtin functions to use pg_lsn instead of text.
The functions in slotfuncs.c don't exist in any released version,
but the changes to xlogfuncs.c represent backward-incompatibilities.
Per discussion, we're hoping that the queries using these functions
are few enough and simple enough that this won't cause too much
breakage for users.
Michael Paquier, reviewed by Andres Freund and further modified
by me.
Diffstat (limited to 'src/backend/access/transam/xlogfuncs.c')
-rw-r--r-- | src/backend/access/transam/xlogfuncs.c | 153 |
1 files changed, 15 insertions, 138 deletions
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c index 9133179a954..5f8d65514c1 100644 --- a/src/backend/access/transam/xlogfuncs.c +++ b/src/backend/access/transam/xlogfuncs.c @@ -30,11 +30,10 @@ #include "utils/builtins.h" #include "utils/numeric.h" #include "utils/guc.h" +#include "utils/pg_lsn.h" #include "utils/timestamp.h" #include "storage/fd.h" -static void validate_xlog_location(char *str); - /* * pg_start_backup: set up for taking an on-line backup dump @@ -52,7 +51,6 @@ pg_start_backup(PG_FUNCTION_ARGS) bool fast = PG_GETARG_BOOL(1); char *backupidstr; XLogRecPtr startpoint; - char startxlogstr[MAXFNAMELEN]; backupidstr = text_to_cstring(backupid); @@ -63,9 +61,7 @@ pg_start_backup(PG_FUNCTION_ARGS) startpoint = do_pg_start_backup(backupidstr, fast, NULL, NULL); - snprintf(startxlogstr, sizeof(startxlogstr), "%X/%X", - (uint32) (startpoint >> 32), (uint32) startpoint); - PG_RETURN_TEXT_P(cstring_to_text(startxlogstr)); + PG_RETURN_LSN(startpoint); } /* @@ -85,7 +81,6 @@ Datum pg_stop_backup(PG_FUNCTION_ARGS) { XLogRecPtr stoppoint; - char stopxlogstr[MAXFNAMELEN]; if (!superuser() && !has_rolreplication(GetUserId())) ereport(ERROR, @@ -94,9 +89,7 @@ pg_stop_backup(PG_FUNCTION_ARGS) stoppoint = do_pg_stop_backup(NULL, true, NULL); - snprintf(stopxlogstr, sizeof(stopxlogstr), "%X/%X", - (uint32) (stoppoint >> 32), (uint32) stoppoint); - PG_RETURN_TEXT_P(cstring_to_text(stopxlogstr)); + PG_RETURN_LSN(stoppoint); } /* @@ -106,7 +99,6 @@ Datum pg_switch_xlog(PG_FUNCTION_ARGS) { XLogRecPtr switchpoint; - char location[MAXFNAMELEN]; if (!superuser()) ereport(ERROR, @@ -124,9 +116,7 @@ pg_switch_xlog(PG_FUNCTION_ARGS) /* * As a convenience, return the WAL location of the switch record */ - snprintf(location, sizeof(location), "%X/%X", - (uint32) (switchpoint >> 32), (uint32) switchpoint); - PG_RETURN_TEXT_P(cstring_to_text(location)); + PG_RETURN_LSN(switchpoint); } /* @@ -138,7 +128,6 @@ pg_create_restore_point(PG_FUNCTION_ARGS) text *restore_name = PG_GETARG_TEXT_P(0); char *restore_name_str; XLogRecPtr restorepoint; - char location[MAXFNAMELEN]; if (!superuser()) ereport(ERROR, @@ -169,9 +158,7 @@ pg_create_restore_point(PG_FUNCTION_ARGS) /* * As a convenience, return the WAL location of the restore point record */ - snprintf(location, sizeof(location), "%X/%X", - (uint32) (restorepoint >> 32), (uint32) restorepoint); - PG_RETURN_TEXT_P(cstring_to_text(location)); + PG_RETURN_LSN(restorepoint); } /* @@ -185,7 +172,6 @@ Datum pg_current_xlog_location(PG_FUNCTION_ARGS) { XLogRecPtr current_recptr; - char location[MAXFNAMELEN]; if (RecoveryInProgress()) ereport(ERROR, @@ -195,9 +181,7 @@ pg_current_xlog_location(PG_FUNCTION_ARGS) current_recptr = GetXLogWriteRecPtr(); - snprintf(location, sizeof(location), "%X/%X", - (uint32) (current_recptr >> 32), (uint32) current_recptr); - PG_RETURN_TEXT_P(cstring_to_text(location)); + PG_RETURN_LSN(current_recptr); } /* @@ -209,7 +193,6 @@ Datum pg_current_xlog_insert_location(PG_FUNCTION_ARGS) { XLogRecPtr current_recptr; - char location[MAXFNAMELEN]; if (RecoveryInProgress()) ereport(ERROR, @@ -219,9 +202,7 @@ pg_current_xlog_insert_location(PG_FUNCTION_ARGS) current_recptr = GetXLogInsertRecPtr(); - snprintf(location, sizeof(location), "%X/%X", - (uint32) (current_recptr >> 32), (uint32) current_recptr); - PG_RETURN_TEXT_P(cstring_to_text(location)); + PG_RETURN_LSN(current_recptr); } /* @@ -234,16 +215,13 @@ Datum pg_last_xlog_receive_location(PG_FUNCTION_ARGS) { XLogRecPtr recptr; - char location[MAXFNAMELEN]; recptr = GetWalRcvWriteRecPtr(NULL, NULL); if (recptr == 0) PG_RETURN_NULL(); - snprintf(location, sizeof(location), "%X/%X", - (uint32) (recptr >> 32), (uint32) recptr); - PG_RETURN_TEXT_P(cstring_to_text(location)); + PG_RETURN_LSN(recptr); } /* @@ -256,16 +234,13 @@ Datum pg_last_xlog_replay_location(PG_FUNCTION_ARGS) { XLogRecPtr recptr; - char location[MAXFNAMELEN]; recptr = GetXLogReplayRecPtr(NULL); if (recptr == 0) PG_RETURN_NULL(); - snprintf(location, sizeof(location), "%X/%X", - (uint32) (recptr >> 32), (uint32) recptr); - PG_RETURN_TEXT_P(cstring_to_text(location)); + PG_RETURN_LSN(recptr); } /* @@ -279,13 +254,9 @@ pg_last_xlog_replay_location(PG_FUNCTION_ARGS) Datum pg_xlogfile_name_offset(PG_FUNCTION_ARGS) { - text *location = PG_GETARG_TEXT_P(0); - char *locationstr; - uint32 hi, - lo; XLogSegNo xlogsegno; uint32 xrecoff; - XLogRecPtr locationpoint; + XLogRecPtr locationpoint = PG_GETARG_LSN(0); char xlogfilename[MAXFNAMELEN]; Datum values[2]; bool isnull[2]; @@ -300,20 +271,6 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS) errhint("pg_xlogfile_name_offset() cannot be executed during recovery."))); /* - * Read input and parse - */ - locationstr = text_to_cstring(location); - - validate_xlog_location(locationstr); - - if (sscanf(locationstr, "%X/%X", &hi, &lo) != 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not parse transaction log location \"%s\"", - locationstr))); - locationpoint = ((uint64) hi) << 32 | lo; - - /* * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ @@ -359,12 +316,8 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS) Datum pg_xlogfile_name(PG_FUNCTION_ARGS) { - text *location = PG_GETARG_TEXT_P(0); - char *locationstr; - uint32 hi, - lo; XLogSegNo xlogsegno; - XLogRecPtr locationpoint; + XLogRecPtr locationpoint = PG_GETARG_LSN(0); char xlogfilename[MAXFNAMELEN]; if (RecoveryInProgress()) @@ -373,17 +326,6 @@ pg_xlogfile_name(PG_FUNCTION_ARGS) errmsg("recovery is in progress"), errhint("pg_xlogfile_name() cannot be executed during recovery."))); - locationstr = text_to_cstring(location); - - validate_xlog_location(locationstr); - - if (sscanf(locationstr, "%X/%X", &hi, &lo) != 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not parse transaction log location \"%s\"", - locationstr))); - locationpoint = ((uint64) hi) << 32 | lo; - XLByteToPrevSeg(locationpoint, xlogsegno); XLogFileName(xlogfilename, ThisTimeLineID, xlogsegno); @@ -482,81 +424,16 @@ pg_is_in_recovery(PG_FUNCTION_ARGS) } /* - * Validate the text form of a transaction log location. - * (Just using sscanf() input allows incorrect values such as - * negatives, so we have to be a bit more careful about that). - */ -static void -validate_xlog_location(char *str) -{ -#define MAXLSNCOMPONENT 8 - - int len1, - len2; - - len1 = strspn(str, "0123456789abcdefABCDEF"); - if (len1 < 1 || len1 > MAXLSNCOMPONENT || str[len1] != '/') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for transaction log location: \"%s\"", str))); - - len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF"); - if (len2 < 1 || len2 > MAXLSNCOMPONENT || str[len1 + 1 + len2] != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for transaction log location: \"%s\"", str))); -} - -/* * Compute the difference in bytes between two WAL locations. */ Datum pg_xlog_location_diff(PG_FUNCTION_ARGS) { - text *location1 = PG_GETARG_TEXT_P(0); - text *location2 = PG_GETARG_TEXT_P(1); - char *str1, - *str2; - XLogRecPtr loc1, - loc2; - Numeric result; - uint64 bytes1, - bytes2; - uint32 hi, - lo; - - /* - * Read and parse input - */ - str1 = text_to_cstring(location1); - str2 = text_to_cstring(location2); - - validate_xlog_location(str1); - validate_xlog_location(str2); + Datum result; - if (sscanf(str1, "%X/%X", &hi, &lo) != 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not parse transaction log location \"%s\"", str1))); - loc1 = ((uint64) hi) << 32 | lo; - - if (sscanf(str2, "%X/%X", &hi, &lo) != 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not parse transaction log location \"%s\"", str2))); - loc2 = ((uint64) hi) << 32 | lo; - - bytes1 = (uint64) loc1; - bytes2 = (uint64) loc2; - - /* - * result = bytes1 - bytes2. - * - * XXX: this won't handle values higher than 2^63 correctly. - */ - result = DatumGetNumeric(DirectFunctionCall2(numeric_sub, - DirectFunctionCall1(int8_numeric, Int64GetDatum((int64) bytes1)), - DirectFunctionCall1(int8_numeric, Int64GetDatum((int64) bytes2)))); + result = DirectFunctionCall2(pg_lsn_mi, + PG_GETARG_DATUM(0), + PG_GETARG_DATUM(1)); PG_RETURN_NUMERIC(result); } |