Add a couple of regression test cases related to array subscripting.
authorTom Lane <[email protected]>
Mon, 7 Dec 2020 16:10:21 +0000 (11:10 -0500)
committerTom Lane <[email protected]>
Mon, 7 Dec 2020 16:10:21 +0000 (11:10 -0500)
Exercise some error cases that were never reached in the existing
regression tests.  This is partly for code-coverage reasons, and
partly to memorialize the current behavior in advance of planned
changes for generic subscripting.

Also, I noticed that type_sanity's check to verify that all standard
types have array types was never extended when we added arrays for
all system catalog rowtypes (f7f70d5e2), nor when we added arrays
over domain types (c12d570fa).  So do that.  Also, since the query's
expected output isn't empty, it seems like a good idea to add an
ORDER BY to make sure the result stays stable.

src/test/regress/expected/arrays.out
src/test/regress/expected/rowtypes.out
src/test/regress/expected/type_sanity.out
src/test/regress/sql/arrays.sql
src/test/regress/sql/rowtypes.sql
src/test/regress/sql/type_sanity.sql

index e0f870e9d7b7f2a3eadf850d7006bd26c5618af3..c03ac65ff89f1055af8b36d552df2511f101211b 100644 (file)
@@ -26,6 +26,16 @@ INSERT INTO arrtest (a, b[1:2][1:2], c, d, e, f, g)
            '{"abc","abcde"}', '{"abc","abcde"}');
 INSERT INTO arrtest (a, b[1:2], c, d[1:2])
    VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
+INSERT INTO arrtest (b[2]) VALUES(now());  -- error, type mismatch
+ERROR:  array assignment to "b" requires type integer but expression is of type timestamp with time zone
+LINE 1: INSERT INTO arrtest (b[2]) VALUES(now());
+                             ^
+HINT:  You will need to rewrite or cast the expression.
+INSERT INTO arrtest (b[1:2]) VALUES(now());  -- error, type mismatch
+ERROR:  array assignment to "b" requires type integer[] but expression is of type timestamp with time zone
+LINE 1: INSERT INTO arrtest (b[1:2]) VALUES(now());
+                             ^
+HINT:  You will need to rewrite or cast the expression.
 SELECT * FROM arrtest;
       a      |        b        |     c     |       d       |        e        |        f        |      g      
 -------------+-----------------+-----------+---------------+-----------------+-----------------+-------------
@@ -225,6 +235,9 @@ UPDATE arrtest
   SET c[1:NULL] = '{"can''t assign"}'
   WHERE array_dims(c) is not null;
 ERROR:  array subscript in assignment must not be null
+-- Un-subscriptable type
+SELECT (now())[1];
+ERROR:  cannot subscript type timestamp with time zone because it is not an array
 -- test slices with empty lower and/or upper index
 CREATE TEMP TABLE arrtest_s (
   a       int2[],
index 2a273f84049918a09a8ff5348a64615d7198feca..0e71baf8fbd48b2cfccd1a2e75e961636ae5b573 100644 (file)
@@ -118,12 +118,18 @@ select * from people;
 (1 row)
 
 insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66);
+update quadtable set q.c1.r = 12 where f1 = 2;
+update quadtable set q.c1 = 12;  -- error, type mismatch
+ERROR:  subfield "c1" is of type complex but expression is of type integer
+LINE 1: update quadtable set q.c1 = 12;
+                             ^
+HINT:  You will need to rewrite or cast the expression.
 select * from quadtable;
  f1 |             q             
 ----+---------------------------
   1 | ("(3.3,4.4)","(5.5,6.6)")
-  2 | ("(,4.4)","(5.5,6.6)")
  44 | ("(55,)","(,66)")
+  2 | ("(12,4.4)","(5.5,6.6)")
 (3 rows)
 
 -- The object here is to ensure that toasted references inside
index 274130e7062b308949e5113a9e60d22573cb2718..ec1cd47623e1a91188b3720e4db22dcd9da18683 100644 (file)
@@ -56,17 +56,17 @@ WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
 -----+---------
 (0 rows)
 
