arrays.sql 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. --
  2. -- ARRAYS
  3. --
  4. CREATE TABLE arrtest (
  5. a int2[],
  6. b int4[][][],
  7. c name[],
  8. d text[][],
  9. e float8[],
  10. f char(5)[],
  11. g varchar(5)[]
  12. );
  13. --
  14. -- only the 'e' array is 0-based, the others are 1-based.
  15. --
  16. INSERT INTO arrtest (a[1:5], b[1:1][1:2][1:2], c, d, f, g)
  17. VALUES ('{1,2,3,4,5}', '{{{0,0},{1,2}}}', '{}', '{}', '{}', '{}');
  18. UPDATE arrtest SET e[0] = '1.1';
  19. UPDATE arrtest SET e[1] = '2.2';
  20. INSERT INTO arrtest (f)
  21. VALUES ('{"too long"}');
  22. INSERT INTO arrtest (a, b[1:2][1:2], c, d, e, f, g)
  23. VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}',
  24. '{{"elt1", "elt2"}}', '{"3.4", "6.7"}',
  25. '{"abc","abcde"}', '{"abc","abcde"}');
  26. INSERT INTO arrtest (a, b[1:2], c, d[1:2])
  27. VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
  28. INSERT INTO arrtest (b[2]) VALUES(now()); -- error, type mismatch
  29. INSERT INTO arrtest (b[1:2]) VALUES(now()); -- error, type mismatch
  30. SELECT * FROM arrtest;
  31. SELECT arrtest.a[1],
  32. arrtest.b[1][1][1],
  33. arrtest.c[1],
  34. arrtest.d[1][1],
  35. arrtest.e[0]
  36. FROM arrtest;
  37. SELECT a[1], b[1][1][1], c[1], d[1][1], e[0]
  38. FROM arrtest;
  39. SELECT a[1:3],
  40. b[1:1][1:2][1:2],
  41. c[1:2],
  42. d[1:1][1:2]
  43. FROM arrtest;
  44. SELECT array_ndims(a) AS a,array_ndims(b) AS b,array_ndims(c) AS c
  45. FROM arrtest;
  46. SELECT array_dims(a) AS a,array_dims(b) AS b,array_dims(c) AS c
  47. FROM arrtest;
  48. -- returns nothing
  49. SELECT *
  50. FROM arrtest
  51. WHERE a[1] < 5 and
  52. c = '{"foobar"}'::_name;
  53. UPDATE arrtest
  54. SET a[1:2] = '{16,25}'
  55. WHERE NOT a = '{}'::_int2;
  56. UPDATE arrtest
  57. SET b[1:1][1:1][1:2] = '{113, 117}',
  58. b[1:1][1:2][2:2] = '{142, 147}'
  59. WHERE array_dims(b) = '[1:1][1:2][1:2]';
  60. UPDATE arrtest
  61. SET c[2:2] = '{"new_word"}'
  62. WHERE array_dims(c) is not null;
  63. SELECT a,b,c FROM arrtest;
  64. SELECT a[1:3],
  65. b[1:1][1:2][1:2],
  66. c[1:2],
  67. d[1:1][2:2]
  68. FROM arrtest;
  69. SELECT b[1:1][2][2],
  70. d[1:1][2]
  71. FROM arrtest;
  72. INSERT INTO arrtest(a) VALUES('{1,null,3}');
  73. SELECT a FROM arrtest;
  74. UPDATE arrtest SET a[4] = NULL WHERE a[2] IS NULL;
  75. SELECT a FROM arrtest WHERE a[2] IS NULL;
  76. DELETE FROM arrtest WHERE a[2] IS NULL AND b IS NULL;
  77. SELECT a,b,c FROM arrtest;
  78. -- test mixed slice/scalar subscripting
  79. select '{{1,2,3},{4,5,6},{7,8,9}}'::int[];
  80. select ('{{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2];
  81. select '[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[];
  82. select ('[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2];
  83. --
  84. -- check subscription corner cases
  85. --
  86. -- More subscripts than MAXDIM (6)
  87. SELECT ('{}'::int[])[1][2][3][4][5][6][7];
  88. -- NULL index yields NULL when selecting
  89. SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL][1];
  90. SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL:1][1];
  91. SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][1:NULL][1];
  92. -- NULL index in assignment is an error
  93. UPDATE arrtest
  94. SET c[NULL] = '{"can''t assign"}'
  95. WHERE array_dims(c) is not null;
  96. UPDATE arrtest
  97. SET c[NULL:1] = '{"can''t assign"}'
  98. WHERE array_dims(c) is not null;
  99. UPDATE arrtest
  100. SET c[1:NULL] = '{"can''t assign"}'
  101. WHERE array_dims(c) is not null;
  102. -- Un-subscriptable type
  103. SELECT (now())[1];
  104. -- test slices with empty lower and/or upper index
  105. CREATE TEMP TABLE arrtest_s (
  106. a int2[],
  107. b int2[][]
  108. );
  109. INSERT INTO arrtest_s VALUES ('{1,2,3,4,5}', '{{1,2,3}, {4,5,6}, {7,8,9}}');
  110. INSERT INTO arrtest_s VALUES ('[0:4]={1,2,3,4,5}', '[0:2][0:2]={{1,2,3}, {4,5,6}, {7,8,9}}');
  111. SELECT * FROM arrtest_s;
  112. SELECT a[:3], b[:2][:2] FROM arrtest_s;
  113. SELECT a[2:], b[2:][2:] FROM arrtest_s;
  114. SELECT a[:], b[:] FROM arrtest_s;
  115. -- updates
  116. UPDATE arrtest_s SET a[:3] = '{11, 12, 13}', b[:2][:2] = '{{11,12}, {14,15}}'
  117. WHERE array_lower(a,1) = 1;
  118. SELECT * FROM arrtest_s;
  119. UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{25,26}, {28,29}}';
  120. SELECT * FROM arrtest_s;
  121. UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}';
  122. SELECT * FROM arrtest_s;
  123. UPDATE arrtest_s SET a[:] = '{23, 24, 25}'; -- fail, too small
  124. INSERT INTO arrtest_s VALUES(NULL, NULL);
  125. UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}'; -- fail, no good with null
  126. -- check with fixed-length-array type, such as point
  127. SELECT f1[0:1] FROM POINT_TBL;
  128. SELECT f1[0:] FROM POINT_TBL;
  129. SELECT f1[:1] FROM POINT_TBL;
  130. SELECT f1[:] FROM POINT_TBL;
  131. -- subscript assignments to fixed-width result in NULL if previous value is NULL
  132. UPDATE point_tbl SET f1[0] = 10 WHERE f1 IS NULL RETURNING *;
  133. INSERT INTO point_tbl(f1[0]) VALUES(0) RETURNING *;
  134. -- NULL assignments get ignored
  135. UPDATE point_tbl SET f1[0] = NULL WHERE f1::text = '(10,10)'::point::text RETURNING *;
  136. -- but non-NULL subscript assignments work
  137. UPDATE point_tbl SET f1[0] = -10, f1[1] = -10 WHERE f1::text = '(10,10)'::point::text RETURNING *;
  138. -- but not to expand the range
  139. UPDATE point_tbl SET f1[3] = 10 WHERE f1::text = '(-10,-10)'::point::text RETURNING *;
  140. --
  141. -- test array extension
  142. --
  143. CREATE TEMP TABLE arrtest1 (i int[], t text[]);
  144. insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']);
  145. select * from arrtest1;
  146. update arrtest1 set i[2] = 22, t[2] = 'twenty-two';
  147. select * from arrtest1;
  148. update arrtest1 set i[5] = 5, t[5] = 'five';
  149. select * from arrtest1;
  150. update arrtest1 set i[8] = 8, t[8] = 'eight';
  151. select * from arrtest1;
  152. update arrtest1 set i[0] = 0, t[0] = 'zero';
  153. select * from arrtest1;
  154. update arrtest1 set i[-3] = -3, t[-3] = 'minus-three';
  155. select * from arrtest1;
  156. update arrtest1 set i[0:2] = array[10,11,12], t[0:2] = array['ten','eleven','twelve'];
  157. select * from arrtest1;
  158. update arrtest1 set i[8:10] = array[18,null,20], t[8:10] = array['p18',null,'p20'];
  159. select * from arrtest1;
  160. update arrtest1 set i[11:12] = array[null,22], t[11:12] = array[null,'p22'];
  161. select * from arrtest1;
  162. update arrtest1 set i[15:16] = array[null,26], t[15:16] = array[null,'p26'];
  163. select * from arrtest1;
  164. update arrtest1 set i[-5:-3] = array[-15,-14,-13], t[-5:-3] = array['m15','m14','m13'];
  165. select * from arrtest1;
  166. update arrtest1 set i[-7:-6] = array[-17,null], t[-7:-6] = array['m17',null];
  167. select * from arrtest1;
  168. update arrtest1 set i[-12:-10] = array[-22,null,-20], t[-12:-10] = array['m22',null,'m20'];
  169. select * from arrtest1;
  170. delete from arrtest1;
  171. insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']);
  172. select * from arrtest1;
  173. update arrtest1 set i[0:5] = array[0,1,2,null,4,5], t[0:5] = array['z','p1','p2',null,'p4','p5'];
  174. select * from arrtest1;
  175. --
  176. -- array expressions and operators
  177. --
  178. -- table creation and INSERTs
  179. CREATE TEMP TABLE arrtest2 (i integer ARRAY[4], f float8[], n numeric[], t text[], d timestamp[]);
  180. INSERT INTO arrtest2 VALUES(
  181. ARRAY[[[113,142],[1,147]]],
  182. ARRAY[1.1,1.2,1.3]::float8[],
  183. ARRAY[1.1,1.2,1.3],
  184. ARRAY[[['aaa','aab'],['aba','abb'],['aca','acb']],[['baa','bab'],['bba','bbb'],['bca','bcb']]],
  185. ARRAY['19620326','19931223','19970117']::timestamp[]
  186. );
  187. -- some more test data
  188. CREATE TEMP TABLE arrtest_f (f0 int, f1 text, f2 float8);
  189. insert into arrtest_f values(1,'cat1',1.21);
  190. insert into arrtest_f values(2,'cat1',1.24);
  191. insert into arrtest_f values(3,'cat1',1.18);
  192. insert into arrtest_f values(4,'cat1',1.26);
  193. insert into arrtest_f values(5,'cat1',1.15);
  194. insert into arrtest_f values(6,'cat2',1.15);
  195. insert into arrtest_f values(7,'cat2',1.26);
  196. insert into arrtest_f values(8,'cat2',1.32);
  197. insert into arrtest_f values(9,'cat2',1.30);
  198. CREATE TEMP TABLE arrtest_i (f0 int, f1 text, f2 int);
  199. insert into arrtest_i values(1,'cat1',21);
  200. insert into arrtest_i values(2,'cat1',24);
  201. insert into arrtest_i values(3,'cat1',18);
  202. insert into arrtest_i values(4,'cat1',26);
  203. insert into arrtest_i values(5,'cat1',15);
  204. insert into arrtest_i values(6,'cat2',15);
  205. insert into arrtest_i values(7,'cat2',26);
  206. insert into arrtest_i values(8,'cat2',32);
  207. insert into arrtest_i values(9,'cat2',30);
  208. -- expressions
  209. SELECT t.f[1][3][1] AS "131", t.f[2][2][1] AS "221" FROM (
  210. SELECT ARRAY[[[111,112],[121,122],[131,132]],[[211,212],[221,122],[231,232]]] AS f
  211. ) AS t;
  212. SELECT ARRAY[[[[[['hello'],['world']]]]]];
  213. SELECT ARRAY[ARRAY['hello'],ARRAY['world']];
  214. SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY";
  215. -- with nulls
  216. SELECT '{1,null,3}'::int[];
  217. SELECT ARRAY[1,NULL,3];
  218. -- functions
  219. SELECT array_append(array[42], 6) AS "{42,6}";
  220. SELECT array_prepend(6, array[42]) AS "{6,42}";
  221. SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}";
  222. SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}";
  223. SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
  224. SELECT array_position(ARRAY[1,2,3,4,5], 4);
  225. SELECT array_position(ARRAY[5,3,4,2,1], 4);
  226. SELECT array_position(ARRAY[[1,2],[3,4]], 3);
  227. SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon');
  228. SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'sat');
  229. SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], NULL);
  230. SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], NULL);
  231. SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], 'sat');
  232. SELECT array_positions(NULL, 10);
  233. SELECT array_positions(NULL, NULL::int);
  234. SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], 4);
  235. SELECT array_positions(ARRAY[[1,2],[3,4]], 4);
  236. SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], NULL);
  237. SELECT array_positions(ARRAY[1,2,3,NULL,5,6,1,2,3,NULL,5,6], NULL);
  238. SELECT array_length(array_positions(ARRAY(SELECT 'AAAAAAAAAAAAAAAAAAAAAAAAA'::text || i % 10
  239. FROM generate_series(1,100) g(i)),
  240. 'AAAAAAAAAAAAAAAAAAAAAAAAA5'), 1);
  241. DO $$
  242. DECLARE
  243. o int;
  244. a int[] := ARRAY[1,2,3,2,3,1,2];
  245. BEGIN
  246. o := array_position(a, 2);
  247. WHILE o IS NOT NULL
  248. LOOP
  249. RAISE NOTICE '%', o;
  250. o := array_position(a, 2, o + 1);
  251. END LOOP;
  252. END
  253. $$ LANGUAGE plpgsql;
  254. SELECT array_position('[2:4]={1,2,3}'::int[], 1);
  255. SELECT array_positions('[2:4]={1,2,3}'::int[], 1);
  256. SELECT
  257. array_position(ids, (1, 1)),
  258. array_positions(ids, (1, 1))
  259. FROM
  260. (VALUES
  261. (ARRAY[(0, 0), (1, 1)]),
  262. (ARRAY[(1, 1)])
  263. ) AS f (ids);
  264. -- operators
  265. SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]];
  266. SELECT NOT ARRAY[1.1,1.2,1.3] = ARRAY[1.1,1.2,1.3] AS "FALSE";
  267. SELECT ARRAY[1,2] || 3 AS "{1,2,3}";
  268. SELECT 0 || ARRAY[1,2] AS "{0,1,2}";
  269. SELECT ARRAY[1,2] || ARRAY[3,4] AS "{1,2,3,4}";
  270. SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY";
  271. SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}";
  272. SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}";
  273. SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
  274. SELECT ARRAY[1.1] || ARRAY[2,3,4];
  275. SELECT array_agg(x) || array_agg(x) FROM (VALUES (ROW(1,2)), (ROW(3,4))) v(x);
  276. SELECT ROW(1,2) || array_agg(x) FROM (VALUES (ROW(3,4)), (ROW(5,6))) v(x);
  277. SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno;
  278. SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno;
  279. SELECT * FROM array_op_test WHERE i @> '{17}' ORDER BY seqno;
  280. SELECT * FROM array_op_test WHERE i && '{17}' ORDER BY seqno;
  281. SELECT * FROM array_op_test WHERE i @> '{32,17}' ORDER BY seqno;
  282. SELECT * FROM array_op_test WHERE i && '{32,17}' ORDER BY seqno;
  283. SELECT * FROM array_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno;
  284. SELECT * FROM array_op_test WHERE i = '{}' ORDER BY seqno;
  285. SELECT * FROM array_op_test WHERE i @> '{}' ORDER BY seqno;
  286. SELECT * FROM array_op_test WHERE i && '{}' ORDER BY seqno;
  287. SELECT * FROM array_op_test WHERE i <@ '{}' ORDER BY seqno;
  288. SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno;
  289. SELECT * FROM array_op_test WHERE i @> '{NULL}' ORDER BY seqno;
  290. SELECT * FROM array_op_test WHERE i && '{NULL}' ORDER BY seqno;
  291. SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno;
  292. SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno;
  293. SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno;
  294. SELECT * FROM array_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno;
  295. SELECT * FROM array_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno;
  296. SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno;
  297. SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno;
  298. SELECT * FROM array_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno;
  299. SELECT * FROM array_op_test WHERE t = '{}' ORDER BY seqno;
  300. SELECT * FROM array_op_test WHERE t @> '{}' ORDER BY seqno;
  301. SELECT * FROM array_op_test WHERE t && '{}' ORDER BY seqno;
  302. SELECT * FROM array_op_test WHERE t <@ '{}' ORDER BY seqno;
  303. -- array casts
  304. SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}";
  305. SELECT pg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[]) AS "double precision[]";
  306. SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}";
  307. SELECT pg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]) AS "character varying[]";
  308. SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}";
  309. SELECT NULL::text[]::int[] AS "NULL";
  310. -- scalar op any/all (array)
  311. select 33 = any ('{1,2,3}');
  312. select 33 = any ('{1,2,33}');
  313. select 33 = all ('{1,2,33}');
  314. select 33 >= all ('{1,2,33}');
  315. -- boundary cases
  316. select null::int >= all ('{1,2,33}');
  317. select null::int >= all ('{}');
  318. select null::int >= any ('{}');
  319. -- cross-datatype
  320. select 33.4 = any (array[1,2,3]);
  321. select 33.4 > all (array[1,2,3]);
  322. -- errors
  323. select 33 * any ('{1,2,3}');
  324. select 33 * any (44);
  325. -- nulls
  326. select 33 = any (null::int[]);
  327. select null::int = any ('{1,2,3}');
  328. select 33 = any ('{1,null,3}');
  329. select 33 = any ('{1,null,33}');
  330. select 33 = all (null::int[]);
  331. select null::int = all ('{1,2,3}');
  332. select 33 = all ('{1,null,3}');
  333. select 33 = all ('{33,null,33}');
  334. -- nulls later in the bitmap
  335. SELECT -1 != ALL(ARRAY(SELECT NULLIF(g.i, 900) FROM generate_series(1,1000) g(i)));
  336. -- test indexes on arrays
  337. create temp table arr_tbl (f1 int[] unique);
  338. insert into arr_tbl values ('{1,2,3}');
  339. insert into arr_tbl values ('{1,2}');
  340. -- failure expected:
  341. insert into arr_tbl values ('{1,2,3}');
  342. insert into arr_tbl values ('{2,3,4}');
  343. insert into arr_tbl values ('{1,5,3}');
  344. insert into arr_tbl values ('{1,2,10}');
  345. set enable_seqscan to off;
  346. set enable_bitmapscan to off;
  347. select * from arr_tbl where f1 > '{1,2,3}' and f1 <= '{1,5,3}';
  348. select * from arr_tbl where f1 >= '{1,2,3}' and f1 < '{1,5,3}';
  349. -- test ON CONFLICT DO UPDATE with arrays
  350. create temp table arr_pk_tbl (pk int4 primary key, f1 int[]);
  351. insert into arr_pk_tbl values (1, '{1,2,3}');
  352. insert into arr_pk_tbl values (1, '{3,4,5}') on conflict (pk)
  353. do update set f1[1] = excluded.f1[1], f1[3] = excluded.f1[3]
  354. returning pk, f1;
  355. insert into arr_pk_tbl(pk, f1[1:2]) values (1, '{6,7,8}') on conflict (pk)
  356. do update set f1[1] = excluded.f1[1],
  357. f1[2] = excluded.f1[2],
  358. f1[3] = excluded.f1[3]
  359. returning pk, f1;
  360. -- note: if above selects don't produce the expected tuple order,
  361. -- then you didn't get an indexscan plan, and something is busted.
  362. reset enable_seqscan;
  363. reset enable_bitmapscan;
  364. -- test [not] (like|ilike) (any|all) (...)
  365. select 'foo' like any (array['%a', '%o']); -- t
  366. select 'foo' like any (array['%a', '%b']); -- f
  367. select 'foo' like all (array['f%', '%o']); -- t
  368. select 'foo' like all (array['f%', '%b']); -- f
  369. select 'foo' not like any (array['%a', '%b']); -- t
  370. select 'foo' not like all (array['%a', '%o']); -- f
  371. select 'foo' ilike any (array['%A', '%O']); -- t
  372. select 'foo' ilike all (array['F%', '%O']); -- t
  373. --
  374. -- General array parser tests
  375. --
  376. -- none of the following should be accepted
  377. select '{{1,{2}},{2,3}}'::text[];
  378. select '{{},{}}'::text[];
  379. select E'{{1,2},\\{2,3}}'::text[];
  380. select '{{"1 2" x},{3}}'::text[];
  381. select '{}}'::text[];
  382. select '{ }}'::text[];
  383. select array[];
  384. -- none of the above should be accepted
  385. -- all of the following should be accepted
  386. select '{}'::text[];
  387. select '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[];
  388. select '{0 second ,0 second}'::interval[];
  389. select '{ { "," } , { 3 } }'::text[];
  390. select ' { { " 0 second " , 0 second } }'::text[];
  391. select '{
  392. 0 second,
  393. @ 1 hour @ 42 minutes @ 20 seconds
  394. }'::interval[];
  395. select array[]::text[];
  396. select '[0:1]={1.1,2.2}'::float8[];
  397. -- all of the above should be accepted
  398. -- tests for array aggregates
  399. CREATE TEMP TABLE arraggtest ( f1 INT[], f2 TEXT[][], f3 FLOAT[]);
  400. INSERT INTO arraggtest (f1, f2, f3) VALUES
  401. ('{1,2,3,4}','{{grey,red},{blue,blue}}','{1.6, 0.0}');
  402. INSERT INTO arraggtest (f1, f2, f3) VALUES
  403. ('{1,2,3}','{{grey,red},{grey,blue}}','{1.6}');
  404. SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
  405. INSERT INTO arraggtest (f1, f2, f3) VALUES
  406. ('{3,3,2,4,5,6}','{{white,yellow},{pink,orange}}','{2.1,3.3,1.8,1.7,1.6}');
  407. SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
  408. INSERT INTO arraggtest (f1, f2, f3) VALUES
  409. ('{2}','{{black,red},{green,orange}}','{1.6,2.2,2.6,0.4}');
  410. SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
  411. INSERT INTO arraggtest (f1, f2, f3) VALUES
  412. ('{4,2,6,7,8,1}','{{red},{black},{purple},{blue},{blue}}',NULL);
  413. SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
  414. INSERT INTO arraggtest (f1, f2, f3) VALUES
  415. ('{}','{{pink,white,blue,red,grey,orange}}','{2.1,1.87,1.4,2.2}');
  416. SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
  417. -- A few simple tests for arrays of composite types
  418. create type comptype as (f1 int, f2 text);
  419. create table comptable (c1 comptype, c2 comptype[]);
  420. -- XXX would like to not have to specify row() construct types here ...
  421. insert into comptable
  422. values (row(1,'foo'), array[row(2,'bar')::comptype, row(3,'baz')::comptype]);
  423. -- check that implicitly named array type _comptype isn't a problem
  424. create type _comptype as enum('fooey');
  425. select * from comptable;
  426. select c2[2].f2 from comptable;
  427. drop type _comptype;
  428. drop table comptable;
  429. drop type comptype;
  430. create or replace function unnest1(anyarray)
  431. returns setof anyelement as $$
  432. select $1[s] from generate_subscripts($1,1) g(s);
  433. $$ language sql immutable;
  434. create or replace function unnest2(anyarray)
  435. returns setof anyelement as $$
  436. select $1[s1][s2] from generate_subscripts($1,1) g1(s1),
  437. generate_subscripts($1,2) g2(s2);
  438. $$ language sql immutable;
  439. select * from unnest1(array[1,2,3]);
  440. select * from unnest2(array[[1,2,3],[4,5,6]]);
  441. drop function unnest1(anyarray);
  442. drop function unnest2(anyarray);
  443. select array_fill(null::integer, array[3,3],array[2,2]);
  444. select array_fill(null::integer, array[3,3]);
  445. select array_fill(null::text, array[3,3],array[2,2]);
  446. select array_fill(null::text, array[3,3]);
  447. select array_fill(7, array[3,3],array[2,2]);
  448. select array_fill(7, array[3,3]);
  449. select array_fill('juhu'::text, array[3,3],array[2,2]);
  450. select array_fill('juhu'::text, array[3,3]);
  451. select a, a = '{}' as is_eq, array_dims(a)
  452. from (select array_fill(42, array[0]) as a) ss;
  453. select a, a = '{}' as is_eq, array_dims(a)
  454. from (select array_fill(42, '{}') as a) ss;
  455. select a, a = '{}' as is_eq, array_dims(a)
  456. from (select array_fill(42, '{}', '{}') as a) ss;
  457. -- raise exception
  458. select array_fill(1, null, array[2,2]);
  459. select array_fill(1, array[2,2], null);
  460. select array_fill(1, array[2,2], '{}');
  461. select array_fill(1, array[3,3], array[1,1,1]);
  462. select array_fill(1, array[1,2,null]);
  463. select array_fill(1, array[[1,2],[3,4]]);
  464. select string_to_array('1|2|3', '|');
  465. select string_to_array('1|2|3|', '|');
  466. select string_to_array('1||2|3||', '||');
  467. select string_to_array('1|2|3', '');
  468. select string_to_array('', '|');
  469. select string_to_array('1|2|3', NULL);
  470. select string_to_array(NULL, '|') IS NULL;
  471. select string_to_array('abc', '');
  472. select string_to_array('abc', '', 'abc');
  473. select string_to_array('abc', ',');
  474. select string_to_array('abc', ',', 'abc');
  475. select string_to_array('1,2,3,4,,6', ',');
  476. select string_to_array('1,2,3,4,,6', ',', '');
  477. select string_to_array('1,2,3,4,*,6', ',', '*');
  478. select v, v is null as "is null" from string_to_table('1|2|3', '|') g(v);
  479. select v, v is null as "is null" from string_to_table('1|2|3|', '|') g(v);
  480. select v, v is null as "is null" from string_to_table('1||2|3||', '||') g(v);
  481. select v, v is null as "is null" from string_to_table('1|2|3', '') g(v);
  482. select v, v is null as "is null" from string_to_table('', '|') g(v);
  483. select v, v is null as "is null" from string_to_table('1|2|3', NULL) g(v);
  484. select v, v is null as "is null" from string_to_table(NULL, '|') g(v);
  485. select v, v is null as "is null" from string_to_table('abc', '') g(v);
  486. select v, v is null as "is null" from string_to_table('abc', '', 'abc') g(v);
  487. select v, v is null as "is null" from string_to_table('abc', ',') g(v);
  488. select v, v is null as "is null" from string_to_table('abc', ',', 'abc') g(v);
  489. select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',') g(v);
  490. select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',', '') g(v);
  491. select v, v is null as "is null" from string_to_table('1,2,3,4,*,6', ',', '*') g(v);
  492. select array_to_string(NULL::int4[], ',') IS NULL;
  493. select array_to_string('{}'::int4[], ',');
  494. select array_to_string(array[1,2,3,4,NULL,6], ',');
  495. select array_to_string(array[1,2,3,4,NULL,6], ',', '*');
  496. select array_to_string(array[1,2,3,4,NULL,6], NULL);
  497. select array_to_string(array[1,2,3,4,NULL,6], ',', NULL);
  498. select array_to_string(string_to_array('1|2|3', '|'), '|');
  499. select array_length(array[1,2,3], 1);
  500. select array_length(array[[1,2,3], [4,5,6]], 0);
  501. select array_length(array[[1,2,3], [4,5,6]], 1);
  502. select array_length(array[[1,2,3], [4,5,6]], 2);
  503. select array_length(array[[1,2,3], [4,5,6]], 3);
  504. select cardinality(NULL::int[]);
  505. select cardinality('{}'::int[]);
  506. select cardinality(array[1,2,3]);
  507. select cardinality('[2:4]={5,6,7}'::int[]);
  508. select cardinality('{{1,2}}'::int[]);
  509. select cardinality('{{1,2},{3,4},{5,6}}'::int[]);
  510. select cardinality('{{{1,9},{5,6}},{{2,3},{3,4}}}'::int[]);
  511. -- array_agg(anynonarray)
  512. select array_agg(unique1) from (select unique1 from tenk1 where unique1 < 15 order by unique1) ss;
  513. select array_agg(ten) from (select ten from tenk1 where unique1 < 15 order by unique1) ss;
  514. select array_agg(nullif(ten, 4)) from (select ten from tenk1 where unique1 < 15 order by unique1) ss;
  515. select array_agg(unique1) from tenk1 where unique1 < -15;
  516. -- array_agg(anyarray)
  517. select array_agg(ar)
  518. from (values ('{1,2}'::int[]), ('{3,4}'::int[])) v(ar);
  519. select array_agg(distinct ar order by ar desc)
  520. from (select array[i / 2] from generate_series(1,10) a(i)) b(ar);
  521. select array_agg(ar)
  522. from (select array_agg(array[i, i+1, i-1])
  523. from generate_series(1,2) a(i)) b(ar);
  524. select array_agg(array[i+1.2, i+1.3, i+1.4]) from generate_series(1,3) g(i);
  525. select array_agg(array['Hello', i::text]) from generate_series(9,11) g(i);
  526. select array_agg(array[i, nullif(i, 3), i+1]) from generate_series(1,4) g(i);
  527. -- errors
  528. select array_agg('{}'::int[]) from generate_series(1,2);
  529. select array_agg(null::int[]) from generate_series(1,2);
  530. select array_agg(ar)
  531. from (values ('{1,2}'::int[]), ('{3}'::int[])) v(ar);
  532. select unnest(array[1,2,3]);
  533. select * from unnest(array[1,2,3]);
  534. select unnest(array[1,2,3,4.5]::float8[]);
  535. select unnest(array[1,2,3,4.5]::numeric[]);
  536. select unnest(array[1,2,3,null,4,null,null,5,6]);
  537. select unnest(array[1,2,3,null,4,null,null,5,6]::text[]);
  538. select abs(unnest(array[1,2,null,-3]));
  539. select array_remove(array[1,2,2,3], 2);
  540. select array_remove(array[1,2,2,3], 5);
  541. select array_remove(array[1,NULL,NULL,3], NULL);
  542. select array_remove(array['A','CC','D','C','RR'], 'RR');
  543. select array_remove(array[1.0, 2.1, 3.3], 1);
  544. select array_remove('{{1,2,2},{1,4,3}}', 2); -- not allowed
  545. select array_remove(array['X','X','X'], 'X') = '{}';
  546. select array_replace(array[1,2,5,4],5,3);
  547. select array_replace(array[1,2,5,4],5,NULL);
  548. select array_replace(array[1,2,NULL,4,NULL],NULL,5);
  549. select array_replace(array['A','B','DD','B'],'B','CC');
  550. select array_replace(array[1,NULL,3],NULL,NULL);
  551. select array_replace(array['AB',NULL,'CDE'],NULL,'12');
  552. -- array(select array-value ...)
  553. select array(select array[i,i/2] from generate_series(1,5) i);
  554. select array(select array['Hello', i::text] from generate_series(9,11) i);
  555. -- Insert/update on a column that is array of composite
  556. create temp table t1 (f1 int8_tbl[]);
  557. insert into t1 (f1[5].q1) values(42);
  558. select * from t1;
  559. update t1 set f1[5].q2 = 43;
  560. select * from t1;
  561. -- Check that arrays of composites are safely detoasted when needed
  562. create temp table src (f1 text);
  563. insert into src
  564. select string_agg(random()::text,'') from generate_series(1,10000);
  565. create type textandtext as (c1 text, c2 text);
  566. create temp table dest (f1 textandtext[]);
  567. insert into dest select array[row(f1,f1)::textandtext] from src;
  568. select length(md5((f1[1]).c2)) from dest;
  569. delete from src;
  570. select length(md5((f1[1]).c2)) from dest;
  571. truncate table src;
  572. drop table src;
  573. select length(md5((f1[1]).c2)) from dest;
  574. drop table dest;
  575. drop type textandtext;
  576. -- Tests for polymorphic-array form of width_bucket()
  577. -- this exercises the varwidth and float8 code paths
  578. SELECT
  579. op,
  580. width_bucket(op::numeric, ARRAY[1, 3, 5, 10.0]::numeric[]) AS wb_n1,
  581. width_bucket(op::numeric, ARRAY[0, 5.5, 9.99]::numeric[]) AS wb_n2,
  582. width_bucket(op::numeric, ARRAY[-6, -5, 2.0]::numeric[]) AS wb_n3,
  583. width_bucket(op::float8, ARRAY[1, 3, 5, 10.0]::float8[]) AS wb_f1,
  584. width_bucket(op::float8, ARRAY[0, 5.5, 9.99]::float8[]) AS wb_f2,
  585. width_bucket(op::float8, ARRAY[-6, -5, 2.0]::float8[]) AS wb_f3
  586. FROM (VALUES
  587. (-5.2),
  588. (-0.0000000001),
  589. (0.000000000001),
  590. (1),
  591. (1.99999999999999),
  592. (2),
  593. (2.00000000000001),
  594. (3),
  595. (4),
  596. (4.5),
  597. (5),
  598. (5.5),
  599. (6),
  600. (7),
  601. (8),
  602. (9),
  603. (9.99999999999999),
  604. (10),
  605. (10.0000000000001)
  606. ) v(op);
  607. -- ensure float8 path handles NaN properly
  608. SELECT
  609. op,
  610. width_bucket(op, ARRAY[1, 3, 9, 'NaN', 'NaN']::float8[]) AS wb
  611. FROM (VALUES
  612. (-5.2::float8),
  613. (4::float8),
  614. (77::float8),
  615. ('NaN'::float8)
  616. ) v(op);
  617. -- these exercise the generic fixed-width code path
  618. SELECT
  619. op,
  620. width_bucket(op, ARRAY[1, 3, 5, 10]) AS wb_1
  621. FROM generate_series(0,11) as op;
  622. SELECT width_bucket(now(),
  623. array['yesterday', 'today', 'tomorrow']::timestamptz[]);
  624. -- corner cases
  625. SELECT width_bucket(5, ARRAY[3]);
  626. SELECT width_bucket(5, '{}');
  627. -- error cases
  628. SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]);
  629. SELECT width_bucket(5, ARRAY[3, 4, NULL]);
  630. SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]);
  631. -- trim_array
  632. SELECT arr, trim_array(arr, 2)
  633. FROM
  634. (VALUES ('{1,2,3,4,5,6}'::bigint[]),
  635. ('{1,2}'),
  636. ('[10:16]={1,2,3,4,5,6,7}'),
  637. ('[-15:-10]={1,2,3,4,5,6}'),
  638. ('{{1,10},{2,20},{3,30},{4,40}}')) v(arr);
  639. SELECT trim_array(ARRAY[1, 2, 3], -1); -- fail
  640. SELECT trim_array(ARRAY[1, 2, 3], 10); -- fail
  641. SELECT trim_array(ARRAY[]::int[], 1); -- fail