On 2019-05-23 16:34, Tom Lane wrote:
> On the whole I think I could live with a policy that says "tuple counts
> shall be 'long long' when being passed around in code, but for persistent
> storage or wire-protocol transmission, use 'int64'".
>
> An alternative and much narrower policy is to say it's okay to do this
> with an int64 value:
>
> printf("processed %lld tuples", (long long) count);
>
> In such code, all we're assuming is long long >= 64 bits, which
> is completely safe per C99, and we dodge the need for a
> platform-varying format string.
Some combination of this seems quite reasonable.
Attached is a patch to implement this in a handful of cases that are
particularly verbose right now. I think those are easy wins.
(Also a second patch that makes use of %zu for size_t where this was not
yet done.)
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From b8cc16cd7172439104a59c2334347660dbc64929 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 6 Jun 2019 14:14:29 +0200
Subject: [PATCH 1/2] Unwind some workarounds for lack of portable int64 format
specifier
Because there is no portable int64/uint64 format specifier and we
can't stick macros like INT64_FORMAT into the middle of a translatable
string, we have been using various workarounds that put the number to
be printed into a string buffer first. Now that we always use our own
sprintf(), we can rely on %lld and %llu to work, so we can use those.
This patch undoes this workaround in a few places where it was
egregiously verbose.
Discussion:
https://www.postgresql.org/message-id/flat/CAH2-Wz%3DWbNxc5ob5NJ9yqo2RMJ0q4HXDS30GVCobeCvC9A1L9A%40mail.gmail.com
---
src/backend/access/transam/xlogreader.c | 16 +++-------------
src/backend/replication/basebackup.c | 11 +++--------
src/bin/pg_controldata/pg_controldata.c | 12 ++----------
src/bin/pg_resetwal/pg_resetwal.c | 13 ++-----------
src/bin/pg_rewind/libpq_fetch.c | 10 ++--------
src/bin/pg_test_timing/pg_test_timing.c | 12 +++---------
6 files changed, 15 insertions(+), 59 deletions(-)
diff --git a/src/backend/access/transam/xlogreader.c
b/src/backend/access/transam/xlogreader.c
index 88be7fe022..41dae916b4 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -783,20 +783,10 @@ XLogReaderValidatePageHeader(XLogReaderState *state,
XLogRecPtr recptr,
if (state->system_identifier &&
longhdr->xlp_sysid != state->system_identifier)
{
- char fhdrident_str[32];
- char sysident_str[32];
-
- /*
- * Format sysids separately to keep platform-dependent
format code
- * out of the translatable message string.
- */
- snprintf(fhdrident_str, sizeof(fhdrident_str),
UINT64_FORMAT,
- longhdr->xlp_sysid);
- snprintf(sysident_str, sizeof(sysident_str),
UINT64_FORMAT,
- state->system_identifier);
report_invalid_record(state,
- "WAL file is
from different database system: WAL file database system identifier is %s,
pg_control database system identifier is %s",
-
fhdrident_str, sysident_str);
+ "WAL file is
from different database system: WAL file database system identifier is %llu,
pg_control database system identifier is %llu",
+ (unsigned
long long) longhdr->xlp_sysid,
+ (unsigned
long long) state->system_identifier);
return false;
}
else if (longhdr->xlp_seg_size != state->wal_segment_size)
diff --git a/src/backend/replication/basebackup.c
b/src/backend/replication/basebackup.c
index c2978a949a..7a1b38466b 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -106,7 +106,7 @@ static TimestampTz throttled_last;
static XLogRecPtr startptr;
/* Total number of checksum failures during base backup. */
-static int64 total_checksum_failures;
+static long long int total_checksum_failures;
/* Do not verify checksums. */
static bool noverify_checksums = false;
@@ -607,14 +607,9 @@ perform_base_backup(basebackup_options *opt)
if (total_checksum_failures)
{
if (total_checksum_failures > 1)
- {
- char buf[64];
-
- snprintf(buf, sizeof(buf), INT64_FORMAT,
total_checksum_failures);
-
ereport(WARNING,
- (errmsg("%s total checksum verification
failures", buf)));
- }
+ (errmsg("%lld total checksum
verification failures", total_checksum_failures)));
+
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("checksum verification failure during
base backup")));
diff --git a/src/bin/pg_controldata/pg_controldata.c
b/src/bin/pg_controldata/pg_controldata.c
index d955b97c0b..390ea0a939 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -99,7 +99,6 @@ main(int argc, char *argv[])
time_t time_tmp;
char pgctime_str[128];
char ckpttime_str[128];
- char sysident_str[32];
char mock_auth_nonce_str[MOCK_AUTH_NONCE_LEN * 2 + 1];
const char *strftime_fmt = "%c";
const char *progname;
@@ -222,13 +221,6 @@ main(int argc, char *argv[])
else
strcpy(xlogfilename, _("???"));
- /*
- * Format system_identifier and mock_authentication_nonce separately to
- * keep platform-dependent format code out of the translatable message
- * string.
- */
- snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
- ControlFile->system_identifier);
for (i = 0; i < MOCK_AUTH_NONCE_LEN; i++)
snprintf(&mock_auth_nonce_str[i * 2], 3, "%02x",
(unsigned char)
ControlFile->mock_authentication_nonce[i]);
@@ -237,8 +229,8 @@ main(int argc, char *argv[])
ControlFile->pg_control_version);
printf(_("Catalog version number: %u\n"),
ControlFile->catalog_version_no);
- printf(_("Database system identifier: %s\n"),
- sysident_str);
+ printf(_("Database system identifier: %llu\n"),
+ (unsigned long long) ControlFile->system_identifier);
printf(_("Database cluster state: %s\n"),
dbState(ControlFile->state));
printf(_("pg_control last modified: %s\n"),
diff --git a/src/bin/pg_resetwal/pg_resetwal.c
b/src/bin/pg_resetwal/pg_resetwal.c
index 2734f87318..ff0f8ea5e7 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -748,26 +748,17 @@ GuessControlValues(void)
static void
PrintControlValues(bool guessed)
{
- char sysident_str[32];
-
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
printf(_("Current pg_control values:\n\n"));
- /*
- * Format system_identifier separately to keep platform-dependent format
- * code out of the translatable message string.
- */
- snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
- ControlFile.system_identifier);
-
printf(_("pg_control version number: %u\n"),
ControlFile.pg_control_version);
printf(_("Catalog version number: %u\n"),
ControlFile.catalog_version_no);
- printf(_("Database system identifier: %s\n"),
- sysident_str);
+ printf(_("Database system identifier: %llu\n"),
+ (unsigned long long) ControlFile.system_identifier);
printf(_("Latest checkpoint's TimeLineID: %u\n"),
ControlFile.checkPointCopy.ThisTimeLineID);
printf(_("Latest checkpoint's full_page_writes: %s\n"),
diff --git a/src/bin/pg_rewind/libpq_fetch.c b/src/bin/pg_rewind/libpq_fetch.c
index d6cbe23926..37eccc3126 100644
--- a/src/bin/pg_rewind/libpq_fetch.c
+++ b/src/bin/pg_rewind/libpq_fetch.c
@@ -251,7 +251,6 @@ receiveFileChunks(const char *sql)
char *filename;
int filenamelen;
int64 chunkoff;
- char chunkoff_str[32];
int chunksize;
char *chunk;
@@ -327,13 +326,8 @@ receiveFileChunks(const char *sql)
continue;
}
- /*
- * Separate step to keep platform-dependent format code out of
- * translatable strings.
- */
- snprintf(chunkoff_str, sizeof(chunkoff_str), INT64_FORMAT,
chunkoff);
- pg_log_debug("received chunk for file \"%s\", offset %s, size
%d",
- filename, chunkoff_str, chunksize);
+ pg_log_debug("received chunk for file \"%s\", offset %lld, size
%d",
+ filename, (long long int) chunkoff,
chunksize);
open_target_file(filename, false);
diff --git a/src/bin/pg_test_timing/pg_test_timing.c
b/src/bin/pg_test_timing/pg_test_timing.c
index 6e2fd1ab8c..e14802372b 100644
--- a/src/bin/pg_test_timing/pg_test_timing.c
+++ b/src/bin/pg_test_timing/pg_test_timing.c
@@ -18,7 +18,7 @@ static uint64 test_timing(int32);
static void output(uint64 loop_count);
/* record duration in powers of 2 microseconds */
-int64 histogram[32];
+long long int histogram[32];
int
main(int argc, char *argv[])
@@ -190,14 +190,8 @@ output(uint64 loop_count)
Max(10, len3), header3);
for (i = 0; i <= max_bit; i++)
- {
- char buf[100];
-
- /* lame hack to work around INT64_FORMAT deficiencies */
- snprintf(buf, sizeof(buf), INT64_FORMAT, histogram[i]);
- printf("%*ld %*.5f %*s\n",
+ printf("%*ld %*.5f %*lld\n",
Max(6, len1), 1l << i,
Max(10, len2) - 1, (double) histogram[i] * 100 /
loop_count,
- Max(10, len3), buf);
- }
+ Max(10, len3), histogram[i]);
}
--
2.21.0
From 8b4ba199e2b61076f49df5220fa5c6310a82bc75 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Thu, 6 Jun 2019 14:32:54 +0200
Subject: [PATCH 2/2] Remove unnecessary casts from size_t to int
We can use the %zu format specifier directly, no need to cast to int.
---
src/interfaces/ecpg/preproc/ecpg.addons | 4 ++--
src/interfaces/ecpg/preproc/ecpg.trailer | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons
b/src/interfaces/ecpg/preproc/ecpg.addons
index 4e30375302..cbffd50e14 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -36,7 +36,7 @@ ECPG: stmtExecuteStmt block
/* It must be cut off double quotation because
new_variable() double-quotes. */
str[strlen(str) - 1] = '\0';
- sprintf(length, "%d", (int) strlen(str));
+ sprintf(length, "%zu", strlen(str));
add_variable_to_tail(&argsinsert,
new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0),
&no_indicator);
}
output_statement(cat_str(3, mm_strdup("execute"),
mm_strdup("$0"), $1.type), 0, ECPGst_exec_with_exprlist);
@@ -63,7 +63,7 @@ ECPG: stmtPrepareStmt block
/* It must be cut off double quotation because
new_variable() double-quotes. */
str[strlen(str) - 1] = '\0';
- sprintf(length, "%d", (int) strlen(str));
+ sprintf(length, "%zu", strlen(str));
add_variable_to_tail(&argsinsert,
new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0),
&no_indicator);
}
output_statement(cat_str(5, mm_strdup("prepare"),
mm_strdup("$0"), $1.type, mm_strdup("as"), $1.stmt), 0, ECPGst_prepare);
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer
b/src/interfaces/ecpg/preproc/ecpg.trailer
index 1d58c778d9..b303a9cbd0 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -1099,7 +1099,7 @@ UsingValue: UsingConst
{
char *length = mm_alloc(32);
- sprintf(length, "%d", (int) strlen($1));
+ sprintf(length, "%zu", strlen($1));
add_variable_to_head(&argsinsert, new_variable($1,
ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
}
| civar { $$ = EMPTY; }
@@ -1226,7 +1226,7 @@ IntConstVar: Iconst
{
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 /
3);
- sprintf(length, "%d", (int) strlen($1));
+ sprintf(length, "%zu", strlen($1));
new_variable($1, ECPGmake_simple_type(ECPGt_const,
length, 0), 0);
$$ = $1;
}
@@ -1272,7 +1272,7 @@ AllConstVar: ecpg_fconst
{
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 /
3);
- sprintf(length, "%d", (int) strlen($1));
+ sprintf(length, "%zu", strlen($1));
new_variable($1, ECPGmake_simple_type(ECPGt_const,
length, 0), 0);
$$ = $1;
}
@@ -1287,7 +1287,7 @@ AllConstVar: ecpg_fconst
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 /
3);
char *var = cat2_str(mm_strdup("-"), $2);
- sprintf(length, "%d", (int) strlen(var));
+ sprintf(length, "%zu", strlen(var));
new_variable(var, ECPGmake_simple_type(ECPGt_const,
length, 0), 0);
$$ = var;
}
@@ -1297,7 +1297,7 @@ AllConstVar: ecpg_fconst
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 /
3);
char *var = cat2_str(mm_strdup("-"), $2);
- sprintf(length, "%d", (int) strlen(var));
+ sprintf(length, "%zu", strlen(var));
new_variable(var, ECPGmake_simple_type(ECPGt_const,
length, 0), 0);
$$ = var;
}
@@ -1308,7 +1308,7 @@ AllConstVar: ecpg_fconst
char *var = $1 + 1;
var[strlen(var) - 1] = '\0';
- sprintf(length, "%d", (int) strlen(var));
+ sprintf(length, "%zu", strlen(var));
new_variable(var, ECPGmake_simple_type(ECPGt_const,
length, 0), 0);
$$ = var;
}
--
2.21.0