summaryrefslogtreecommitdiff
path: root/src/test/regress
diff options
context:
space:
mode:
authorTom Lane2011-11-15 02:42:04 +0000
committerTom Lane2011-11-15 02:42:04 +0000
commitad50934eaadb626de682defe0ad270bbf31e92a2 (patch)
treeb6bfb3e949b397de41e7278538c62e11460fa575 /src/test/regress
parent4165d5b6d7d2e399edbc6d027039358794aa8f04 (diff)
Fix alignment and toasting bugs in range types.
A range type whose element type has 'd' alignment must have 'd' alignment itself, else there is no guarantee that the element value can be used in-place. (Because range_deserialize uses att_align_pointer which forcibly aligns the given pointer, violations of this rule did not lead to SIGBUS but rather to garbage data being extracted, as in one of the added regression test cases.) Also, you can't put a toast pointer inside a range datum, since the referenced value could disappear with the range datum still present. For consistency with the handling of arrays and records, I also forced decompression of in-line-compressed bound values. It would work to store them as-is, but our policy is to avoid situations that might result in double compression. Add assorted regression tests for this, and bump catversion because of fixes to built-in pg_type entries. Also some marginal cleanup of inconsistent/unnecessary error checks.
Diffstat (limited to 'src/test/regress')
-rw-r--r--src/test/regress/expected/rangetypes.out10
-rw-r--r--src/test/regress/expected/type_sanity.out32
-rw-r--r--src/test/regress/sql/rangetypes.sql6
-rw-r--r--src/test/regress/sql/type_sanity.sql24
4 files changed, 70 insertions, 2 deletions
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index 9b879486170..b2258b9045c 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -822,7 +822,6 @@ select * from float8range_test;
(1 row)
drop table float8range_test;
-drop type float8range;
--
-- Test range types over domains
--
@@ -909,6 +908,15 @@ select ARRAY[numrange(1.1), numrange(12.3,155.5)];
{"[1.1,1.1]","[12.3,155.5)"}
(1 row)
+create table i8r_array (f1 int, f2 int8range[]);
+insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]);
+select * from i8r_array;
+ f1 | f2
+----+---------------------
+ 42 | {"[1,10)","[2,20)"}
+(1 row)
+
+drop table i8r_array;
--
-- Ranges of arrays
--
diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out
index 7ca7a95ec66..a159ac718a2 100644
--- a/src/test/regress/expected/type_sanity.out
+++ b/src/test/regress/expected/type_sanity.out
@@ -81,6 +81,28 @@ WHERE p1.typarray <> 0 AND
-----+----------+-----------+---------+--------
(0 rows)
+-- Look for range types that do not have a pg_range entry
+SELECT p1.oid, p1.typname
+FROM pg_type as p1
+WHERE p1.typtype = 'r' AND
+ NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = p1.oid);
+ oid | typname
+-----+---------
+(0 rows)
+
+-- Look for range types whose typalign isn't sufficient
+SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign
+FROM pg_type as p1
+ LEFT JOIN pg_range as r ON rngtypid = p1.oid
+ LEFT JOIN pg_type as p2 ON rngsubtype = p2.oid
+WHERE p1.typtype = 'r' AND
+ (p1.typalign != (CASE WHEN p2.typalign = 'd' THEN 'd'::"char"
+ ELSE 'i'::"char" END)
+ OR p2.oid IS NULL);
+ oid | typname | typalign | typname | typalign
+-----+---------+----------+---------+----------
+(0 rows)
+
-- Text conversion routines must be provided.
SELECT p1.oid, p1.typname
FROM pg_type as p1
@@ -263,6 +285,16 @@ WHERE p1.typarray = p2.oid AND NOT (p1.typdelim = p2.typdelim);
-----+---------+-----+---------
(0 rows)
+-- Look for array types whose typalign isn't sufficient
+SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign
+FROM pg_type AS p1, pg_type AS p2
+WHERE p1.typarray = p2.oid AND
+ p2.typalign != (CASE WHEN p1.typalign = 'd' THEN 'd'::"char"
+ ELSE 'i'::"char" END);
+ oid | typname | typalign | typname | typalign
+-----+---------+----------+---------+----------
+(0 rows)
+
-- Check for bogus typanalyze routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql
index 573e85ebb25..4b455f1d357 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -260,7 +260,6 @@ create table float8range_test(f8r float8range, i int);
insert into float8range_test values(float8range(-100.00007, '1.111113e9'));
select * from float8range_test;
drop table float8range_test;
-drop type float8range;
--
-- Test range types over domains
@@ -327,6 +326,11 @@ select range_add_bounds(numrange(1.0001, 123.123));
select ARRAY[numrange(1.1), numrange(12.3,155.5)];
+create table i8r_array (f1 int, f2 int8range[]);
+insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]);
+select * from i8r_array;
+drop table i8r_array;
+
--
-- Ranges of arrays
--
diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql
index 1638861bc1d..2ed03f39bc1 100644
--- a/src/test/regress/sql/type_sanity.sql
+++ b/src/test/regress/sql/type_sanity.sql
@@ -67,6 +67,22 @@ FROM pg_type p1 LEFT JOIN pg_type p2 ON (p1.typarray = p2.oid)
WHERE p1.typarray <> 0 AND
(p2.oid IS NULL OR p2.typelem <> p1.oid OR p2.typlen <> -1);
+-- Look for range types that do not have a pg_range entry
+SELECT p1.oid, p1.typname
+FROM pg_type as p1
+WHERE p1.typtype = 'r' AND
+ NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = p1.oid);
+
+-- Look for range types whose typalign isn't sufficient
+SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign
+FROM pg_type as p1
+ LEFT JOIN pg_range as r ON rngtypid = p1.oid
+ LEFT JOIN pg_type as p2 ON rngsubtype = p2.oid
+WHERE p1.typtype = 'r' AND
+ (p1.typalign != (CASE WHEN p2.typalign = 'd' THEN 'd'::"char"
+ ELSE 'i'::"char" END)
+ OR p2.oid IS NULL);
+
-- Text conversion routines must be provided.
SELECT p1.oid, p1.typname
@@ -202,6 +218,14 @@ SELECT p1.oid, p1.typname, p2.oid, p2.typname
FROM pg_type AS p1, pg_type AS p2
WHERE p1.typarray = p2.oid AND NOT (p1.typdelim = p2.typdelim);
+-- Look for array types whose typalign isn't sufficient
+
+SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign
+FROM pg_type AS p1, pg_type AS p2
+WHERE p1.typarray = p2.oid AND
+ p2.typalign != (CASE WHEN p1.typalign = 'd' THEN 'd'::"char"
+ ELSE 'i'::"char" END);
+
-- Check for bogus typanalyze routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname