map.slt 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. mode cockroach
  10. # The MAP type has an uncommon OID. If tokio-postres (the driver used
  11. # by sqllogictest) encounters an OID it doesn't recognize (MAP in
  12. # this case), then it queries pg_type (a wrapper around mz_types) for
  13. # information about it. Our MAP type currently doesn't have an entry in
  14. # mz_types, so that query fails and tokio-postgres is unable to execute
  15. # queries with MAPs. As a workaround until MAP is reflected in pg_type,
  16. # we just convert everything to `text`.
  17. # Test basic string to map casts.
  18. query error VALUE TYPE option is required
  19. CREATE TYPE custom AS MAP (KEY TYPE = text)
  20. query error KEY TYPE option is required
  21. CREATE TYPE custom AS MAP (VALUE TYPE = bool)
  22. query error Expected one of KEY or VALUE, found identifier "extra_type"
  23. CREATE TYPE custom AS MAP (KEY TYPE = text, VALUE TYPE = bool, extra_type=customthing)
  24. query error type "pg_enum" does not exist
  25. CREATE TYPE tbl_map AS MAP (KEY TYPE = pg_enum, VALUE TYPE = text)
  26. query error type "pg_enum" does not exist
  27. CREATE TYPE tbl_map AS MAP (KEY TYPE = text, VALUE TYPE = pg_enum)
  28. query error CREATE TYPE ... AS MAP option VALUE TYPE can only use named data types, but found unnamed data type pg_catalog.int4 list. Use CREATE TYPE to create a named type first
  29. CREATE TYPE unnamed_element_map AS MAP (KEY TYPE = text, VALUE TYPE = int4 list)
  30. statement ok
  31. CREATE TYPE custom AS MAP (KEY TYPE = text, VALUE TYPE = bool)
  32. query error expected '\{', found a: "a=>1"
  33. SELECT ('a=>1'::map[text=>int])::text
  34. query T
  35. SELECT ('{a=>1}'::map[text=>int])::text
  36. ----
  37. {a=>1}
  38. query T
  39. SELECT ('{ c =>3, a=> 2, a => 1 }'::map[text=>int])::text
  40. ----
  41. {a=>1,c=>3}
  42. query error map key type must be text, got integer
  43. SELECT '{1=>true}'::map[int=>bool]
  44. query T
  45. SELECT ('{1=>true}'::map[text=>bool])::text
  46. ----
  47. {1=>t}
  48. query T
  49. SELECT ('{}'::map[text=>int])::text
  50. ----
  51. {}
  52. query error invalid input syntax for type boolean: "2.0"
  53. SELECT ('{a=>1, b=>false, c=>2.0}'::map[text=>bool])::text
  54. query T
  55. SELECT ('{a\=\>=>2}'::map[text=>int])::text
  56. ----
  57. {"a=>"=>2}
  58. query T
  59. SELECT ('{13=>hello \[\=\> value\], 31=> normal }'::map[text=>text])::text
  60. ----
  61. {13=>"hello [=> value]",31=>normal}
  62. query T
  63. SELECT ('{"a"=>"hello there!", b=>"129387123"}'::map[text=>text])::text
  64. ----
  65. {a=>"hello there!",b=>129387123}
  66. query T
  67. SELECT ('{key=>"here is a string => with a map operator in it"}'::map[text=>text])::text
  68. ----
  69. {key=>"here is a string => with a map operator in it"}
  70. query T
  71. SELECT ('{31=> normal \ }'::map[text=>text])::text
  72. ----
  73. {31=>"normal "}
  74. query T
  75. SELECT ('{31=> \ normal }'::map[text=>text])::text
  76. ----
  77. {31=>" normal"}
  78. query error unterminated quoted string
  79. SELECT ('{"a"=>"hello there!}'::map[text=>text])::text
  80. ### Can be cast back to text
  81. query T
  82. SELECT '{a=>1}'::map[text=>int]::text
  83. ----
  84. {a=>1}
  85. ## Nested maps
  86. query error expected '\{', found a: "a": "\{a=>a\}"
  87. SELECT (('{a=>a}'::map[text=>map[text=>text]])::text)::text
  88. query error expected =>: "\{a\}": "\{a=>\{a\}\}"
  89. SELECT ('{a=>{a}}'::map[text=>map[text=>text]])::text
  90. query error expected '\{', found b: "b": "\{a=>\{a=>a\}, b=>b\}"
  91. SELECT ('{a=>{a=>a}, b=>b}'::map[text=>map[text=>text]])::text
  92. query error unterminated embedded element
  93. SELECT ('{hello=>{world=>broken'::map[text=>map[text=>text]])::text
  94. query error unescaped '\{' at beginning of value; perhaps you want a nested map
  95. SELECT ('{hello=>{world=>true}}'::map[text=>bool])::text
  96. query T
  97. SELECT ('{hello=>{world=>nested}}'::map[text=>map[text=>text]])::text
  98. ----
  99. {hello=>{world=>nested}}
  100. query error map key type must be text, got integer
  101. SELECT '{hello=>{1=>false}}'::map[text=>map[int=>bool]]
  102. query T
  103. SELECT ('{hello=>{world=>"2020-11-23"}}'::map[text=>map[text=>timestamp]])::text
  104. ----
  105. {hello=>{world=>"2020-11-23 00:00:00"}}
  106. query T
  107. SELECT ('{hello=>{\{\}=>\"\"}}'::map[text=>map[text=>text]])::text
  108. ----
  109. {hello=>{"{}"=>"\"\""}}
  110. # Test MAP literals.
  111. query T
  112. SELECT MAP['a' => 1]::text
  113. ----
  114. {a=>1}
  115. query T
  116. SELECT MAP['a' => 1 + 1]::text
  117. ----
  118. {a=>2}
  119. query T
  120. SELECT MAP['a' => 2 * 1 + 1]::text
  121. ----
  122. {a=>3}
  123. query T
  124. SELECT MAP['a' => 2 * 1 + 2 / 2]::text
  125. ----
  126. {a=>3}
  127. query T
  128. SELECT MAP['a' => 2 * (1 + 1) / 2]::text
  129. ----
  130. {a=>2}
  131. query T
  132. SELECT MAP['a' || 'b' => 1]::text
  133. ----
  134. {ab=>1}
  135. query T
  136. SELECT MAP['a' || 'b' => 1 + 1]::text
  137. ----
  138. {ab=>2}
  139. query T
  140. SELECT MAP['a' => 1, 'a' => 2]::text
  141. ----
  142. {a=>2}
  143. query T
  144. SELECT MAP['a' => 1, 'b' => 2, 'a' => 3]::text
  145. ----
  146. {a=>3,b=>2}
  147. query T
  148. SELECT MAP['a' => MAP['b' => 'c']]::text
  149. ----
  150. {a=>{b=>c}}
  151. query T
  152. SELECT MAP['a' => ['b' => 'c']]::text
  153. ----
  154. {a=>{b=>c}}
  155. query T
  156. SELECT MAP['a' => list[[1], [2]]]::text
  157. ----
  158. {a=>{{1},{2}}}
  159. query T
  160. SELECT MAP['a' => ['b' => list[[1], [2]]]]::text
  161. ----
  162. {a=>{b=>{{1},{2}}}}
  163. query T
  164. SELECT MAP[column1 => column2]::text FROM (VALUES ('a', 1), ('b', 2), ('c', 3))
  165. ----
  166. {a=>1}
  167. {b=>2}
  168. {c=>3}
  169. query error cannot determine type of empty map
  170. SELECT MAP[]::text
  171. query T
  172. SELECT MAP[]::map[text => text]::text
  173. ----
  174. {}
  175. statement ok
  176. CREATE TABLE mlt(t text, y int)
  177. statement ok
  178. INSERT INTO mlt VALUES ('a', 6), ('b', 8), ('c', 10), ('c', 11)
  179. query T
  180. SELECT MAP(SELECT * FROM mlt WHERE t > 'a' ORDER BY y DESC)::text;
  181. ----
  182. {b=>8,c=>10}
  183. query T rowsort
  184. SELECT MAP(SELECT * FROM mlt WHERE mlt.t > mlt_outer.t)::text
  185. FROM mlt AS mlt_outer;
  186. ----
  187. {}
  188. {}
  189. {c=>11}
  190. {b=>8,c=>11}
  191. query TII rowsort
  192. SELECT list_agg(t)::text, min(y), max(y)
  193. FROM mlt AS mlt_outer
  194. GROUP BY MAP(SELECT * FROM mlt WHERE mlt.t < mlt_outer.t);
  195. ----
  196. {a} 6 6
  197. {b} 8 8
  198. {c,c} 10 11
  199. query T
  200. SELECT MAP(SELECT * FROM mlt WHERE t < 'a')::text
  201. ----
  202. {}
  203. # Test MAP subqueries.
  204. query T
  205. SELECT MAP(VALUES ('a', 1), ('b', 2), ('c', 3))::text
  206. ----
  207. {a=>1,b=>2,c=>3}
  208. query T
  209. SELECT MAP(VALUES ('a', 1), ('a', 2) ORDER BY 2)::text
  210. ----
  211. {a=>2}
  212. query T
  213. SELECT MAP(VALUES ('a', 1), ('a', 2) ORDER BY 2 DESC)::text
  214. ----
  215. {a=>1}
  216. query error cannot build map from subquery because first column is not of type text
  217. SELECT MAP(VALUES (1, 1))
  218. query error expected map subquery to return 2 columns, got 1 columns
  219. SELECT MAP(VALUES (1))
  220. query error expected map subquery to return 2 columns, got 3 columns
  221. SELECT MAP(VALUES (1, 2, 3))
  222. # Test map operators.
  223. ## ?
  224. query T
  225. SELECT '{a=>1, b=>2}'::map[text=>int] ? 'a'
  226. ----
  227. true
  228. query T
  229. SELECT '{a=>1, b=>2}'::map[text=>int] ? 'b'
  230. ----
  231. true
  232. query T
  233. SELECT '{a=>1, b=>2}'::map[text=>int] ? 'c'
  234. ----
  235. false
  236. query error operator does not exist: map\[text=>integer\] \? integer
  237. SELECT '{a=>1, b=>2}'::map[text=>int] ? 1
  238. query T
  239. SELECT '{a=>1}'::map[text=>int] ? ''
  240. ----
  241. false
  242. query T
  243. SELECT '{""=>1}'::map[text=>int] ? ''
  244. ----
  245. true
  246. query T
  247. SELECT '{"1" => NULL}'::map[text=>text] ? ''
  248. ----
  249. false
  250. query T
  251. SELECT '{hello=>{world=>false}}'::map[text=>map[text=>bool]] -> 'hello'::text ? 'world'::text
  252. ----
  253. true
  254. query error operator is not unique: unknown \? unknown
  255. SELECT NULL ? 'a'
  256. ## ?&
  257. query error invalid input syntax for type array: Array value must start with "\{": "a"
  258. SELECT '{a=>1, b=>2}'::map[text=>int] ?& 'a'
  259. query error operator does not exist: map\[text=>integer\] \?\& integer\[\]
  260. SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY[1]
  261. query error cannot determine type of empty array
  262. SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY[]
  263. query error could not determine polymorphic type because input has type unknown
  264. SELECT NULL ?& 'a'
  265. query T
  266. SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY[NULL]
  267. ----
  268. false
  269. query T
  270. SELECT '{a=>1, b=>2}'::map[text=>int] ?& '{a}'
  271. ----
  272. true
  273. query T
  274. SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY['a']
  275. ----
  276. true
  277. query T
  278. SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY['b', 'a']
  279. ----
  280. true
  281. query T
  282. SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY['c', 'b']
  283. ----
  284. false
  285. query error operator does not exist: map\[text=>boolean\] \?\& integer\[\]
  286. SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY[1]
  287. query T
  288. SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY['1']
  289. ----
  290. true
  291. query T
  292. SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY['']
  293. ----
  294. false
  295. query T
  296. SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY['']
  297. ----
  298. false
  299. query T
  300. SELECT '{hello=>{world=>123.40}}'::map[text=>map[text=>double]] -> 'hello'::text ?& ARRAY['world']
  301. ----
  302. true
  303. query T
  304. SELECT '{hello=>{world=>1293}}'::map[text=>map[text=>smallint]] -> 'hello'::text ?& ARRAY['world', 'extra']
  305. ----
  306. false
  307. ## ?|
  308. query error invalid input syntax for type array: Array value must start with "\{": "a"
  309. SELECT '{a=>1, b=>2}'::map[text=>int] ?| 'a'
  310. query error operator does not exist: map\[text=>integer\] \?\| integer\[\]
  311. SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY[1]
  312. query error could not determine polymorphic type because input has type unknown
  313. SELECT NULL ?| 'a'
  314. query T
  315. SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY[NULL]
  316. ----
  317. false
  318. query T
  319. SELECT '{a=>1, b=>2}'::map[text=>int] ?| '{a}'
  320. ----
  321. true
  322. query T
  323. SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY['a']
  324. ----
  325. true
  326. query T
  327. SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY['c', 'b']
  328. ----
  329. true
  330. query T
  331. SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY['c', 'd', '1']
  332. ----
  333. false
  334. query error operator does not exist: map\[text=>boolean\] \?\| integer\[\]
  335. SELECT '{1=>t, 2=>f}'::map[text=>bool] ?| ARRAY[1]
  336. query T
  337. SELECT '{1=>t, 2=>f}'::map[text=>bool] ?| ARRAY['1']
  338. ----
  339. true
  340. query T
  341. SELECT '{hello=>{world=>63616665-6630-3064-6465-616462656568}}'::map[text=>map[text=>uuid]] -> 'hello'::text ?| ARRAY['world', 'extra']
  342. ----
  343. true
  344. query T
  345. SELECT '{hello=>{world=>"2020-11-23"}}'::map[text=>map[text=>date]] -> 'hello'::text ?| ARRAY['missing']
  346. ----
  347. false
  348. ## @>
  349. query error invalid input syntax for type map: expected '\{', found c: "c"
  350. SELECT '{a=>1, b=>2}'::map[text=>int] @> 'c'
  351. query error operator does not exist: map\[text=>integer\] @> text
  352. SELECT '{a=>1, b=>2}'::map[text=>int] @> 'a'::text
  353. query error operator does not exist: map\[text=>integer\] @> integer\[\]
  354. SELECT '{a=>1, b=>2}'::map[text=>int] @> ARRAY[1]
  355. query error operator does not exist: map\[text=>integer\] @> map\[text=>boolean\]
  356. SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>t}'::map[text=>bool]
  357. ----
  358. false
  359. query T
  360. SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>1}'::map[text=>int]
  361. ----
  362. true
  363. query T
  364. SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>1, b=>2}'::map[text=>int]
  365. ----
  366. true
  367. query T
  368. SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>10, b=>20}'::map[text=>int]
  369. ----
  370. false
  371. query T
  372. SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>1, b=>2, c=>3}'::map[text=>int]
  373. ----
  374. false
  375. query error operator does not exist: map\[text=>map\[text=>bytea\]\] @> map\[text=>text\]
  376. SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>bytea]] @> '{hello=>world}'::map[text=>text]
  377. ----
  378. false
  379. query T
  380. SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>text]] @> '{hello=>{world=>nested}}'::map[text=>map[text=>text]]
  381. ----
  382. true
  383. query T
  384. SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>text]] @> '{hello=>{world=>nested}, extra=>{elements=>here}}'::map[text=>map[text=>text]]
  385. ----
  386. false
  387. ## <@
  388. query error operator does not exist: map\[text=>integer\] <@ map\[text=>boolean\]
  389. SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>t}'::map[text=>bool]
  390. ----
  391. false
  392. query T
  393. SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>1}'::map[text=>int]
  394. ----
  395. false
  396. query T
  397. SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>1, b=>2}'::map[text=>int]
  398. ----
  399. true
  400. query T
  401. SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>10, b=>20}'::map[text=>int]
  402. ----
  403. false
  404. query T
  405. SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>1, b=>2, c=>3}'::map[text=>int]
  406. ----
  407. true
  408. query error db error: ERROR: CAST does not support casting from map\[text=>map\[text=>char\]\] to map\[text=>map\[text=>char\(1\)\]\]
  409. SELECT '{hello=>{world=>a}}'::map[text=>map[text=>char]] <@ '{hello=>c}'::map[text=>char]
  410. ----
  411. false
  412. query T
  413. SELECT '{hello=>{world=>16}}'::map[text=>map[text=>oid]] <@ '{hello=>{world=>16}}'::map[text=>map[text=>oid]]
  414. ----
  415. true
  416. query T
  417. SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>text]] <@ '{hello=>{world=>nested}, extra=>{elements=>here}}'::map[text=>map[text=>text]]
  418. ----
  419. true
  420. ## ->
  421. query T
  422. SELECT '{a=>1, b=>2}'::map[text=>int] -> ''
  423. ----
  424. NULL
  425. query T
  426. SELECT '{a=>1, b=>2}'::map[text=>int] -> 'a'
  427. ----
  428. 1
  429. query T
  430. SELECT '{a=>1, b=>2}'::map[text=>int] -> 'b'
  431. ----
  432. 2
  433. query T
  434. SELECT '{a=>1, b=>2}'::map[text=>int] -> 'c'
  435. ----
  436. NULL
  437. query error operator does not exist: map\[text=>integer\] \-> integer
  438. SELECT '{a=>1, b=>2}'::map[text=>int] -> 1
  439. query T
  440. SELECT '{a=>true, b=>false}'::map[text=>bool] -> 'b'
  441. ----
  442. false
  443. query T
  444. SELECT ('{hello=>{world=>nested}, another=>{map=>here}}'::map[text=>map[text=>text]] -> 'missing'::text)::text
  445. ----
  446. NULL
  447. query T
  448. SELECT ('{hello=>{world=>nested}, another=>{map=>here}}'::map[text=>map[text=>text]] -> 'hello'::text)::text
  449. ----
  450. {world=>nested}
  451. query T
  452. SELECT '{hello=>{world=>nested}, another=>{map=>here}}'::map[text=>map[text=>text]] -> 'hello'::text -> 'world'::text
  453. ----
  454. nested
  455. query error operator is not unique: unknown \-> text
  456. SELECT NULL -> 'hello'::text
  457. # 🔬 CREATE TYPE .. AS MAP
  458. statement ok
  459. CREATE TYPE int4_map AS MAP (KEY TYPE = text, VALUE TYPE = int4);
  460. query T
  461. SELECT '{a=>1,b=>2}'::int4_map::text;
  462. ----
  463. {a=>1,b=>2}
  464. query T
  465. SELECT pg_typeof(NULL::int4_map);
  466. ----
  467. int4_map
  468. # 🔬🔬 Check each valid value type
  469. statement ok
  470. CREATE TYPE bool_map_c AS MAP (KEY TYPE = text, VALUE TYPE = bool);
  471. query T
  472. SELECT '{a=>true}'::bool_map_c::text
  473. ----
  474. {a=>t}
  475. statement ok
  476. CREATE TYPE int8_map_c AS MAP (KEY TYPE = text, VALUE TYPE = int8);
  477. query T
  478. SELECT '{a=>1}'::int8_map_c::text
  479. ----
  480. {a=>1}
  481. statement ok
  482. CREATE TYPE int4_map_c AS MAP (KEY TYPE = text, VALUE TYPE = int4);
  483. query T
  484. SELECT '{a=>1}'::int4_map_c::text
  485. ----
  486. {a=>1}
  487. statement ok
  488. CREATE TYPE text_map_c AS MAP (KEY TYPE = text, VALUE TYPE = text);
  489. query T
  490. SELECT '{a=>a}'::text_map_c::text
  491. ----
  492. {a=>a}
  493. statement ok
  494. CREATE TYPE float4_map_c AS MAP (KEY TYPE = text, VALUE TYPE = float4);
  495. query T
  496. SELECT '{a=>1.2}'::float4_map_c::text
  497. ----
  498. {a=>1.2}
  499. statement ok
  500. CREATE TYPE float8_map_c AS MAP (KEY TYPE = text, VALUE TYPE = float8);
  501. query T
  502. SELECT '{a=>1.2}'::float8_map_c::text
  503. ----
  504. {a=>1.2}
  505. statement ok
  506. CREATE TYPE date_map_c AS MAP (KEY TYPE = text, VALUE TYPE = date);
  507. query T
  508. SELECT '{a=>2001-01-01}'::date_map_c::text
  509. ----
  510. {a=>2001-01-01}
  511. statement ok
  512. CREATE TYPE time_map_c AS MAP (KEY TYPE = text, VALUE TYPE = time);
  513. query T
  514. SELECT '{a=>12:34:56}'::time_map_c::text
  515. ----
  516. {a=>12:34:56}
  517. statement ok
  518. CREATE TYPE timestamp_map_c AS MAP (KEY TYPE = text, VALUE TYPE = timestamp);
  519. query T
  520. SELECT '{a=>2001-01-01 12:34:56}'::timestamp_map_c::text
  521. ----
  522. {a=>"2001-01-01 12:34:56"}
  523. statement ok
  524. CREATE TYPE timestamptz_map_c AS MAP (KEY TYPE = text, VALUE TYPE = timestamptz);
  525. query T
  526. SELECT '{a=>2001-01-01 12:34:56}'::timestamptz_map_c::text
  527. ----
  528. {a=>"2001-01-01 12:34:56+00"}
  529. statement ok
  530. CREATE TYPE interval_map_c AS MAP (KEY TYPE = text, VALUE TYPE = interval);
  531. query T
  532. SELECT '{a=>1y 2d 3h 4m}'::interval_map_c::text
  533. ----
  534. {a=>"1 year 2 days 03:04:00"}
  535. statement ok
  536. CREATE TYPE numeric_map_c AS MAP (KEY TYPE = text, VALUE TYPE = numeric);
  537. query T
  538. SELECT '{a=>1.23}'::numeric_map_c::text
  539. ----
  540. {a=>1.23}
  541. statement ok
  542. CREATE TYPE jsonb_map_c AS MAP (KEY TYPE = text, VALUE TYPE = jsonb);
  543. query T
  544. SELECT '{a=>\{\"1\":2\}}'::jsonb_map_c::text;
  545. ----
  546. {a=>"{\"1\":2}"}
  547. # 🔬🔬 Check custom type name resolution
  548. statement ok
  549. CREATE TYPE bool AS MAP (KEY TYPE = text, VALUE TYPE = int4)
  550. query error invalid input syntax for type boolean: "\{a=>1\}"
  551. SELECT '{a=>1}'::bool;
  552. query T
  553. SELECT '{a=>1}'::public.bool::text;
  554. ----
  555. {a=>1}
  556. # 🔬🔬 Check subtype resolution
  557. # Supports qualified subtypes
  558. statement ok
  559. CREATE TYPE qualified_int4_map AS MAP (KEY TYPE = pg_catalog.text, VALUE TYPE = pg_catalog.int4)
  560. statement ok
  561. CREATE TYPE qualified_qualified_int4_map AS MAP (KEY TYPE = pg_catalog.text, VALUE TYPE = public.qualified_int4_map)
  562. # Supports type aliases
  563. statement ok
  564. CREATE TYPE int_map AS MAP (KEY TYPE = pg_catalog.text, VALUE TYPE = int)
  565. # `map_length`
  566. query T
  567. SELECT map_length('{}'::map[text=>int])
  568. ----
  569. 0
  570. query T
  571. SELECT map_length('{a=>1}'::map[text=>int])
  572. ----
  573. 1
  574. query T
  575. SELECT map_length('{a=>1, b=>2}'::map[text=>int])
  576. ----
  577. 2
  578. query T
  579. SELECT map_length(NULL::map[text=>int])
  580. ----
  581. NULL
  582. # map_build
  583. query T
  584. SELECT map_build(LIST[ROW('a', 1), ROW('b', 2)])::TEXT;
  585. ----
  586. {a=>1,b=>2}
  587. query error LIST could not convert type record\(f1: text,f2: integer\) to text
  588. SELECT map_build(LIST[ROW('a', 1), ROW('b')])::TEXT;
  589. query error function map_build\(record\(f1: integer,f2: integer\) list\) does not exist
  590. SELECT map_build(LIST[ROW(1, 1), ROW(2, 2)])::TEXT;
  591. statement ok
  592. CREATE TYPE r AS (f1 TEXT, f2 INT);
  593. query T
  594. SELECT map_build(LIST[ROW('a', 1), ROW('b', 2)::r])::TEXT;
  595. ----
  596. {a=>1,b=>2}
  597. query T
  598. SELECT map_build(LIST[ROW('a', 1), ROW('b', 2)]::r list)::TEXT;
  599. ----
  600. {a=>1,b=>2}
  601. query T
  602. SELECT map_build(LIST[ROW('a', 1), ROW('a', 2)]::r list)::TEXT;
  603. ----
  604. {a=>2}
  605. query T
  606. SELECT map_build(LIST[ROW('a', 2), ROW('a', 1)]::r list)::TEXT;
  607. ----
  608. {a=>1}
  609. # skip null keys
  610. query T
  611. SELECT map_build(LIST[ROW('a', 1), ROW(NULL, 2)]::r list)::TEXT;
  612. ----
  613. {a=>1}
  614. query T
  615. SELECT map_build(LIST[NULL]::r list)::TEXT;
  616. ----
  617. {}
  618. query T
  619. SELECT map_build(LIST[ROW('a', 1), NULL]::r list)::TEXT;
  620. ----
  621. {a=>1}
  622. query T
  623. SELECT map_build(LIST[NULL, ROW('a', 1)]::r list)::TEXT;
  624. ----
  625. {a=>1}
  626. query T
  627. SELECT map_build(LIST[ROW('a', 9), NULL, ROW('a', 1)]::r list)::TEXT;
  628. ----
  629. {a=>1}
  630. query error could not determine polymorphic type because input has type unknown
  631. SELECT map_build(NULL)::TEXT;
  632. query T
  633. SELECT map_build(NULL::r list)::TEXT;
  634. ----
  635. NULL
  636. statement ok
  637. CREATE TYPE int_list AS LIST (ELEMENT TYPE = int4);
  638. statement ok
  639. CREATE TYPE l AS (f1 TEXT, f2 int_list);
  640. query T
  641. SELECT map_build(LIST[ROW('a', LIST[1]), ROW('a', LIST[2])]::l list)::TEXT;
  642. ----
  643. {a=>{2}}
  644. query T
  645. SELECT map_build(LIST[ROW('a', LIST[2]), ROW('a', LIST[1])]::l list)::TEXT;
  646. ----
  647. {a=>{1}}
  648. statement ok
  649. CREATE TYPE int_key AS (f1 INT, f2 INT);
  650. query error db error: ERROR: function map_build\(int_key list\) does not exist
  651. SELECT map_build(LIST[ROW(1, 1), ROW(1, 2)]::int_key list)::TEXT;
  652. statement ok
  653. CREATE TYPE missing_value AS (f1 TEXT);
  654. query error db error: ERROR: function map_build\(missing_value list\) does not exist
  655. SELECT map_build(LIST[ROW('a'), ROW('a')]::missing_value list)::TEXT;
  656. query error db error: ERROR: function map_build\(integer\) does not exist
  657. SELECT map_build(1)::TEXT;
  658. query error db error: ERROR: function map_build\(integer list\) does not exist
  659. SELECT map_build(LIST[1])::TEXT;
  660. # map_agg
  661. statement ok
  662. CREATE TABLE t1 (a int)
  663. statement ok
  664. INSERT INTO t1 VALUES (1), (2), (3), (NULL)
  665. query error db error: ERROR: function map_agg\(integer, integer\) does not exist
  666. SELECT map_agg(k, v)::TEXT FROM (SELECT 1 AS k, 2 AS V WHERE false)
  667. query T
  668. SELECT map_agg(k, v)::TEXT FROM (SELECT 1::TEXT AS k, 2 AS V WHERE false)
  669. ----
  670. NULL
  671. query T
  672. SELECT map_agg('one', 2)::TEXT
  673. ----
  674. {one=>2}
  675. query error db error: ERROR: function map_agg\(integer, integer\) does not exist
  676. SELECT map_agg(1, 2)
  677. query T
  678. SELECT map_agg(k, v)::TEXT FROM (SELECT (a - 1)::TEXT AS k, a AS v FROM t1 WHERE a IS NOT NULL)
  679. ----
  680. {0=>1,1=>2,2=>3}
  681. query T
  682. SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('a', null), ('b', 1))
  683. ----
  684. {a=>NULL,b=>1}
  685. query T
  686. SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('b', 2), ('a', 1))
  687. ----
  688. {a=>1,b=>2}
  689. query T
  690. SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('a', 1), ('a', 2))
  691. ----
  692. {a=>2}
  693. query T
  694. SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('a', 2), ('a', 1))
  695. ----
  696. {a=>2}
  697. query T
  698. SELECT map_agg(a, b ORDER BY b DESC)::TEXT FROM (VALUES ('a', 2), ('a', 1)) AS t (a, b);
  699. ----
  700. {a=>1}
  701. query T
  702. SELECT map_agg(a, b ORDER BY b ASC)::TEXT FROM (VALUES ('a', 2), ('a', 1)) AS t (a, b);
  703. ----
  704. {a=>2}
  705. query T
  706. SELECT map_agg(null, null)::TEXT
  707. ----
  708. {}
  709. query T
  710. SELECT map_agg(null, null)::TEXT
  711. ----
  712. {}
  713. query T
  714. SELECT map_agg(null, 1)::TEXT
  715. ----
  716. {}
  717. query T
  718. SELECT (map_agg(a::TEXT, a) FILTER (WHERE a IS NOT NULL))::TEXT FROM t1
  719. ----
  720. {1=>1,2=>2,3=>3}
  721. query T
  722. SELECT map_agg(a::TEXT, a)::TEXT FROM t1
  723. ----
  724. {1=>1,2=>2,3=>3}
  725. query T
  726. SELECT (map_agg(a::TEXT, a) FILTER (WHERE a = 1))::TEXT FROM t1
  727. ----
  728. {1=>1}
  729. # unnest
  730. query TT colnames
  731. SELECT key, value FROM unnest('{a=>NULL}'::map[text=>int4]);
  732. ----
  733. key value
  734. a NULL
  735. query TT
  736. SELECT upper(key), value * 100 FROM unnest('{a=>1}'::map[text=>int4]);
  737. ----
  738. A 100
  739. query T
  740. WITH v (a) AS (
  741. SELECT '{a=>1}'::map[text=>int]
  742. ),
  743. unnest (key, value) AS (
  744. SELECT (a).key, (a).value FROM (
  745. SELECT unnest(a) FROM v
  746. ) AS u (a)
  747. ),
  748. manipulate (key, value) AS (
  749. SELECT upper(key), value * 100 FROM unnest
  750. )
  751. SELECT map_agg(key, value)::TEXT FROM manipulate;
  752. ----
  753. {A=>100}
  754. query T
  755. SELECT unnest(NULL::map[text=>int4]);
  756. ----
  757. query T
  758. SELECT unnest('{a=>NULL}'::map[text=>int4]);
  759. ----
  760. (a,)