mirror of
https://github.com/postgres/postgres.git
synced 2025-12-13 14:22:43 +03:00
First phase of work on array improvements. ARRAY[x,y,z] constructor
expressions, ARRAY(sub-SELECT) expressions, some array functions. Polymorphic functions using ANYARRAY/ANYELEMENT argument and return types. Some regression tests in place, documentation is lacking. Joe Conway, with some kibitzing from Tom Lane.
This commit is contained in:
@@ -117,3 +117,204 @@ SELECT a[1:3],
|
||||
{16,25,23} | | {foobar,new_word} | {{elt2}}
|
||||
(3 rows)
|
||||
|
||||
--
|
||||
-- array expressions and operators
|
||||
--
|
||||
-- table creation and INSERTs
|
||||
CREATE TEMP TABLE arrtest2 (i integer ARRAY[4], f float8[], n numeric[], t text[], d timestamp[]);
|
||||
INSERT INTO arrtest2 VALUES(
|
||||
ARRAY[[[113,142],[1,147]]],
|
||||
ARRAY[1.1,1.2,1.3]::float8[],
|
||||
ARRAY[1.1,1.2,1.3],
|
||||
ARRAY[[['aaa','aab'],['aba','abb'],['aca','acb']],[['baa','bab'],['bba','bbb'],['bca','bcb']]],
|
||||
ARRAY['19620326','19931223','19970117']::timestamp[]
|
||||
);
|
||||
-- some more test data
|
||||
CREATE TEMP TABLE arrtest_f (f0 int, f1 text, f2 float8);
|
||||
insert into arrtest_f values(1,'cat1',1.21);
|
||||
insert into arrtest_f values(2,'cat1',1.24);
|
||||
insert into arrtest_f values(3,'cat1',1.18);
|
||||
insert into arrtest_f values(4,'cat1',1.26);
|
||||
insert into arrtest_f values(5,'cat1',1.15);
|
||||
insert into arrtest_f values(6,'cat2',1.15);
|
||||
insert into arrtest_f values(7,'cat2',1.26);
|
||||
insert into arrtest_f values(8,'cat2',1.32);
|
||||
insert into arrtest_f values(9,'cat2',1.30);
|
||||
CREATE TEMP TABLE arrtest_i (f0 int, f1 text, f2 int);
|
||||
insert into arrtest_i values(1,'cat1',21);
|
||||
insert into arrtest_i values(2,'cat1',24);
|
||||
insert into arrtest_i values(3,'cat1',18);
|
||||
insert into arrtest_i values(4,'cat1',26);
|
||||
insert into arrtest_i values(5,'cat1',15);
|
||||
insert into arrtest_i values(6,'cat2',15);
|
||||
insert into arrtest_i values(7,'cat2',26);
|
||||
insert into arrtest_i values(8,'cat2',32);
|
||||
insert into arrtest_i values(9,'cat2',30);
|
||||
-- expressions
|
||||
SELECT t.f[1][3][1] AS "131", t.f[2][2][1] AS "221" FROM (
|
||||
SELECT ARRAY[[[111,112],[121,122],[131,132]],[[211,212],[221,122],[231,232]]] AS f
|
||||
) AS t;
|
||||
131 | 221
|
||||
-----+-----
|
||||
131 | 221
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[[[[[['hello'],['world']]]]]];
|
||||
array
|
||||
---------------------------
|
||||
{{{{{{hello},{world}}}}}}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[ARRAY['hello'],ARRAY['world']];
|
||||
array
|
||||
-------------------
|
||||
{{hello},{world}}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY";
|
||||
ARRAY
|
||||
-----------------------------------------------
|
||||
{1.15,1.15,1.18,1.21,1.24,1.26,1.26,1.3,1.32}
|
||||
(1 row)
|
||||
|
||||
-- functions
|
||||
SELECT singleton_array(42) AS "{42}";
|
||||
{42}
|
||||
------
|
||||
{42}
|
||||
(1 row)
|
||||
|
||||
SELECT array_append(singleton_array(42), 6) AS "{42,6}";
|
||||
{42,6}
|
||||
--------
|
||||
{42,6}
|
||||
(1 row)
|
||||
|
||||
SELECT array_prepend(6, singleton_array(42)) AS "{6,42}";
|
||||
{6,42}
|
||||
--------
|
||||
{6,42}
|
||||
(1 row)
|
||||
|
||||
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{{1,2},{3,4}}";
|
||||
{{1,2},{3,4}}
|
||||
---------------
|
||||
{{1,2},{3,4}}
|
||||
(1 row)
|
||||
|
||||
SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}";
|
||||
{{1,2},{3,4},{5,6}}
|
||||
---------------------
|
||||
{{1,2},{3,4},{5,6}}
|
||||
(1 row)
|
||||
|
||||
SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
|
||||
{{3,4},{5,6},{1,2}}
|
||||
---------------------
|
||||
{{3,4},{5,6},{1,2}}
|
||||
(1 row)
|
||||
|
||||
SELECT array_subscript(n, 2) AS "1.2" FROM arrtest2;
|
||||
1.2
|
||||
-----
|
||||
1.2
|
||||
(1 row)
|
||||
|
||||
SELECT array_assign(n, 2, 9.99) AS "{1.1,9.99,1.3}" FROM arrtest2;
|
||||
{1.1,9.99,1.3}
|
||||
----------------
|
||||
{1.1,9.99,1.3}
|
||||
(1 row)
|
||||
|
||||
SELECT array_subscript(array_assign(n, 2, 9.99), 2) AS "9.99" FROM arrtest2;
|
||||
9.99
|
||||
------
|
||||
9.99
|
||||
(1 row)
|
||||
|
||||
-- operators
|
||||
SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]];
|
||||
a
|
||||
---------------
|
||||
{16,25,3,4,5}
|
||||
(1 row)
|
||||
|
||||
SELECT NOT ARRAY[1.1,1.2,1.3] = ARRAY[1.1,1.2,1.3] AS "FALSE";
|
||||
FALSE
|
||||
-------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[1,2] || 3 AS "{1,2,3}";
|
||||
{1,2,3}
|
||||
---------
|
||||
{1,2,3}
|
||||
(1 row)
|
||||
|
||||
SELECT 0 || ARRAY[1,2] AS "{0,1,2}";
|
||||
{0,1,2}
|
||||
---------
|
||||
{0,1,2}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[1,2] || ARRAY[3,4] AS "{{1,2},{3,4}}";
|
||||
{{1,2},{3,4}}
|
||||
---------------
|
||||
{{1,2},{3,4}}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY";
|
||||
ARRAY
|
||||
------------------------------------------
|
||||
{{{{hello,world}}},{{{happy,birthday}}}}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}";
|
||||
{{1,2},{3,4},{5,6}}
|
||||
---------------------
|
||||
{{1,2},{3,4},{5,6}}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{{0,0},{1,1},{2,2}}";
|
||||
{{0,0},{1,1},{2,2}}
|
||||
---------------------
|
||||
{{0,0},{1,1},{2,2}}
|
||||
(1 row)
|
||||
|
||||
SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
|
||||
{0,1,2,3}
|
||||
-----------
|
||||
{0,1,2,3}
|
||||
(1 row)
|
||||
|
||||
-- array casts
|
||||
SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}";
|
||||
{1,2,3}
|
||||
---------
|
||||
{1,2,3}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[1,2,3]::text[]::int[]::float8[] is of (float8[]) as "TRUE";
|
||||
TRUE
|
||||
------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}";
|
||||
{{a,bc},{def,hijk}}
|
||||
---------------------
|
||||
{{a,bc},{def,hijk}}
|
||||
(1 row)
|
||||
|
||||
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] is of (varchar[]) as "TRUE";
|
||||
TRUE
|
||||
------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}";
|
||||
{{{{{{a,bb,ccc}}}}}}
|
||||
----------------------
|
||||
{{{{{{a,bb,ccc}}}}}}
|
||||
(1 row)
|
||||
|
||||
|
||||
@@ -73,10 +73,12 @@ WHERE p1.oid != p2.oid AND
|
||||
|
||||
-- Look for uses of different type OIDs in the argument/result type fields
|
||||
-- for different aliases of the same built-in function.
|
||||
-- This indicates that the types are being presumed to be binary-equivalent.
|
||||
-- This indicates that the types are being presumed to be binary-equivalent,
|
||||
-- or that the built-in function is prepared to deal with different types.
|
||||
-- That's not wrong, necessarily, but we make lists of all the types being
|
||||
-- so treated. Note that the expected output of this part of the test will
|
||||
-- need to be modified whenever new pairs of types are made binary-equivalent!
|
||||
-- need to be modified whenever new pairs of types are made binary-equivalent,
|
||||
-- or when new polymorphic built-in functions are added!
|
||||
-- Note: ignore aggregate functions here, since they all point to the same
|
||||
-- dummy built-in function.
|
||||
SELECT DISTINCT p1.prorettype, p2.prorettype
|
||||
@@ -104,7 +106,8 @@ WHERE p1.oid != p2.oid AND
|
||||
25 | 1043
|
||||
1114 | 1184
|
||||
1560 | 1562
|
||||
(3 rows)
|
||||
2277 | 2283
|
||||
(4 rows)
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[1], p2.proargtypes[1]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
@@ -117,7 +120,8 @@ WHERE p1.oid != p2.oid AND
|
||||
-------------+-------------
|
||||
1114 | 1184
|
||||
1560 | 1562
|
||||
(2 rows)
|
||||
2277 | 2283
|
||||
(3 rows)
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[2], p2.proargtypes[2]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
|
||||
@@ -70,16 +70,6 @@ WHERE p1.typtype in ('b') AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS
|
||||
705 | unknown
|
||||
(3 rows)
|
||||
|
||||
-- Look for array types that don't have an equality operator.
|
||||
SELECT p1.oid, p1.typname
|
||||
FROM pg_type as p1
|
||||
WHERE p1.typtype != 'c' AND p1.typname LIKE '\\_%' AND NOT EXISTS
|
||||
(SELECT 1 FROM pg_operator
|
||||
WHERE oprname = '=' AND oprleft = p1.oid AND oprright = p1.oid);
|
||||
oid | typname
|
||||
-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Conversion routines must be provided except in 'c' entries.
|
||||
SELECT p1.oid, p1.typname
|
||||
FROM pg_type as p1
|
||||
|
||||
@@ -83,3 +83,77 @@ SELECT a[1:3],
|
||||
c[1:2],
|
||||
d[1:1][2:2]
|
||||
FROM arrtest;
|
||||
|
||||
--
|
||||
-- array expressions and operators
|
||||
--
|
||||
|
||||
-- table creation and INSERTs
|
||||
CREATE TEMP TABLE arrtest2 (i integer ARRAY[4], f float8[], n numeric[], t text[], d timestamp[]);
|
||||
INSERT INTO arrtest2 VALUES(
|
||||
ARRAY[[[113,142],[1,147]]],
|
||||
ARRAY[1.1,1.2,1.3]::float8[],
|
||||
ARRAY[1.1,1.2,1.3],
|
||||
ARRAY[[['aaa','aab'],['aba','abb'],['aca','acb']],[['baa','bab'],['bba','bbb'],['bca','bcb']]],
|
||||
ARRAY['19620326','19931223','19970117']::timestamp[]
|
||||
);
|
||||
|
||||
-- some more test data
|
||||
CREATE TEMP TABLE arrtest_f (f0 int, f1 text, f2 float8);
|
||||
insert into arrtest_f values(1,'cat1',1.21);
|
||||
insert into arrtest_f values(2,'cat1',1.24);
|
||||
insert into arrtest_f values(3,'cat1',1.18);
|
||||
insert into arrtest_f values(4,'cat1',1.26);
|
||||
insert into arrtest_f values(5,'cat1',1.15);
|
||||
insert into arrtest_f values(6,'cat2',1.15);
|
||||
insert into arrtest_f values(7,'cat2',1.26);
|
||||
insert into arrtest_f values(8,'cat2',1.32);
|
||||
insert into arrtest_f values(9,'cat2',1.30);
|
||||
|
||||
CREATE TEMP TABLE arrtest_i (f0 int, f1 text, f2 int);
|
||||
insert into arrtest_i values(1,'cat1',21);
|
||||
insert into arrtest_i values(2,'cat1',24);
|
||||
insert into arrtest_i values(3,'cat1',18);
|
||||
insert into arrtest_i values(4,'cat1',26);
|
||||
insert into arrtest_i values(5,'cat1',15);
|
||||
insert into arrtest_i values(6,'cat2',15);
|
||||
insert into arrtest_i values(7,'cat2',26);
|
||||
insert into arrtest_i values(8,'cat2',32);
|
||||
insert into arrtest_i values(9,'cat2',30);
|
||||
|
||||
-- expressions
|
||||
SELECT t.f[1][3][1] AS "131", t.f[2][2][1] AS "221" FROM (
|
||||
SELECT ARRAY[[[111,112],[121,122],[131,132]],[[211,212],[221,122],[231,232]]] AS f
|
||||
) AS t;
|
||||
SELECT ARRAY[[[[[['hello'],['world']]]]]];
|
||||
SELECT ARRAY[ARRAY['hello'],ARRAY['world']];
|
||||
SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY";
|
||||
|
||||
-- functions
|
||||
SELECT singleton_array(42) AS "{42}";
|
||||
SELECT array_append(singleton_array(42), 6) AS "{42,6}";
|
||||
SELECT array_prepend(6, singleton_array(42)) AS "{6,42}";
|
||||
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{{1,2},{3,4}}";
|
||||
SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}";
|
||||
SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
|
||||
SELECT array_subscript(n, 2) AS "1.2" FROM arrtest2;
|
||||
SELECT array_assign(n, 2, 9.99) AS "{1.1,9.99,1.3}" FROM arrtest2;
|
||||
SELECT array_subscript(array_assign(n, 2, 9.99), 2) AS "9.99" FROM arrtest2;
|
||||
|
||||
-- operators
|
||||
SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]];
|
||||
SELECT NOT ARRAY[1.1,1.2,1.3] = ARRAY[1.1,1.2,1.3] AS "FALSE";
|
||||
SELECT ARRAY[1,2] || 3 AS "{1,2,3}";
|
||||
SELECT 0 || ARRAY[1,2] AS "{0,1,2}";
|
||||
SELECT ARRAY[1,2] || ARRAY[3,4] AS "{{1,2},{3,4}}";
|
||||
SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY";
|
||||
SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}";
|
||||
SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{{0,0},{1,1},{2,2}}";
|
||||
SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
|
||||
|
||||
-- array casts
|
||||
SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}";
|
||||
SELECT ARRAY[1,2,3]::text[]::int[]::float8[] is of (float8[]) as "TRUE";
|
||||
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}";
|
||||
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] is of (varchar[]) as "TRUE";
|
||||
SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}";
|
||||
|
||||
@@ -69,10 +69,12 @@ WHERE p1.oid != p2.oid AND
|
||||
|
||||
-- Look for uses of different type OIDs in the argument/result type fields
|
||||
-- for different aliases of the same built-in function.
|
||||
-- This indicates that the types are being presumed to be binary-equivalent.
|
||||
-- This indicates that the types are being presumed to be binary-equivalent,
|
||||
-- or that the built-in function is prepared to deal with different types.
|
||||
-- That's not wrong, necessarily, but we make lists of all the types being
|
||||
-- so treated. Note that the expected output of this part of the test will
|
||||
-- need to be modified whenever new pairs of types are made binary-equivalent!
|
||||
-- need to be modified whenever new pairs of types are made binary-equivalent,
|
||||
-- or when new polymorphic built-in functions are added!
|
||||
-- Note: ignore aggregate functions here, since they all point to the same
|
||||
-- dummy built-in function.
|
||||
|
||||
|
||||
@@ -59,14 +59,6 @@ WHERE p1.typtype in ('b') AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS
|
||||
WHERE p2.typname = ('_' || p1.typname)::name AND
|
||||
p2.typelem = p1.oid);
|
||||
|
||||
-- Look for array types that don't have an equality operator.
|
||||
|
||||
SELECT p1.oid, p1.typname
|
||||
FROM pg_type as p1
|
||||
WHERE p1.typtype != 'c' AND p1.typname LIKE '\\_%' AND NOT EXISTS
|
||||
(SELECT 1 FROM pg_operator
|
||||
WHERE oprname = '=' AND oprleft = p1.oid AND oprright = p1.oid);
|
||||
|
||||
-- Conversion routines must be provided except in 'c' entries.
|
||||
|
||||
SELECT p1.oid, p1.typname
|
||||
|
||||
Reference in New Issue
Block a user