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.
'{"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
-------------+-----------------+-----------+---------------+-----------------+-----------------+-------------
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[],
(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
-----+---------
(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
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;
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 (
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
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,