summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2025-01-31 18:52:40 +0000
committerTom Lane2025-01-31 18:52:40 +0000
commit041e8b95b8cd251bfec6a3c9c3dd6614de6a4c9b (patch)
tree58c23012141617cec375499045af409ae0c24afd /src/include
parentf8d8581ed882b79b512daaa7f71ca19c8eafcaef (diff)
Get rid of our dependency on type "long" for memory size calculations.
Consistently use "Size" (or size_t, or in some places int64 or double) as the type for variables holding memory allocation sizes. In most places variables' data types were fine already, but we had an ancient habit of computing bytes from kilobytes-units GUCs with code like "work_mem * 1024L". That risks overflow on Win64 where they did not make "long" as wide as "size_t". We worked around that by restricting such GUCs' ranges, so you couldn't set work_mem et al higher than 2GB on Win64. This patch removes that restriction, after replacing such calculations with "work_mem * (Size) 1024" or variants of that. It should be noted that this patch was constructed by searching outwards from the GUCs that have MAX_KILOBYTES as upper limit. So I can't positively guarantee there are no other places doing memory-size arithmetic in int or long variables. I do however feel pretty confident that increasing MAX_KILOBYTES on Win64 is safe now. Also, nothing in our code should be dealing in multiple-gigabyte allocations without authorization from a relevant GUC, so it seems pretty likely that this search caught everything that could be at risk of overflow. Author: Vladlen Popolitov <v.popolitov@postgrespro.ru> Co-authored-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/1a01f0-66ec2d80-3b-68487680@27595217
Diffstat (limited to 'src/include')
-rw-r--r--src/include/executor/hashjoin.h2
-rw-r--r--src/include/nodes/tidbitmap.h4
-rw-r--r--src/include/utils/dsa.h2
-rw-r--r--src/include/utils/guc.h10
4 files changed, 11 insertions, 7 deletions
diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h
index 67ae89c8257..ecff4842fd3 100644
--- a/src/include/executor/hashjoin.h
+++ b/src/include/executor/hashjoin.h
@@ -147,7 +147,7 @@ typedef struct HashMemoryChunkData
typedef struct HashMemoryChunkData *HashMemoryChunk;
-#define HASH_CHUNK_SIZE (32 * 1024L)
+#define HASH_CHUNK_SIZE ((Size) (32 * 1024))
#define HASH_CHUNK_HEADER_SIZE MAXALIGN(sizeof(HashMemoryChunkData))
#define HASH_CHUNK_DATA(hc) (((char *) (hc)) + HASH_CHUNK_HEADER_SIZE)
/* tuples exceeding HASH_CHUNK_THRESHOLD bytes are put in their own chunk */
diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h
index fedbf69eb53..a6ffeac90be 100644
--- a/src/include/nodes/tidbitmap.h
+++ b/src/include/nodes/tidbitmap.h
@@ -62,7 +62,7 @@ typedef struct TBMIterateResult
/* function prototypes in nodes/tidbitmap.c */
-extern TIDBitmap *tbm_create(long maxbytes, dsa_area *dsa);
+extern TIDBitmap *tbm_create(Size maxbytes, dsa_area *dsa);
extern void tbm_free(TIDBitmap *tbm);
extern void tbm_free_shared_area(dsa_area *dsa, dsa_pointer dp);
@@ -84,7 +84,7 @@ extern void tbm_end_private_iterate(TBMPrivateIterator *iterator);
extern void tbm_end_shared_iterate(TBMSharedIterator *iterator);
extern TBMSharedIterator *tbm_attach_shared_iterate(dsa_area *dsa,
dsa_pointer dp);
-extern long tbm_calculate_entries(double maxbytes);
+extern int tbm_calculate_entries(Size maxbytes);
extern TBMIterator tbm_begin_iterate(TIDBitmap *tbm,
dsa_area *dsa, dsa_pointer dsp);
diff --git a/src/include/utils/dsa.h b/src/include/utils/dsa.h
index 44f546f5940..9eca8788908 100644
--- a/src/include/utils/dsa.h
+++ b/src/include/utils/dsa.h
@@ -97,7 +97,7 @@ typedef pg_atomic_uint64 dsa_pointer_atomic;
#define DSA_DEFAULT_INIT_SEGMENT_SIZE ((size_t) (1 * 1024 * 1024))
/* The minimum size of a DSM segment. */
-#define DSA_MIN_SEGMENT_SIZE ((size_t) (256 * 1024L))
+#define DSA_MIN_SEGMENT_SIZE ((size_t) (256 * 1024))
/* The maximum size of a DSM segment. */
#define DSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH)
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 532d6642bb4..1233e07d7da 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -17,9 +17,13 @@
#include "utils/array.h"
-/* upper limit for GUC variables measured in kilobytes of memory */
-/* note that various places assume the byte size fits in a "long" variable */
-#if SIZEOF_SIZE_T > 4 && SIZEOF_LONG > 4
+/*
+ * Maximum for integer GUC variables that are measured in kilobytes of memory.
+ * This value is chosen to ensure that the corresponding number of bytes fits
+ * into a variable of type size_t or ssize_t. Be sure to compute the number
+ * of bytes like "guc_var * (Size) 1024" to avoid int-width overflow.
+ */
+#if SIZEOF_SIZE_T > 4
#define MAX_KILOBYTES INT_MAX
#else
#define MAX_KILOBYTES (INT_MAX / 1024)