Add %z support to elog/ereport?
Hi,
I'd like to add support for the length modifier %z. Linux' manpages
describes it as:
z A following integer conversion corresponds to a size_t or ssize_t argument.
Since gcc's printf format checks understand it, we can add support for
it similar to the way we added %m support.
Currently we just deal with wanting to print size_t/Size values by
casting them to uint32, uint64 or similar, but that's a) annoying
because 64bit numbers require the annoying UINT64_FORMAT b) more and
more likely to be problematic when casting to 32bit numbers.
Does anybody see prolbems with that?
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
I'd like to add support for the length modifier %z. Linux' manpages
describes it as:
z A following integer conversion corresponds to a size_t or ssize_t argument.
Since gcc's printf format checks understand it, we can add support for
it similar to the way we added %m support.
I think you'll find that %m is a totally different animal, because it
doesn't involve consuming an argument position. I'm less than sure that
every version of gcc will recognize %z, either ... and what about the
translation infrastructure?
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-11-11 11:18:22 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
I'd like to add support for the length modifier %z. Linux' manpages
describes it as:
z A following integer conversion corresponds to a size_t or ssize_t argument.Since gcc's printf format checks understand it, we can add support for
it similar to the way we added %m support.I think you'll find that %m is a totally different animal, because it
doesn't involve consuming an argument position.
I was thinking of just replacing '%z' by '%l', '%ll' or '%' as needed
and not expand it inplace. That should deal with keeping the argument
position and such.
But that won't easily work if somebody specifies flags like padding :/
I'm less than sure that every version of gcc will recognize %z, either
...
It's been in recognized in 2.95 afaics, so I think we're good.
and what about the translation infrastructure?
That I have no clue about yet.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-11-11 17:33:53 +0100, Andres Freund wrote:
On 2013-11-11 11:18:22 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
I'd like to add support for the length modifier %z. Linux' manpages
describes it as:
z A following integer conversion corresponds to a size_t or ssize_t argument.
and what about the translation infrastructure?
That I have no clue about yet.
gettext has support for it afaics, it's part of POSIX:
http://www.gnu.org/software/gettext/manual/gettext.html#c_002dformat
http://www.opengroup.org/onlinepubs/007904975/functions/fprintf.html
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
On 2013-11-11 11:18:22 -0500, Tom Lane wrote:
I think you'll find that %m is a totally different animal, because it
doesn't involve consuming an argument position.
I was thinking of just replacing '%z' by '%l', '%ll' or '%' as needed
and not expand it inplace. That should deal with keeping the argument
position and such.
But that won't easily work if somebody specifies flags like padding :/
[ reads manual ] Oh, I see that actually z *is* a flag, so you'd be
talking about replacing it with a different flag, ie %zu -> %llu or
similar. Yes, in principle that could work, but you'd have to be
prepared to cope with other flags, field width/precision, n$, etc,
appearing first. Sounds a bit messy, and this code is probably a
hot spot, remembering what we found out about the cost of fooling
with log_line_prefix.
I'm less than sure that every version of gcc will recognize %z, either
...
It's been in recognized in 2.95 afaics, so I think we're good.
[ fires up old HPUX box ] Nope:
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char**argv)
{
char buf[256];
size_t x = 0;
sprintf(buf, "%zu", (int)x);
return 0;
}
$ gcc -O2 -Wall test.c
test.c: In function `main':
test.c:9: warning: unknown conversion type character `z' in format
test.c:9: warning: too many arguments for format
$ gcc -v
Reading specs from /usr/local/lib/gcc-lib/hppa2.0-hp-hpux10.20/2.95.3/specs
gcc version 2.95.3 20010315 (release)
We might be willing to toss 2.95 overboard by now, but we'd need to be
sure of exactly what the new minimum usable version is.
and what about the translation infrastructure?
That I have no clue about yet.
Me either. I do recall Peter saying that the infrastructure knows how to
verify conversion specs in translated strings, so it would have to be
aware of 'z' flags for this to work.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
gettext has support for it afaics, it's part of POSIX:
Really? [ pokes around at pubs.opengroup.org ] Hm, I don't see it
in Single Unix Spec v2 (1997), but it is there in POSIX issue 7 (2008).
Also, the POSIX page says it defers to the C standard, and I see it
in C99. Too bad not all our platforms are C99 yet :-(
Actually this raises an interesting testing question: how sure are we
that there aren't already some format strings in the code that depend
on C99 additions to the printf spec? If they're not in code paths
exercised by the regression tests, I'm not sure we'd find out from
the buildfarm.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-11-11 12:01:40 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
I'm less than sure that every version of gcc will recognize %z, either
...It's been in recognized in 2.95 afaics, so I think we're good.
Hm. Strange. Has to have been backpatched to the ancient debian I have
around. Unfortunately I can't easily "apt-get source" there...
The commit that added it to upstream is:
commit 44e9fa656d60bb19ab81d76698a61e47a4b0857c
Author: drepper <drepper@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon Jan 3 21:48:49 2000 +0000
(format_char_info): Update comment. (check_format_info): Recognize 'z'
modifier in the same way 'Z' was recognized. Emit warning for formats
new in ISO C99 only if flag_isoc9x is not set.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31188 138bc75d-0d04-0410-961f-82ee72b054a4
That's 3.0. Verified it in the 3.0. tarball, although I didn't compile
test it.
We might be willing to toss 2.95 overboard by now, but we'd need to be
sure of exactly what the new minimum usable version is.
Well, we don't even need to toss it overboard, just live with useless
warnings there since we'd translate it ourselves.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Mon, Nov 11, 2013 at 10:50 AM, Andres Freund <andres@2ndquadrant.com> wrote:
Hi,
I'd like to add support for the length modifier %z. Linux' manpages
describes it as:
z A following integer conversion corresponds to a size_t or ssize_t argument.Since gcc's printf format checks understand it, we can add support for
it similar to the way we added %m support.
I seem to recall that our %m support involves rewriting the error
string twice, which I think is actually kind of expensive if, for
example, you've got a loop around a PL/pgsql EXCEPTION block. I'd
actually like to find a way to get rid of the existing %m support,
maybe by having a flag that says "oh, and by the way append the system
error to my format string"; or by changing %m to %s and having the
caller pass system_error_string() or similar for that format position.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-11-11 12:18:46 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
gettext has support for it afaics, it's part of POSIX:
Really? [ pokes around at pubs.opengroup.org ] Hm, I don't see it
in Single Unix Spec v2 (1997), but it is there in POSIX issue 7 (2008).
Also, the POSIX page says it defers to the C standard, and I see it
in C99. Too bad not all our platforms are C99 yet :-(
Seems to be 2001:
http://pubs.opengroup.org/onlinepubs/007904975/functions/fprintf.html
Even though the date says it's from 2004, it's IEEE Std 1003.1 + minor
errata.
Actually this raises an interesting testing question: how sure are we
that there aren't already some format strings in the code that depend
on C99 additions to the printf spec? If they're not in code paths
exercised by the regression tests, I'm not sure we'd find out from
the buildfarm.
I agree, it's problematic. Especially as such code is likely to be in
error paths. I seem to recall you fixing some occurances you found
manually some time back so we clearly don't have an automated process
for it yet.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-11-11 12:31:55 -0500, Robert Haas wrote:
On Mon, Nov 11, 2013 at 10:50 AM, Andres Freund <andres@2ndquadrant.com> wrote:
Hi,
I'd like to add support for the length modifier %z. Linux' manpages
describes it as:
z A following integer conversion corresponds to a size_t or ssize_t argument.Since gcc's printf format checks understand it, we can add support for
it similar to the way we added %m support.I seem to recall that our %m support involves rewriting the error
string twice, which I think is actually kind of expensive if, for
example, you've got a loop around a PL/pgsql EXCEPTION block.
Yes, it does that. Is that actually where a significant amount of time
is spent? I have a somewhat hard time believing that.
I'd
actually like to find a way to get rid of the existing %m support,
maybe by having a flag that says "oh, and by the way append the system
error to my format string"; or by changing %m to %s and having the
caller pass system_error_string() or similar for that format position.
I'd rather get our own printf implementation from somewhere before doing
that which would quite likely result in a bigger speedup besides the
significant portability improvments.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
On 2013-11-11 12:31:55 -0500, Robert Haas wrote:
I seem to recall that our %m support involves rewriting the error
string twice, which I think is actually kind of expensive if, for
example, you've got a loop around a PL/pgsql EXCEPTION block.
Yes, it does that. Is that actually where a significant amount of time
is spent? I have a somewhat hard time believing that.
I don't see any double copying. There is *one* copy made by
expand_fmt_string. Like Andres, I'd want to see proof that
expand_fmt_string is a significant time sink before we jump through
these kinds of hoops to get rid of it. It looks like a pretty cheap
loop to me. (It might be less cheap if we made it smart enough to
identify 'z' flags, though :-()
I'd
actually like to find a way to get rid of the existing %m support,
maybe by having a flag that says "oh, and by the way append the system
error to my format string"; or by changing %m to %s and having the
caller pass system_error_string() or similar for that format position.
The first of these doesn't work unless you require translations to
assemble the string the same way the English version does. The second
would work, I guess, but it'd sure be a pain to convert everything.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 11/11/13, 12:01 PM, Tom Lane wrote:
I do recall Peter saying that the infrastructure knows how to
verify conversion specs in translated strings, so it would have to be
aware of 'z' flags for this to work.
It just checks that the same conversion placeholders appear in the
translation. It doesn't interpret the actual placeholders. I don't
think this will be a problem.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-12-06 09:54:59 -0500, Peter Eisentraut wrote:
On 11/11/13, 12:01 PM, Tom Lane wrote:
I do recall Peter saying that the infrastructure knows how to
verify conversion specs in translated strings, so it would have to be
aware of 'z' flags for this to work.It just checks that the same conversion placeholders appear in the
translation. It doesn't interpret the actual placeholders. I don't
think this will be a problem.
Ok, so here's a patch.
Patch 01 introduces infrastructure, and elog.c implementation.
Patch 02 converts some elog/ereport() callers to using the z modifier,
some were wrong at least on 64 bit windows.
In patch 01, I've modified configure to not define [U]INT64_FORMAT
directly, but rather just define INT64_LENGTH_MODIFIER as
appropriate. The formats are now defined in c.h.
INT64_LENGTH_MODIFIER is defined without quotes - I am not sure whether
that was the right choice, it requires using CppAsString2() in some
places. Maybe I should just have defined it with quotes instead. Happy
to rejigger it if somebody thinks the other way would be better.
Note that I have decided to only support the z modifier properly if no
further modifiers (precision, width) are present. That seems sufficient
for now, given the usecases, and more complete support seems to be
potentially expensive without much use.
I wonder if we should also introduce SIZE_T_FORMAT and SSIZE_T_FORMAT,
there's some places that have #ifdef _WIN64 guards and similar that look
like they could be simplified.
Btw, walsender.c/walreceiver.c upcast an int into an unsigned long for
printing? That's a bit strange.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
0001-Add-support-for-printing-Size-arguments-to-elog-erep.patchtext/x-patch; charset=us-asciiDownload
>From b31f7c5fc2b2d4451c650a54bb02e656b8fd3bbf Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 7 Dec 2013 19:23:15 +0100
Subject: [PATCH 1/2] Add support for printing Size arguments to
elog()/ereport() using %zu.
Similar to the way %m is special-case supported in elog.c routines, add
support for the z length modifier by replacing it by the platform's modifier
for the pointer size.
To do that, refactor the configure checks that define [U]INT64_FORMAT, to
instead define the used length modifier as INT64_LENGTH_MODIFIER. Currently we
don't support flag, width, precision modifiers in addition to z, but that's
fine for the current callsites.
---
config/c-library.m4 | 36 ++++++++++++++---------------
configure | 51 +++++++++++++++++-------------------------
configure.in | 28 +++++++++--------------
src/backend/utils/error/elog.c | 16 +++++++++++++
src/include/c.h | 10 ++++++---
src/include/pg_config.h.in | 7 ++----
src/include/pg_config.h.win32 | 8 ++-----
7 files changed, 77 insertions(+), 79 deletions(-)
diff --git a/config/c-library.m4 b/config/c-library.m4
index 1e3997b..b836c2a 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -221,22 +221,22 @@ HAVE_POSIX_SIGNALS=$pgac_cv_func_posix_signals
AC_SUBST(HAVE_POSIX_SIGNALS)])# PGAC_FUNC_POSIX_SIGNALS
-# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
+# PGAC_FUNC_SNPRINTF_LONG_LONG_LENGTH_MODIFIER
# ---------------------------------------
-# Determine which format snprintf uses for long long int. We handle
-# %lld, %qd, %I64d. The result is in shell variable
-# LONG_LONG_INT_FORMAT.
+# Determine which format snprintf uses for long long integers. We
+# handle %ll, %q, %I64. The detected length modifer is stored in
+# the shell variable LONG_LONG_LENGTH_MODIFIER.
#
-# MinGW uses '%I64d', though gcc throws an warning with -Wall,
-# while '%lld' doesn't generate a warning, but doesn't work.
+# MinGW uses '%I64', though gcc throws an warning with -Wall,
+# while '%ll' doesn't generate a warning, but doesn't work.
#
-AC_DEFUN([PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT],
-[AC_MSG_CHECKING([snprintf format for long long int])
-AC_CACHE_VAL(pgac_cv_snprintf_long_long_int_format,
-[for pgac_format in '%lld' '%qd' '%I64d'; do
+AC_DEFUN([PGAC_FUNC_SNPRINTF_LONG_LONG_LENGTH_MODIFIER],
+[AC_MSG_CHECKING([snprintf length modifier for long long])
+AC_CACHE_VAL(pgac_cv_snprintf_long_long_length_modifier,
+[for pgac_format in 'll' 'q' 'I64'; do
AC_TRY_RUN([#include <stdio.h>
typedef long long int ac_int64;
-#define INT64_FORMAT "$pgac_format"
+#define INT64_FORMAT "%${pgac_format}d"
ac_int64 a = 20000001;
ac_int64 b = 40000005;
@@ -258,19 +258,19 @@ int does_int64_snprintf_work()
main() {
exit(! does_int64_snprintf_work());
}],
-[pgac_cv_snprintf_long_long_int_format=$pgac_format; break],
+[pgac_cv_snprintf_long_long_length_modifier=$pgac_format; break],
[],
-[pgac_cv_snprintf_long_long_int_format=cross; break])
+[pgac_cv_snprintf_long_long_length_modifier=cross; break])
done])dnl AC_CACHE_VAL
-LONG_LONG_INT_FORMAT=''
+LONG_LONG_LENGTH_MODIFIER=''
-case $pgac_cv_snprintf_long_long_int_format in
+case $pgac_cv_snprintf_long_long_length_modifier in
cross) AC_MSG_RESULT([cannot test (not on host machine)]);;
- ?*) AC_MSG_RESULT([$pgac_cv_snprintf_long_long_int_format])
- LONG_LONG_INT_FORMAT=$pgac_cv_snprintf_long_long_int_format;;
+ ?*) AC_MSG_RESULT([$pgac_cv_snprintf_long_long_length_modifier])
+ LONG_LONG_LENGTH_MODIFIER=$pgac_cv_snprintf_long_long_length_modifier;;
*) AC_MSG_RESULT(none);;
-esac])# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
+esac])# PGAC_FUNC_SNPRINTF_LONG_LONG_LENGTH_MODIFIER
# PGAC_FUNC_PRINTF_ARG_CONTROL
diff --git a/configure b/configure
index 0165c3c..8a04cc9 100755
--- a/configure
+++ b/configure
@@ -24812,19 +24812,19 @@ fi
# If we found "long int" is 64 bits, assume snprintf handles it. If
# we found we need to use "long long int", better check. We cope with
-# snprintfs that use %lld, %qd, or %I64d as the format. If none of these
-# work, fall back to our own snprintf emulation (which we know uses %lld).
+# snprintfs that use lld, qd, or I64d as the modifier. If none of these
+# work, fall back to our own snprintf emulation (which we know uses ll).
if test "$HAVE_LONG_LONG_INT_64" = yes ; then
if test $pgac_need_repl_snprintf = no; then
- { $as_echo "$as_me:$LINENO: checking snprintf format for long long int" >&5
-$as_echo_n "checking snprintf format for long long int... " >&6; }
-if test "${pgac_cv_snprintf_long_long_int_format+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking snprintf length modifier for long long" >&5
+$as_echo_n "checking snprintf length modifier for long long... " >&6; }
+if test "${pgac_cv_snprintf_long_long_length_modifier+set}" = set; then
$as_echo_n "(cached) " >&6
else
- for pgac_format in '%lld' '%qd' '%I64d'; do
+ for pgac_format in 'll' 'q' 'I64'; do
if test "$cross_compiling" = yes; then
- pgac_cv_snprintf_long_long_int_format=cross; break
+ pgac_cv_snprintf_long_long_length_modifier=cross; break
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -24834,7 +24834,7 @@ cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdio.h>
typedef long long int ac_int64;
-#define INT64_FORMAT "$pgac_format"
+#define INT64_FORMAT "%${pgac_format}d"
ac_int64 a = 20000001;
ac_int64 b = 40000005;
@@ -24879,7 +24879,7 @@ $as_echo "$ac_try_echo") >&5
ac_status=$?
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- pgac_cv_snprintf_long_long_int_format=$pgac_format; break
+ pgac_cv_snprintf_long_long_length_modifier=$pgac_format; break
else
$as_echo "$as_me: program exited with status $ac_status" >&5
$as_echo "$as_me: failed program was:" >&5
@@ -24894,44 +24894,35 @@ fi
done
fi
-LONG_LONG_INT_FORMAT=''
+LONG_LONG_LENGTH_MODIFIER=''
-case $pgac_cv_snprintf_long_long_int_format in
+case $pgac_cv_snprintf_long_long_length_modifier in
cross) { $as_echo "$as_me:$LINENO: result: cannot test (not on host machine)" >&5
$as_echo "cannot test (not on host machine)" >&6; };;
- ?*) { $as_echo "$as_me:$LINENO: result: $pgac_cv_snprintf_long_long_int_format" >&5
-$as_echo "$pgac_cv_snprintf_long_long_int_format" >&6; }
- LONG_LONG_INT_FORMAT=$pgac_cv_snprintf_long_long_int_format;;
+ ?*) { $as_echo "$as_me:$LINENO: result: $pgac_cv_snprintf_long_long_length_modifier" >&5
+$as_echo "$pgac_cv_snprintf_long_long_length_modifier" >&6; }
+ LONG_LONG_LENGTH_MODIFIER=$pgac_cv_snprintf_long_long_length_modifier;;
*) { $as_echo "$as_me:$LINENO: result: none" >&5
$as_echo "none" >&6; };;
esac
- if test "$LONG_LONG_INT_FORMAT" = ""; then
+ if test "$LONG_LONG_LENGTH_MODIFIER" = ""; then
# Force usage of our own snprintf, since system snprintf is broken
pgac_need_repl_snprintf=yes
- LONG_LONG_INT_FORMAT='%lld'
+ LONG_LONG_LENGTH_MODIFIER='ll'
fi
else
# Here if we previously decided we needed to use our own snprintf
- LONG_LONG_INT_FORMAT='%lld'
+ LONG_LONG_LENGTH_MODIFIER='ll'
fi
- LONG_LONG_UINT_FORMAT=`echo "$LONG_LONG_INT_FORMAT" | sed 's/d$/u/'`
- INT64_FORMAT="\"$LONG_LONG_INT_FORMAT\""
- UINT64_FORMAT="\"$LONG_LONG_UINT_FORMAT\""
+ INT64_LENGTH_MODIFIER="$LONG_LONG_LENGTH_MODIFIER"
else
- # Here if we are not using 'long long int' at all
- INT64_FORMAT='"%ld"'
- UINT64_FORMAT='"%lu"'
+ # Here if we are not using 'long long' at all
+ INT64_LENGTH_MODIFIER='l'
fi
cat >>confdefs.h <<_ACEOF
-#define INT64_FORMAT $INT64_FORMAT
-_ACEOF
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define UINT64_FORMAT $UINT64_FORMAT
+#define INT64_LENGTH_MODIFIER $INT64_LENGTH_MODIFIER
_ACEOF
diff --git a/configure.in b/configure.in
index 5479eab..134ea55 100644
--- a/configure.in
+++ b/configure.in
@@ -1628,35 +1628,29 @@ fi
# If we found "long int" is 64 bits, assume snprintf handles it. If
# we found we need to use "long long int", better check. We cope with
-# snprintfs that use %lld, %qd, or %I64d as the format. If none of these
-# work, fall back to our own snprintf emulation (which we know uses %lld).
+# snprintfs that use lld, qd, or I64d as the modifier. If none of these
+# work, fall back to our own snprintf emulation (which we know uses ll).
if test "$HAVE_LONG_LONG_INT_64" = yes ; then
if test $pgac_need_repl_snprintf = no; then
- PGAC_FUNC_SNPRINTF_LONG_LONG_INT_FORMAT
- if test "$LONG_LONG_INT_FORMAT" = ""; then
+ PGAC_FUNC_SNPRINTF_LONG_LONG_LENGTH_MODIFIER
+ if test "$LONG_LONG_LENGTH_MODIFIER" = ""; then
# Force usage of our own snprintf, since system snprintf is broken
pgac_need_repl_snprintf=yes
- LONG_LONG_INT_FORMAT='%lld'
+ LONG_LONG_LENGTH_MODIFIER='ll'
fi
else
# Here if we previously decided we needed to use our own snprintf
- LONG_LONG_INT_FORMAT='%lld'
+ LONG_LONG_LENGTH_MODIFIER='ll'
fi
- LONG_LONG_UINT_FORMAT=`echo "$LONG_LONG_INT_FORMAT" | sed 's/d$/u/'`
- INT64_FORMAT="\"$LONG_LONG_INT_FORMAT\""
- UINT64_FORMAT="\"$LONG_LONG_UINT_FORMAT\""
+ INT64_LENGTH_MODIFIER="$LONG_LONG_LENGTH_MODIFIER"
else
- # Here if we are not using 'long long int' at all
- INT64_FORMAT='"%ld"'
- UINT64_FORMAT='"%lu"'
+ # Here if we are not using 'long long' at all
+ INT64_LENGTH_MODIFIER='l'
fi
-AC_DEFINE_UNQUOTED(INT64_FORMAT, $INT64_FORMAT,
- [Define to the appropriate snprintf format for 64-bit ints.])
-
-AC_DEFINE_UNQUOTED(UINT64_FORMAT, $UINT64_FORMAT,
- [Define to the appropriate snprintf format for unsigned 64-bit ints.])
+AC_DEFINE_UNQUOTED(INT64_LENGTH_MODIFIER, $INT64_LENGTH_MODIFIER,
+ [Define to the appropriate snprintf length modifier for 64-bit ints.])
# Now we have checked all the reasons to replace snprintf
if test $pgac_need_repl_snprintf = yes; then
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 65eb3bd..a2d0856 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -3185,6 +3185,22 @@ expand_fmt_string(const char *fmt, ErrorData *edata)
appendStringInfoCharMacro(&buf, *cp2);
}
}
+ else if (*cp == 'z')
+ {
+ /*
+ * Replace %z by the appropriate length modifier for printing
+ * Size/size_t or ssize_t arguments for the current
+ * platform. Note that we don't support specifying with and
+ * precision modifiers, but that's ok for the current
+ * callsites.
+ */
+#if SIZEOF_SIZE_T == 4
+ /* no modifier needed */
+#else
+ appendBinaryStringInfo(&buf, CppAsString2(INT64_LENGTH_MODIFIER),
+ strlen(CppAsString2(INT64_LENGTH_MODIFIER)));
+#endif
+ }
else
{
/* copy % and next char --- this avoids trouble with %%m */
diff --git a/src/include/c.h b/src/include/c.h
index beb20b0..4e6f827 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -127,6 +127,8 @@
/*
* CppAsString
* Convert the argument to a string, using the C preprocessor.
+ * CppAsString2
+ * Convert the argument's value to a string, using the C preprocessor.
* CppConcat
* Concatenate two arguments together, using the C preprocessor.
*
@@ -135,6 +137,8 @@
* backward compatibility with existing PostgreSQL code.
*/
#define CppAsString(identifier) #identifier
+/* need a second indirection because we want to stringize the macro value, not the name */
+#define CppAsString2(x) CppAsString(x)
#define CppConcat(x, y) x##y
/*
@@ -279,6 +283,9 @@ typedef unsigned long long int uint64;
#define UINT64CONST(x) ((uint64) x)
#endif
+/* format codes for 64bit integers */
+#define INT64_FORMAT "%"CppAsString2(INT64_LENGTH_MODIFIER)"d"
+#define UINT64_FORMAT "%"CppAsString2(INT64_LENGTH_MODIFIER)"u"
/* Select timestamp representation (float8 or int64) */
#ifdef USE_INTEGER_DATETIMES
@@ -894,9 +901,6 @@ typedef NameData *Name;
* Make sure this matches the installation rules in nls-global.mk.
*/
-/* need a second indirection because we want to stringize the macro value, not the name */
-#define CppAsString2(x) CppAsString(x)
-
#ifdef SO_MAJOR_VERSION
#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION)
#else
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index d482e58..52aa03d 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -650,8 +650,8 @@
/* Define to 1 if your compiler understands __VA_ARGS__ in macros. */
#undef HAVE__VA_ARGS
-/* Define to the appropriate snprintf format for 64-bit ints. */
-#undef INT64_FORMAT
+/* Define to the appropriate snprintf length modifier for 64-bit ints. */
+#undef INT64_LENGTH_MODIFIER
/* Define to build with Kerberos 5 support. (--with-krb5) */
#undef KRB5
@@ -745,9 +745,6 @@
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
-/* Define to the appropriate snprintf format for unsigned 64-bit ints. */
-#undef UINT64_FORMAT
-
/* Define to 1 to build with assertion checks. (--enable-cassert) */
#undef USE_ASSERT_CHECKING
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index b69414f..e7eac3a 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -538,8 +538,8 @@
/* Define to 1 if your compiler understands __VA_ARGS__ in macros. */
#define HAVE__VA_ARGS 1
-/* Define to the appropriate snprintf format for 64-bit ints, if any. */
-#define INT64_FORMAT "%lld"
+/* Define to the appropriate snprintf length modifier for 64-bit ints. */
+#define INT64_LENGTH_MODIFIER ll
/* Define to build with Kerberos 5 support. (--with-krb5) */
/* #undef KRB5 */
@@ -617,10 +617,6 @@
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */
-/* Define to the appropriate snprintf format for unsigned 64-bit ints, if any.
- */
-#define UINT64_FORMAT "%llu"
-
/* Define to 1 to build with assertion checks. (--enable-cassert) */
/* #undef USE_ASSERT_CHECKING */
--
1.8.5.rc2.dirty
0002-Use-the-new-z-support-in-several-elog-ereport-caller.patchtext/x-patch; charset=us-asciiDownload
>From 9614445f287f49a1f30fc6c1aab3b4c003d278cc Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 7 Dec 2013 19:23:39 +0100
Subject: [PATCH 2/2] Use the new %z support in several elog()/ereport()
callers.
Some of the callsites were actually wrong, notably in aset.c and
mcxt.c, because they simply cast Size arguments to unsigned long,
which will give wrong results on LLP64 platforms like 64bit
windows. Many others just are shorter the new way.
---
src/backend/access/hash/hashinsert.c | 5 ++---
src/backend/access/heap/hio.c | 7 +++----
src/backend/access/heap/rewriteheap.c | 5 ++---
src/backend/access/spgist/spgdoinsert.c | 6 +++---
src/backend/access/transam/xlog.c | 4 ++--
src/backend/nodes/readfuncs.c | 13 +++++--------
src/backend/port/sysv_shmem.c | 4 ++--
src/backend/port/win32_shmem.c | 4 ++--
src/backend/storage/file/fd.c | 2 +-
src/backend/storage/freespace/freespace.c | 3 +--
src/backend/storage/ipc/dsm.c | 4 ++--
src/backend/storage/ipc/dsm_impl.c | 12 ++++++------
src/backend/storage/ipc/ipci.c | 3 +--
src/backend/storage/ipc/shmem.c | 14 ++++++--------
src/backend/storage/lmgr/predicate.c | 8 ++++----
src/backend/utils/mmgr/aset.c | 23 ++++++++++-------------
src/backend/utils/mmgr/mcxt.c | 24 ++++++++----------------
17 files changed, 60 insertions(+), 81 deletions(-)
diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c
index 4508a36..bcc1713 100644
--- a/src/backend/access/hash/hashinsert.c
+++ b/src/backend/access/hash/hashinsert.c
@@ -65,9 +65,8 @@ _hash_doinsert(Relation rel, IndexTuple itup)
if (itemsz > HashMaxItemSize((Page) metap))
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("index row size %lu exceeds hash maximum %lu",
- (unsigned long) itemsz,
- (unsigned long) HashMaxItemSize((Page) metap)),
+ errmsg("index row size %zu exceeds hash maximum %zu",
+ itemsz, HashMaxItemSize((Page) metap)),
errhint("Values larger than a buffer page cannot be indexed.")));
/*
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index 8da2690..e15c416 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -237,9 +237,8 @@ RelationGetBufferForTuple(Relation relation, Size len,
if (len > MaxHeapTupleSize)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("row is too big: size %lu, maximum size %lu",
- (unsigned long) len,
- (unsigned long) MaxHeapTupleSize)));
+ errmsg("row is too big: size %zu, maximum size %zu",
+ len, MaxHeapTupleSize)));
/* Compute desired extra freespace due to fillfactor option */
saveFreeSpace = RelationGetTargetPageFreeSpace(relation,
@@ -477,7 +476,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
if (len > PageGetHeapFreeSpace(page))
{
/* We should not get here given the test at the top */
- elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
+ elog(PANIC, "tuple is too big: size %zu", len);
}
/*
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index deec77d..eb418d3 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -601,9 +601,8 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
if (len > MaxHeapTupleSize)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("row is too big: size %lu, maximum size %lu",
- (unsigned long) len,
- (unsigned long) MaxHeapTupleSize)));
+ errmsg("row is too big: size %zu, maximum size %zu",
+ len, MaxHeapTupleSize)));
/* Compute desired extra freespace due to fillfactor option */
saveFreeSpace = RelationGetTargetPageFreeSpace(state->rs_new_rel,
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
index 9f425ca..a739f1b 100644
--- a/src/backend/access/spgist/spgdoinsert.c
+++ b/src/backend/access/spgist/spgdoinsert.c
@@ -1885,9 +1885,9 @@ spgdoinsert(Relation index, SpGistState *state,
if (leafSize > SPGIST_PAGE_CAPACITY && !state->config.longValuesOK)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("index row size %lu exceeds maximum %lu for index \"%s\"",
- (unsigned long) (leafSize - sizeof(ItemIdData)),
- (unsigned long) (SPGIST_PAGE_CAPACITY - sizeof(ItemIdData)),
+ errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
+ leafSize - sizeof(ItemIdData),
+ SPGIST_PAGE_CAPACITY - sizeof(ItemIdData),
RelationGetRelationName(index)),
errhint("Values larger than a buffer page cannot be indexed.")));
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index b68230d..4bdbe38 100755
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2728,9 +2728,9 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not write to log file %s "
- "at offset %u, length %lu: %m",
+ "at offset %u, length %zu: %m",
XLogFileNameP(ThisTimeLineID, openLogSegNo),
- openLogOff, (unsigned long) nbytes)));
+ openLogOff, nbytes)));
}
nleft -= written;
from += written;
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 2e2cfa7..955bd6a 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1435,15 +1435,13 @@ readDatum(bool typbyval)
token = pg_strtok(&tokenLength); /* read the '[' */
if (token == NULL || token[0] != '[')
- elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %lu",
- token ? (const char *) token : "[NULL]",
- (unsigned long) length);
+ elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
+ token ? (const char *) token : "[NULL]", length);
if (typbyval)
{
if (length > (Size) sizeof(Datum))
- elog(ERROR, "byval datum but length = %lu",
- (unsigned long) length);
+ elog(ERROR, "byval datum but length = %zu", length);
res = (Datum) 0;
s = (char *) (&res);
for (i = 0; i < (Size) sizeof(Datum); i++)
@@ -1467,9 +1465,8 @@ readDatum(bool typbyval)
token = pg_strtok(&tokenLength); /* read the ']' */
if (token == NULL || token[0] != ']')
- elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %lu",
- token ? (const char *) token : "[NULL]",
- (unsigned long) length);
+ elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
+ token ? (const char *) token : "[NULL]", length);
return res;
}
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index b604407..34f211e 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -138,8 +138,8 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
*/
ereport(FATAL,
(errmsg("could not create shared memory segment: %m"),
- errdetail("Failed system call was shmget(key=%lu, size=%lu, 0%o).",
- (unsigned long) memKey, (unsigned long) size,
+ errdetail("Failed system call was shmget(key=%lu, size=%zu, 0%o).",
+ (unsigned long) memKey, size,
IPC_CREAT | IPC_EXCL | IPCProtection),
(errno == EINVAL) ?
errhint("This error usually means that PostgreSQL's request for a shared memory "
diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c
index 0db8e8f..e456f65 100644
--- a/src/backend/port/win32_shmem.c
+++ b/src/backend/port/win32_shmem.c
@@ -166,8 +166,8 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
if (!hmap)
ereport(FATAL,
(errmsg("could not create shared memory segment: error code %lu", GetLastError()),
- errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s).",
- (unsigned long) size, szShareMem)));
+ errdetail("Failed system call was CreateFileMapping(size=%zu, name=%s).",
+ size, szShareMem)));
/*
* If the segment already existed, CreateFileMapping() will return a
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index de4d902..494ca9e 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -829,7 +829,7 @@ AllocateVfd(void)
Index i;
File file;
- DO_DB(elog(LOG, "AllocateVfd. Size %lu", (unsigned long) SizeVfdCache));
+ DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index b15cf8f..1e91563 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -379,8 +379,7 @@ fsm_space_needed_to_cat(Size needed)
/* Can't ask for more space than the highest category represents */
if (needed > MaxFSMRequestSize)
- elog(ERROR, "invalid FSM request size %lu",
- (unsigned long) needed);
+ elog(ERROR, "invalid FSM request size %zu", needed);
if (needed == 0)
return 1;
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 6df402f..7e6e1a5 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -193,8 +193,8 @@ dsm_postmaster_startup(void)
dsm_control = dsm_control_address;
on_shmem_exit(dsm_postmaster_shutdown, 0);
elog(DEBUG2,
- "created dynamic shared memory control segment %u (%lu bytes)",
- dsm_control_handle, (unsigned long) segsize);
+ "created dynamic shared memory control segment %u (%zu bytes)",
+ dsm_control_handle, segsize);
dsm_write_state_file(dsm_control_handle);
/* Initialize control segment. */
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index 7c346e6..5b3589a 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -329,8 +329,8 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
ereport(elevel,
(errcode_for_dynamic_shared_memory(),
- errmsg("could not resize shared memory segment %s to %lu bytes: %m",
- name, (unsigned long) request_size)));
+ errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+ name, request_size)));
return false;
}
@@ -871,8 +871,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
ereport(elevel,
(errcode_for_dynamic_shared_memory(),
- errmsg("could not resize shared memory segment %s to %lu bytes: %m",
- name, (unsigned long) request_size)));
+ errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+ name, request_size)));
return false;
}
else if (*mapped_size < request_size)
@@ -919,8 +919,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
ereport(elevel,
(errcode_for_dynamic_shared_memory(),
- errmsg("could not resize shared memory segment %s to %lu bytes: %m",
- name, (unsigned long) request_size)));
+ errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+ name, request_size)));
return false;
}
}
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 040c7aa..57e2b9d 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -141,8 +141,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
/* might as well round it off to a multiple of a typical page size */
size = add_size(size, 8192 - (size % 8192));
- elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
- (unsigned long) size);
+ elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
/*
* Create the shmem segment
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 18ba426..8183931 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -344,8 +344,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for data structure"
- " \"%s\" (%lu bytes requested)",
- name, (unsigned long) size)));
+ " \"%s\" (%zu bytes requested)",
+ name, size)));
shmemseghdr->index = structPtr;
*foundPtr = FALSE;
}
@@ -378,10 +378,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
LWLockRelease(ShmemIndexLock);
ereport(ERROR,
(errmsg("ShmemIndex entry size is wrong for data structure"
- " \"%s\": expected %lu, actual %lu",
- name,
- (unsigned long) size,
- (unsigned long) result->size)));
+ " \"%s\": expected %zu, actual %zu",
+ name, size, result->size)));
}
structPtr = result->location;
}
@@ -397,8 +395,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for data structure"
- " \"%s\" (%lu bytes requested)",
- name, (unsigned long) size)));
+ " \"%s\" (%zu bytes requested)",
+ name, size)));
}
result->size = size;
result->location = structPtr;
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index a8a0e98..12a9e85 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -1185,8 +1185,8 @@ InitPredicateLocks(void)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for elements of data structure"
- " \"%s\" (%lu bytes requested)",
- "PredXactList", (unsigned long) requestSize)));
+ " \"%s\" (%zu bytes requested)",
+ "PredXactList", requestSize)));
/* Add all elements to available list, clean. */
memset(PredXact->element, 0, requestSize);
for (i = 0; i < max_table_size; i++)
@@ -1257,8 +1257,8 @@ InitPredicateLocks(void)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for elements of data structure"
- " \"%s\" (%lu bytes requested)",
- "RWConflictPool", (unsigned long) requestSize)));
+ " \"%s\" (%zu bytes requested)",
+ "RWConflictPool", requestSize)));
/* Add all elements to available list, clean. */
memset(RWConflictPool->element, 0, requestSize);
for (i = 0; i < max_table_size; i++)
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index ff04a38..b6bbc7a 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -676,8 +676,7 @@ AllocSetAlloc(MemoryContext context, Size size)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"),
- errdetail("Failed on request of size %lu.",
- (unsigned long) size)));
+ errdetail("Failed on request of size %zu.", size)));
}
block->aset = set;
block->freeptr = block->endptr = ((char *) block) + blksize;
@@ -871,8 +870,7 @@ AllocSetAlloc(MemoryContext context, Size size)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"),
- errdetail("Failed on request of size %lu.",
- (unsigned long) size)));
+ errdetail("Failed on request of size %zu.", size)));
}
block->aset = set;
@@ -1114,8 +1112,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"),
- errdetail("Failed on request of size %lu.",
- (unsigned long) size)));
+ errdetail("Failed on request of size %zu.", size)));
}
block->freeptr = block->endptr = ((char *) block) + blksize;
@@ -1245,10 +1242,10 @@ static void
AllocSetStats(MemoryContext context, int level)
{
AllocSet set = (AllocSet) context;
- long nblocks = 0;
- long nchunks = 0;
- long totalspace = 0;
- long freespace = 0;
+ Size nblocks = 0;
+ Size nchunks = 0;
+ Size totalspace = 0;
+ Size freespace = 0;
AllocBlock block;
AllocChunk chunk;
int fidx;
@@ -1274,7 +1271,7 @@ AllocSetStats(MemoryContext context, int level)
fprintf(stderr, " ");
fprintf(stderr,
- "%s: %lu total in %ld blocks; %lu free (%ld chunks); %lu used\n",
+ "%s: %zu total in %zd blocks; %zu free (%zd chunks); %zu used\n",
set->header.name, totalspace, nblocks, freespace, nchunks,
totalspace - freespace);
}
@@ -1338,8 +1335,8 @@ AllocSetCheck(MemoryContext context)
elog(WARNING, "problem in alloc set %s: req size > alloc size for chunk %p in block %p",
name, chunk, block);
if (chsize < (1 << ALLOC_MINBITS))
- elog(WARNING, "problem in alloc set %s: bad size %lu for chunk %p in block %p",
- name, (unsigned long) chsize, chunk, block);
+ elog(WARNING, "problem in alloc set %s: bad size %zu for chunk %p in block %p",
+ name, chsize, chunk, block);
/* single-chunk block? */
if (chsize > set->allocChunkLimit &&
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 9574fd3..b97c098 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -573,8 +573,7 @@ MemoryContextAlloc(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -599,8 +598,7 @@ MemoryContextAllocZero(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -627,8 +625,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -649,8 +646,7 @@ palloc(Size size)
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
CurrentMemoryContext->isReset = false;
@@ -669,8 +665,7 @@ palloc0(Size size)
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
CurrentMemoryContext->isReset = false;
@@ -722,8 +717,7 @@ repalloc(void *pointer, Size size)
void *ret;
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
/*
* Try to detect bogus pointers handed to us, poorly though we can.
@@ -764,8 +758,7 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocHugeSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -787,8 +780,7 @@ repalloc_huge(void *pointer, Size size)
void *ret;
if (!AllocHugeSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
/*
* Try to detect bogus pointers handed to us, poorly though we can.
--
1.8.5.rc2.dirty
On Sun, 2013-12-08 at 01:32 +0100, Andres Freund wrote:
Patch 02 converts some elog/ereport() callers to using the z modifier,
some were wrong at least on 64 bit windows.
This is making the assumption that Size is the same as size_t. If we
are going to commit to that, we might as well get rid of Size.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-12-08 11:43:46 -0500, Peter Eisentraut wrote:
On Sun, 2013-12-08 at 01:32 +0100, Andres Freund wrote:
Patch 02 converts some elog/ereport() callers to using the z modifier,
some were wrong at least on 64 bit windows.This is making the assumption that Size is the same as size_t. If we
are going to commit to that, we might as well get rid of Size.
Well, we're unconditionally defining it as such in c.h and its usage is
pretty much what size_t is for. Given how widespread Size's use is, I am
not seing a realistic way of getting rid of it though.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-12-08 01:32:45 +0100, Andres Freund wrote:
On 2013-12-06 09:54:59 -0500, Peter Eisentraut wrote:
On 11/11/13, 12:01 PM, Tom Lane wrote:
I do recall Peter saying that the infrastructure knows how to
verify conversion specs in translated strings, so it would have to be
aware of 'z' flags for this to work.It just checks that the same conversion placeholders appear in the
translation. It doesn't interpret the actual placeholders. I don't
think this will be a problem.Ok, so here's a patch.
Patch 01 introduces infrastructure, and elog.c implementation.
Patch 02 converts some elog/ereport() callers to using the z modifier,
some were wrong at least on 64 bit windows.
There's just been another instance of printing size_t values being
annoying, reminding me of this patch. I'll add it to the current
commitfest given I've posted it over a month ago unless somebody
protests?
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
[ 0001-Add-support-for-printing-Size-arguments-to-elog-erep.patch ]
I think this approach is fundamentally broken, because it can't reasonably
cope with any case more complicated than "%zu" or "%zd". While it's
arguable that we can get along without the ability to specify field width,
since the [U]INT64_FORMAT macros never allowed that, it is surely going
to be the case that translators will need to insert "n$" flags in the
translated versions of messages.
Another objection is that this only fixes the problem in elog/ereport
format strings, not anyplace else that it might be useful to print a
size_t value. You suggest below that we could invent some additional
macros to support that; but since the "z" flag is in C99, there really
ought to be only a small minority of platforms where it doesn't work.
So I don't think we should be contorting our code with some nonstandard
notation for the case, if there's any way to avoid that.
I think a better solution approach is to teach our src/port/snprintf.c
about the z flag, then extend configure's checking to force use of our
snprintf if the platform's version doesn't handle z. While it might be
objected that this creates a need for a run-time check in configure,
we already have one to check if snprintf handles "n$", so this approach
doesn't really make life any worse for cross-compiles.
In patch 01, I've modified configure to not define [U]INT64_FORMAT
directly, but rather just define INT64_LENGTH_MODIFIER as
appropriate. The formats are now defined in c.h.
INT64_LENGTH_MODIFIER is defined without quotes - I am not sure whether
that was the right choice, it requires using CppAsString2() in some
places. Maybe I should just have defined it with quotes instead. Happy
to rejigger it if somebody thinks the other way would be better.
Meh. This isn't needed if we do what I suggest above, but in any case
I don't approve of removing the existing [U]INT64_FORMAT macros.
That breaks code that doesn't need to get broken, probably including
third-party modules. It'd be more sensible to just add an additional
macro for the flag character(s). (And yeah, I'd put quotes in it.)
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
I wrote:
Meh. This isn't needed if we do what I suggest above, but in any case
I don't approve of removing the existing [U]INT64_FORMAT macros.
That breaks code that doesn't need to get broken, probably including
third-party modules.
After looking more closely I see you didn't actually *remove* those
macros, just define them in a different place/way. So the above objection
is just noise, sorry. (Though I think it'd be notationally cleaner to let
configure continue to define the macros; it doesn't need to do anything as
ugly as CppAsString2() to concatenate...)
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi,
On 2014-01-17 13:50:08 -0500, Tom Lane wrote:
I think a better solution approach is to teach our src/port/snprintf.c
about the z flag, then extend configure's checking to force use of our
snprintf if the platform's version doesn't handle z. While it might be
objected that this creates a need for a run-time check in configure,
we already have one to check if snprintf handles "n$", so this approach
doesn't really make life any worse for cross-compiles.
Hm. I had thought about that, but dismissed it because I thought people
would argue about it being too invasive...
If we're going there, we should just eliminate expand_fmt_string() from
elog.c and test for it in configure too, right?
You suggest below that we could invent some additional
macros to support that; but since the "z" flag is in C99, there really
ought to be only a small minority of platforms where it doesn't work.
Well, maybe just a minority numberwise, but one of them being windows
surely makes it count in number of installations...
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-17 14:18:55 -0500, Tom Lane wrote:
I wrote:
Meh. This isn't needed if we do what I suggest above, but in any case
I don't approve of removing the existing [U]INT64_FORMAT macros.
That breaks code that doesn't need to get broken, probably including
third-party modules.After looking more closely I see you didn't actually *remove* those
macros, just define them in a different place/way. So the above objection
is just noise, sorry. (Though I think it'd be notationally cleaner to let
configure continue to define the macros; it doesn't need to do anything as
ugly as CppAsString2() to concatenate...)
I prefer having configure just define the lenght modifier since that
allows to define further macros containing formats. But I think defining
them as strings instead row literals as I had might make it a bit less ugly...
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-17 13:50:08 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
[ 0001-Add-support-for-printing-Size-arguments-to-elog-erep.patch ]
I think this approach is fundamentally broken, because it can't reasonably
cope with any case more complicated than "%zu" or "%zd". While it's
arguable that we can get along without the ability to specify field width,
since the [U]INT64_FORMAT macros never allowed that, it is surely going
to be the case that translators will need to insert "n$" flags in the
translated versions of messages.
Am I just too tired, or am I not getting how INT64_FORMAT currently
allows the arguments to be used posititional?
Admittedly most places currently just cast down the value avoiding the
need for INT64_FORMAT in many places.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-17 13:50:08 -0500, Tom Lane wrote:
I think a better solution approach is to teach our src/port/snprintf.c
about the z flag, then extend configure's checking to force use of our
snprintf if the platform's version doesn't handle z.
Hm. I had thought about that, but dismissed it because I thought people
would argue about it being too invasive...
How so? It'd be a lot less invasive than what we'd have to do to use
'z' flags the other way.
If we're going there, we should just eliminate expand_fmt_string() from
elog.c and test for it in configure too, right?
If you mean "let's rely on glibc for %m", the answer is "not bloody
likely". See useful_strerror(), which is functionality we'd lose if
we short-circuit that.
You suggest below that we could invent some additional
macros to support that; but since the "z" flag is in C99, there really
ought to be only a small minority of platforms where it doesn't work.
Well, maybe just a minority numberwise, but one of them being windows
surely makes it count in number of installations...
Agreed, but I believe we're already using src/port/snprintf.c on Windows
because of lack of %n$ support (which is also required by C99).
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-17 13:50:08 -0500, Tom Lane wrote:
I think this approach is fundamentally broken, because it can't reasonably
cope with any case more complicated than "%zu" or "%zd".
Am I just too tired, or am I not getting how INT64_FORMAT currently
allows the arguments to be used posititional?
It doesn't, which is one of the reasons for not allowing it in
translatable strings (the other being lack of standardization of the
strings that would be subject to translation). Adding 'z' will only
fix this for cases where what we want to print is really a size_t.
That's a usefully large set, but not all the cases by any means.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
I wrote:
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-17 13:50:08 -0500, Tom Lane wrote:
I think this approach is fundamentally broken, because it can't reasonably
cope with any case more complicated than "%zu" or "%zd".
Am I just too tired, or am I not getting how INT64_FORMAT currently
allows the arguments to be used posititional?
It doesn't, which is one of the reasons for not allowing it in
translatable strings (the other being lack of standardization of the
strings that would be subject to translation).
On second thought, that answer was too glib. There's no need for %n$
in the format strings *in the source code*, so INT64_FORMAT isn't getting
in the way from that perspective. However, expand_fmt_string() is
necessarily applied to formats *after* they've been through gettext(),
so it has to expect that it might see %n$ in the now-translated strings.
It's still the case that we need a policy against INT64_FORMAT in
translatable strings, though, because what's passed to the gettext
mechanism has to be a fixed string not something with platform
dependencies in it. Or so I would assume, anyway.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Jan 17, 2014 at 8:36 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I wrote:
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-17 13:50:08 -0500, Tom Lane wrote:
I think this approach is fundamentally broken, because it can't reasonably
cope with any case more complicated than "%zu" or "%zd".Am I just too tired, or am I not getting how INT64_FORMAT currently
allows the arguments to be used posititional?It doesn't, which is one of the reasons for not allowing it in
translatable strings (the other being lack of standardization of the
strings that would be subject to translation).On second thought, that answer was too glib. There's no need for %n$
in the format strings *in the source code*, so INT64_FORMAT isn't getting
in the way from that perspective. However, expand_fmt_string() is
necessarily applied to formats *after* they've been through gettext(),
so it has to expect that it might see %n$ in the now-translated strings.It's still the case that we need a policy against INT64_FORMAT in
translatable strings, though, because what's passed to the gettext
mechanism has to be a fixed string not something with platform
dependencies in it. Or so I would assume, anyway.
Well, that's kinda problematic, isn't it? Printing the variable into
a static buffer so that it can then be formatted with %s is pretty
pessimal for a message that we might not even be planning to emit.
Perhaps we should jettison entirely the idea of using the operating
system's built-in sprintf and use one of our own that has all of the
nice widgets we need, like a format code that's guaranteed to be right
for uint64 and one that's guaranteed to be right for Size. This could
turn out to be a bad idea if the best sprintf we can write is much
slower than the native sprintf on any common platforms ... and maybe
it wouldn't play nice with GCC's desire to check format strings. But
what we're doing now is a real nuisance, too.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Robert Haas escribi�:
On Fri, Jan 17, 2014 at 8:36 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
I wrote:
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-17 13:50:08 -0500, Tom Lane wrote:
Am I just too tired, or am I not getting how INT64_FORMAT currently
allows the arguments to be used posititional?It doesn't, which is one of the reasons for not allowing it in
translatable strings (the other being lack of standardization of the
strings that would be subject to translation).On second thought, that answer was too glib. There's no need for %n$
in the format strings *in the source code*, so INT64_FORMAT isn't getting
in the way from that perspective. However, expand_fmt_string() is
necessarily applied to formats *after* they've been through gettext(),
so it has to expect that it might see %n$ in the now-translated strings.
How difficult would it be to have expand_fmt_string deal with positional
modifiers? I don't think we need anything from it other than the %n$
notation, so perhaps it's not so problematic.
Perhaps we should jettison entirely the idea of using the operating
system's built-in sprintf and use one of our own that has all of the
nice widgets we need, like a format code that's guaranteed to be right
for uint64 and one that's guaranteed to be right for Size. This could
turn out to be a bad idea if the best sprintf we can write is much
slower than the native sprintf on any common platforms ... and maybe
it wouldn't play nice with GCC's desire to check format strings. But
what we're doing now is a real nuisance, too.
Maybe we can use our own implementation if the system's doesn't support
%z. It's present in glibc 2.1 at least, and it's part of in the 2004
edition of POSIX:2001.
http://pubs.opengroup.org/onlinepubs/009695399/functions/sprintf.html
(It is not present in SUSv2 (1997), and I wasn't able to find the
original POSIX:2001 version.)
--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-21 12:11:23 -0300, Alvaro Herrera wrote:
How difficult would it be to have expand_fmt_string deal with positional
modifiers? I don't think we need anything from it other than the %n$
notation, so perhaps it's not so problematic.
I don't think there's much reason to go there. I didn't go for the
pg-supplied sprintf() because I thought it'd be considered to
invasive. Since that's apparently not the case...
Perhaps we should jettison entirely the idea of using the operating
system's built-in sprintf and use one of our own that has all of the
nice widgets we need, like a format code that's guaranteed to be right
for uint64 and one that's guaranteed to be right for Size. This could
turn out to be a bad idea if the best sprintf we can write is much
slower than the native sprintf on any common platforms ... and maybe
it wouldn't play nice with GCC's desire to check format strings. But
what we're doing now is a real nuisance, too.Maybe we can use our own implementation if the system's doesn't support
%z. It's present in glibc 2.1 at least, and it's part of in the 2004
edition of POSIX:2001.
http://pubs.opengroup.org/onlinepubs/009695399/functions/sprintf.html
Yea, I have a patch for that, will send it as soon as some other stuff
is finished.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-21 12:11:23 -0300, Alvaro Herrera wrote:
How difficult would it be to have expand_fmt_string deal with positional
modifiers? I don't think we need anything from it other than the %n$
notation, so perhaps it's not so problematic.
I don't think there's much reason to go there. I didn't go for the
pg-supplied sprintf() because I thought it'd be considered to
invasive. Since that's apparently not the case...
Yeah, that would make expand_fmt_string considerably more complicated
and so presumably slower. We don't really need that when we can make
what I expect is a pretty trivial addition to snprintf.c. Also, fixing
snprintf.c will make it safe to use the z flag in contexts other than
ereport/elog.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Robert Haas <robertmhaas@gmail.com> writes:
On Fri, Jan 17, 2014 at 8:36 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
It's still the case that we need a policy against INT64_FORMAT in
translatable strings, though, because what's passed to the gettext
mechanism has to be a fixed string not something with platform
dependencies in it. Or so I would assume, anyway.
Well, that's kinda problematic, isn't it? Printing the variable into
a static buffer so that it can then be formatted with %s is pretty
pessimal for a message that we might not even be planning to emit.
Well, it's a tad annoying, but a quick grep says there are maybe 40
cases of this in our source code, so I'm not sure it's rising to the
level of a must-fix problem.
Perhaps we should jettison entirely the idea of using the operating
system's built-in sprintf and use one of our own that has all of the
nice widgets we need, like a format code that's guaranteed to be right
for uint64 and one that's guaranteed to be right for Size. This could
turn out to be a bad idea if the best sprintf we can write is much
slower than the native sprintf on any common platforms ... and maybe
it wouldn't play nice with GCC's desire to check format strings.
That last is a deal-breaker. It's not just whether "gcc desires" to check
this --- we *need* that checking, because people get it wrong without it.
I thought about proposing that we insist that snprintf support the "ll"
flag (substituting our own if not). But that doesn't really fix anything
unless we're willing to explicitly cast the corresponding values to
"long long", which is probably not workable from a portability standpoint.
I'm not really worried about platforms thinking long long is 128 bits ---
I'm worried about old compilers that don't have such a datatype.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Jan21, 2014, at 18:56 , Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
Perhaps we should jettison entirely the idea of using the operating
system's built-in sprintf and use one of our own that has all of the
nice widgets we need, like a format code that's guaranteed to be right
for uint64 and one that's guaranteed to be right for Size. This could
turn out to be a bad idea if the best sprintf we can write is much
slower than the native sprintf on any common platforms ... and maybe
it wouldn't play nice with GCC's desire to check format strings.That last is a deal-breaker. It's not just whether "gcc desires" to check
this --- we *need* that checking, because people get it wrong without it.
There's an attribute that enables this check for arbitrary functions AFAIR.
best regards,
Florian Pflug
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Florian Pflug <fgp@phlo.org> writes:
On Jan21, 2014, at 18:56 , Tom Lane <tgl@sss.pgh.pa.us> wrote:
Robert Haas <robertmhaas@gmail.com> writes:
it wouldn't play nice with GCC's desire to check format strings.
That last is a deal-breaker. It's not just whether "gcc desires" to check
this --- we *need* that checking, because people get it wrong without it.
There's an attribute that enables this check for arbitrary functions AFAIR.
Yeah, we use it (to enable checking for ereport et al). The issue is that
the semantics of the format-string are pretty much hard-wired into gcc;
eg it knows that "%ld" should match an argument of type "long int".
IIRC it does know a couple of different styles corresponding to popular
libc implementations ... but it is not going to support some random
semantics that we dream up.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-21 11:33:40 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-21 12:11:23 -0300, Alvaro Herrera wrote:
How difficult would it be to have expand_fmt_string deal with positional
modifiers? I don't think we need anything from it other than the %n$
notation, so perhaps it's not so problematic.I don't think there's much reason to go there. I didn't go for the
pg-supplied sprintf() because I thought it'd be considered to
invasive. Since that's apparently not the case...Yeah, that would make expand_fmt_string considerably more complicated
and so presumably slower. We don't really need that when we can make
what I expect is a pretty trivial addition to snprintf.c. Also, fixing
snprintf.c will make it safe to use the z flag in contexts other than
ereport/elog.
So, here's a patch adding %z support to port/snprintf.c including a
configure check to test whether we need to fall back. I am not too
happy about the runtime check as the test isn't all that meaningful, but
I couldn't think of anything better.
The second patch is a slightly updated version of a previously sent
version which is starting to use %z in some more places.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
0001-Add-support-for-the-z-modifier-in-error-messages-and.patchtext/x-patch; charset=us-asciiDownload
>From 5c91e08cb2c4b3cc8779ed0cd89387eb38ea3690 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 23 Jan 2014 15:45:36 +0100
Subject: [PATCH 1/2] Add support for the %z modifier in error messages and
other usages of printf.
The %z modifier allows to print size_t/Size variables without platform
dependent modifiers like UINT64_FORMAT and is included in C99 and
posix. As it's not present in all supported platforms add a configure
check which tests whether it's supported and actually working to some
degree and fall back to our existing snprintf.c fallback which now
supports the modifier if not.
---
config/c-library.m4 | 38 ++++++++++++++++++++++++++++++++++++++
configure | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.in | 8 ++++++++
src/port/snprintf.c | 26 ++++++++++++++++++++++++++
4 files changed, 124 insertions(+)
diff --git a/config/c-library.m4 b/config/c-library.m4
index 1e3997b..171d39c 100644
--- a/config/c-library.m4
+++ b/config/c-library.m4
@@ -303,6 +303,44 @@ int main()
AC_MSG_RESULT([$pgac_cv_printf_arg_control])
])# PGAC_FUNC_PRINTF_ARG_CONTROL
+# PGAC_FUNC_PRINTF_SIZE_T_SUPPORT
+# ---------------------------------------
+# Determine if printf supports the z length modifier for printing
+# sizeof(size_t) sized variables. That's supported by C99 and posix but not
+# all platforms play ball, so we test whether it's working.
+# Useful for printing sizes in error messages et al. without up/downcasting
+# arguments.
+#
+AC_DEFUN([PGAC_FUNC_PRINTF_SIZE_T_SUPPORT],
+[AC_MSG_CHECKING([whether printf supports the %z modifier])
+AC_CACHE_VAL(pgac_cv_printf_size_t_support,
+[AC_TRY_RUN([#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+ char buf64[100];
+ char bufz[100];
+
+ /*
+ * Check whether we print correctly using %z by printing the biggest
+ * unsigned number fitting in a size_t and using both %zu and the format for
+ * 64bit numbers.
+ */
+
+ snprintf(bufz, 100, "%zu, ~(size_t)0);
+ snprintf(buf64, 100, UINT64_FORMAT, ~(size_t)0);
+ if (strcmp(bufz, buf64) != 0)
+ return 1;
+ return 0;
+}],
+[pgac_cv_printf_size_t_support=yes],
+[pgac_cv_printf_size_t_support=no],
+[pgac_cv_printf_size_t_support=cross])
+])dnl AC_CACHE_VAL
+AC_MSG_RESULT([$pgac_cv_printf_size_t_support])
+])# PGAC_FUNC_PRINTF_SIZE_T_SUPPORT
+
# PGAC_TYPE_LOCALE_T
# ------------------
diff --git a/configure b/configure
index e1ff704..d786b17 100755
--- a/configure
+++ b/configure
@@ -13036,6 +13036,58 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# Also force our snprintf if the system's doesn't support the %z modifier.
+if test "$pgac_need_repl_snprintf" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether printf supports the %z modifier" >&5
+$as_echo_n "checking whether printf supports the %z modifier... " >&6; }
+if ${pgac_cv_printf_size_t_support+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ pgac_cv_printf_size_t_support=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+ char buf64[100];
+ char bufz[100];
+
+ /*
+ * Check whether we print correctly using %z by printing the biggest
+ * unsigned number fitting in a size_t and using both %zu and the format for
+ * 64bit numbers.
+ */
+
+ snprintf(bufz, 100, "%zu, ~(size_t)0);
+ snprintf(buf64, 100, UINT64_FORMAT, ~(size_t)0);
+ if (strcmp(bufz, buf64) != 0)
+ return 1;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ pgac_cv_printf_size_t_support=yes
+else
+ pgac_cv_printf_size_t_support=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_printf_size_t_support" >&5
+$as_echo "$pgac_cv_printf_size_t_support" >&6; }
+
+ if test $pgac_cv_printf_size_t_support != yes ; then
+ pgac_need_repl_snprintf=yes
+ fi
+fi
+
# Now we have checked all the reasons to replace snprintf
if test $pgac_need_repl_snprintf = yes; then
diff --git a/configure.in b/configure.in
index 3826237..e6cfac1 100644
--- a/configure.in
+++ b/configure.in
@@ -1617,6 +1617,14 @@ AC_DEFINE_UNQUOTED(INT64_FORMAT, $INT64_FORMAT,
AC_DEFINE_UNQUOTED(UINT64_FORMAT, $UINT64_FORMAT,
[Define to the appropriate snprintf format for unsigned 64-bit ints.])
+# Also force our snprintf if the system's doesn't support the %z modifier.
+if test "$pgac_need_repl_snprintf" = no; then
+ PGAC_FUNC_PRINTF_SIZE_T_SUPPORT
+ if test $pgac_cv_printf_size_t_support != yes ; then
+ pgac_need_repl_snprintf=yes
+ fi
+fi
+
# Now we have checked all the reasons to replace snprintf
if test $pgac_need_repl_snprintf = yes; then
AC_DEFINE(USE_REPL_SNPRINTF, 1, [Use replacement snprintf() functions.])
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 9f71950..dc12399 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -386,6 +386,19 @@ nextch1:
else
longflag = 1;
goto nextch1;
+ case 'z':
+#if SIZEOF_SIZE_T == 8
+# ifdef HAVE_LONG_INT_64
+ longflag = 1;
+# elif defined(HAVE_LONG_LONG_INT_64)
+ longlongflag = 1;
+# else
+# error "Don't know how to print 64bit integers"
+# endif
+#else
+ /* standard length is ok */
+#endif
+ goto nextch1;
case 'h':
case '\'':
/* ignore these */
@@ -619,6 +632,19 @@ nextch2:
else
longflag = 1;
goto nextch2;
+ case 'z':
+#if SIZEOF_SIZE_T == 8
+# ifdef HAVE_LONG_INT_64
+ longflag = 1;
+# elif defined(HAVE_LONG_LONG_INT_64)
+ longlongflag = 1;
+# else
+# error "Don't know how to print 64bit integers"
+# endif
+#else
+ /* standard length is ok */
+#endif
+ goto nextch2;
case 'h':
case '\'':
/* ignore these */
--
1.8.5.rc2.dirty
0002-Use-the-new-z-support-in-several-elog-ereport-caller.patchtext/x-patch; charset=us-asciiDownload
>From b5546f4797acf5c4e471fd289f8faf44f3a0d975 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 7 Dec 2013 19:23:39 +0100
Subject: [PATCH 2/2] Use the new %z support in several elog()/ereport()
callers.
Some of the callsites were actually wrong, notably in aset.c and
mcxt.c, because they simply cast Size arguments to unsigned long,
which will give wrong results on LLP64 platforms like 64bit
windows. Others just are shorter the new way.
---
src/backend/access/hash/hashinsert.c | 5 ++---
src/backend/access/heap/hio.c | 7 +++----
src/backend/access/heap/rewriteheap.c | 5 ++---
src/backend/access/spgist/spgdoinsert.c | 6 +++---
src/backend/access/transam/xlog.c | 4 ++--
src/backend/nodes/readfuncs.c | 13 +++++--------
src/backend/port/sysv_shmem.c | 8 ++++----
src/backend/port/win32_shmem.c | 4 ++--
src/backend/storage/file/fd.c | 2 +-
src/backend/storage/freespace/freespace.c | 3 +--
src/backend/storage/ipc/dsm.c | 4 ++--
src/backend/storage/ipc/dsm_impl.c | 12 ++++++------
src/backend/storage/ipc/ipci.c | 3 +--
src/backend/storage/ipc/shmem.c | 14 ++++++--------
src/backend/storage/lmgr/predicate.c | 8 ++++----
src/backend/utils/mmgr/aset.c | 23 ++++++++++-------------
src/backend/utils/mmgr/mcxt.c | 24 ++++++++----------------
17 files changed, 62 insertions(+), 83 deletions(-)
diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c
index 090db0b..49211ee 100644
--- a/src/backend/access/hash/hashinsert.c
+++ b/src/backend/access/hash/hashinsert.c
@@ -65,9 +65,8 @@ _hash_doinsert(Relation rel, IndexTuple itup)
if (itemsz > HashMaxItemSize((Page) metap))
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("index row size %lu exceeds hash maximum %lu",
- (unsigned long) itemsz,
- (unsigned long) HashMaxItemSize((Page) metap)),
+ errmsg("index row size %zu exceeds hash maximum %zu",
+ itemsz, HashMaxItemSize((Page) metap)),
errhint("Values larger than a buffer page cannot be indexed.")));
/*
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index a0a9778..b306398 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -237,9 +237,8 @@ RelationGetBufferForTuple(Relation relation, Size len,
if (len > MaxHeapTupleSize)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("row is too big: size %lu, maximum size %lu",
- (unsigned long) len,
- (unsigned long) MaxHeapTupleSize)));
+ errmsg("row is too big: size %zu, maximum size %zu",
+ len, MaxHeapTupleSize)));
/* Compute desired extra freespace due to fillfactor option */
saveFreeSpace = RelationGetTargetPageFreeSpace(relation,
@@ -477,7 +476,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
if (len > PageGetHeapFreeSpace(page))
{
/* We should not get here given the test at the top */
- elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
+ elog(PANIC, "tuple is too big: size %zu", len);
}
/*
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index bb719c7..c34ab98 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -601,9 +601,8 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
if (len > MaxHeapTupleSize)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("row is too big: size %lu, maximum size %lu",
- (unsigned long) len,
- (unsigned long) MaxHeapTupleSize)));
+ errmsg("row is too big: size %zu, maximum size %zu",
+ len, MaxHeapTupleSize)));
/* Compute desired extra freespace due to fillfactor option */
saveFreeSpace = RelationGetTargetPageFreeSpace(state->rs_new_rel,
diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c
index 2f6a878..1f5d976 100644
--- a/src/backend/access/spgist/spgdoinsert.c
+++ b/src/backend/access/spgist/spgdoinsert.c
@@ -1885,9 +1885,9 @@ spgdoinsert(Relation index, SpGistState *state,
if (leafSize > SPGIST_PAGE_CAPACITY && !state->config.longValuesOK)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("index row size %lu exceeds maximum %lu for index \"%s\"",
- (unsigned long) (leafSize - sizeof(ItemIdData)),
- (unsigned long) (SPGIST_PAGE_CAPACITY - sizeof(ItemIdData)),
+ errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",
+ leafSize - sizeof(ItemIdData),
+ SPGIST_PAGE_CAPACITY - sizeof(ItemIdData),
RelationGetRelationName(index)),
errhint("Values larger than a buffer page cannot be indexed.")));
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 8679d0a..9559d6d 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2738,9 +2738,9 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not write to log file %s "
- "at offset %u, length %lu: %m",
+ "at offset %u, length %zu: %m",
XLogFileNameP(ThisTimeLineID, openLogSegNo),
- openLogOff, (unsigned long) nbytes)));
+ openLogOff, nbytes)));
}
nleft -= written;
from += written;
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index c22acd5..216d75e 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1439,15 +1439,13 @@ readDatum(bool typbyval)
token = pg_strtok(&tokenLength); /* read the '[' */
if (token == NULL || token[0] != '[')
- elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %lu",
- token ? (const char *) token : "[NULL]",
- (unsigned long) length);
+ elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
+ token ? (const char *) token : "[NULL]", length);
if (typbyval)
{
if (length > (Size) sizeof(Datum))
- elog(ERROR, "byval datum but length = %lu",
- (unsigned long) length);
+ elog(ERROR, "byval datum but length = %zu", length);
res = (Datum) 0;
s = (char *) (&res);
for (i = 0; i < (Size) sizeof(Datum); i++)
@@ -1471,9 +1469,8 @@ readDatum(bool typbyval)
token = pg_strtok(&tokenLength); /* read the ']' */
if (token == NULL || token[0] != ']')
- elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %lu",
- token ? (const char *) token : "[NULL]",
- (unsigned long) length);
+ elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
+ token ? (const char *) token : "[NULL]", length);
return res;
}
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index 36674ad..0d01617 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -138,8 +138,8 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
*/
ereport(FATAL,
(errmsg("could not create shared memory segment: %m"),
- errdetail("Failed system call was shmget(key=%lu, size=%lu, 0%o).",
- (unsigned long) memKey, (unsigned long) size,
+ errdetail("Failed system call was shmget(key=%lu, size=%zu, 0%o).",
+ (unsigned long) memKey, size,
IPC_CREAT | IPC_EXCL | IPCProtection),
(errno == EINVAL) ?
errhint("This error usually means that PostgreSQL's request for a shared memory "
@@ -395,10 +395,10 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
errhint("This error usually means that PostgreSQL's request "
"for a shared memory segment exceeded available memory "
"or swap space. To reduce the request size (currently "
- "%lu bytes), reduce PostgreSQL's shared memory usage, "
+ "%zu bytes), reduce PostgreSQL's shared memory usage, "
"perhaps by reducing shared_buffers or "
"max_connections.",
- (unsigned long) size) : 0));
+ size) : 0));
AnonymousShmemSize = size;
/* Now we need only allocate a minimal-sized SysV shmem block. */
diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c
index 2887d10..80f1982 100644
--- a/src/backend/port/win32_shmem.c
+++ b/src/backend/port/win32_shmem.c
@@ -166,8 +166,8 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
if (!hmap)
ereport(FATAL,
(errmsg("could not create shared memory segment: error code %lu", GetLastError()),
- errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s).",
- (unsigned long) size, szShareMem)));
+ errdetail("Failed system call was CreateFileMapping(size=%zu, name=%s).",
+ size, szShareMem)));
/*
* If the segment already existed, CreateFileMapping() will return a
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index a733cfb..2918f75 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -829,7 +829,7 @@ AllocateVfd(void)
Index i;
File file;
- DO_DB(elog(LOG, "AllocateVfd. Size %lu", (unsigned long) SizeVfdCache));
+ DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index 8d49928..24e69eb 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -379,8 +379,7 @@ fsm_space_needed_to_cat(Size needed)
/* Can't ask for more space than the highest category represents */
if (needed > MaxFSMRequestSize)
- elog(ERROR, "invalid FSM request size %lu",
- (unsigned long) needed);
+ elog(ERROR, "invalid FSM request size %zu", needed);
if (needed == 0)
return 1;
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 4ee453e..327d685 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -201,8 +201,8 @@ dsm_postmaster_startup(void)
dsm_control = dsm_control_address;
on_shmem_exit(dsm_postmaster_shutdown, 0);
elog(DEBUG2,
- "created dynamic shared memory control segment %u (%lu bytes)",
- dsm_control_handle, (unsigned long) segsize);
+ "created dynamic shared memory control segment %u (%zu bytes)",
+ dsm_control_handle, segsize);
dsm_write_state_file(dsm_control_handle);
/* Initialize control segment. */
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index fc74990..a8d8a64 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -329,8 +329,8 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
ereport(elevel,
(errcode_for_dynamic_shared_memory(),
- errmsg("could not resize shared memory segment %s to %lu bytes: %m",
- name, (unsigned long) request_size)));
+ errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+ name, request_size)));
return false;
}
@@ -871,8 +871,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
ereport(elevel,
(errcode_for_dynamic_shared_memory(),
- errmsg("could not resize shared memory segment %s to %lu bytes: %m",
- name, (unsigned long) request_size)));
+ errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+ name, request_size)));
return false;
}
else if (*mapped_size < request_size)
@@ -919,8 +919,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
ereport(elevel,
(errcode_for_dynamic_shared_memory(),
- errmsg("could not resize shared memory segment %s to %lu bytes: %m",
- name, (unsigned long) request_size)));
+ errmsg("could not resize shared memory segment %s to %zu bytes: %m",
+ name, request_size)));
return false;
}
}
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 3c04fc3..cc21923 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -142,8 +142,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
/* might as well round it off to a multiple of a typical page size */
size = add_size(size, 8192 - (size % 8192));
- elog(DEBUG3, "invoking IpcMemoryCreate(size=%lu)",
- (unsigned long) size);
+ elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
/*
* Create the shmem segment
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 70b02ca..1d27a89 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -359,8 +359,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for data structure"
- " \"%s\" (%lu bytes requested)",
- name, (unsigned long) size)));
+ " \"%s\" (%zu bytes requested)",
+ name, size)));
shmemseghdr->index = structPtr;
*foundPtr = FALSE;
}
@@ -393,10 +393,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
LWLockRelease(ShmemIndexLock);
ereport(ERROR,
(errmsg("ShmemIndex entry size is wrong for data structure"
- " \"%s\": expected %lu, actual %lu",
- name,
- (unsigned long) size,
- (unsigned long) result->size)));
+ " \"%s\": expected %zu, actual %zu",
+ name, size, result->size)));
}
structPtr = result->location;
}
@@ -412,8 +410,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for data structure"
- " \"%s\" (%lu bytes requested)",
- name, (unsigned long) size)));
+ " \"%s\" (%zu bytes requested)",
+ name, size)));
}
result->size = size;
result->location = structPtr;
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 633b37d..e7f44cc 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -1185,8 +1185,8 @@ InitPredicateLocks(void)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for elements of data structure"
- " \"%s\" (%lu bytes requested)",
- "PredXactList", (unsigned long) requestSize)));
+ " \"%s\" (%zu bytes requested)",
+ "PredXactList", requestSize)));
/* Add all elements to available list, clean. */
memset(PredXact->element, 0, requestSize);
for (i = 0; i < max_table_size; i++)
@@ -1257,8 +1257,8 @@ InitPredicateLocks(void)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for elements of data structure"
- " \"%s\" (%lu bytes requested)",
- "RWConflictPool", (unsigned long) requestSize)));
+ " \"%s\" (%zu bytes requested)",
+ "RWConflictPool", requestSize)));
/* Add all elements to available list, clean. */
memset(RWConflictPool->element, 0, requestSize);
for (i = 0; i < max_table_size; i++)
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index 56e53f4..099200c 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -676,8 +676,7 @@ AllocSetAlloc(MemoryContext context, Size size)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"),
- errdetail("Failed on request of size %lu.",
- (unsigned long) size)));
+ errdetail("Failed on request of size %zu.", size)));
}
block->aset = set;
block->freeptr = block->endptr = ((char *) block) + blksize;
@@ -871,8 +870,7 @@ AllocSetAlloc(MemoryContext context, Size size)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"),
- errdetail("Failed on request of size %lu.",
- (unsigned long) size)));
+ errdetail("Failed on request of size %zu.", size)));
}
block->aset = set;
@@ -1114,8 +1112,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory"),
- errdetail("Failed on request of size %lu.",
- (unsigned long) size)));
+ errdetail("Failed on request of size %zu.", size)));
}
block->freeptr = block->endptr = ((char *) block) + blksize;
@@ -1245,10 +1242,10 @@ static void
AllocSetStats(MemoryContext context, int level)
{
AllocSet set = (AllocSet) context;
- long nblocks = 0;
- long nchunks = 0;
- long totalspace = 0;
- long freespace = 0;
+ Size nblocks = 0;
+ Size nchunks = 0;
+ Size totalspace = 0;
+ Size freespace = 0;
AllocBlock block;
AllocChunk chunk;
int fidx;
@@ -1274,7 +1271,7 @@ AllocSetStats(MemoryContext context, int level)
fprintf(stderr, " ");
fprintf(stderr,
- "%s: %lu total in %ld blocks; %lu free (%ld chunks); %lu used\n",
+ "%s: %zu total in %zd blocks; %zu free (%zd chunks); %zu used\n",
set->header.name, totalspace, nblocks, freespace, nchunks,
totalspace - freespace);
}
@@ -1338,8 +1335,8 @@ AllocSetCheck(MemoryContext context)
elog(WARNING, "problem in alloc set %s: req size > alloc size for chunk %p in block %p",
name, chunk, block);
if (chsize < (1 << ALLOC_MINBITS))
- elog(WARNING, "problem in alloc set %s: bad size %lu for chunk %p in block %p",
- name, (unsigned long) chsize, chunk, block);
+ elog(WARNING, "problem in alloc set %s: bad size %zu for chunk %p in block %p",
+ name, chsize, chunk, block);
/* single-chunk block? */
if (chsize > set->allocChunkLimit &&
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7b089f7..a7ca44d 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -577,8 +577,7 @@ MemoryContextAlloc(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -603,8 +602,7 @@ MemoryContextAllocZero(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -631,8 +629,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -653,8 +650,7 @@ palloc(Size size)
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
CurrentMemoryContext->isReset = false;
@@ -673,8 +669,7 @@ palloc0(Size size)
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
CurrentMemoryContext->isReset = false;
@@ -726,8 +721,7 @@ repalloc(void *pointer, Size size)
void *ret;
if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
/*
* Try to detect bogus pointers handed to us, poorly though we can.
@@ -768,8 +762,7 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
AssertArg(MemoryContextIsValid(context));
if (!AllocHugeSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
context->isReset = false;
@@ -791,8 +784,7 @@ repalloc_huge(void *pointer, Size size)
void *ret;
if (!AllocHugeSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %lu",
- (unsigned long) size);
+ elog(ERROR, "invalid memory alloc request size %zu", size);
/*
* Try to detect bogus pointers handed to us, poorly though we can.
--
1.8.5.rc2.dirty
Andres Freund <andres@2ndquadrant.com> writes:
So, here's a patch adding %z support to port/snprintf.c including a
configure check to test whether we need to fall back.
OK, I'll take a look.
I am not too
happy about the runtime check as the test isn't all that meaningful, but
I couldn't think of anything better.
Yeah, it's problematic for cross-compiles, but no more so than configure's
existing test for "%n$" support. In practice, since both these features
are required by C99, I think it wouldn't be such an issue for most people.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-23 11:14:05 -0500, Tom Lane wrote:
OK, I'll take a look.
Thanks.
I am not too
happy about the runtime check as the test isn't all that meaningful, but
I couldn't think of anything better.Yeah, it's problematic for cross-compiles, but no more so than configure's
existing test for "%n$" support. In practice, since both these features
are required by C99, I think it wouldn't be such an issue for most people.
Currently we automatically fall back to our implementation if we're
cross compiling unless I am missing something, that's a bit odd, but it
should work ;)
I was wondering more about the nature of the runtime check than the fact
that it's a runtime check at all... E.g. snprintf.c simply skips over
unknown format characters and might not have been detected as faulty on
32bit platforms by that check. Which might be considered a good thing :)
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
I was wondering more about the nature of the runtime check than the fact
that it's a runtime check at all... E.g. snprintf.c simply skips over
unknown format characters and might not have been detected as faulty on
32bit platforms by that check. Which might be considered a good thing :)
Oh ... gotcha. Yeah, it's possible that snprintf would behave in a way
that masks the fact that it doesn't really recognize the "z" flag, but
that seems rather unlikely to me. More likely it would abandon processing
the %-sequence on grounds it's malformed.
I will try the patch on my old HPUX dinosaur, which I'm pretty sure
does not know "z", and verify this is the case.
Also, I'm guessing Windows' version of snprintf doesn't have "z" either.
Could someone try the patch's configure test program on Windows and see
what the result is?
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-23 11:25:56 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
I was wondering more about the nature of the runtime check than the fact
that it's a runtime check at all... E.g. snprintf.c simply skips over
unknown format characters and might not have been detected as faulty on
32bit platforms by that check. Which might be considered a good thing :)Oh ... gotcha. Yeah, it's possible that snprintf would behave in a way
that masks the fact that it doesn't really recognize the "z" flag, but
that seems rather unlikely to me. More likely it would abandon processing
the %-sequence on grounds it's malformed.
Yea, hopefully.
I will try the patch on my old HPUX dinosaur, which I'm pretty sure
does not know "z", and verify this is the case.
I don't know how, but I've introduced a typo in the version I sent if
you haven't noticed yet, there's a " missing in
PGAC_FUNC_PRINTF_SIZE_T_SUPPORT. "%zu" instead of "%zu
Also, I'm guessing Windows' version of snprintf doesn't have "z" either.
Could someone try the patch's configure test program on Windows and see
what the result is?
I've attached a version of that here, for $windowsperson's
convenience. I hope I got the llp stuff right...
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
Andres Freund <andres@2ndquadrant.com> writes:
snprintf(buf64, 100, UINT64_FORMAT, ~(size_t)0);
Actually, that coding isn't gonna work at all on platforms where size_t
isn't the same size as uint64. We could make it work by explicitly
casting the argument to whatever type we've decided to use as uint64
... but unless we want to include c.h here, that would require a lot of
extra cruft, and I'm really not sure it's gaining anything anyway.
I'm inclined to just print (size_t)0xFFFFFFFF and see if it produces
the expected result.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-23 12:54:22 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
snprintf(buf64, 100, UINT64_FORMAT, ~(size_t)0);
Actually, that coding isn't gonna work at all on platforms where size_t
isn't the same size as uint64. We could make it work by explicitly
casting the argument to whatever type we've decided to use as uint64
... but unless we want to include c.h here, that would require a lot of
extra cruft, and I'm really not sure it's gaining anything anyway.
Hm, yea, it should be casted. I think we should have the type ready in
PG_INT64_TYPE, confdefs.h should contain it at that point.
I'm inclined to just print (size_t)0xFFFFFFFF and see if it produces
the expected result.
Well, the reasoning, weak as it may be, was that that we want to see
whether we successfully recognize z as a 64bit modifier or not. And I
couldn't think of a better way to test that both for 32 and 64 bit
platforms...
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
On 2014-01-23 12:54:22 -0500, Tom Lane wrote:
Andres Freund <andres@2ndquadrant.com> writes:
snprintf(buf64, 100, UINT64_FORMAT, ~(size_t)0);
Actually, that coding isn't gonna work at all on platforms where size_t
isn't the same size as uint64. We could make it work by explicitly
casting the argument to whatever type we've decided to use as uint64
... but unless we want to include c.h here, that would require a lot of
extra cruft, and I'm really not sure it's gaining anything anyway.
Hm, yea, it should be casted. I think we should have the type ready in
PG_INT64_TYPE, confdefs.h should contain it at that point.
Ah, I'd forgotten that configure defined any such symbol. Yeah, that
will work.
Well, the reasoning, weak as it may be, was that that we want to see
whether we successfully recognize z as a 64bit modifier or not.
I'm dubious that this is really adding much, but whatever.
I checked on my HPUX box and find that what it prints for "%zu" is
"zu", confirming my thought that it'd just abandon processing of the
%-sequence. (Interesting that it doesn't eat the "z" while doing
so, though.)
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
I wrote:
I checked on my HPUX box and find that what it prints for "%zu" is
"zu", confirming my thought that it'd just abandon processing of the
%-sequence. (Interesting that it doesn't eat the "z" while doing
so, though.)
Further testing on that box shows that its ancient gcc (2.95.3) doesn't
know "z" either, which means that the patch produces a boatload of
compile warnings like this:
mcxt.c: In function `MemoryContextAllocZero':
mcxt.c:605: warning: unknown conversion type character `z' in format
mcxt.c:605: warning: too many arguments for format
While I am not really expecting this gcc to compile PG cleanly anymore,
the idea that we might get many dozen such warnings on more-current
compilers is scarier, as that might well interfere with people's
ability to do development on, say, Windows. Could somebody check
whether MSVC for instance complains about format strings using "z"?
Or shall I just commit this and we'll see what the buildfarm says?
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
I wrote:
the idea that we might get many dozen such warnings on more-current
compilers is scarier, as that might well interfere with people's
ability to do development on, say, Windows. Could somebody check
whether MSVC for instance complains about format strings using "z"?
Or shall I just commit this and we'll see what the buildfarm says?
Given the lack of response, I've pushed the patch, and will canvass
the buildfarm results later.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2014-01-23 17:21:11 -0500, Tom Lane wrote:
I wrote:
the idea that we might get many dozen such warnings on more-current
compilers is scarier, as that might well interfere with people's
ability to do development on, say, Windows. Could somebody check
whether MSVC for instance complains about format strings using "z"?
Or shall I just commit this and we'll see what the buildfarm says?Given the lack of response, I've pushed the patch, and will canvass
the buildfarm results later.
Thanks, I was afk, otherwise I'd have tried to pushing it to windows via
jenkins if that machine was running (it's running in Craig's flat...)…
Do we have a real policy against indenting nested preprocessor
statments? Just so I don't do those in future patches...
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Andres Freund <andres@2ndquadrant.com> writes:
Do we have a real policy against indenting nested preprocessor
statments? Just so I don't do those in future patches...
Indent 'em if you like, but pgindent will undo it. I ran the patch
through pgindent to see what it would do with those, and it left-justified
them, so I committed it that way.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
I wrote:
the idea that we might get many dozen such warnings on more-current
compilers is scarier, as that might well interfere with people's
ability to do development on, say, Windows. Could somebody check
whether MSVC for instance complains about format strings using "z"?
Or shall I just commit this and we'll see what the buildfarm says?
Given the lack of response, I've pushed the patch, and will canvass
the buildfarm results later.
Just to follow up on that, I couldn't find any related warnings in the
buildfarm this morning (although there is one laggard machine, "anole",
which uses an unusual compiler and still hasn't reported in).
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers