Autoconfiscate selection of 64-bit int type for 64-bit large object API.

Get rid of the fundamentally indefensible assumption that "long long int"
exists and is exactly 64 bits wide on every platform Postgres runs on.
Instead let the configure script select the type to use for "pg_int64".

This is a bit of a pain in the rear since we do not want to pollute client
namespace with all the random symbols that pg_config.h defines; instead
we have to create a separate generated header file, "pg_config_ext.h".
But now that the infrastructure is there, we might have the ability to
add some other stuff that's long been wanting in this area.
This commit is contained in:
Tom Lane 2012-10-07 21:52:07 -04:00
parent ea72bb8ae5
commit 95d035e66d
22 changed files with 130 additions and 66 deletions

21
configure vendored
View File

@ -24238,7 +24238,9 @@ _ACEOF
fi
if test x"$HAVE_LONG_INT_64" = x"no" ; then
if test x"$HAVE_LONG_INT_64" = x"yes" ; then
pg_int64_type="long int"
else
{ $as_echo "$as_me:$LINENO: checking whether long long int is 64 bits" >&5
$as_echo_n "checking whether long long int is 64 bits... " >&6; }
if test "${pgac_cv_type_long_long_int_64+set}" = set; then
@ -24374,7 +24376,9 @@ _ACEOF
fi
if test x"$HAVE_LONG_LONG_INT_64" = x"no" ; then
if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
pg_int64_type="long long int"
else
{ { $as_echo "$as_me:$LINENO: error: Cannot find a working 64-bit integer type." >&5
$as_echo "$as_me: error: Cannot find a working 64-bit integer type." >&2;}
{ (exit 1); exit 1; }; }
@ -24382,6 +24386,11 @@ $as_echo "$as_me: error: Cannot find a working 64-bit integer type." >&2;}
fi
cat >>confdefs.h <<_ACEOF
#define PG_INT64_TYPE $pg_int64_type
_ACEOF
if test x"$HAVE_LONG_LONG_INT_64" = xyes ; then
cat >conftest.$ac_ext <<_ACEOF
@ -29930,6 +29939,9 @@ fi
ac_config_headers="$ac_config_headers src/include/pg_config.h"
ac_config_headers="$ac_config_headers src/include/pg_config_ext.h"
ac_config_headers="$ac_config_headers src/interfaces/ecpg/include/ecpg_config.h"
@ -30550,6 +30562,7 @@ do
"src/Makefile.port") CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;;
"check_win32_symlinks") CONFIG_COMMANDS="$CONFIG_COMMANDS check_win32_symlinks" ;;
"src/include/pg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config.h" ;;
"src/include/pg_config_ext.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config_ext.h" ;;
"src/interfaces/ecpg/include/ecpg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/interfaces/ecpg/include/ecpg_config.h" ;;
*) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
@ -31220,6 +31233,10 @@ $as_echo "$as_me: WARNING: *** link for $FILE -- please fix by hand" >&2;}
"src/include/pg_config.h":H)
# Update timestamp for pg_config.h (see Makefile.global)
echo >src/include/stamp-h
;;
"src/include/pg_config_ext.h":H)
# Update timestamp for pg_config_ext.h (see Makefile.global)
echo >src/include/stamp-ext-h
;;
"src/interfaces/ecpg/include/ecpg_config.h":H) echo >src/interfaces/ecpg/include/stamp-h ;;

View File

@ -1580,13 +1580,19 @@ dnl 64-bit type. But we still handle the case of snprintf being broken.
PGAC_TYPE_64BIT_INT([long int])
if test x"$HAVE_LONG_INT_64" = x"no" ; then
if test x"$HAVE_LONG_INT_64" = x"yes" ; then
pg_int64_type="long int"
else
PGAC_TYPE_64BIT_INT([long long int])
if test x"$HAVE_LONG_LONG_INT_64" = x"no" ; then
if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
pg_int64_type="long long int"
else
AC_MSG_ERROR([Cannot find a working 64-bit integer type.])
fi
fi
AC_DEFINE_UNQUOTED(PG_INT64_TYPE, $pg_int64_type,
[Define to the name of a signed 64-bit integer type.])
dnl If we need to use "long long int", figure out whether nnnLL notation works.
@ -1935,6 +1941,12 @@ AC_CONFIG_HEADERS([src/include/pg_config.h],
echo >src/include/stamp-h
])
AC_CONFIG_HEADERS([src/include/pg_config_ext.h],
[
# Update timestamp for pg_config_ext.h (see Makefile.global)
echo >src/include/stamp-ext-h
])
AC_CONFIG_HEADERS([src/interfaces/ecpg/include/ecpg_config.h],
[echo >src/interfaces/ecpg/include/stamp-h])

View File

@ -539,6 +539,12 @@ $(top_builddir)/src/include/pg_config.h: $(top_builddir)/src/include/stamp-h ;
$(top_builddir)/src/include/stamp-h: $(top_srcdir)/src/include/pg_config.h.in $(top_builddir)/config.status
cd $(top_builddir) && ./config.status src/include/pg_config.h
# Also remake pg_config_ext.h from pg_config_ext.h.in, same logic as above.
$(top_builddir)/src/include/pg_config_ext.h: $(top_builddir)/src/include/stamp-ext-h ;
$(top_builddir)/src/include/stamp-ext-h: $(top_srcdir)/src/include/pg_config_ext.h.in $(top_builddir)/config.status
cd $(top_builddir) && ./config.status src/include/pg_config_ext.h
# Also remake ecpg_config.h from ecpg_config.h.in if the latter changed, same
# logic as above.
$(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/interfaces/ecpg/include/stamp-h ;

View File

@ -26,6 +26,7 @@ NULL=nul
ALL:
cd include
if not exist pg_config.h copy pg_config.h.win32 pg_config.h
if not exist pg_config_ext.h copy pg_config_ext.h.win32 pg_config_ext.h
if not exist pg_config_os.h copy port\win32.h pg_config_os.h
cd ..
cd interfaces\libpq
@ -42,5 +43,5 @@ CLEAN:
DISTCLEAN: CLEAN
cd include
del pg_config.h pg_config_os.h
del pg_config.h pg_config_ext.h pg_config_os.h
cd ..

View File

@ -1,5 +1,6 @@
/stamp-h
/stamp-ext-h
/pg_config.h
/pg_config_ext.h
/pg_config_os.h
/dynloader.h

View File

@ -13,7 +13,7 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global
all: pg_config.h pg_config_os.h
all: pg_config.h pg_config_ext.h pg_config_os.h
# Subdirectories containing headers for server-side dev
@ -29,8 +29,9 @@ install: all installdirs
# These headers are needed by the public headers of the interfaces.
$(INSTALL_DATA) $(srcdir)/postgres_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/libpq/libpq-fs.h '$(DESTDIR)$(includedir)/libpq'
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/pg_config_manual.h '$(DESTDIR)$(includedir)'
# These headers are needed by the not-so-public headers of the interfaces.
$(INSTALL_DATA) $(srcdir)/c.h '$(DESTDIR)$(includedir_internal)'
@ -38,8 +39,9 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/postgres_fe.h '$(DESTDIR)$(includedir_internal)'
$(INSTALL_DATA) $(srcdir)/libpq/pqcomm.h '$(DESTDIR)$(includedir_internal)/libpq'
# These headers are needed for server-side development
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils'
$(INSTALL_DATA) utils/fmgroids.h '$(DESTDIR)$(includedir_server)/utils'
# We don't use INSTALL_DATA for performance reasons --- there are a lot of files
@ -62,7 +64,7 @@ installdirs:
uninstall:
rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h)
# heuristic...
rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)
@ -72,7 +74,7 @@ clean:
rm -f utils/fmgroids.h utils/errcodes.h parser/gram.h utils/probes.h catalog/schemapg.h
distclean maintainer-clean: clean
rm -f pg_config.h dynloader.h pg_config_os.h stamp-h
rm -f pg_config.h pg_config_ext.h pg_config_os.h dynloader.h stamp-h stamp-ext-h
maintainer-check:
cd catalog && ./duplicate_oids

View File

