123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986 |
- # Copyright Materialize, Inc. and contributors. All rights reserved.
- #
- # Use of this software is governed by the Business Source License
- # included in the LICENSE file at the root of this repository.
- #
- # As of the Change Date specified in that file, in accordance with
- # the Business Source License, use of this software will be governed
- # by the Apache License, Version 2.0.
- mode cockroach
- # The MAP type has an uncommon OID. If tokio-postres (the driver used
- # by sqllogictest) encounters an OID it doesn't recognize (MAP in
- # this case), then it queries pg_type (a wrapper around mz_types) for
- # information about it. Our MAP type currently doesn't have an entry in
- # mz_types, so that query fails and tokio-postgres is unable to execute
- # queries with MAPs. As a workaround until MAP is reflected in pg_type,
- # we just convert everything to `text`.
- # Test basic string to map casts.
- query error VALUE TYPE option is required
- CREATE TYPE custom AS MAP (KEY TYPE = text)
- query error KEY TYPE option is required
- CREATE TYPE custom AS MAP (VALUE TYPE = bool)
- query error Expected one of KEY or VALUE, found identifier "extra_type"
- CREATE TYPE custom AS MAP (KEY TYPE = text, VALUE TYPE = bool, extra_type=customthing)
- query error type "pg_enum" does not exist
- CREATE TYPE tbl_map AS MAP (KEY TYPE = pg_enum, VALUE TYPE = text)
- query error type "pg_enum" does not exist
- CREATE TYPE tbl_map AS MAP (KEY TYPE = text, VALUE TYPE = pg_enum)
- 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
- CREATE TYPE unnamed_element_map AS MAP (KEY TYPE = text, VALUE TYPE = int4 list)
- statement ok
- CREATE TYPE custom AS MAP (KEY TYPE = text, VALUE TYPE = bool)
- query error expected '\{', found a: "a=>1"
- SELECT ('a=>1'::map[text=>int])::text
- query T
- SELECT ('{a=>1}'::map[text=>int])::text
- ----
- {a=>1}
- query T
- SELECT ('{ c =>3, a=> 2, a => 1 }'::map[text=>int])::text
- ----
- {a=>1,c=>3}
- query error map key type must be text, got integer
- SELECT '{1=>true}'::map[int=>bool]
- query T
- SELECT ('{1=>true}'::map[text=>bool])::text
- ----
- {1=>t}
- query T
- SELECT ('{}'::map[text=>int])::text
- ----
- {}
- query error invalid input syntax for type boolean: "2.0"
- SELECT ('{a=>1, b=>false, c=>2.0}'::map[text=>bool])::text
- query T
- SELECT ('{a\=\>=>2}'::map[text=>int])::text
- ----
- {"a=>"=>2}
- query T
- SELECT ('{13=>hello \[\=\> value\], 31=> normal }'::map[text=>text])::text
- ----
- {13=>"hello [=> value]",31=>normal}
- query T
- SELECT ('{"a"=>"hello there!", b=>"129387123"}'::map[text=>text])::text
- ----
- {a=>"hello there!",b=>129387123}
- query T
- SELECT ('{key=>"here is a string => with a map operator in it"}'::map[text=>text])::text
- ----
- {key=>"here is a string => with a map operator in it"}
- query T
- SELECT ('{31=> normal \ }'::map[text=>text])::text
- ----
- {31=>"normal "}
- query T
- SELECT ('{31=> \ normal }'::map[text=>text])::text
- ----
- {31=>" normal"}
- query error unterminated quoted string
- SELECT ('{"a"=>"hello there!}'::map[text=>text])::text
- ### Can be cast back to text
- query T
- SELECT '{a=>1}'::map[text=>int]::text
- ----
- {a=>1}
- ## Nested maps
- query error expected '\{', found a: "a": "\{a=>a\}"
- SELECT (('{a=>a}'::map[text=>map[text=>text]])::text)::text
- query error expected =>: "\{a\}": "\{a=>\{a\}\}"
- SELECT ('{a=>{a}}'::map[text=>map[text=>text]])::text
- query error expected '\{', found b: "b": "\{a=>\{a=>a\}, b=>b\}"
- SELECT ('{a=>{a=>a}, b=>b}'::map[text=>map[text=>text]])::text
- query error unterminated embedded element
- SELECT ('{hello=>{world=>broken'::map[text=>map[text=>text]])::text
- query error unescaped '\{' at beginning of value; perhaps you want a nested map
- SELECT ('{hello=>{world=>true}}'::map[text=>bool])::text
- query T
- SELECT ('{hello=>{world=>nested}}'::map[text=>map[text=>text]])::text
- ----
- {hello=>{world=>nested}}
- query error map key type must be text, got integer
- SELECT '{hello=>{1=>false}}'::map[text=>map[int=>bool]]
- query T
- SELECT ('{hello=>{world=>"2020-11-23"}}'::map[text=>map[text=>timestamp]])::text
- ----
- {hello=>{world=>"2020-11-23 00:00:00"}}
- query T
- SELECT ('{hello=>{\{\}=>\"\"}}'::map[text=>map[text=>text]])::text
- ----
- {hello=>{"{}"=>"\"\""}}
- # Test MAP literals.
- query T
- SELECT MAP['a' => 1]::text
- ----
- {a=>1}
- query T
- SELECT MAP['a' => 1 + 1]::text
- ----
- {a=>2}
- query T
- SELECT MAP['a' => 2 * 1 + 1]::text
- ----
- {a=>3}
- query T
- SELECT MAP['a' => 2 * 1 + 2 / 2]::text
- ----
- {a=>3}
- query T
- SELECT MAP['a' => 2 * (1 + 1) / 2]::text
- ----
- {a=>2}
- query T
- SELECT MAP['a' || 'b' => 1]::text
- ----
- {ab=>1}
- query T
- SELECT MAP['a' || 'b' => 1 + 1]::text
- ----
- {ab=>2}
- query T
- SELECT MAP['a' => 1, 'a' => 2]::text
- ----
- {a=>2}
- query T
- SELECT MAP['a' => 1, 'b' => 2, 'a' => 3]::text
- ----
- {a=>3,b=>2}
- query T
- SELECT MAP['a' => MAP['b' => 'c']]::text
- ----
- {a=>{b=>c}}
- query T
- SELECT MAP['a' => ['b' => 'c']]::text
- ----
- {a=>{b=>c}}
- query T
- SELECT MAP['a' => list[[1], [2]]]::text
- ----
- {a=>{{1},{2}}}
- query T
- SELECT MAP['a' => ['b' => list[[1], [2]]]]::text
- ----
- {a=>{b=>{{1},{2}}}}
- query T
- SELECT MAP[column1 => column2]::text FROM (VALUES ('a', 1), ('b', 2), ('c', 3))
- ----
- {a=>1}
- {b=>2}
- {c=>3}
- query error cannot determine type of empty map
- SELECT MAP[]::text
- query T
- SELECT MAP[]::map[text => text]::text
- ----
- {}
- statement ok
- CREATE TABLE mlt(t text, y int)
- statement ok
- INSERT INTO mlt VALUES ('a', 6), ('b', 8), ('c', 10), ('c', 11)
- query T
- SELECT MAP(SELECT * FROM mlt WHERE t > 'a' ORDER BY y DESC)::text;
- ----
- {b=>8,c=>10}
- query T rowsort
- SELECT MAP(SELECT * FROM mlt WHERE mlt.t > mlt_outer.t)::text
- FROM mlt AS mlt_outer;
- ----
- {}
- {}
- {c=>11}
- {b=>8,c=>11}
- query TII rowsort
- SELECT list_agg(t)::text, min(y), max(y)
- FROM mlt AS mlt_outer
- GROUP BY MAP(SELECT * FROM mlt WHERE mlt.t < mlt_outer.t);
- ----
- {a} 6 6
- {b} 8 8
- {c,c} 10 11
- query T
- SELECT MAP(SELECT * FROM mlt WHERE t < 'a')::text
- ----
- {}
- # Test MAP subqueries.
- query T
- SELECT MAP(VALUES ('a', 1), ('b', 2), ('c', 3))::text
- ----
- {a=>1,b=>2,c=>3}
- query T
- SELECT MAP(VALUES ('a', 1), ('a', 2) ORDER BY 2)::text
- ----
- {a=>2}
- query T
- SELECT MAP(VALUES ('a', 1), ('a', 2) ORDER BY 2 DESC)::text
- ----
- {a=>1}
- query error cannot build map from subquery because first column is not of type text
- SELECT MAP(VALUES (1, 1))
- query error expected map subquery to return 2 columns, got 1 columns
- SELECT MAP(VALUES (1))
- query error expected map subquery to return 2 columns, got 3 columns
- SELECT MAP(VALUES (1, 2, 3))
- # Test map operators.
- ## ?
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ? 'a'
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ? 'b'
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ? 'c'
- ----
- false
- query error operator does not exist: map\[text=>integer\] \? integer
- SELECT '{a=>1, b=>2}'::map[text=>int] ? 1
- query T
- SELECT '{a=>1}'::map[text=>int] ? ''
- ----
- false
- query T
- SELECT '{""=>1}'::map[text=>int] ? ''
- ----
- true
- query T
- SELECT '{"1" => NULL}'::map[text=>text] ? ''
- ----
- false
- query T
- SELECT '{hello=>{world=>false}}'::map[text=>map[text=>bool]] -> 'hello'::text ? 'world'::text
- ----
- true
- query error operator is not unique: unknown \? unknown
- SELECT NULL ? 'a'
- ## ?&
- query error invalid input syntax for type array: Array value must start with "\{": "a"
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& 'a'
- query error operator does not exist: map\[text=>integer\] \?\& integer\[\]
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY[1]
- query error cannot determine type of empty array
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY[]
- query error could not determine polymorphic type because input has type unknown
- SELECT NULL ?& 'a'
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY[NULL]
- ----
- false
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& '{a}'
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY['a']
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY['b', 'a']
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?& ARRAY['c', 'b']
- ----
- false
- query error operator does not exist: map\[text=>boolean\] \?\& integer\[\]
- SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY[1]
- query T
- SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY['1']
- ----
- true
- query T
- SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY['']
- ----
- false
- query T
- SELECT '{1=>t, 2=>f}'::map[text=>bool] ?& ARRAY['']
- ----
- false
- query T
- SELECT '{hello=>{world=>123.40}}'::map[text=>map[text=>double]] -> 'hello'::text ?& ARRAY['world']
- ----
- true
- query T
- SELECT '{hello=>{world=>1293}}'::map[text=>map[text=>smallint]] -> 'hello'::text ?& ARRAY['world', 'extra']
- ----
- false
- ## ?|
- query error invalid input syntax for type array: Array value must start with "\{": "a"
- SELECT '{a=>1, b=>2}'::map[text=>int] ?| 'a'
- query error operator does not exist: map\[text=>integer\] \?\| integer\[\]
- SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY[1]
- query error could not determine polymorphic type because input has type unknown
- SELECT NULL ?| 'a'
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY[NULL]
- ----
- false
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?| '{a}'
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY['a']
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY['c', 'b']
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] ?| ARRAY['c', 'd', '1']
- ----
- false
- query error operator does not exist: map\[text=>boolean\] \?\| integer\[\]
- SELECT '{1=>t, 2=>f}'::map[text=>bool] ?| ARRAY[1]
- query T
- SELECT '{1=>t, 2=>f}'::map[text=>bool] ?| ARRAY['1']
- ----
- true
- query T
- SELECT '{hello=>{world=>63616665-6630-3064-6465-616462656568}}'::map[text=>map[text=>uuid]] -> 'hello'::text ?| ARRAY['world', 'extra']
- ----
- true
- query T
- SELECT '{hello=>{world=>"2020-11-23"}}'::map[text=>map[text=>date]] -> 'hello'::text ?| ARRAY['missing']
- ----
- false
- ## @>
- query error invalid input syntax for type map: expected '\{', found c: "c"
- SELECT '{a=>1, b=>2}'::map[text=>int] @> 'c'
- query error operator does not exist: map\[text=>integer\] @> text
- SELECT '{a=>1, b=>2}'::map[text=>int] @> 'a'::text
- query error operator does not exist: map\[text=>integer\] @> integer\[\]
- SELECT '{a=>1, b=>2}'::map[text=>int] @> ARRAY[1]
- query error operator does not exist: map\[text=>integer\] @> map\[text=>boolean\]
- SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>t}'::map[text=>bool]
- ----
- false
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>1}'::map[text=>int]
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>1, b=>2}'::map[text=>int]
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>10, b=>20}'::map[text=>int]
- ----
- false
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] @> '{a=>1, b=>2, c=>3}'::map[text=>int]
- ----
- false
- query error operator does not exist: map\[text=>map\[text=>bytea\]\] @> map\[text=>text\]
- SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>bytea]] @> '{hello=>world}'::map[text=>text]
- ----
- false
- query T
- SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>text]] @> '{hello=>{world=>nested}}'::map[text=>map[text=>text]]
- ----
- true
- query T
- SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>text]] @> '{hello=>{world=>nested}, extra=>{elements=>here}}'::map[text=>map[text=>text]]
- ----
- false
- ## <@
- query error operator does not exist: map\[text=>integer\] <@ map\[text=>boolean\]
- SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>t}'::map[text=>bool]
- ----
- false
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>1}'::map[text=>int]
- ----
- false
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>1, b=>2}'::map[text=>int]
- ----
- true
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>10, b=>20}'::map[text=>int]
- ----
- false
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] <@ '{a=>1, b=>2, c=>3}'::map[text=>int]
- ----
- true
- query error db error: ERROR: CAST does not support casting from map\[text=>map\[text=>char\]\] to map\[text=>map\[text=>char\(1\)\]\]
- SELECT '{hello=>{world=>a}}'::map[text=>map[text=>char]] <@ '{hello=>c}'::map[text=>char]
- ----
- false
- query T
- SELECT '{hello=>{world=>16}}'::map[text=>map[text=>oid]] <@ '{hello=>{world=>16}}'::map[text=>map[text=>oid]]
- ----
- true
- query T
- SELECT '{hello=>{world=>nested}}'::map[text=>map[text=>text]] <@ '{hello=>{world=>nested}, extra=>{elements=>here}}'::map[text=>map[text=>text]]
- ----
- true
- ## ->
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] -> ''
- ----
- NULL
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] -> 'a'
- ----
- 1
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] -> 'b'
- ----
- 2
- query T
- SELECT '{a=>1, b=>2}'::map[text=>int] -> 'c'
- ----
- NULL
- query error operator does not exist: map\[text=>integer\] \-> integer
- SELECT '{a=>1, b=>2}'::map[text=>int] -> 1
- query T
- SELECT '{a=>true, b=>false}'::map[text=>bool] -> 'b'
- ----
- false
- query T
- SELECT ('{hello=>{world=>nested}, another=>{map=>here}}'::map[text=>map[text=>text]] -> 'missing'::text)::text
- ----
- NULL
- query T
- SELECT ('{hello=>{world=>nested}, another=>{map=>here}}'::map[text=>map[text=>text]] -> 'hello'::text)::text
- ----
- {world=>nested}
- query T
- SELECT '{hello=>{world=>nested}, another=>{map=>here}}'::map[text=>map[text=>text]] -> 'hello'::text -> 'world'::text
- ----
- nested
- query error operator is not unique: unknown \-> text
- SELECT NULL -> 'hello'::text
- # 🔬 CREATE TYPE .. AS MAP
- statement ok
- CREATE TYPE int4_map AS MAP (KEY TYPE = text, VALUE TYPE = int4);
- query T
- SELECT '{a=>1,b=>2}'::int4_map::text;
- ----
- {a=>1,b=>2}
- query T
- SELECT pg_typeof(NULL::int4_map);
- ----
- int4_map
- # 🔬🔬 Check each valid value type
- statement ok
- CREATE TYPE bool_map_c AS MAP (KEY TYPE = text, VALUE TYPE = bool);
- query T
- SELECT '{a=>true}'::bool_map_c::text
- ----
- {a=>t}
- statement ok
- CREATE TYPE int8_map_c AS MAP (KEY TYPE = text, VALUE TYPE = int8);
- query T
- SELECT '{a=>1}'::int8_map_c::text
- ----
- {a=>1}
- statement ok
- CREATE TYPE int4_map_c AS MAP (KEY TYPE = text, VALUE TYPE = int4);
- query T
- SELECT '{a=>1}'::int4_map_c::text
- ----
- {a=>1}
- statement ok
- CREATE TYPE text_map_c AS MAP (KEY TYPE = text, VALUE TYPE = text);
- query T
- SELECT '{a=>a}'::text_map_c::text
- ----
- {a=>a}
- statement ok
- CREATE TYPE float4_map_c AS MAP (KEY TYPE = text, VALUE TYPE = float4);
- query T
- SELECT '{a=>1.2}'::float4_map_c::text
- ----
- {a=>1.2}
- statement ok
- CREATE TYPE float8_map_c AS MAP (KEY TYPE = text, VALUE TYPE = float8);
- query T
- SELECT '{a=>1.2}'::float8_map_c::text
- ----
- {a=>1.2}
- statement ok
- CREATE TYPE date_map_c AS MAP (KEY TYPE = text, VALUE TYPE = date);
- query T
- SELECT '{a=>2001-01-01}'::date_map_c::text
- ----
- {a=>2001-01-01}
- statement ok
- CREATE TYPE time_map_c AS MAP (KEY TYPE = text, VALUE TYPE = time);
- query T
- SELECT '{a=>12:34:56}'::time_map_c::text
- ----
- {a=>12:34:56}
- statement ok
- CREATE TYPE timestamp_map_c AS MAP (KEY TYPE = text, VALUE TYPE = timestamp);
- query T
- SELECT '{a=>2001-01-01 12:34:56}'::timestamp_map_c::text
- ----
- {a=>"2001-01-01 12:34:56"}
- statement ok
- CREATE TYPE timestamptz_map_c AS MAP (KEY TYPE = text, VALUE TYPE = timestamptz);
- query T
- SELECT '{a=>2001-01-01 12:34:56}'::timestamptz_map_c::text
- ----
- {a=>"2001-01-01 12:34:56+00"}
- statement ok
- CREATE TYPE interval_map_c AS MAP (KEY TYPE = text, VALUE TYPE = interval);
- query T
- SELECT '{a=>1y 2d 3h 4m}'::interval_map_c::text
- ----
- {a=>"1 year 2 days 03:04:00"}
- statement ok
- CREATE TYPE numeric_map_c AS MAP (KEY TYPE = text, VALUE TYPE = numeric);
- query T
- SELECT '{a=>1.23}'::numeric_map_c::text
- ----
- {a=>1.23}
- statement ok
- CREATE TYPE jsonb_map_c AS MAP (KEY TYPE = text, VALUE TYPE = jsonb);
- query T
- SELECT '{a=>\{\"1\":2\}}'::jsonb_map_c::text;
- ----
- {a=>"{\"1\":2}"}
- # 🔬🔬 Check custom type name resolution
- statement ok
- CREATE TYPE bool AS MAP (KEY TYPE = text, VALUE TYPE = int4)
- query error invalid input syntax for type boolean: "\{a=>1\}"
- SELECT '{a=>1}'::bool;
- query T
- SELECT '{a=>1}'::public.bool::text;
- ----
- {a=>1}
- # 🔬🔬 Check subtype resolution
- # Supports qualified subtypes
- statement ok
- CREATE TYPE qualified_int4_map AS MAP (KEY TYPE = pg_catalog.text, VALUE TYPE = pg_catalog.int4)
- statement ok
- CREATE TYPE qualified_qualified_int4_map AS MAP (KEY TYPE = pg_catalog.text, VALUE TYPE = public.qualified_int4_map)
- # Supports type aliases
- statement ok
- CREATE TYPE int_map AS MAP (KEY TYPE = pg_catalog.text, VALUE TYPE = int)
- # `map_length`
- query T
- SELECT map_length('{}'::map[text=>int])
- ----
- 0
- query T
- SELECT map_length('{a=>1}'::map[text=>int])
- ----
- 1
- query T
- SELECT map_length('{a=>1, b=>2}'::map[text=>int])
- ----
- 2
- query T
- SELECT map_length(NULL::map[text=>int])
- ----
- NULL
- # map_build
- query T
- SELECT map_build(LIST[ROW('a', 1), ROW('b', 2)])::TEXT;
- ----
- {a=>1,b=>2}
- query error LIST could not convert type record\(f1: text,f2: integer\) to text
- SELECT map_build(LIST[ROW('a', 1), ROW('b')])::TEXT;
- query error function map_build\(record\(f1: integer,f2: integer\) list\) does not exist
- SELECT map_build(LIST[ROW(1, 1), ROW(2, 2)])::TEXT;
- statement ok
- CREATE TYPE r AS (f1 TEXT, f2 INT);
- query T
- SELECT map_build(LIST[ROW('a', 1), ROW('b', 2)::r])::TEXT;
- ----
- {a=>1,b=>2}
- query T
- SELECT map_build(LIST[ROW('a', 1), ROW('b', 2)]::r list)::TEXT;
- ----
- {a=>1,b=>2}
- query T
- SELECT map_build(LIST[ROW('a', 1), ROW('a', 2)]::r list)::TEXT;
- ----
- {a=>2}
- query T
- SELECT map_build(LIST[ROW('a', 2), ROW('a', 1)]::r list)::TEXT;
- ----
- {a=>1}
- # skip null keys
- query T
- SELECT map_build(LIST[ROW('a', 1), ROW(NULL, 2)]::r list)::TEXT;
- ----
- {a=>1}
- query T
- SELECT map_build(LIST[NULL]::r list)::TEXT;
- ----
- {}
- query T
- SELECT map_build(LIST[ROW('a', 1), NULL]::r list)::TEXT;
- ----
- {a=>1}
- query T
- SELECT map_build(LIST[NULL, ROW('a', 1)]::r list)::TEXT;
- ----
- {a=>1}
- query T
- SELECT map_build(LIST[ROW('a', 9), NULL, ROW('a', 1)]::r list)::TEXT;
- ----
- {a=>1}
- query error could not determine polymorphic type because input has type unknown
- SELECT map_build(NULL)::TEXT;
- query T
- SELECT map_build(NULL::r list)::TEXT;
- ----
- NULL
- statement ok
- CREATE TYPE int_list AS LIST (ELEMENT TYPE = int4);
- statement ok
- CREATE TYPE l AS (f1 TEXT, f2 int_list);
- query T
- SELECT map_build(LIST[ROW('a', LIST[1]), ROW('a', LIST[2])]::l list)::TEXT;
- ----
- {a=>{2}}
- query T
- SELECT map_build(LIST[ROW('a', LIST[2]), ROW('a', LIST[1])]::l list)::TEXT;
- ----
- {a=>{1}}
- statement ok
- CREATE TYPE int_key AS (f1 INT, f2 INT);
- query error db error: ERROR: function map_build\(int_key list\) does not exist
- SELECT map_build(LIST[ROW(1, 1), ROW(1, 2)]::int_key list)::TEXT;
- statement ok
- CREATE TYPE missing_value AS (f1 TEXT);
- query error db error: ERROR: function map_build\(missing_value list\) does not exist
- SELECT map_build(LIST[ROW('a'), ROW('a')]::missing_value list)::TEXT;
- query error db error: ERROR: function map_build\(integer\) does not exist
- SELECT map_build(1)::TEXT;
- query error db error: ERROR: function map_build\(integer list\) does not exist
- SELECT map_build(LIST[1])::TEXT;
- # map_agg
- statement ok
- CREATE TABLE t1 (a int)
- statement ok
- INSERT INTO t1 VALUES (1), (2), (3), (NULL)
- query error db error: ERROR: function map_agg\(integer, integer\) does not exist
- SELECT map_agg(k, v)::TEXT FROM (SELECT 1 AS k, 2 AS V WHERE false)
- query T
- SELECT map_agg(k, v)::TEXT FROM (SELECT 1::TEXT AS k, 2 AS V WHERE false)
- ----
- NULL
- query T
- SELECT map_agg('one', 2)::TEXT
- ----
- {one=>2}
- query error db error: ERROR: function map_agg\(integer, integer\) does not exist
- SELECT map_agg(1, 2)
- query T
- SELECT map_agg(k, v)::TEXT FROM (SELECT (a - 1)::TEXT AS k, a AS v FROM t1 WHERE a IS NOT NULL)
- ----
- {0=>1,1=>2,2=>3}
- query T
- SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('a', null), ('b', 1))
- ----
- {a=>NULL,b=>1}
- query T
- SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('b', 2), ('a', 1))
- ----
- {a=>1,b=>2}
- query T
- SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('a', 1), ('a', 2))
- ----
- {a=>2}
- query T
- SELECT map_agg(column1, column2)::TEXT FROM (VALUES ('a', 2), ('a', 1))
- ----
- {a=>2}
- query T
- SELECT map_agg(a, b ORDER BY b DESC)::TEXT FROM (VALUES ('a', 2), ('a', 1)) AS t (a, b);
- ----
- {a=>1}
- query T
- SELECT map_agg(a, b ORDER BY b ASC)::TEXT FROM (VALUES ('a', 2), ('a', 1)) AS t (a, b);
- ----
- {a=>2}
- query T
- SELECT map_agg(null, null)::TEXT
- ----
- {}
- query T
- SELECT map_agg(null, null)::TEXT
- ----
- {}
- query T
- SELECT map_agg(null, 1)::TEXT
- ----
- {}
- query T
- SELECT (map_agg(a::TEXT, a) FILTER (WHERE a IS NOT NULL))::TEXT FROM t1
- ----
- {1=>1,2=>2,3=>3}
- query T
- SELECT map_agg(a::TEXT, a)::TEXT FROM t1
- ----
- {1=>1,2=>2,3=>3}
- query T
- SELECT (map_agg(a::TEXT, a) FILTER (WHERE a = 1))::TEXT FROM t1
- ----
- {1=>1}
- # unnest
- query TT colnames
- SELECT key, value FROM unnest('{a=>NULL}'::map[text=>int4]);
- ----
- key value
- a NULL
- query TT
- SELECT upper(key), value * 100 FROM unnest('{a=>1}'::map[text=>int4]);
- ----
- A 100
- query T
- WITH v (a) AS (
- SELECT '{a=>1}'::map[text=>int]
- ),
- unnest (key, value) AS (
- SELECT (a).key, (a).value FROM (
- SELECT unnest(a) FROM v
- ) AS u (a)
- ),
- manipulate (key, value) AS (
- SELECT upper(key), value * 100 FROM unnest
- )
- SELECT map_agg(key, value)::TEXT FROM manipulate;
- ----
- {A=>100}
- query T
- SELECT unnest(NULL::map[text=>int4]);
- ----
- query T
- SELECT unnest('{a=>NULL}'::map[text=>int4]);
- ----
- (a,)
|