Fix alignment in multirange_get_range() function
authorAlexander Korotkov <akorotkov@postgresql.org>
Mon, 13 Dec 2021 14:17:33 +0000 (17:17 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Mon, 13 Dec 2021 14:17:33 +0000 (17:17 +0300)
The multirange_get_range() function fails when two boundaries of the same
range have different alignments.  Fix that by adding proper pointer alignment.

Reported-by: Alexander Lakhin
Discussion: https://postgr.es/m/17300-dced2d01ddeb1f2f%40postgresql.org
Backpatch-through: 14

src/backend/utils/adt/multirangetypes.c
src/test/regress/expected/multirangetypes.out
src/test/regress/expected/rangetypes.out
src/test/regress/sql/multirangetypes.sql
src/test/regress/sql/rangetypes.sql

index 77732155647a7901ac4691f32204f6511370a729..51b0ec95ab4f547c3ca7398dd17f477b23004848 100644 (file)
@@ -713,7 +713,10 @@ multirange_get_range(TypeCacheEntry *rangetyp,
    if (RANGE_HAS_LBOUND(flags))
        ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
    if (RANGE_HAS_UBOUND(flags))
+   {
+       ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
        ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
+   }
    len = (ptr - begin) + sizeof(RangeType) + sizeof(uint8);
 
    range = palloc0(len);
index f5f089741c1720870245507de12382cc03a66d6a..bde3f248a752da071a1f08d3835c458673531ff0 100644 (file)
@@ -97,6 +97,12 @@ select ' {( " a " " a ", " z " " z " )  }'::textmultirange;
  {("  a   a ","  z   z  ")}
 (1 row)
 
+select textrange('\\\\', repeat('a', 200))::textmultirange;
+                                                                                                        textrange                                                                                                        
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ {["\\\\\\\\",aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)}
+(1 row)
+
 select '{(,z)}'::textmultirange;
  textmultirange 
 ----------------
@@ -289,10 +295,10 @@ select textmultirange(textrange('a', 'c'), textrange('f', 'g'));
  {[a,c),[f,g)}
 (1 row)
 
-select textmultirange(textrange('a', 'c'), textrange('b', 'd'));
- textmultirange 
-----------------
- {[a,d)}
+select textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd'));
+                                                                                                        textmultirange                                                                                                         
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ {["\\\\\\\\",aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),[c,d)}
 (1 row)
 
 --
@@ -363,6 +369,13 @@ select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e')));
  [d,e)
 (2 rows)
 
+select unnest(textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd')));
+                                                                                                        unnest                                                                                                         
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ ["\\\\\\\\",aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)
+ [c,d)
+(2 rows)
+
 --
 -- create some test data and test the operators
 --
index e6ca99d43dc9ac31cda8247dbed63b4e2097e47b..2eaed6e1f4e5e63499905cd2c941afc9ef369371 100644 (file)
@@ -72,12 +72,6 @@ select ' ( " a " " a ", " z " " z " )  '::textrange;
  ("  a   a ","  z   z  ")
 (1 row)
 
-select '(,z)'::textrange;
- textrange 
------------
- (,z)
-(1 row)
-
 select '(a,)'::textrange;
  textrange 
 -----------
index ad50afc0f5537c5d6e63d70043167d4ff8025e1c..df1edb4d31acc385ae6d0d4d9f8d4997da2da07c 100644 (file)
@@ -25,6 +25,7 @@ select '{}'::textmultirange;
 select '  {}  '::textmultirange;
 select ' { empty, empty }  '::textmultirange;
 select ' {( " a " " a ", " z " " z " )  }'::textmultirange;
+select textrange('\\\\', repeat('a', 200))::textmultirange;
 select '{(,z)}'::textmultirange;
 select '{(a,)}'::textmultirange;
 select '{[,z]}'::textmultirange;
@@ -63,7 +64,7 @@ select '{(a,a)}'::textmultirange;
 select textmultirange();
 select textmultirange(textrange('a', 'c'));
 select textmultirange(textrange('a', 'c'), textrange('f', 'g'));
-select textmultirange(textrange('a', 'c'), textrange('b', 'd'));
+select textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd'));
 
 --
 -- test casts, both a built-in range type and a user-defined one:
@@ -82,6 +83,7 @@ select textrange(null, null)::textmultirange;
 --
 select unnest(int4multirange(int4range('5', '6'), int4range('1', '2')));
 select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e')));
+select unnest(textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd')));
 
 --
 -- create some test data and test the operators
index cb5353de6fbf2cb19d2f67d71498a4fb02fc4430..a2d411d0daf757761e1e9e98a3b79939a0a0d6a5 100644 (file)
@@ -22,7 +22,6 @@ select '[z,a]'::textrange;
 select '  empty  '::textrange;
 select ' ( empty, empty )  '::textrange;
 select ' ( " a " " a ", " z " " z " )  '::textrange;
-select '(,z)'::textrange;
 select '(a,)'::textrange;
 select '[,z]'::textrange;
 select '[a,]'::textrange;