public inbox for [email protected]
help / color / mirror / Atom feedFrom: Srirama Kucherlapati <[email protected]>
To: Heikki Linnakangas <[email protected]>
To: Heikki Linnakangas <[email protected]>
To: Tom Lane <[email protected]>
Cc: Peter Eisentraut <[email protected]>
Cc: Alvaro Herrera <[email protected]>
Cc: [email protected] <[email protected]>
Cc: Laurenz Albe <[email protected]>
Cc: Noah Misch <[email protected]>
Cc: Michael Paquier <[email protected]>
Cc: Andres Freund <[email protected]>
Cc: Thomas Munro <[email protected]>
Cc: [email protected] <[email protected]>
Cc: [email protected] <[email protected]>
Cc: Bruce Momjian <[email protected]>
Subject: RE: AIX support
Date: Tue, 24 Sep 2024 11:25:35 +0000
Message-ID: <CY8PR15MB5602F4F63D8F8811A5987EFFDB682@CY8PR15MB5602.namprd15.prod.outlook.com> (raw)
In-Reply-To: <CY8PR15MB5602561E7BF438A1B6C5371BDB612@CY8PR15MB5602.namprd15.prod.outlook.com>
References: <CY5PR11MB639218D04CFAED0FC09ED9DFFDED2@CY5PR11MB6392.namprd11.prod.outlook.com>
<[email protected]>
<CY8PR15MB5602AA47C13A33DBF68BEA73DBFB2@CY8PR15MB5602.namprd15.prod.outlook.com>
<[email protected]>
<CY8PR15MB56029161FE37A1DE9DE36B70DBC72@CY8PR15MB5602.namprd15.prod.outlook.com>
<CY8PR15MB5602CAFFE00371049D68CD25DBCD2@CY8PR15MB5602.namprd15.prod.outlook.com>
<[email protected]>
<CY8PR15MB560282A99569E110AEED3257DBCF2@CY8PR15MB5602.namprd15.prod.outlook.com>
<CY8PR15MB56029A55A848E9089D29FBE6DBC92@CY8PR15MB5602.namprd15.prod.outlook.com>
<CY8PR15MB5602C6D2B148615EBD7F1AF5DB872@CY8PR15MB5602.namprd15.prod.outlook.com>
<[email protected]>
<CY8PR15MB5602A5D9064A401347684A06DB872@CY8PR15MB5602.namprd15.prod.outlook.com>
<[email protected]>
<CY8PR15MB5602B407BBD1B7B7C5FF1D8CDB9B2@CY8PR15MB5602.namprd15.prod.outlook.com>
<[email protected]>
<DS0PR15MB5623ECC0499C5087EFD729EADB652@DS0PR15MB5623.namprd15.prod.outlook.com>
<CY8PR15MB5602561E7BF438A1B6C5371BDB612@CY8PR15MB5602.namprd15.prod.outlook.com>
Hi Heikki & team,
Could you please let me know your comments on the previous details?
Attached are the individual patches for AIX and gcc(__sync) routines.
Thanks,
Sriram.
Attachments:
[application/octet-stream] 0001-AIX-support-revert-the-changes-from-0b16bb8776bb8.v5.patch (43.9K, 3-0001-AIX-support-revert-the-changes-from-0b16bb8776bb8.v5.patch)
download | inline diff:
From f8260d015857d3a65292e55f08ec3a13b60f00b3 Mon Sep 17 00:00:00 2001
From: Sriram RK <[email protected]>
Date: Mon, 20 May 2024 01:38:59 -0500
Subject: [PATCH 1/1] AIX support, revert the changes from 0b16bb8776bb8. Trim
AIX/XLC changes to support gcc only.
- Review comments from Heikki.
- Replace tas() AIX asm with gcc __sync_lock_test_and_set().
- Fix tas() for powerPC.
- Include only AIX specific changes in s_lock.h
---
Makefile | 2 -
configure | 37 +++---
configure.ac | 28 ++---
doc/src/sgml/dfunc.sgml | 19 +++
doc/src/sgml/installation.sgml | 118 +++++++++++++++++-
doc/src/sgml/runtime.sgml | 23 ++++
meson.build | 57 +++++----
src/Makefile.shlib | 29 +++++
src/backend/Makefile | 20 +++
src/backend/meson.build | 15 +++
src/backend/port/aix/mkldexport.sh | 61 +++++++++
src/backend/utils/error/elog.c | 2 +
src/backend/utils/misc/ps_status.c | 4 +-
src/bin/pg_basebackup/t/010_pg_basebackup.pl | 3 +-
src/bin/pg_verifybackup/t/008_untar.pl | 3 +-
src/bin/pg_verifybackup/t/010_client_untar.pl | 3 +-
src/include/c.h | 4 +-
src/include/port/aix.h | 6 +
src/include/storage/s_lock.h | 25 +++-
src/interfaces/libpq/Makefile | 2 +-
src/interfaces/libpq/meson.build | 5 +-
src/makefiles/Makefile.aix | 39 ++++++
src/port/README | 2 +-
src/port/strerror.c | 2 +
src/template/aix | 14 +++
src/test/regress/Makefile | 5 +
src/test/regress/expected/sanity_check.out | 29 +++++
src/test/regress/expected/test_setup.out | 4 +
src/test/regress/regress.c | 40 ++++++
src/test/regress/sql/sanity_check.sql | 26 ++++
src/test/regress/sql/test_setup.sql | 5 +
src/tools/gen_export.pl | 11 +-
src/tools/pginclude/headerscheck | 1 +
33 files changed, 555 insertions(+), 89 deletions(-)
create mode 100755 src/backend/port/aix/mkldexport.sh
create mode 100644 src/include/port/aix.h
create mode 100644 src/makefiles/Makefile.aix
create mode 100644 src/template/aix
diff --git a/Makefile b/Makefile
index 8a2ec9396b..9bc1a4ec17 100644
--- a/Makefile
+++ b/Makefile
@@ -13,8 +13,6 @@
# AIX make defaults to building *every* target of the first rule. Start with
# a single-target, empty rule to make the other targets non-default.
-# (We don't support AIX anymore, but if someone tries to build on AIX anyway,
-# at least they'll get the instructions to run 'configure' first.)
all:
all check install installdirs installcheck installcheck-parallel uninstall clean distclean maintainer-clean dist distcheck world check-world install-world installcheck-world:
diff --git a/configure b/configure
index 89644f2249..f218b2e040 100755
--- a/configure
+++ b/configure
@@ -2988,6 +2988,7 @@ else
# --with-template not given
case $host_os in
+ aix*) template=aix ;;
cygwin*|msys*) template=cygwin ;;
darwin*) template=darwin ;;
dragonfly*) template=netbsd ;;
@@ -6848,7 +6849,6 @@ if test x"$pgac_cv_prog_CXX_cxxflags__fno_strict_aliasing" = x"yes"; then
CXXFLAGS="${CXXFLAGS} -fno-strict-aliasing"
fi
-
fi
# If the compiler knows how to hide symbols, add the switch needed for that to
@@ -12860,7 +12860,8 @@ fi
fi
-# Note: We can test for libldap_r only after we know PTHREAD_LIBS
+# Note: We can test for libldap_r only after we know PTHREAD_LIBS;
+# also, on AIX, we may need to have openssl in LIBS for this step.
if test "$with_ldap" = yes ; then
_LIBS="$LIBS"
if test "$PORTNAME" != "win32"; then
@@ -16951,28 +16952,18 @@ _ACEOF
# Compute maximum alignment of any basic type.
-#
-# We require 'double' to have the strictest alignment among the basic types,
-# because otherwise the C ABI might impose 8-byte alignment on some of the
-# other C types that correspond to TYPALIGN_DOUBLE SQL types. That could
-# cause a mismatch between the tuple layout and the C struct layout of a
-# catalog tuple. We used to carefully order catalog columns such that any
-# fixed-width, attalign=4 columns were at offsets divisible by 8 regardless
-# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms
-# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF.
-#
-# We assume without checking that long's alignment is at least as strong as
-# char, short, or int. Note that we intentionally do not consider any types
-# wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8 would be too
-# much of a penalty for disk and memory space.
-
-MAX_ALIGNOF=$ac_cv_alignof_double
+# We assume long's alignment is at least as strong as char, short, or int;
+# but we must check long long (if it is being used for int64) and double.
+# Note that we intentionally do not consider any types wider than 64 bits,
+# as allowing MAXIMUM_ALIGNOF to exceed 8 would be too much of a penalty
+# for disk and memory space.
-if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
- as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
+MAX_ALIGNOF=$ac_cv_alignof_long
+if test $MAX_ALIGNOF -lt $ac_cv_alignof_double ; then
+ MAX_ALIGNOF=$ac_cv_alignof_double
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- as_fn_error $? "alignment of 'long long int' is greater than the alignment of 'double'" "$LINENO" 5
+if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $MAX_ALIGNOF -lt $ac_cv_alignof_long_long_int ; then
+ MAX_ALIGNOF="$ac_cv_alignof_long_long_int"
fi
cat >>confdefs.h <<_ACEOF
@@ -17090,7 +17081,7 @@ else
/* end confdefs.h. */
/* This must match the corresponding code in c.h: */
-#if defined(__GNUC__) || defined(__SUNPRO_C)
+#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
#elif defined(_MSC_VER)
#define pg_attribute_aligned(a) __declspec(align(a))
diff --git a/configure.ac b/configure.ac
index c7322e292c..a059509cd9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,6 +62,7 @@ PGAC_ARG_REQ(with, template, [NAME], [override operating system template],
# --with-template not given
case $host_os in
+ aix*) template=aix ;;
cygwin*|msys*) template=cygwin ;;
darwin*) template=darwin ;;
dragonfly*) template=netbsd ;;
@@ -1385,7 +1386,8 @@ if test "$with_zstd" = yes ; then
AC_CHECK_LIB(zstd, ZSTD_compress, [], [AC_MSG_ERROR([library 'zstd' is required for ZSTD support])])
fi
-# Note: We can test for libldap_r only after we know PTHREAD_LIBS
+# Note: We can test for libldap_r only after we know PTHREAD_LIBS;
+# also, on AIX, we may need to have openssl in LIBS for this step.
if test "$with_ldap" = yes ; then
_LIBS="$LIBS"
if test "$PORTNAME" != "win32"; then
@@ -1643,8 +1645,9 @@ PGAC_TYPE_LOCALE_T
# spelling it understands, because it conflicts with
# __declspec(restrict). Therefore we define pg_restrict to the
# appropriate definition, which presumably won't conflict.
+#
AC_C_RESTRICT
-if test "$ac_cv_c_restrict" = "no"; then
+if test "$ac_cv_c_restrict" = "no" ; then
pg_restrict=""
else
pg_restrict="$ac_cv_c_restrict"
@@ -1996,22 +1999,11 @@ fi
AC_CHECK_ALIGNOF(double)
# Compute maximum alignment of any basic type.
-#
-# We require 'double' to have the strictest alignment among the basic types,
-# because otherwise the C ABI might impose 8-byte alignment on some of the
-# other C types that correspond to TYPALIGN_DOUBLE SQL types. That could
-# cause a mismatch between the tuple layout and the C struct layout of a
-# catalog tuple. We used to carefully order catalog columns such that any
-# fixed-width, attalign=4 columns were at offsets divisible by 8 regardless
-# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms
-# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF.
-#
-# We assume without checking that long's alignment is at least as strong as
-# char, short, or int. Note that we intentionally do not consider any types
-# wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8 would be too
-# much of a penalty for disk and memory space.
-
-MAX_ALIGNOF=$ac_cv_alignof_double
+# We assume long's alignment is at least as strong as char, short, or int;
+# but we must check long long (if it is being used for int64) and double.
+# Note that we intentionally do not consider any types wider than 64 bits,
+# as allowing MAXIMUM_ALIGNOF to exceed 8 would be too much of a penalty
+# for disk and memory space.
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
AC_MSG_ERROR([alignment of 'long' is greater than the alignment of 'double'])
diff --git a/doc/src/sgml/dfunc.sgml b/doc/src/sgml/dfunc.sgml
index b94aefcd0c..554f9fac4c 100644
--- a/doc/src/sgml/dfunc.sgml
+++ b/doc/src/sgml/dfunc.sgml
@@ -202,4 +202,23 @@ gcc -G -o foo.so foo.o
server expects to find the shared library files.
</para>
+<!--
+Under AIX, object files are compiled normally but building the shared
+library requires a couple of steps. First, create the object file:
+.nf
+cc <other flags> -c foo.c
+.fi
+You must then create a symbol \*(lqexports\*(rq file for the object
+file:
+.nf
+mkldexport foo.o `pwd` > foo.exp
+.fi
+Finally, you can create the shared library:
+.nf
+ld <other flags> -H512 -T512 -o foo.so -e _nostart \e
+ -bI:.../lib/postgres.exp -bE:foo.exp foo.o \e
+ -lm -lc 2>/dev/null
+.fi
+ -->
+
</sect2>
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 1b32d5ca62..60e9a34a03 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -3401,7 +3401,7 @@ export MANPATH
<para>
<productname>PostgreSQL</productname> can be expected to work on current
versions of these operating systems: Linux, Windows,
- FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, macOS, Solaris, and illumos.
+ FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, macOS, AIX, Solaris, and illumos.
Other Unix-like systems may also work but are not currently
being tested. In most cases, all CPU architectures supported by
a given operating system will work. Look in
@@ -3445,6 +3445,122 @@ export MANPATH
installation issues.
</para>
+ <sect2 id="installation-notes-aix">
+ <title>AIX</title>
+
+ <indexterm zone="installation-notes-aix">
+ <primary>AIX</primary>
+ <secondary>installation on</secondary>
+ </indexterm>
+
+ <para>
+ You can use GCC to build <productname>PostgreSQL</productname>
+ on <productname>AIX</productname>.
+ </para>
+
+ <para>
+ <productname>AIX</productname> versions before 7.1 are no longer
+ tested nor supported by the <productname>PostgreSQL</productname>
+ community.
+ </para>
+
+ <sect3 id="installation-notes-aix-mem-management">
+ <title>Memory Management</title>
+ <!-- https://archives.postgresql.org/message-id/[email protected] -->
+
+ <para>
+ AIX can be somewhat peculiar with regards to the way it does
+ memory management. You can have a server with many multiples of
+ gigabytes of RAM free, but still get out of memory or address
+ space errors when running applications. One example
+ is loading of extensions failing with unusual errors.
+ For example, running as the owner of the PostgreSQL installation:
+<screen>
+=# CREATE EXTENSION plperl;
+ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process.
+</screen>
+ Running as a non-owner in the group possessing the PostgreSQL
+ installation:
+<screen>
+=# CREATE EXTENSION plperl;
+ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address
+</screen>
+ Another example is out of memory errors in the PostgreSQL server
+ logs, with every memory allocation near or greater than 256 MB
+ failing.
+ </para>
+
+ <para>
+ The overall cause of all these problems is the default bittedness
+ and memory model used by the server process. By default, all
+ binaries built on AIX are 32-bit. This does not depend upon
+ hardware type or kernel in use. These 32-bit processes are
+ limited to 4 GB of memory laid out in 256 MB segments using one
+ of a few models. The default allows for less than 256 MB in the
+ heap as it shares a single segment with the stack.
+ </para>
+
+ <para>
+ In the case of the <literal>plperl</literal> example, above,
+ check your umask and the permissions of the binaries in your
+ PostgreSQL installation. The binaries involved in that example
+ were 32-bit and installed as mode 750 instead of 755. Due to the
+ permissions being set in this fashion, only the owner or a member
+ of the possessing group can load the library. Since it isn't
+ world-readable, the loader places the object into the process'
+ heap instead of the shared library segments where it would
+ otherwise be placed.
+ </para>
+
+ <para>
+ The <quote>ideal</quote> solution for this is to use a 64-bit
+ build of PostgreSQL, but that is not always practical, because
+ systems with 32-bit processors can build, but not run, 64-bit
+ binaries.
+ </para>
+
+ <para>
+ If a 32-bit binary is desired, set <symbol>LDR_CNTRL</symbol> to
+ <literal>MAXDATA=0x<replaceable>n</replaceable>0000000</literal>,
+ where 1 <= n <= 8, before starting the PostgreSQL server,
+ and try different values and <filename>postgresql.conf</filename>
+ settings to find a configuration that works satisfactorily. This
+ use of <symbol>LDR_CNTRL</symbol> tells AIX that you want the
+ server to have <symbol>MAXDATA</symbol> bytes set aside for the
+ heap, allocated in 256 MB segments. When you find a workable
+ configuration,
+ <command>ldedit</command> can be used to modify the binaries so
+ that they default to using the desired heap size. PostgreSQL can
+ also be rebuilt, passing <literal>configure
+ LDFLAGS="-Wl,-bmaxdata:0x<replaceable>n</replaceable>0000000"</literal>
+ to achieve the same effect.
+ </para>
+
+ <para>
+ For a 64-bit build, set <envar>OBJECT_MODE</envar> to 64 and
+ pass <literal>CC="gcc -maix64"</literal>
+ and <literal>LDFLAGS="-Wl,-bbigtoc"</literal>
+ to <command>configure</command>.
+ If you omit the export of
+ <envar>OBJECT_MODE</envar>, your build may fail with linker errors. When
+ <envar>OBJECT_MODE</envar> is set, it tells AIX's build utilities
+ such as <command>ar</command>, <command>as</command>, and <command>ld</command> what
+ type of objects to default to handling.
+ </para>
+
+ <para>
+ By default, overcommit of paging space can happen. While we have
+ not seen this occur, AIX will kill processes when it runs out of
+ memory and the overcommit is accessed. The closest to this that
+ we have seen is fork failing because the system decided that
+ there was not enough memory for another process. Like many other
+ parts of AIX, the paging space allocation method and
+ out-of-memory kill is configurable on a system- or process-wide
+ basis if this becomes a problem.
+ </para>
+ </sect3>
+ </sect2>
+
<sect2 id="installation-notes-cygwin">
<title>Cygwin</title>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 6047b8171d..64753d9c01 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -891,6 +891,29 @@ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such
<variablelist>
+ <varlistentry>
+ <term><systemitem class="osname">AIX</systemitem>
+ <indexterm><primary>AIX</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ It should not be necessary to do
+ any special configuration for such parameters as
+ <varname>SHMMAX</varname>, as it appears this is configured to
+ allow all memory to be used as shared memory. That is the
+ sort of configuration commonly used for other databases such
+ as <application>DB/2</application>.</para>
+
+ <para> It might, however, be necessary to modify the global
+ <command>ulimit</command> information in
+ <filename>/etc/security/limits</filename>, as the default hard
+ limits for file sizes (<varname>fsize</varname>) and numbers of
+ files (<varname>nofiles</varname>) might be too low.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
<varlistentry>
<term><systemitem class="osname">FreeBSD</systemitem>
<indexterm><primary>FreeBSD</primary><secondary>IPC configuration</secondary></indexterm>
diff --git a/meson.build b/meson.build
index 1c0579d5a6..f1ac154cdc 100644
--- a/meson.build
+++ b/meson.build
@@ -196,7 +196,26 @@ endif
# that purpose.
portname = host_system
-if host_system == 'cygwin'
+if host_system == 'aix'
+ library_path_var = 'LIBPATH'
+
+ export_file_format = 'aix'
+ export_fmt = '-Wl,-bE:@0@'
+ mod_link_args_fmt = ['-Wl,-bI:@0@']
+ mod_link_with_dir = 'libdir'
+ mod_link_with_name = '@[email protected]'
+
+ # M:SRE sets a flag indicating that an object is a shared library. Seems to
+ # work in some circumstances without, but required in others.
+ ldflags_sl += '-Wl,-bM:SRE'
+ ldflags_be += '-Wl,-brtllib'
+
+ # Native memset() is faster, tested on:
+ # - AIX 5.1 and 5.2, XLC 6.0 (IBM's cc)
+ # - AIX 5.3 ML3, gcc 4.0.1
+ memset_loop_limit = 0
+
+elif host_system == 'cygwin'
sema_kind = 'unnamed_posix'
cppflags += '-D_GNU_SOURCE'
dlsuffix = '.dll'
@@ -1490,11 +1509,11 @@ sizeof_long = cc.sizeof('long', args: test_c_args)
cdata.set('SIZEOF_LONG', sizeof_long)
if sizeof_long == 8
cdata.set('HAVE_LONG_INT_64', 1)
- pg_int64_type = 'long int'
+ cdata.set('PG_INT64_TYPE', 'long int')
cdata.set_quoted('INT64_MODIFIER', 'l')
elif sizeof_long == 4 and cc.sizeof('long long', args: test_c_args) == 8
cdata.set('HAVE_LONG_LONG_INT_64', 1)
- pg_int64_type = 'long long int'
+ cdata.set('PG_INT64_TYPE', 'long long int')
cdata.set_quoted('INT64_MODIFIER', 'll')
else
error('do not know how to get a 64bit int')
@@ -1508,31 +1527,15 @@ endif
# Determine memory alignment requirements for the basic C data types.
alignof_types = ['short', 'int', 'long', 'double']
+maxalign = 0
foreach t : alignof_types
align = cc.alignment(t, args: test_c_args)
+ if maxalign < align
+ maxalign = align
+ endif
cdata.set('ALIGNOF_@0@'.format(t.to_upper()), align)
endforeach
-
-# Compute maximum alignment of any basic type.
-#
-# We require 'double' to have the strictest alignment among the basic types,
-# because otherwise the C ABI might impose 8-byte alignment on some of the
-# other C types that correspond to TYPALIGN_DOUBLE SQL types. That could
-# cause a mismatch between the tuple layout and the C struct layout of a
-# catalog tuple. We used to carefully order catalog columns such that any
-# fixed-width, attalign=4 columns were at offsets divisible by 8 regardless
-# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms
-# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF.
-#
-# We assume without checking that int64's alignment is at least as strong
-# as long, char, short, or int. Note that we intentionally do not consider
-# any types wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8
-# would be too much of a penalty for disk and memory space.
-alignof_double = cdata.get('ALIGNOF_DOUBLE')
-if cc.alignment(pg_int64_type, args: test_c_args) > alignof_double
- error('alignment of int64 is greater than the alignment of double')
-endif
-cdata.set('MAXIMUM_ALIGNOF', alignof_double)
+cdata.set('MAXIMUM_ALIGNOF', maxalign)
cdata.set('SIZEOF_VOID_P', cc.sizeof('void *', args: test_c_args))
cdata.set('SIZEOF_SIZE_T', cc.sizeof('size_t', args: test_c_args))
@@ -1581,7 +1584,7 @@ if cc.links('''
if not meson.is_cross_build()
r = cc.run('''
/* This must match the corresponding code in c.h: */
- #if defined(__GNUC__) || defined(__SUNPRO_C)
+ #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
#elif defined(_MSC_VER)
#define pg_attribute_aligned(a) __declspec(align(a))
@@ -2476,6 +2479,10 @@ endif
# conflict.
#
# We assume C99 support, so we don't need to make this conditional.
+#
+# XXX: Historically we allowed platforms to disable restrict in template
+# files, but that was only added for AIX when building with XLC, which we
+# don't support yet.
cdata.set('pg_restrict', '__restrict')
diff --git a/src/Makefile.shlib b/src/Makefile.shlib
index fa81f6ffdd..8ca51ca03f 100644
--- a/src/Makefile.shlib
+++ b/src/Makefile.shlib
@@ -106,6 +106,20 @@ ifdef SO_MAJOR_VERSION
override CPPFLAGS += -DSO_MAJOR_VERSION=$(SO_MAJOR_VERSION)
endif
+ifeq ($(PORTNAME), aix)
+ LINK.shared = $(COMPILER)
+ ifdef SO_MAJOR_VERSION
+ shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION)
+ endif
+ haslibarule = yes
+ # $(exports_file) is also usable as an import file
+ exports_file = lib$(NAME).exp
+ BUILD.exports = ( echo '\#! $(shlib)'; $(AWK) '/^[^\#]/ {printf "%s\n",$$1}' $< ) > $@
+ ifneq (,$(SHLIB_EXPORTS))
+ LINK.shared += -Wl,-bE:$(exports_file)
+ endif
+endif
+
ifeq ($(PORTNAME), darwin)
ifdef soname
# linkable library
@@ -254,6 +268,14 @@ $(stlib): $(OBJS) | $(SHLIB_PREREQS)
touch $@
endif #haslibarule
+# AIX wraps shared libraries inside a static library, can be used both
+# for static and shared linking
+ifeq ($(PORTNAME), aix)
+$(stlib): $(shlib)
+ rm -f $(stlib)
+ $(AR) $(AROPT) $(stlib) $(shlib)
+endif # aix
+
ifeq (,$(filter cygwin win32,$(PORTNAME)))
# Normal case
@@ -267,8 +289,11 @@ ifneq ($(shlib), $(shlib_major))
endif
# Make sure we have a link to a name without any version numbers
ifneq ($(shlib), $(shlib_bare))
+# except on AIX, where that's not a thing
+ifneq ($(PORTNAME), aix)
rm -f $(shlib_bare)
$(LN_S) $(shlib) $(shlib_bare)
+endif # aix
endif # shlib_bare
endif # shlib_major
@@ -376,6 +401,9 @@ install-lib-static: $(stlib) installdirs-lib
install-lib-shared: $(shlib) installdirs-lib
ifdef soname
+# we don't install $(shlib) on AIX
+# (see http://archives.postgresql.org/message-id/52EF20B2E3209443BC37736D00C3C1380A6E79FE@EXADV1.host.magwien.gv.at)
+ifneq ($(PORTNAME), aix)
$(INSTALL_SHLIB) $< '$(DESTDIR)$(libdir)/$(shlib)'
ifneq ($(PORTNAME), cygwin)
ifneq ($(PORTNAME), win32)
@@ -391,6 +419,7 @@ ifneq ($(shlib), $(shlib_bare))
endif
endif # not win32
endif # not cygwin
+endif # not aix
ifneq (,$(findstring $(PORTNAME),win32 cygwin))
$(INSTALL_SHLIB) $< '$(DESTDIR)$(bindir)/$(shlib)'
endif
diff --git a/src/backend/Makefile b/src/backend/Makefile
index 6700aec039..954b14962f 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -62,12 +62,14 @@ all: submake-libpgport submake-catalog-headers submake-utils-headers postgres $(
ifneq ($(PORTNAME), cygwin)
ifneq ($(PORTNAME), win32)
+ifneq ($(PORTNAME), aix)
postgres: $(OBJS)
$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LIBS) -o $@
endif
endif
+endif
ifeq ($(PORTNAME), cygwin)
@@ -94,6 +96,24 @@ libpostgres.a: postgres
endif # win32
+ifeq ($(PORTNAME), aix)
+
+postgres: $(POSTGRES_IMP)
+ $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(LDFLAGS) -Wl,-bE:$(top_builddir)/src/backend/$(POSTGRES_IMP) $(LIBS) -Wl,-brtllib -o $@
+
+# Linking to a single .o with -r is a lot faster than building a .a or passing
+# all objects to MKLDEXPORT.
+#
+# It looks alluring to use $(CC) -r instead of ld -r, but that doesn't
+# trivially work with gcc, due to gcc specific static libraries linked in with
+# -r.
+$(POSTGRES_IMP): $(OBJS)
+ ld -r -o SUBSYS.o $(call expand_subsys,$^)
+ $(MKLDEXPORT) SUBSYS.o . > $@
+ @rm -f SUBSYS.o
+
+endif # aix
+
$(top_builddir)/src/port/libpgport_srv.a: | submake-libpgport
diff --git a/src/backend/meson.build b/src/backend/meson.build
index 436c04af08..8767aaba67 100644
--- a/src/backend/meson.build
+++ b/src/backend/meson.build
@@ -91,6 +91,21 @@ if cc.get_id() == 'msvc'
# be restricted to b_pch=true.
backend_link_with += postgres_lib
+elif host_system == 'aix'
+ # The '.' argument leads mkldexport.sh to emit "#! .", which refers to the
+ # main executable, allowing extension libraries to resolve their undefined
+ # symbols to symbols in the postgres binary.
+ postgres_imp = custom_target('postgres.imp',
+ command: [files('port/aix/mkldexport.sh'), '@INPUT@', '.'],
+ input: postgres_lib,
+ output: 'postgres.imp',
+ capture: true,
+ install: true,
+ install_dir: dir_lib,
+ build_by_default: false,
+ )
+ backend_link_args += '-Wl,-bE:@0@'.format(postgres_imp.full_path())
+ backend_link_depends += postgres_imp
endif
backend_input = []
diff --git a/src/backend/port/aix/mkldexport.sh b/src/backend/port/aix/mkldexport.sh
new file mode 100755
index 0000000000..adf3793e86
--- /dev/null
+++ b/src/backend/port/aix/mkldexport.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# mkldexport
+# create an AIX exports file from an object file
+#
+# src/backend/port/aix/mkldexport.sh
+#
+# Usage:
+# mkldexport objectfile [location]
+# where
+# objectfile is the current location of the object file.
+# location is the eventual (installed) location of the
+# object file (if different from the current
+# working directory).
+#
+# [This file comes from the Postgres 4.2 distribution. - ay 7/95]
+#
+# Header: /usr/local/devel/postgres/src/tools/mkldexport/RCS/mkldexport.sh,v 1.2 1994/03/13 04:59:12 aoki Exp
+#
+
+# setting this to nm -B might be better
+# ... due to changes in AIX 4.x ...
+# ... let us search in different directories - Gerhard Reithofer
+if [ -x /usr/ucb/nm ]
+then NM=/usr/ucb/nm
+elif [ -x /usr/bin/nm ]
+then NM=/usr/bin/nm
+elif [ -x /usr/ccs/bin/nm ]
+then NM=/usr/ccs/bin/nm
+elif [ -x /usr/usg/bin/nm ]
+then NM=/usr/usg/bin/nm
+else echo "Fatal error: cannot find `nm' ... please check your installation."
+ exit 1
+fi
+
+CMDNAME=`basename $0`
+if [ -z "$1" ]; then
+ echo "Usage: $CMDNAME object [location]"
+ exit 1
+fi
+OBJNAME=`basename $1`
+if [ "`basename $OBJNAME`" != "`basename $OBJNAME .o`" ]; then
+ OBJNAME=`basename $OBJNAME .o`.so
+fi
+if [ -z "$2" ]; then
+ echo '#!'
+else
+ if [ "$2" = "." ]; then
+ # for the base executable (AIX 4.2 and up)
+ echo '#! .'
+ else
+ echo '#!' $2
+ fi
+fi
+$NM -BCg $1 | \
+ egrep ' [TDB] ' | \
+ sed -e 's/.* //' | \
+ egrep -v '\$' | \
+ sed -e 's/^[.]//' | \
+ sort | \
+ uniq
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index d91a85cb2d..7b51e94f4a 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -908,7 +908,9 @@ errcode_for_file_access(void)
/* Wrong object type or state */
case ENOTDIR: /* Not a directory */
case EISDIR: /* Is a directory */
+#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
case ENOTEMPTY: /* Directory not empty */
+#endif
edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;
break;
diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c
index 9da6377402..532eac31b4 100644
--- a/src/backend/utils/misc/ps_status.c
+++ b/src/backend/utils/misc/ps_status.c
@@ -50,7 +50,7 @@ bool update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
#define PS_USE_SETPROCTITLE_FAST
#elif defined(HAVE_SETPROCTITLE)
#define PS_USE_SETPROCTITLE
-#elif defined(__linux__) || defined(__sun) || defined(__darwin__)
+#elif defined(__linux__) || defined(_AIX) || defined(__sun) || defined(__darwin__)
#define PS_USE_CLOBBER_ARGV
#elif defined(WIN32)
#define PS_USE_WIN32
@@ -60,7 +60,7 @@ bool update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
/* Different systems want the buffer padded differently */
-#if defined(__linux__) || defined(__darwin__)
+#if defined(_AIX) || defined(__linux__) || defined(__darwin__)
#define PS_PADDING '\0'
#else
#define PS_PADDING ' '
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index 2d4b75a6fe..ce936959c1 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -401,7 +401,8 @@ SKIP:
{
my $tar = $ENV{TAR};
# don't check for a working tar here, to accommodate various odd
- # cases. If tar doesn't work the init_from_backup below will fail.
+ # cases such as AIX. If tar doesn't work the init_from_backup below
+ # will fail.
skip "no tar program available", 1
if (!defined $tar || $tar eq '');
diff --git a/src/bin/pg_verifybackup/t/008_untar.pl b/src/bin/pg_verifybackup/t/008_untar.pl
index 7a09f3b75b..30d9f3f7f0 100644
--- a/src/bin/pg_verifybackup/t/008_untar.pl
+++ b/src/bin/pg_verifybackup/t/008_untar.pl
@@ -104,7 +104,8 @@ for my $tc (@test_configuration)
{
my $tar = $ENV{TAR};
# don't check for a working tar here, to accommodate various odd
- # cases. If tar doesn't work the init_from_backup below will fail.
+ # cases such as AIX. If tar doesn't work the init_from_backup below
+ # will fail.
skip "no tar program available", 1
if (!defined $tar || $tar eq '');
diff --git a/src/bin/pg_verifybackup/t/010_client_untar.pl b/src/bin/pg_verifybackup/t/010_client_untar.pl
index 8c076d46de..45010d79ac 100644
--- a/src/bin/pg_verifybackup/t/010_client_untar.pl
+++ b/src/bin/pg_verifybackup/t/010_client_untar.pl
@@ -134,7 +134,8 @@ for my $tc (@test_configuration)
{
my $tar = $ENV{TAR};
# don't check for a working tar here, to accommodate various odd
- # cases. If tar doesn't work the init_from_backup below will fail.
+ # cases such as AIX. If tar doesn't work the init_from_backup below
+ # will fail.
skip "no tar program available", 1
if (!defined $tar || $tar eq '');
diff --git a/src/include/c.h b/src/include/c.h
index dc1841346c..641cd9bdf1 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -182,7 +182,7 @@
#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused()
#endif
-/* GCC supports format attributes */
+/* GCC support format attributes */
#if defined(__GNUC__)
#define pg_attribute_format_arg(a) __attribute__((format_arg(a)))
#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a)))
@@ -192,7 +192,7 @@
#endif
/* GCC and Sunpro support aligned, packed and noreturn */
-#if defined(__GNUC__) || defined(__SUNPRO_C)
+#if defined(__GNUC__) || defined(__SUNPRO_C)
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
#define pg_attribute_noreturn() __attribute__((noreturn))
#define pg_attribute_packed() __attribute__((packed))
diff --git a/src/include/port/aix.h b/src/include/port/aix.h
new file mode 100644
index 0000000000..1c2d166791
--- /dev/null
+++ b/src/include/port/aix.h
@@ -0,0 +1,6 @@
+/*
+ * src/include/port/aix.h
+ */
+#define CLASS_CONFLICT
+#define DISABLE_XOPEN_NLS
+
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 29ac6cdcd9..2f6eb5df2a 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -424,17 +424,15 @@ tas(volatile slock_t *lock)
__asm__ __volatile__(
" lwarx %0,0,%3,1 \n"
" cmpwi %0,0 \n"
-" bne 1f \n"
+" bne $+16 \n" /* branch to li %1,1 */
" addi %0,%0,1 \n"
" stwcx. %0,0,%3 \n"
-" beq 2f \n"
-"1: \n"
+" beq $+12 \n" /* branch to lwsync */
" li %1,1 \n"
-" b 3f \n"
-"2: \n"
+" b $+12 \n" /* branch to end of asm sequence */
" lwsync \n"
" li %1,0 \n"
-"3: \n"
+
: "=&b"(_t), "=r"(_res), "+m"(*lock)
: "r"(lock)
: "memory", "cc");
@@ -662,6 +660,21 @@ tas(volatile slock_t *lock)
#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */
+#if defined(_AIX) /* AIX */
+/*
+ * AIX (POWER)
+ */
+#define HAS_TEST_AND_SET
+
+#include <sys/atomic_op.h>
+
+typedef int slock_t;
+
+#define TAS(lock) _check_lock((slock_t *) (lock), 0, 1)
+#define S_UNLOCK(lock) _clear_lock((slock_t *) (lock), 0)
+#endif /* _AIX */
+
+
/* These are in sunstudio_(sparc|x86).s */
#if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc))
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index b36a765764..154429d4d1 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -114,7 +114,7 @@ backend_src = $(top_srcdir)/src/backend
# coding rule.
libpq-refs-stamp: $(shlib)
ifneq ($(enable_coverage), yes)
-ifeq (,$(filter solaris,$(PORTNAME)))
+ifeq (,$(filter aix solaris,$(PORTNAME)))
@if nm -A -u $< 2>/dev/null | grep -v -e __cxa_atexit -e __tsan_func_exit | grep exit; then \
echo 'libpq must not be calling any function which invokes exit'; exit 1; \
fi
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index ed2a4048d1..7e2017daf0 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -54,8 +54,9 @@ libpq_c_args = ['-DSO_MAJOR_VERSION=5']
# libpq_st, and {pgport,common}_shlib for libpq_sh
#
# We could try to avoid building the source files twice, but it probably adds
-# more complexity than its worth (reusing object files requires also linking
-# to the library on windows or breaks precompiled headers).
+# more complexity than its worth (AIX doesn't support link_whole yet, reusing
+# object files requires also linking to the library on windows or breaks
+# precompiled headers).
libpq_st = static_library('libpq',
libpq_sources,
include_directories: [libpq_inc],
diff --git a/src/makefiles/Makefile.aix b/src/makefiles/Makefile.aix
new file mode 100644
index 0000000000..dd16a7a037
--- /dev/null
+++ b/src/makefiles/Makefile.aix
@@ -0,0 +1,39 @@
+# MAKE_EXPORTS is required for svr4 loaders that want a file of
+# symbol names to tell them what to export/import.
+MAKE_EXPORTS= true
+
+# -blibpath must contain ALL directories where we should look for libraries
+libpath := $(shell echo $(subst -L,:,$(filter -L/%,$(LDFLAGS))) | sed -e's/ //g'):/usr/lib:/lib
+
+# when building with gcc, need to make sure that libgcc can be found
+ifeq ($(GCC), yes)
+libpath := $(libpath):$(dir $(shell gcc -print-libgcc-file-name))
+endif
+
+rpath = -Wl,-blibpath:'$(rpathdir)$(libpath)'
+
+LDFLAGS_SL += -Wl,-bnoentry -Wl,-H512 -Wl,-bM:SRE
+
+# gcc needs to know it's building a shared lib, otherwise it'll not emit
+# correct code / link to the right support libraries
+ifeq ($(GCC), yes)
+LDFLAGS_SL += -shared
+endif
+
+# env var name to use in place of LD_LIBRARY_PATH
+ld_library_path_var = LIBPATH
+
+
+POSTGRES_IMP= postgres.imp
+
+ifdef PGXS
+BE_DLLLIBS= -Wl,-bI:$(pkglibdir)/$(POSTGRES_IMP)
+else
+BE_DLLLIBS= -Wl,-bI:$(top_builddir)/src/backend/$(POSTGRES_IMP)
+endif
+
+MKLDEXPORT_DIR=src/backend/port/aix
+MKLDEXPORT=$(top_srcdir)/$(MKLDEXPORT_DIR)/mkldexport.sh
+
+%$(DLSUFFIX): %.o
+ $(CC) $(CFLAGS) $*.o $(LDFLAGS) $(LDFLAGS_SL) -o $@ $(BE_DLLLIBS)
diff --git a/src/port/README b/src/port/README
index ed5c54a72f..97f18a6233 100644
--- a/src/port/README
+++ b/src/port/README
@@ -28,5 +28,5 @@ applications.
from libpgport are linked first. This avoids having applications
dependent on symbols that are _used_ by libpq, but not intended to be
exported by libpq. libpq's libpgport usage changes over time, so such a
-dependency is a problem. Windows, Linux, and macOS use an export
+dependency is a problem. Windows, Linux, AIX, and macOS use an export
list to control the symbols exported by libpq.
diff --git a/src/port/strerror.c b/src/port/strerror.c
index 4918ba821c..1070a49802 100644
--- a/src/port/strerror.c
+++ b/src/port/strerror.c
@@ -214,8 +214,10 @@ get_errno_symbol(int errnum)
return "ENOTCONN";
case ENOTDIR:
return "ENOTDIR";
+#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
case ENOTEMPTY:
return "ENOTEMPTY";
+#endif
case ENOTSOCK:
return "ENOTSOCK";
#ifdef ENOTSUP
diff --git a/src/template/aix b/src/template/aix
new file mode 100644
index 0000000000..0a788676c0
--- /dev/null
+++ b/src/template/aix
@@ -0,0 +1,14 @@
+# src/template/aix
+
+ # Due to a compiler bug, see [email protected] for details,
+ # force restrict not to be used when compiling with xlc.
+# FORCE_DISABLE_RESTRICT=yes
+#fi
+
+# Extra CFLAGS for code that will go into a shared library
+CFLAGS_SL=""
+
+# Native memset() is faster, tested on:
+# AIX 5.1 and 5.2, XLC 6.0 (IBM's cc)
+# AIX 5.3 ML3, gcc 4.0.1
+MEMSET_LOOP_LIMIT=0
diff --git a/src/test/regress/Makefile b/src/test/regress/Makefile
index 6409a485e8..7c665ff892 100644
--- a/src/test/regress/Makefile
+++ b/src/test/regress/Makefile
@@ -7,6 +7,11 @@
# GNU make uses a make file named "GNUmakefile" in preference to "Makefile"
# if it exists. Postgres is shipped with a "GNUmakefile".
+
+# AIX make defaults to building *every* target of the first rule. Start with
+# a single-target, empty rule to make the other targets non-default.
+all:
+
all install clean check installcheck:
@echo "You must use GNU make to use Postgres. It may be installed"
@echo "on your system with the name 'gmake'."
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index 8370c1561c..c5c675b750 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -25,3 +25,32 @@ SELECT relname, relkind
---------+---------
(0 rows)
+--
+-- When ALIGNOF_DOUBLE==4 (e.g. AIX), the C ABI may impose 8-byte alignment on
+-- some of the C types that correspond to TYPALIGN_DOUBLE SQL types. To ensure
+-- catalog C struct layout matches catalog tuple layout, arrange for the tuple
+-- offset of each fixed-width, attalign='d' catalog column to be divisible by 8
+-- unconditionally. Keep such columns before the first NameData column of the
+-- catalog, since packagers can override NAMEDATALEN to an odd number.
+--
+WITH check_columns AS (
+ SELECT relname, attname,
+ array(
+ SELECT t.oid
+ FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
+ WHERE pa.attrelid = a.attrelid AND
+ pa.attnum > 0 AND pa.attnum < a.attnum
+ ORDER BY pa.attnum) AS coltypes
+ FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
+ JOIN pg_namespace n ON c.relnamespace = n.oid
+ WHERE attalign = 'd' AND relkind = 'r' AND
+ attnotnull AND attlen <> -1 AND n.nspname = 'pg_catalog'
+)
+SELECT relname, attname, coltypes, get_columns_length(coltypes)
+ FROM check_columns
+ WHERE get_columns_length(coltypes) % 8 != 0 OR
+ 'name'::regtype::oid = ANY(coltypes);
+ relname | attname | coltypes | get_columns_length
+---------+---------+----------+--------------------
+(0 rows)
+
diff --git a/src/test/regress/expected/test_setup.out b/src/test/regress/expected/test_setup.out
index 3d0eeec996..5d9e6bf12b 100644
--- a/src/test/regress/expected/test_setup.out
+++ b/src/test/regress/expected/test_setup.out
@@ -209,6 +209,10 @@ CREATE FUNCTION ttdummy ()
RETURNS trigger
AS :'regresslib'
LANGUAGE C;
+CREATE FUNCTION get_columns_length(oid[])
+ RETURNS int
+ AS :'regresslib'
+ LANGUAGE C STRICT STABLE PARALLEL SAFE;
-- Use hand-rolled hash functions and operator classes to get predictable
-- result on different machines. The hash function for int4 simply returns
-- the sum of the values passed to it and the one for text returns the length
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index deffaea578..cc633864d7 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -1221,3 +1221,43 @@ binary_coercible(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(IsBinaryCoercible(srctype, targettype));
}
+
+/*
+ * Return the length of the portion of a tuple consisting of the given array
+ * of data types. The input data types must be fixed-length data types.
+ */
+PG_FUNCTION_INFO_V1(get_columns_length);
+Datum
+get_columns_length(PG_FUNCTION_ARGS)
+{
+ ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
+ Oid *type_oids;
+ int ntypes;
+ int column_offset = 0;
+
+ if (ARR_HASNULL(ta) && array_contains_nulls(ta))
+ elog(ERROR, "argument must not contain nulls");
+
+ if (ARR_NDIM(ta) > 1)
+ elog(ERROR, "argument must be empty or one-dimensional array");
+
+ type_oids = (Oid *) ARR_DATA_PTR(ta);
+ ntypes = ArrayGetNItems(ARR_NDIM(ta), ARR_DIMS(ta));
+ for (int i = 0; i < ntypes; i++)
+ {
+ Oid typeoid = type_oids[i];
+ int16 typlen;
+ bool typbyval;
+ char typalign;
+
+ get_typlenbyvalalign(typeoid, &typlen, &typbyval, &typalign);
+
+ /* the data type must be fixed-length */
+ if (typlen < 0)
+ elog(ERROR, "type %u is not fixed-length data type", typeoid);
+
+ column_offset = att_align_nominal(column_offset + typlen, typalign);
+ }
+
+ PG_RETURN_INT32(column_offset);
+}
diff --git a/src/test/regress/sql/sanity_check.sql b/src/test/regress/sql/sanity_check.sql
index 162e5324b5..7f338d191c 100644
--- a/src/test/regress/sql/sanity_check.sql
+++ b/src/test/regress/sql/sanity_check.sql
@@ -19,3 +19,29 @@ SELECT relname, relkind
FROM pg_class
WHERE relkind IN ('v', 'c', 'f', 'p', 'I')
AND relfilenode <> 0;
+
+--
+-- When ALIGNOF_DOUBLE==4 (e.g. AIX), the C ABI may impose 8-byte alignment on
+-- some of the C types that correspond to TYPALIGN_DOUBLE SQL types. To ensure
+-- catalog C struct layout matches catalog tuple layout, arrange for the tuple
+-- offset of each fixed-width, attalign='d' catalog column to be divisible by 8
+-- unconditionally. Keep such columns before the first NameData column of the
+-- catalog, since packagers can override NAMEDATALEN to an odd number.
+--
+WITH check_columns AS (
+ SELECT relname, attname,
+ array(
+ SELECT t.oid
+ FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
+ WHERE pa.attrelid = a.attrelid AND
+ pa.attnum > 0 AND pa.attnum < a.attnum
+ ORDER BY pa.attnum) AS coltypes
+ FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
+ JOIN pg_namespace n ON c.relnamespace = n.oid
+ WHERE attalign = 'd' AND relkind = 'r' AND
+ attnotnull AND attlen <> -1 AND n.nspname = 'pg_catalog'
+)
+SELECT relname, attname, coltypes, get_columns_length(coltypes)
+ FROM check_columns
+ WHERE get_columns_length(coltypes) % 8 != 0 OR
+ 'name'::regtype::oid = ANY(coltypes);
diff --git a/src/test/regress/sql/test_setup.sql b/src/test/regress/sql/test_setup.sql
index 06b0e2121f..1b2d434683 100644
--- a/src/test/regress/sql/test_setup.sql
+++ b/src/test/regress/sql/test_setup.sql
@@ -257,6 +257,11 @@ CREATE FUNCTION ttdummy ()
AS :'regresslib'
LANGUAGE C;
+CREATE FUNCTION get_columns_length(oid[])
+ RETURNS int
+ AS :'regresslib'
+ LANGUAGE C STRICT STABLE PARALLEL SAFE;
+
-- Use hand-rolled hash functions and operator classes to get predictable
-- result on different machines. The hash function for int4 simply returns
-- the sum of the values passed to it and the one for text returns the length
diff --git a/src/tools/gen_export.pl b/src/tools/gen_export.pl
index d9fdaaaf6d..888c8a197a 100644
--- a/src/tools/gen_export.pl
+++ b/src/tools/gen_export.pl
@@ -16,11 +16,12 @@ GetOptions(
'input:s' => \$input,
'output:s' => \$output) or die "wrong arguments";
-if (not( $format eq 'darwin'
+if (not( $format eq 'aix'
+ or $format eq 'darwin'
or $format eq 'gnu'
or $format eq 'win'))
{
- die "$0: $format is not yet handled (only darwin, gnu, win are)\n";
+ die "$0: $format is not yet handled (only aix, darwin, gnu, win are)\n";
}
open(my $input_handle, '<', $input)
@@ -55,7 +56,11 @@ while (<$input_handle>)
}
elsif (/^(\S+)\s+(\S+)/)
{
- if ($format eq 'darwin')
+ if ($format eq 'aix')
+ {
+ print $output_handle "$1\n";
+ }
+ elsif ($format eq 'darwin')
{
print $output_handle "_$1\n";
}
diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck
index 4a157d0a5f..cfd8c6896c 100755
--- a/src/tools/pginclude/headerscheck
+++ b/src/tools/pginclude/headerscheck
@@ -85,6 +85,7 @@ do
# These files are platform-specific, and c.h will include the
# one that's relevant for our current platform anyway.
+ test "$f" = src/include/port/aix.h && continue
test "$f" = src/include/port/cygwin.h && continue
test "$f" = src/include/port/darwin.h && continue
test "$f" = src/include/port/freebsd.h && continue
--
2.41.0
[application/octet-stream] 0001-Replace-tas-asm-with-gcc-routines-for-powerPC-implem.patch (2.3K, 4-0001-Replace-tas-asm-with-gcc-routines-for-powerPC-implem.patch)
download | inline diff:
From a08fbe47316034c458fcfb748efd7caabad9893f Mon Sep 17 00:00:00 2001
From: Sriram RK <[email protected]>
Date: Tue, 24 Sep 2024 05:04:51 -0500
Subject: [PATCH 1/1] Replace tas() asm with gcc routines for powerPC
implementaion in s_lock.h .
---
src/include/storage/s_lock.h | 43 ++++--------------------------------
1 file changed, 4 insertions(+), 39 deletions(-)
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 2f6eb5df2a..c0cc7bd38b 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -401,54 +401,19 @@ typedef unsigned int slock_t;
#define TAS(lock) tas(lock)
-/* On PPC, it's a win to use a non-locking test before the lwarx */
+/* On PPC, use the gcc atomic routines, to set the lock. */
#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
-/*
- * The second operand of addi can hold a constant zero or a register number,
- * hence constraint "=&b" to avoid allocating r0. "b" stands for "address
- * base register"; most operands having this register-or-zero property are
- * address bases, e.g. the second operand of lwax.
- *
- * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002,
- * an isync is a sufficient synchronization barrier after a lwarx/stwcx loop.
- * But if the spinlock is in ordinary memory, we can use lwsync instead for
- * better performance.
- */
static __inline__ int
tas(volatile slock_t *lock)
{
- slock_t _t;
- int _res;
-
- __asm__ __volatile__(
-" lwarx %0,0,%3,1 \n"
-" cmpwi %0,0 \n"
-" bne $+16 \n" /* branch to li %1,1 */
-" addi %0,%0,1 \n"
-" stwcx. %0,0,%3 \n"
-" beq $+12 \n" /* branch to lwsync */
-" li %1,1 \n"
-" b $+12 \n" /* branch to end of asm sequence */
-" lwsync \n"
-" li %1,0 \n"
-
-: "=&b"(_t), "=r"(_res), "+m"(*lock)
-: "r"(lock)
-: "memory", "cc");
- return _res;
+ return __sync_lock_test_and_set(lock, 1);
}
/*
- * PowerPC S_UNLOCK is almost standard but requires a "sync" instruction.
- * But we can use lwsync instead for better performance.
+ * PowerPC S_UNLOCK use the gcc atomic routines.
*/
-#define S_UNLOCK(lock) \
-do \
-{ \
- __asm__ __volatile__ (" lwsync \n" ::: "memory"); \
- *((volatile slock_t *) (lock)) = 0; \
-} while (0)
+#define S_UNLOCK(lock) __sync_lock_release(lock)
#endif /* powerpc */
--
2.41.0
view thread (20+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
Subject: RE: AIX support
In-Reply-To: <CY8PR15MB5602F4F63D8F8811A5987EFFDB682@CY8PR15MB5602.namprd15.prod.outlook.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox