Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

32-bit support #232

Merged
merged 4 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 2 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -127,32 +127,11 @@ $(PGDIR):
cd $(PGDIR); make -C src/port pg_config_paths.h
cd $(PGDIR); make -C src/backend generated-headers
cd $(PGDIR); make -C src/backend parser-recursive # Triggers copying of includes to where they belong, as well as generating gram.c/scan.c
# This causes compatibility problems on some Linux distros, with "xlocale.h" not being available
echo "#undef HAVE_LOCALE_T" >> $(PGDIR)/src/include/pg_config.h
echo "#undef LOCALE_T_IN_XLOCALE" >> $(PGDIR)/src/include/pg_config.h
echo "#undef WCSTOMBS_L_IN_XLOCALE" >> $(PGDIR)/src/include/pg_config.h
# Support 32-bit systems without reconfiguring
echo "#undef PG_INT128_TYPE" >> $(PGDIR)/src/include/pg_config.h
# Support gcc earlier than 4.6.0 without reconfiguring
echo "#undef HAVE__STATIC_ASSERT" >> $(PGDIR)/src/include/pg_config.h
# Avoid problems with static asserts
echo "#undef StaticAssertDecl" >> $(PGDIR)/src/include/c.h
echo "#define StaticAssertDecl(condition, errmessage)" >> $(PGDIR)/src/include/c.h
# Avoid dependency on execinfo (requires extra library on musl-libc based systems)
echo "#undef HAVE_EXECINFO_H" >> $(PGDIR)/src/include/pg_config.h
echo "#undef HAVE_BACKTRACE_SYMBOLS" >> $(PGDIR)/src/include/pg_config.h
# Avoid dependency on hardware popcount instructions (POPQNTQ) on x86
echo "#undef HAVE_X86_64_POPCNTQ" >> $(PGDIR)/src/include/pg_config.h
# Avoid dependency on cpuid.h (only supported on x86 systems)
echo "#undef HAVE__GET_CPUID" >> $(PGDIR)/src/include/pg_config.h
# Avoid CRC extension usage to ensure we are not architecture-dependent
echo "#undef USE_ARMV8_CRC32C" >> $(PGDIR)/src/include/pg_config.h
echo "#undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK" >> $(PGDIR)/src/include/pg_config.h
# Ensure we don't fail on systems that have strchrnul support (FreeBSD and NetBSD)
echo "#include <stdlib.h>" >> $(PGDIR)/src/include/pg_config.h
echo "#if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2))" >> $(PGDIR)/src/include/pg_config.h
echo "#define HAVE_STRCHRNUL" >> $(PGDIR)/src/include/pg_config.h
echo "#endif" >> $(PGDIR)/src/include/pg_config.h
# Add pg_config.h overrides
cat scripts/pg_config_overrides.h >> $(PGDIR)/src/include/pg_config.h

extract_source: $(PGDIR)
-@ $(RM) -rf ./src/postgres/
Expand Down
2 changes: 1 addition & 1 deletion examples/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ int main() {
} else {
scan_result = pg_query__scan_result__unpack(NULL, result.pbuf.len, (void *) result.pbuf.data);

printf(" version: %d, tokens: %ld, size: %zu\n", scan_result->version, scan_result->n_tokens, result.pbuf.len);
printf(" version: %d, tokens: %zu, size: %zu\n", scan_result->version, scan_result->n_tokens, result.pbuf.len);
for (j = 0; j < scan_result->n_tokens; j++) {
scan_token = scan_result->tokens[j];
token_kind = protobuf_c_enum_descriptor_get_value(&pg_query__token__descriptor, scan_token->token);
Expand Down
2 changes: 1 addition & 1 deletion protobuf/pg_query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ message RTEPermissionInfo
{
uint32 relid = 1 [json_name="relid"];
bool inh = 2 [json_name="inh"];
int64 required_perms = 3 [json_name="requiredPerms"];
uint64 required_perms = 3 [json_name="requiredPerms"];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted in the commit message, this is okay to do only because this struct isn't actually used in raw parse trees. Otherwise this would be an API break (which may be okay in the context of how we use these protobufs, but at least we should talk about doing this outside of major releases).

uint32 check_as_user = 4 [json_name="checkAsUser"];
repeated uint64 selected_cols = 5 [json_name="selectedCols"];
repeated uint64 inserted_cols = 6 [json_name="insertedCols"];
Expand Down
6 changes: 6 additions & 0 deletions scripts/extract_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,12 @@ def write_out
# Other required functions
runner.deep_resolve('pg_printf')

# Retain these functions for optional 32-bit support
# (see BITS_PER_BITMAPWORD checks in bitmapset.c)
runner.deep_resolve('pg_leftmost_one_pos32')
runner.deep_resolve('pg_rightmost_one_pos32')
runner.deep_resolve('pg_popcount32')

runner.write_out

#puts runner.unresolved.inspect
Expand Down
15 changes: 14 additions & 1 deletion scripts/generate_fingerprint_outfuncs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ def initialize

EOL

FINGERPRINT_UINT64 = <<-EOL
if (node->%<name>s != 0) {
char buffer[50];
sprintf(buffer, UINT64_FORMAT, node->%<name>s);
_fingerprintString(ctx, "%<name>s");
_fingerprintString(ctx, buffer);
}

EOL

FINGERPRINT_FLOAT = <<-EOL
if (node->%<name>s != 0) {
char buffer[50];
Expand Down Expand Up @@ -258,7 +268,8 @@ def initialize
['RawStmt', 'stmt_location'] => :skip,
}
INT_TYPES = ['bits32', 'uint32', 'int', 'int32', 'uint16', 'int16', 'Oid', 'Index', 'AttrNumber', 'SubTransactionId', 'RelFileNumber']
LONG_INT_TYPES = ['long', 'uint64', 'AclMode']
LONG_INT_TYPES = ['long']
UINT64_TYPES = ['uint64', 'AclMode']
INT_ARRAY_TYPES = ['Bitmapset*', 'Bitmapset', 'Relids']
FLOAT_TYPES = ['Cost', 'double', 'Cardinality']

Expand Down Expand Up @@ -317,6 +328,8 @@ def generate_fingerprint_defs!
fingerprint_def += format(FINGERPRINT_INT, name: name)
when *LONG_INT_TYPES
fingerprint_def += format(FINGERPRINT_LONG_INT, name: name)
when *UINT64_TYPES
fingerprint_def += format(FINGERPRINT_UINT64, name: name)
when *INT_ARRAY_TYPES
fingerprint_def += format(FINGERPRINT_INT_ARRAY, name: name)
when *FLOAT_TYPES
Expand Down
7 changes: 6 additions & 1 deletion scripts/generate_protobuf_and_funcs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def generate_outmethods!
@readmethods[node_type] += format(" READ_BOOL_FIELD(%s, %s, %s);\n", outname, outname_json, name)
@protobuf_messages[node_type] += format(" bool %s = %d [json_name=\"%s\"];\n", outname, protobuf_field_count, name)
protobuf_field_count += 1
elsif ['long', 'AclMode'].include?(type)
elsif ['long'].include?(type)
@outmethods[node_type] += format(" WRITE_LONG_FIELD(%s, %s, %s);\n", outname, outname_json, name)
@readmethods[node_type] += format(" READ_LONG_FIELD(%s, %s, %s);\n", outname, outname_json, name)
@protobuf_messages[node_type] += format(" int64 %s = %d [json_name=\"%s\"];\n", outname, protobuf_field_count, name)
Expand All @@ -89,6 +89,11 @@ def generate_outmethods!
@readmethods[node_type] += format(" READ_UINT_FIELD(%s, %s, %s);\n", outname, outname_json, name)
@protobuf_messages[node_type] += format(" uint32 %s = %d [json_name=\"%s\"];\n", outname, protobuf_field_count, name)
protobuf_field_count += 1
elsif ['uint64', 'AclMode'].include?(type)
@outmethods[node_type] += format(" WRITE_UINT64_FIELD(%s, %s, %s);\n", outname, outname_json, name)
@readmethods[node_type] += format(" READ_UINT64_FIELD(%s, %s, %s);\n", outname, outname_json, name)
@protobuf_messages[node_type] += format(" uint64 %s = %d [json_name=\"%s\"];\n", outname, protobuf_field_count, name)
protobuf_field_count += 1
elsif type == 'char*'
@outmethods[node_type] += format(" WRITE_STRING_FIELD(%s, %s, %s);\n", outname, outname_json, name)
@readmethods[node_type] += format(" READ_STRING_FIELD(%s, %s, %s);\n", outname, outname_json, name)
Expand Down
52 changes: 52 additions & 0 deletions scripts/pg_config_overrides.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* This causes compatibility problems on some Linux distros, with "xlocale.h" not being available */
#undef HAVE_LOCALE_T
#undef LOCALE_T_IN_XLOCALE
#undef WCSTOMBS_L_IN_XLOCALE

/* Support gcc earlier than 4.6.0 and MSVC */
#undef HAVE__STATIC_ASSERT

/* Avoid dependency on execinfo (requires extra library on musl-libc based systems, not supported on Windows) */
#undef HAVE_EXECINFO_H
#undef HAVE_BACKTRACE_SYMBOLS

/* Avoid dependency on hardware popcount instructions (POPQNTQ) on x86 */
#undef HAVE_X86_64_POPCNTQ

/* Avoid dependency on cpuid.h (only supported on x86 systems) */
#undef HAVE__GET_CPUID

/* Avoid CRC extension usage to ensure we are not architecture-dependent */
#undef USE_ARMV8_CRC32C
#undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK

/* Ensure we do not fail on systems that have strchrnul support (FreeBSD, NetBSD and newer glibc) */
#include <stdlib.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2))
#define HAVE_STRCHRNUL
#endif

/* 32-bit */
#if defined(_WIN32) || __SIZEOF_POINTER__ == 4
#undef ALIGNOF_DOUBLE
#define ALIGNOF_DOUBLE 4
#undef ALIGNOF_LONG
#define ALIGNOF_LONG 4
#define ALIGNOF_LONG_LONG_INT 4
#undef ALIGNOF_PG_INT128_TYPE
#undef HAVE_LONG_INT_64
#define HAVE_LONG_LONG_INT_64 1
#undef INT64_MODIFIER
#define INT64_MODIFIER "ll"
#undef PG_INT128_TYPE
#undef PG_INT64_TYPE
#define PG_INT64_TYPE long long int
#undef SIZEOF_LONG
#define SIZEOF_LONG 4
#undef SIZEOF_OFF_T
#define SIZEOF_OFF_T 4
#undef SIZEOF_SIZE_T
#define SIZEOF_SIZE_T 4
#undef SIZEOF_VOID_P
#define SIZEOF_VOID_P 4
#endif
2 changes: 1 addition & 1 deletion src/pg_query_fingerprint_defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -5894,7 +5894,7 @@ _fingerprintRTEPermissionInfo(FingerprintContext *ctx, const RTEPermissionInfo *

if (node->requiredPerms != 0) {
char buffer[50];
sprintf(buffer, "%ld", node->requiredPerms);
sprintf(buffer, UINT64_FORMAT, node->requiredPerms);
_fingerprintString(ctx, "requiredPerms");
_fingerprintString(ctx, buffer);
}
Expand Down
2 changes: 1 addition & 1 deletion src/pg_query_outfuncs_defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ _outRTEPermissionInfo(OUT_TYPE(RTEPermissionInfo, RTEPermissionInfo) out, const
{
WRITE_UINT_FIELD(relid, relid, relid);
WRITE_BOOL_FIELD(inh, inh, inh);
WRITE_LONG_FIELD(required_perms, requiredPerms, requiredPerms);
WRITE_UINT64_FIELD(required_perms, requiredPerms, requiredPerms);
WRITE_UINT_FIELD(check_as_user, checkAsUser, checkAsUser);
WRITE_BITMAPSET_FIELD(selected_cols, selectedCols, selectedCols);
WRITE_BITMAPSET_FIELD(inserted_cols, insertedCols, insertedCols);
Expand Down
6 changes: 6 additions & 0 deletions src/pg_query_outfuncs_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
appendStringInfo(out, "\"" CppAsString(outname_json) "\":%u,", node->fldname); \
}

/* Write an unsigned integer field */
#define WRITE_UINT64_FIELD(outname, outname_json, fldname) \
if (node->fldname != 0) { \
appendStringInfo(out, "\"" CppAsString(outname_json) "\":" UINT64_FORMAT ",", node->fldname); \
}

/* Write a long-integer field */
#define WRITE_LONG_FIELD(outname, outname_json, fldname) \
if (node->fldname != 0) { \
Expand Down
1 change: 1 addition & 0 deletions src/pg_query_outfuncs_protobuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#define WRITE_INT_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
#define WRITE_UINT_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
#define WRITE_UINT64_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
#define WRITE_LONG_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
#define WRITE_FLOAT_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
#define WRITE_BOOL_FIELD(outname, outname_json, fldname) out->outname = node->fldname;
Expand Down
1 change: 1 addition & 0 deletions src/pg_query_outfuncs_protobuf_cpp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern "C"

#define WRITE_INT_FIELD(outname, outname_json, fldname) out->set_##outname(node->fldname);
#define WRITE_UINT_FIELD(outname, outname_json, fldname) out->set_##outname(node->fldname);
#define WRITE_UINT64_FIELD(outname, outname_json, fldname) out->set_##outname(node->fldname);
#define WRITE_LONG_FIELD(outname, outname_json, fldname) out->set_##outname(node->fldname);
#define WRITE_FLOAT_FIELD(outname, outname_json, fldname) out->set_##outname(node->fldname);
#define WRITE_BOOL_FIELD(outname, outname_json, fldname) out->set_##outname(node->fldname);
Expand Down
2 changes: 1 addition & 1 deletion src/pg_query_readfuncs_defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1419,7 +1419,7 @@ _readRTEPermissionInfo(OUT_TYPE(RTEPermissionInfo, RTEPermissionInfo) msg)
RTEPermissionInfo *node = makeNode(RTEPermissionInfo);
READ_UINT_FIELD(relid, relid, relid);
READ_BOOL_FIELD(inh, inh, inh);
READ_LONG_FIELD(required_perms, requiredPerms, requiredPerms);
READ_UINT64_FIELD(required_perms, requiredPerms, requiredPerms);
READ_UINT_FIELD(check_as_user, checkAsUser, checkAsUser);
READ_BITMAPSET_FIELD(selected_cols, selectedCols, selectedCols);
READ_BITMAPSET_FIELD(inserted_cols, insertedCols, insertedCols);
Expand Down
1 change: 1 addition & 0 deletions src/pg_query_readfuncs_protobuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#define READ_INT_FIELD(outname, outname_json, fldname) node->fldname = msg->outname;
#define READ_UINT_FIELD(outname, outname_json, fldname) node->fldname = msg->outname;
#define READ_UINT64_FIELD(outname, outname_json, fldname) node->fldname = msg->outname;
#define READ_LONG_FIELD(outname, outname_json, fldname) node->fldname = msg->outname;
#define READ_FLOAT_FIELD(outname, outname_json, fldname) node->fldname = msg->outname;
#define READ_BOOL_FIELD(outname, outname_json, fldname) node->fldname = msg->outname;
Expand Down
39 changes: 38 additions & 1 deletion src/postgres/include/pg_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -826,18 +826,55 @@

/* Define to how the compiler spells `typeof'. */
/* #undef typeof */
/* This causes compatibility problems on some Linux distros, with "xlocale.h" not being available */
#undef HAVE_LOCALE_T
#undef LOCALE_T_IN_XLOCALE
#undef WCSTOMBS_L_IN_XLOCALE
#undef PG_INT128_TYPE

/* Support gcc earlier than 4.6.0 and MSVC */
#undef HAVE__STATIC_ASSERT

/* Avoid dependency on execinfo (requires extra library on musl-libc based systems, not supported on Windows) */
#undef HAVE_EXECINFO_H
#undef HAVE_BACKTRACE_SYMBOLS

/* Avoid dependency on hardware popcount instructions (POPQNTQ) on x86 */
#undef HAVE_X86_64_POPCNTQ

/* Avoid dependency on cpuid.h (only supported on x86 systems) */
#undef HAVE__GET_CPUID

/* Avoid CRC extension usage to ensure we are not architecture-dependent */
#undef USE_ARMV8_CRC32C
#undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK

/* Ensure we do not fail on systems that have strchrnul support (FreeBSD, NetBSD and newer glibc) */
#include <stdlib.h>
#if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2))
#define HAVE_STRCHRNUL
#endif

/* 32-bit */
#if defined(_WIN32) || __SIZEOF_POINTER__ == 4
#undef ALIGNOF_DOUBLE
#define ALIGNOF_DOUBLE 4
#undef ALIGNOF_LONG
#define ALIGNOF_LONG 4
#define ALIGNOF_LONG_LONG_INT 4
#undef ALIGNOF_PG_INT128_TYPE
#undef HAVE_LONG_INT_64
#define HAVE_LONG_LONG_INT_64 1
#undef INT64_MODIFIER
#define INT64_MODIFIER "ll"
#undef PG_INT128_TYPE
#undef PG_INT64_TYPE
#define PG_INT64_TYPE long long int
#undef SIZEOF_LONG
#define SIZEOF_LONG 4
#undef SIZEOF_OFF_T
#define SIZEOF_OFF_T 4
#undef SIZEOF_SIZE_T
#define SIZEOF_SIZE_T 4
#undef SIZEOF_VOID_P
#define SIZEOF_VOID_P 4
#endif
22 changes: 21 additions & 1 deletion src/postgres/src_port_pg_bitutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Symbols referenced in this file:
* - pg_popcount64
* - pg_popcount64_slow
* - pg_popcount32
* - pg_popcount32_slow
*--------------------------------------------------------------------
*/

Expand Down Expand Up @@ -175,9 +177,23 @@ __asm__ __volatile__(" popcntq %1,%0\n":"=q"(res):"rm"(word):"cc");
* pg_popcount32_slow
* Return the number of 1 bits set in word
*/
static int
pg_popcount32_slow(uint32 word)
{
#ifdef HAVE__BUILTIN_POPCOUNT
return __builtin_popcount(word);
#else /* !HAVE__BUILTIN_POPCOUNT */
int result = 0;

while (word != 0)
{
result += pg_number_of_ones[word & 255];
word >>= 8;
}

return result;
#endif /* HAVE__BUILTIN_POPCOUNT */
}

/*
* pg_popcount64_slow
Expand Down Expand Up @@ -216,7 +232,11 @@ pg_popcount64_slow(uint64 word)
* TRY_POPCNT_FAST is not defined. The compiler should be able to inline
* the slow versions here.
*/

int
pg_popcount32(uint32 word)
{
return pg_popcount32_slow(word);
}

int
pg_popcount64(uint64 word)
Expand Down
Loading