--- Look for types that should have an array type according to their typtype,
--- but don't.  We exclude composites here because we have not bothered to
--- make array types corresponding to the system catalogs' rowtypes.
--- NOTE: as of v10, this check finds pg_node_tree, pg_ndistinct, smgr.
+-- Look for types that should have an array type but don't.
+-- Generally anything that's not a pseudotype should have an array type.
+-- However, we do have a small number of exceptions.
 SELECT p1.oid, p1.typname
 FROM pg_type as p1
-WHERE p1.typtype not in ('c','d','p') AND p1.typname NOT LIKE E'\\_%'
+WHERE p1.typtype not in ('p') AND p1.typname NOT LIKE E'\\_%'
     AND NOT EXISTS
     (SELECT 1 FROM pg_type as p2
      WHERE p2.typname = ('_' || p1.typname)::name AND
-           p2.typelem = p1.oid and p1.typarray = p2.oid);
+           p2.typelem = p1.oid and p1.typarray = p2.oid)
+ORDER BY p1.oid;
  oid  |     typname     
 ------+-----------------
   194 | pg_node_tree
index 199049b2a27ca46f49feef6f776fae4539229994..891491e0466636ea337423dbee481ac6a52b2ce8 100644 (file)
@@ -34,6 +34,9 @@ INSERT INTO arrtest (a, b[1:2][1:2], c, d, e, f, g)
 INSERT INTO arrtest (a, b[1:2], c, d[1:2])
    VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
 
+INSERT INTO arrtest (b[2]) VALUES(now());  -- error, type mismatch
+
+INSERT INTO arrtest (b[1:2]) VALUES(now());  -- error, type mismatch
 
 SELECT * FROM arrtest;
 
@@ -122,6 +125,8 @@ UPDATE arrtest
 UPDATE arrtest
   SET c[1:NULL] = '{"can''t assign"}'
   WHERE array_dims(c) is not null;
+-- Un-subscriptable type
+SELECT (now())[1];
 
 -- test slices with empty lower and/or upper index
 CREATE TEMP TABLE arrtest_s (
index 83cf4a1e791593596353a7d88bfe167814907e8c..845e3305f38fb5deec6381c86e28e2f5d12128af 100644 (file)
@@ -63,6 +63,10 @@ select * from people;
 
 insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66);
 
+update quadtable set q.c1.r = 12 where f1 = 2;
+
+update quadtable set q.c1 = 12;  -- error, type mismatch
+
 select * from quadtable;
 
 -- The object here is to ensure that toasted references inside
index 4b492ce06250684eb17e97b20fdf3e2f66a28fd7..5e433388cdc27c5632b7b11814e1b50487e09a6b 100644 (file)
@@ -50,18 +50,18 @@ FROM pg_type as p1
 WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
     (p1.typtype != 'c' AND p1.typrelid != 0);
 
--- Look for types that should have an array type according to their typtype,
--- but don't.  We exclude composites here because we have not bothered to
--- make array types corresponding to the system catalogs' rowtypes.
--- NOTE: as of v10, this check finds pg_node_tree, pg_ndistinct, smgr.
+-- Look for types that should have an array type but don't.
+-- Generally anything that's not a pseudotype should have an array type.
+-- However, we do have a small number of exceptions.
 
 SELECT p1.oid, p1.typname
 FROM pg_type as p1
-WHERE p1.typtype not in ('c','d','p') AND p1.typname NOT LIKE E'\\_%'
+WHERE p1.typtype not in ('p') AND p1.typname NOT LIKE E'\\_%'
     AND NOT EXISTS
     (SELECT 1 FROM pg_type as p2
      WHERE p2.typname = ('_' || p1.typname)::name AND
-           p2.typelem = p1.oid and p1.typarray = p2.oid);
+           p2.typelem = p1.oid and p1.typarray = p2.oid)
+ORDER BY p1.oid;
 
 -- Make sure typarray points to a varlena array type of our own base
 SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype,