Disallow setting MAX_PARTITION_BUFFERS to less than 2
authorDavid Rowley <[email protected]>
Tue, 30 Jul 2024 08:19:59 +0000 (20:19 +1200)
committerDavid Rowley <[email protected]>
Tue, 30 Jul 2024 08:19:59 +0000 (20:19 +1200)
Add some comments to mention that this value must be at least 2 and also
add a StaticAssertDecl to cause compilation failure if anyone tries to
build with an invalid value.

The multiInsertBuffers list must have at least two elements due to how the
code in CopyMultiInsertInfoFlush() pushes the current ResultRelInfo's
CopyMultiInsertBuffer to the end of the list.  If the first element is
also the last element, bad things will happen.

Author: Zhang Mingli <[email protected]>
Discussion: https://postgr.es/m/CAApHDvpQ6t9ROcqbD-OgqR04Kfq4vQKw79Vo6r5j%2BciHwsSfkA%40mail.gmail.com

src/backend/commands/copyfrom.c

index ce4d62e707c952dc6940b5e5e20f5dcd50f31bbb..c42a5621d5a6b4d1545d54a8801a1dfd50b4b0b4 100644 (file)
  */
 #define MAX_BUFFERED_BYTES     65535
 
-/* Trim the list of buffers back down to this number after flushing */
+/*
+ * Trim the list of buffers back down to this number after flushing.  This
+ * must be >= 2.
+ */
 #define MAX_PARTITION_BUFFERS  32
 
 /* Stores multi-insert data related to a single relation in CopyFrom. */
@@ -550,6 +553,13 @@ CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri,
         */
        if (buffer->resultRelInfo == curr_rri)
        {
+           /*
+            * The code below would misbehave if we were trying to reduce the
+            * list to less than two items.
+            */
+           StaticAssertDecl(MAX_PARTITION_BUFFERS >= 2,
+                            "MAX_PARTITION_BUFFERS must be >= 2");
+
            miinfo->multiInsertBuffers = list_delete_first(miinfo->multiInsertBuffers);
            miinfo->multiInsertBuffers = lappend(miinfo->multiInsertBuffers, buffer);
            buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers);