Skip to content

Commit 5d97e27

Browse files
author
Antonin Houska
committed
Do not explicitly create NOT NULL constraints for columns in PRIMARY KEY.
NOT NULL constraint is created automatically for each column in the PRIMARY KEY. So far it was fine to create the NOT NULL constraint explicitly - the attempt was silently ignored. However, it causes ERROR in PostgreSQL >= 18.2. Bumped version number to 2.1.
1 parent 96998b2 commit 5d97e27

6 files changed

Lines changed: 45 additions & 5 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ PGFILEDESC = "pg_rewrite - tools for maintenance that requires table rewriting."
55

66
EXTENSION = pg_rewrite
77
DATA = pg_rewrite--1.0.sql pg_rewrite--1.0--1.1.sql pg_rewrite--1.1--1.2.sql\
8-
pg_rewrite--1.2--2.0.sql pg_rewrite--1.3--2.0.sql
8+
pg_rewrite--1.2--2.0.sql pg_rewrite--1.3--2.0.sql pg_rewrite--2.0--2.1.sql
99
DOCS = pg_rewrite.md
1010

1111
REGRESS = pg_rewrite generated

NEWS

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
Release 2.1
2+
===========
3+
4+
1. Do not try to create NOT NULL constraint unnecessarily.
5+
6+
NOT NULL constraint is automatically created for columns involved in PRIMARY
7+
KEY constraint. Thus if the old table has a NOT NULL constraint in the
8+
catalog, we should only create it on the new table if the related column is
9+
not part of primary key.
10+
11+
While this unnecessary ALTER TABLE ... ADD CONSTRAINT ... NOT NULL command
12+
used to be ignored silently so far, it causes ERROR since PostgreSQL 18.2.
13+
14+
115
Release 2.0
216
===========
317

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ source table. It's recommended to handle constraints creation this way:
154154
constraints of the source table to the target table. `rewrite_table()`
155155
by-passes validation of these, but all the rows it inserts into the target
156156
table must have been validated in the source table. Even if the column
157-
data tape is different in the target table, the data type conversion
157+
data type is different in the target table, the data type conversion
158158
should not turn non-NULL value to NULL or vice versa.
159159

160160
3. CHECK constraints are created automatically by `rewrite_table()`

pg_rewrite--2.0--2.1.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-- No SQL changes for this upgrade.

pg_rewrite.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
#include "utils/varlena.h"
7878

7979
#ifdef PG_MODULE_MAGIC_EXT
80-
PG_MODULE_MAGIC_EXT(.name = "pg_rewrite", .version = "2.0");
80+
PG_MODULE_MAGIC_EXT(.name = "pg_rewrite", .version = "2.1");
8181
#else
8282
PG_MODULE_MAGIC;
8383
#endif
@@ -179,6 +179,7 @@ static void dump_check_constraint(Oid relid_dst, const char *relname_dst,
179179
#if PG_VERSION_NUM >= 180000
180180
static void dump_null_constraint(Oid relid_dst, const char *relname_dst,
181181
HeapTuple tup, StringInfo buf);
182+
static bool is_notnull_in_pk(Form_pg_constraint notnull, Oid relid);
182183
#endif
183184
static void dump_constraint_common(const char *nsp, const char *relname,
184185
Form_pg_constraint con, StringInfo buf);
@@ -3327,7 +3328,12 @@ copy_constraints(Oid relid_dst, const char *relname_dst, Oid relid_src)
33273328
#if PG_VERSION_NUM >= 180000
33283329
case CONSTRAINT_NOTNULL:
33293330
{
3330-
if (con->conrelid == relid_src)
3331+
/*
3332+
* Do not create NOT NULL constraint if it should already
3333+
* exist due to primary key constraint.
3334+
*/
3335+
if (con->conrelid == relid_src &&
3336+
!is_notnull_in_pk(con, relid_src))
33313337
dump_null_constraint(relid_dst, relname_dst, tuple,
33323338
buf);
33333339
break;
@@ -3655,6 +3661,25 @@ dump_null_constraint(Oid relid_dst, const char *relname_dst,
36553661
appendStringInfoString(buf, " NO INHERIT");
36563662

36573663
}
3664+
3665+
/*
3666+
* Should NOT NULL constraint have already been created due to PK of table
3667+
* specified by 'relid'?
3668+
*/
3669+
static bool
3670+
is_notnull_in_pk(Form_pg_constraint notnull, Oid relid)
3671+
{
3672+
Bitmapset *notnull_attnos, *pk_attnos;
3673+
Oid notnullid, pkoid;
3674+
3675+
notnull_attnos = get_relation_constraint_attnos(relid,
3676+
NameStr(notnull->conname),
3677+
false, &notnullid);
3678+
Assert(bms_num_members(notnull_attnos) == 1);
3679+
pk_attnos = get_primary_key_attnos(relid, true, &pkoid);
3680+
3681+
return bms_overlap(notnull_attnos, pk_attnos);
3682+
}
36583683
#endif
36593684

36603685
static void

pg_rewrite.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# pg_rewrite extension
22
comment = 'Tool for maintenance that requires table rewriting.'
3-
default_version = '2.0'
3+
default_version = '2.1'
44
module_pathname = '$libdir/pg_rewrite'
55
relocatable = true

0 commit comments

Comments
 (0)