Re: pg_subscription.subslotname is wrongly marked NOT NULL

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: pg_subscription.subslotname is wrongly marked NOT NULL
Дата
Msg-id 229396.1595191345@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: pg_subscription.subslotname is wrongly marked NOT NULL  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
I wrote:
> (2) In pre-v13 branches, hack the JIT tuple deconstruction code
> to be specifically aware that it can't trust attnotnull for
> pg_subscription.subslotname.  Yeah, it's ugly, but at least it's
> not ugly going forwards.

Concretely, as attached for v12.

            regards, tom lane

diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c
index 835aea83e9..4b2144e1a7 100644
--- a/src/backend/jit/llvm/llvmjit_deform.c
+++ b/src/backend/jit/llvm/llvmjit_deform.c
@@ -22,11 +22,24 @@

 #include "access/htup_details.h"
 #include "access/tupdesc_details.h"
+#include "catalog/pg_subscription.h"
 #include "executor/tuptable.h"
 #include "jit/llvmjit.h"
 #include "jit/llvmjit_emit.h"


+/*
+ * Through an embarrassing oversight, pre-v13 installations may have
+ * pg_subscription.subslotname marked as attnotnull, which it should not be.
+ * To avoid possible crashes, use this macro instead of testing attnotnull
+ * directly.
+ */
+#define ATTNOTNULL(att) \
+    ((att)->attnotnull && \
+     ((att)->attrelid != SubscriptionRelationId || \
+      (att)->attnum != Anum_pg_subscription_subslotname))
+
+
 /*
  * Create a function that deforms a tuple of type desc up to natts columns.
  */
@@ -121,7 +134,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
          * combination of attisdropped && attnotnull combination shouldn't
          * exist.
          */
-        if (att->attnotnull &&
+        if (ATTNOTNULL(att) &&
             !att->atthasmissing &&
             !att->attisdropped)
             guaranteed_column_number = attnum;
@@ -419,7 +432,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
          * into account, because if they're present the heaptuple's natts
          * would have indicated that a slot_getmissingattrs() is needed.
          */
-        if (!att->attnotnull)
+        if (!ATTNOTNULL(att))
         {
             LLVMBasicBlockRef b_ifnotnull;
             LLVMBasicBlockRef b_ifnull;
@@ -586,6 +599,9 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
          * to generate better code. Without that LLVM can't figure out that
          * the offset might be constant due to the jumps for previously
          * decoded columns.
+         *
+         * Note: these two tests on attnotnull don't need the ATTNOTNULL hack,
+         * because they are harmless on pg_subscription anyway.
          */
         if (attguaranteedalign)
         {
diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out
index e7add9d2b8..3ba1e5dcdd 100644
--- a/src/test/regress/expected/subscription.out
+++ b/src/test/regress/expected/subscription.out
@@ -147,6 +147,13 @@ DROP SUBSCRIPTION regress_testsub;
 ERROR:  DROP SUBSCRIPTION cannot run inside a transaction block
 COMMIT;
 ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE);
+\dRs+
+                                                      List of subscriptions
+      Name       |           Owner            | Enabled |     Publication     | Synchronous commit |
Conninfo           

+-----------------+----------------------------+---------+---------------------+--------------------+------------------------------
+ regress_testsub | regress_subscription_user2 | f       | {testpub2,testpub3} | local              |
dbname=regress_doesnotexist2
+(1 row)
+
 -- now it works
 BEGIN;
 DROP SUBSCRIPTION regress_testsub;
diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql
index 9e234ab8b3..1bc58887f7 100644
--- a/src/test/regress/sql/subscription.sql
+++ b/src/test/regress/sql/subscription.sql
@@ -109,6 +109,8 @@ COMMIT;

 ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE);

+\dRs+
+
 -- now it works
 BEGIN;
 DROP SUBSCRIPTION regress_testsub;

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Fix initdb's unsafe not-null-marking rule
Следующее
От: Jeff Davis
Дата:
Сообщение: Re: Default setting for enable_hashagg_disk