@ -44,19 +44,17 @@
#ifndef C_H
#define C_H
/*
* We have to include stdlib.h here because it defines many of these macros
* on some platforms, and we only want our definitions used if stdlib.h doesn't
* have its own. The same goes for stddef and stdarg if present.
*/
#include "postgres_ext.h"
/* Must undef pg_config_ext.h symbols before including pg_config.h */
#undef PG_INT64_TYPE
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 will include further
* down */
#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 includes further down */
#include "pg_config_os.h" /* must be before any system header files */
#endif
#include "postgres_ext.h"
#if _MSC_VER >= 1400 || defined(HAVE_CRTDEFS_H)
#define errcode __msvc_errcode
@ -64,6 +62,12 @@
#undef errcode
#endif
/*
* We have to include stdlib.h here because it defines many of these macros
* on some platforms, and we only want our definitions used if stdlib.h doesn't
* have its own. The same goes for stddef and stdarg if present.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@ -671,6 +671,9 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to the name of a signed 64-bit integer type. */
#undef PG_INT64_TYPE
/* Define to the name of the default PostgreSQL service principal in Kerberos.
(--with-krb-srvnam=NAME) */
#undef PG_KRB_SRVNAM

View File

@ -562,6 +562,9 @@
/* Define to the version of this package. */
#define PACKAGE_VERSION "9.3devel"
/* Define to the name of a signed 64-bit integer type. */
#define PG_INT64_TYPE long long int
/* PostgreSQL version as a string */
#define PG_VERSION "9.3devel"

View File

@ -0,0 +1,7 @@
/*
* src/include/pg_config_ext.h.in. This is generated manually, not by
* autoheader, since we want to limit which symbols get defined here.
*/
/* Define to the name of a signed 64-bit integer type. */
#undef PG_INT64_TYPE

View File

@ -0,0 +1,7 @@
/*
* src/include/pg_config_ext.h.win32. This is generated manually, not by
* autoheader, since we want to limit which symbols get defined here.
*/
/* Define to the name of a signed 64-bit integer type. */
#define PG_INT64_TYPE long long int

View File

@ -23,6 +23,8 @@
#ifndef POSTGRES_EXT_H
#define POSTGRES_EXT_H
#include "pg_config_ext.h"
/*
* Object ID is a fundamental type in Postgres.
*/
@ -37,6 +39,9 @@ typedef unsigned int Oid;
#define OID_MAX UINT_MAX
/* you will need to include <limits.h> to use the above #define */
/* Define a signed 64-bit integer type for use in client API declarations. */
typedef PG_INT64_TYPE pg_int64;
/*
* Identifiers of error message fields. Kept here to keep common
@ -56,9 +61,4 @@ typedef unsigned int Oid;
#define PG_DIAG_SOURCE_LINE 'L'
#define PG_DIAG_SOURCE_FUNCTION 'R'
#ifndef NO_PG_INT64
#define HAVE_PG_INT64 1
typedef long long int pg_int64;
#endif
#endif
#endif /* POSTGRES_EXT_H */

View File

@ -62,10 +62,13 @@ typedef struct LargeObjectDesc
* This avoids unnecessary tuple updates caused by partial-page writes.
*/
#define LOBLKSIZE (BLCKSZ / 4)
/*
* Maximum byte length for each large object
*/
#define MAX_LARGE_OBJECT_SIZE ((int64)INT_MAX * LOBLKSIZE)
* Maximum length in bytes for a large object. To make this larger, we'd
* have to widen pg_largeobject.pageno as well as various internal variables.
*/
#define MAX_LARGE_OBJECT_SIZE ((int64) INT_MAX * LOBLKSIZE)
/*
* Function definitions...
@ -77,8 +80,8 @@ extern Oid inv_create(Oid lobjId);
extern LargeObjectDesc *inv_open(Oid lobjId, int flags, MemoryContext mcxt);
extern void inv_close(LargeObjectDesc *obj_desc);
extern int inv_drop(Oid lobjId);
extern int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence);
extern int64 inv_tell(LargeObjectDesc *obj_desc);
extern int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence);
extern int64 inv_tell(LargeObjectDesc *obj_desc);
extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes);
extern int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes);
extern void inv_truncate(LargeObjectDesc *obj_desc, int64 len);

View File

@ -153,11 +153,14 @@ LIB32_OBJS= \
"$(INTDIR)\pthread-win32.obj"
config: ..\..\include\pg_config.h ..\..\include\pg_config_os.h pg_config_paths.h
config: ..\..\include\pg_config.h ..\..\include\pg_config_ext.h ..\..\include\pg_config_os.h pg_config_paths.h
..\..\include\pg_config.h: ..\..\include\pg_config.h.win32
copy ..\..\include\pg_config.h.win32 ..\..\include\pg_config.h
..\..\include\pg_config_ext.h: ..\..\include\pg_config_ext.h.win32
copy ..\..\include\pg_config_ext.h.win32 ..\..\include\pg_config_ext.h
..\..\include\pg_config_os.h: ..\..\include\port\win32.h
copy ..\..\include\port\win32.h ..\..\include\pg_config_os.h

View File

@ -187,7 +187,6 @@ lo_truncate(PGconn *conn, int fd, size_t len)
* returns 0 upon success
* returns -1 upon failure
*/
#ifdef HAVE_PG_INT64
int
lo_truncate64(PGconn *conn, int fd, pg_int64 len)
{
@ -232,7 +231,6 @@ lo_truncate64(PGconn *conn, int fd, pg_int64 len)
return -1;
}
}
#endif
/*
* lo_read
@ -325,10 +323,7 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
/*
* lo_lseek
* change the current read or write location on a large object
* currently, only L_SET is a legal value for whence
*
*/
int
lo_lseek(PGconn *conn, int fd, int offset, int whence)
{
@ -372,11 +367,7 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
/*
* lo_lseek64
* change the current read or write location on a large object
* currently, only L_SET is a legal value for whence
*
*/
#ifdef HAVE_PG_INT64
pg_int64
lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
{
@ -424,7 +415,6 @@ lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
return -1;
}
}
#endif
/*
* lo_creat
@ -554,9 +544,7 @@ lo_tell(PGconn *conn, int fd)
/*
* lo_tell64
* returns the current seek location of the large object
*
*/
#ifdef HAVE_PG_INT64
pg_int64
lo_tell64(PGconn *conn, int fd)
{
@ -595,12 +583,10 @@ lo_tell64(PGconn *conn, int fd)
return -1;
}
}
#endif
/*
* lo_unlink
* delete a file
*
*/
int
@ -1031,6 +1017,7 @@ lo_initialize(PGconn *conn)
return -1;
}
}
/*
* Put the structure into the connection control
*/

View File

@ -507,24 +507,21 @@ extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_lengt
/* === in fe-print.c === */
extern void
PQprint(FILE *fout, /* output stream */
extern void PQprint(FILE *fout, /* output stream */
const PGresult *res,
const PQprintOpt *ps); /* option structure */
/*
* really old printing routines
*/
extern void
PQdisplayTuples(const PGresult *res,
extern void PQdisplayTuples(const PGresult *res,
FILE *fp, /* where to send the output */
int fillAlign, /* pad the fields with spaces */
const char *fieldSep, /* field separator */
int printHeader, /* display headers? */
int quiet);
extern void
PQprintTuples(const PGresult *res,
extern void PQprintTuples(const PGresult *res,
FILE *fout, /* output stream */
int printAttName, /* print attribute names */
int terseOutput, /* delimiter bars */
@ -539,21 +536,18 @@ extern int lo_close(PGconn *conn, int fd);
extern int lo_read(PGconn *conn, int fd, char *buf, size_t len);
extern int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
extern int lo_lseek(PGconn *conn, int fd, int offset, int whence);
extern pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);
extern Oid lo_creat(PGconn *conn, int mode);
extern Oid lo_create(PGconn *conn, Oid lobjId);
extern int lo_tell(PGconn *conn, int fd);
extern pg_int64 lo_tell64(PGconn *conn, int fd);
extern int lo_truncate(PGconn *conn, int fd, size_t len);
extern int lo_truncate64(PGconn *conn, int fd, pg_int64 len);
extern int lo_unlink(PGconn *conn, Oid lobjId);
extern Oid lo_import(PGconn *conn, const char *filename);
extern Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
extern int lo_export(PGconn *conn, Oid lobjId, const char *filename);
#ifdef HAVE_PG_INT64
extern pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);
extern pg_int64 lo_tell64(PGconn *conn, int fd);
extern int lo_truncate64(PGconn *conn, int fd, pg_int64 len);
#endif
/* === in fe-misc.c === */
/* Get the version of the libpq library in use */

View File

@ -271,11 +271,11 @@ typedef struct pgLobjfuncs
Oid fn_lo_create; /* OID of backend function lo_create */
Oid fn_lo_unlink; /* OID of backend function lo_unlink */
Oid fn_lo_lseek; /* OID of backend function lo_lseek */
Oid fn_lo_lseek64; /* OID of backend function lo_lseek64 */
Oid fn_lo_lseek64; /* OID of backend function lo_lseek64 */
Oid fn_lo_tell; /* OID of backend function lo_tell */
Oid fn_lo_tell64; /* OID of backend function lo_tell64 */
Oid fn_lo_tell64; /* OID of backend function lo_tell64 */
Oid fn_lo_truncate; /* OID of backend function lo_truncate */
Oid fn_lo_truncate64; /* OID of backend function lo_truncate64 */
Oid fn_lo_truncate64; /* OID of function lo_truncate64 */
Oid fn_lo_read; /* OID of backend function LOread */
Oid fn_lo_write; /* OID of backend function LOwrite */
} PGlobjfuncs;

View File

@ -164,11 +164,14 @@ LIB32_OBJS= \
"$(INTDIR)\pthread-win32.obj"
config: ..\..\include\pg_config.h pg_config_paths.h ..\..\include\pg_config_os.h
config: ..\..\include\pg_config.h ..\..\include\pg_config_ext.h pg_config_paths.h ..\..\include\pg_config_os.h
..\..\include\pg_config.h: ..\..\include\pg_config.h.win32
copy ..\..\include\pg_config.h.win32 ..\..\include\pg_config.h
..\..\include\pg_config_ext.h: ..\..\include\pg_config_ext.h.win32
copy ..\..\include\pg_config_ext.h.win32 ..\..\include\pg_config_ext.h
..\..\include\pg_config_os.h:
copy ..\..\include\port\win32.h ..\..\include\pg_config_os.h

View File

@ -490,7 +490,8 @@ sub CopyIncludeFiles
CopyFiles(
'Public headers',
$target . '/include/',
'src/include/', 'postgres_ext.h', 'pg_config.h', 'pg_config_os.h',
'src/include/', 'postgres_ext.h',
'pg_config.h', 'pg_config_ext.h', 'pg_config_os.h',
'pg_config_manual.h');
lcopy('src/include/libpq/libpq-fs.h', $target . '/include/libpq/')
|| croak 'Could not copy libpq-fs.h';
@ -514,7 +515,7 @@ sub CopyIncludeFiles
CopyFiles(
'Server headers',
$target . '/include/server/',
'src/include/', 'pg_config.h', 'pg_config_os.h');
'src/include/', 'pg_config.h', 'pg_config_ext.h', 'pg_config_os.h');
CopyFiles(
'Grammar header',
$target . '/include/server/parser/',

View File

@ -242,6 +242,14 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
close(I);
}
if (IsNewer(
"src\\include\\pg_config_ext.h", "src\\include\\pg_config_ext.h.win32"))
{
print "Copying pg_config_ext.h...\n";
copyFile("src\\include\\pg_config_ext.h.win32",
"src\\include\\pg_config_ext.h");
}
$self->GenerateDefFile(
"src\\interfaces\\libpq\\libpqdll.def",
"src\\interfaces\\libpq\\exports.txt",

View File

@ -22,6 +22,7 @@ if exist src\backend\win32ver.rc del /q src\backend\win32ver.rc
REM Delete files created with GenerateFiles() in Solution.pm
if exist src\include\pg_config.h del /q src\include\pg_config.h
if exist src\include\pg_config_ext.h del /q src\include\pg_config_ext.h
if exist src\include\pg_config_os.h del /q src\include\pg_config_os.h
if %DIST%==1 if exist src\backend\parser\gram.h del /q src\backend\parser\gram.h
if exist src\include\utils\errcodes.h del /q src\include\utils\errcodes.h

View File

@ -12,6 +12,7 @@ NULL=nul
ALL:
cd include
if not exist pg_config.h copy pg_config.h.win32 pg_config.h
if not exist pg_config_ext.h copy pg_config_ext.h.win32 pg_config_ext.h
if not exist pg_config_os.h copy port\win32.h pg_config_os.h
cd ..
cd interfaces\libpq
@ -27,5 +28,5 @@ CLEAN:
DISTCLEAN: CLEAN
cd include
del pg_config.h pg_config_os.h
del pg_config.h pg_config_ext.h pg_config_os.h
cd ..