Fix segmentation fault in MergeInheritedAttribute()
authorPeter Eisentraut <[email protected]>
Fri, 3 May 2024 09:10:40 +0000 (11:10 +0200)
committerPeter Eisentraut <[email protected]>
Fri, 3 May 2024 09:10:40 +0000 (11:10 +0200)
While converting a pg_attribute tuple into a ColumnDef,
ColumnDef::compression remains NULL if there is no compression method
set fot the attribute.  Calling strcmp() with NULL
ColumnDef::compression, when comparing compression methods of parents,
causes segmentation fault in MergeInheritedAttribute().  Skip
comparing compression methods if either of them is NULL.

Author: Ashutosh Bapat <[email protected]>
Reported-by: Alexander Lakhin <[email protected]>
Discussion: https://www.postgresql.org/message-id/b22a6834-aacb-7b18-0424-a3f5fe889667%40gmail.com

src/backend/commands/tablecmds.c
src/test/regress/expected/compression.out
src/test/regress/sql/compression.sql

index 3309332f1ae6217f25fba5109dc73ff6374ac5aa..a79ac884f7cbcfcaa9a90c144790aa70977c48d2 100644 (file)
@@ -3432,12 +3432,16 @@ MergeInheritedAttribute(List *inh_columns,
     */
    if (prevdef->compression == NULL)
        prevdef->compression = newdef->compression;
-   else if (strcmp(prevdef->compression, newdef->compression) != 0)
-       ereport(ERROR,
-               (errcode(ERRCODE_DATATYPE_MISMATCH),
-                errmsg("column \"%s\" has a compression method conflict",
-                       attributeName),
-                errdetail("%s versus %s", prevdef->compression, newdef->compression)));
+   else if (newdef->compression != NULL)
+   {
+       if (strcmp(prevdef->compression, newdef->compression) != 0)
+           ereport(ERROR,
+                   (errcode(ERRCODE_DATATYPE_MISMATCH),
+                    errmsg("column \"%s\" has a compression method conflict",
+                           attributeName),
+                    errdetail("%s versus %s",
+                              prevdef->compression, newdef->compression)));
+   }
 
    /*
     * Check for GENERATED conflicts
index 834b7555cbc8036e37a984d2d942774cd042865b..4dd9ee7200d187c8dc572410f3149c70dfa96c56 100644 (file)
@@ -223,15 +223,18 @@ SELECT pg_column_compression(f1) FROM cmpart2;
  pglz
 (1 row)
 
--- test compression with inheritance, error
-CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
+-- test compression with inheritance
+CREATE TABLE cminh() INHERITS(cmdata, cmdata1); -- error
 NOTICE:  merging multiple inherited definitions of column "f1"
 ERROR:  column "f1" has a compression method conflict
 DETAIL:  pglz versus lz4
-CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
+CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata); -- error
 NOTICE:  merging column "f1" with inherited definition
 ERROR:  column "f1" has a compression method conflict
 DETAIL:  pglz versus lz4
+CREATE TABLE cmdata3(f1 text);
+CREATE TABLE cminh() INHERITS (cmdata, cmdata3);
+NOTICE:  merging multiple inherited definitions of column "f1"
 -- test default_toast_compression GUC
 SET default_toast_compression = '';
 ERROR:  invalid value for parameter "default_toast_compression": ""
@@ -251,6 +254,7 @@ INSERT INTO cmdata VALUES (repeat('123456789', 4004));
  f1     | text |           |          |         | extended | lz4         |              | 
 Indexes:
     "idx" btree (f1)
+Child tables: cminh
 
 SELECT pg_column_compression(f1) FROM cmdata;
  pg_column_compression 
index 7179a5002ec5da6d15836a641d680ea908cb5e1d..490595fcfb263a15a066ea624a8479cfdb2e18d7 100644 (file)
@@ -93,9 +93,11 @@ INSERT INTO cmpart VALUES (repeat('123456789', 4004));
 SELECT pg_column_compression(f1) FROM cmpart1;
 SELECT pg_column_compression(f1) FROM cmpart2;
 
--- test compression with inheritance, error
-CREATE TABLE cminh() INHERITS(cmdata, cmdata1);
-CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata);
+-- test compression with inheritance
+CREATE TABLE cminh() INHERITS(cmdata, cmdata1); -- error
+CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata); -- error
+CREATE TABLE cmdata3(f1 text);
+CREATE TABLE cminh() INHERITS (cmdata, cmdata3);
 
 -- test default_toast_compression GUC
 SET default_toast_compression = '';