Skip to content

Commit 798b4fa

Browse files
committed
Kluge slot_compile_deform() to ignore incorrect attnotnull markings.
Since we mustn't force an initdb in released branches, there is no simple way to correct the markings of pg_subscription.subslotname and pg_subscription_rel.srsublsn as attnotnull in existing pre-v13 installations. Fortunately, released branches don't rely on attnotnull being correct for much. The planner looks at it in relation_excluded_by_constraints, but it'd be difficult to get that to matter for a query on a system catalog. The only place where it's really problematic is in JIT's slot_compile_deform(), which can produce incorrect code that crashes if there are NULLs in an allegedly not-null column. Hence, hack up slot_compile_deform() to be specifically aware of these two incorrect markings and not trust them. This applies to v11 and v12; the JIT code didn't exist before that, and we've fixed the markings in v13. Discussion: https://postgr.es/m/229396.1595191345@sss.pgh.pa.us
1 parent 71e561b commit 798b4fa

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

src/backend/jit/llvm/llvmjit_deform.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,27 @@
2222

2323
#include "access/htup_details.h"
2424
#include "access/tupdesc_details.h"
25+
#include "catalog/pg_subscription.h"
26+
#include "catalog/pg_subscription_rel.h"
2527
#include "executor/tuptable.h"
2628
#include "jit/llvmjit.h"
2729
#include "jit/llvmjit_emit.h"
2830

2931

32+
/*
33+
* Through an embarrassing oversight, pre-v13 installations may have
34+
* pg_subscription.subslotname and pg_subscription_rel.srsublsn marked as
35+
* attnotnull, which they should not be. To avoid possible crashes, use
36+
* this macro instead of testing attnotnull directly.
37+
*/
38+
#define ATTNOTNULL(att) \
39+
((att)->attnotnull && \
40+
!(((att)->attrelid == SubscriptionRelationId && \
41+
(att)->attnum == Anum_pg_subscription_subslotname) || \
42+
((att)->attrelid == SubscriptionRelRelationId && \
43+
(att)->attnum == Anum_pg_subscription_rel_srsublsn)))
44+
45+
3046
/*
3147
* Create a function that deforms a tuple of type desc up to natts columns.
3248
*/
@@ -121,7 +137,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
121137
* combination of attisdropped && attnotnull combination shouldn't
122138
* exist.
123139
*/
124-
if (att->attnotnull &&
140+
if (ATTNOTNULL(att) &&
125141
!att->atthasmissing &&
126142
!att->attisdropped)
127143
guaranteed_column_number = attnum;
@@ -419,7 +435,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
419435
* into account, because if they're present the heaptuple's natts
420436
* would have indicated that a slot_getmissingattrs() is needed.
421437
*/
422-
if (!att->attnotnull)
438+
if (!ATTNOTNULL(att))
423439
{
424440
LLVMBasicBlockRef b_ifnotnull;
425441
LLVMBasicBlockRef b_ifnull;
@@ -600,7 +616,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
600616
known_alignment = -1;
601617
attguaranteedalign = false;
602618
}
603-
else if (att->attnotnull && attguaranteedalign && known_alignment >= 0)
619+
else if (ATTNOTNULL(att) && attguaranteedalign && known_alignment >= 0)
604620
{
605621
/*
606622
* If the offset to the column was previously known, a NOT NULL &
@@ -610,7 +626,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
610626
Assert(att->attlen > 0);
611627
known_alignment += att->attlen;
612628
}
613-
else if (att->attnotnull && (att->attlen % alignto) == 0)
629+
else if (ATTNOTNULL(att) && (att->attlen % alignto) == 0)
614630
{
615631
/*
616632
* After a NOT NULL fixed-width column with a length that is a

src/test/regress/expected/subscription.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ DROP SUBSCRIPTION regress_testsub;
147147
ERROR: DROP SUBSCRIPTION cannot run inside a transaction block
148148
COMMIT;
149149
ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE);
150+
\dRs+
151+
List of subscriptions
152+
Name | Owner | Enabled | Publication | Synchronous commit | Conninfo
153+
-----------------+----------------------------+---------+---------------------+--------------------+------------------------------
154+
regress_testsub | regress_subscription_user2 | f | {testpub2,testpub3} | local | dbname=regress_doesnotexist2
155+
(1 row)
156+
150157
-- now it works
151158
BEGIN;
152159
DROP SUBSCRIPTION regress_testsub;

src/test/regress/sql/subscription.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ COMMIT;
109109

110110
ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE);
111111

112+
\dRs+
113+
112114
-- now it works
113115
BEGIN;
114116
DROP SUBSCRIPTION regress_testsub;

0 commit comments

Comments
 (0)