1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040 |
- # 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 LIST type has an uncommon OID. If tokio-postres (the driver used
- # by sqllogictest) encounters an OID it doesn't recognize (LIST in
- # this case), then it queries pg_type (a wrapper around mz_types) for
- # information about it. Our LIST type currently doesn't have an entry in
- # mz_types, so that query fails and tokio-postgres is unable to execute
- # queries with LISTs. As a workaround until LIST is reflected in pg_type,
- # we just convert everything to `text`.
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_list_n_layers = true
- ----
- COMPLETE 0
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_list_length_max = true
- ----
- COMPLETE 0
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_list_remove = true
- ----
- COMPLETE 0
- query T
- SELECT (LIST[1,2,3])::text
- ----
- {1,2,3}
- query error LIST types integer and integer list cannot be matched
- SELECT LIST[1,LIST[2,3]]
- query T
- SELECT (LIST[[1],[2,3]])::text
- ----
- {{1},{2,3}}
- query error cannot determine type of empty list
- SELECT LIST[]
- query T
- SELECT (LIST[] :: INT LIST)::text
- ----
- {}
- query T
- SELECT (LIST[null])::text
- ----
- {NULL}
- query T
- SELECT (LIST[1, null])::text
- ----
- {1,NULL}
- query T
- SELECT (LIST[1, null] :: INT LIST)::text
- ----
- {1,NULL}
- query T
- SELECT (LIST[[1, null], []] :: INT LIST LIST)::text
- ----
- {{1,NULL},{}}
- # Lists support arbitrarily deep nesting
- query T
- SELECT (LIST[[[[1], [2]]], [[[3]]]])::text
- ----
- {{{{1},{2}}},{{{3}}}}
- # List(Int) cannot be cast to List(List(Int))
- query error LIST could not convert type integer to integer list
- SELECT LIST[1, null] :: INT LIST LIST
- query T
- SELECT (LIST[1, null] :: TEXT LIST)::text
- ----
- {1,NULL}
- query T
- SELECT (LIST['foo', 'f}o', '"\', null, 'null', 'NULL'])::text
- ----
- {foo,"f}o","\"\\",NULL,null,"NULL"}
- query T
- SELECT (list[list[list['"']]])::text
- ----
- {{{"\""}}}
- query T
- SELECT (list['{1}'])::text
- ----
- {"{1}"}
- query T
- SELECT (LIST[LIST[]::text list, LIST['a', 'b'], LIST['z']])::text
- ----
- {{},{a,b},{z}}
- # 🔬 list subscripts
- # 🔬🔬 list indexes
- query R
- SELECT LIST [1, 2, 3][2]
- ----
- 2
- # exceeds maximum index
- query R
- SELECT LIST [1, 2, 3][100]
- ----
- NULL
- # negative
- query R
- SELECT LIST [1, 2, 3][-1]
- ----
- NULL
- # exceeds maximum layer
- query error cannot index into
- SELECT LIST [1, 2, 3][1][1]
- # exceeds maximum layer
- query error cannot subscript
- SELECT LIST[1,2,3][1:1][1][1:1];
- query error cannot subscript
- SELECT LIST[1,2,3][1][1:1][1];
- # 🔬🔬 list slices
- query T
- SELECT (LIST [1, 2, 3][2:3])::text
- ----
- {2,3}
- query T
- SELECT (LIST [1, 2, 3][2:])::text
- ----
- {2,3}
- query T
- SELECT (LIST [1, 2, 3][:2])::text
- ----
- {1,2}
- query T
- SELECT (LIST [1, 2, 3][:])::text
- ----
- {1,2,3}
- # start exceeds maximum index
- query T
- SELECT (LIST [1, 2, 3][100:])::text
- ----
- {}
- # end exceeds maximum index
- query T
- SELECT (LIST [1, 2, 3][:100])::text
- ----
- {1,2,3}
- # 🔬🔬 list repeated slices
- query T
- SELECT (LIST [1, 2, 3, 4, 5][3:5][1:2][:])::text
- ----
- {3,4}
- # 🔬🔬 list slices + index
- query T
- SELECT (LIST [[1],[2],[3]][2:3])[2]::text
- ----
- {3}
- # 🔬 list list subscripts
- # 🔬🔬 list list indexes
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][1])::text
- ----
- {1,2,3}
- query R
- SELECT LIST [[1, 2, 3], [4, 5]][1][3]
- ----
- 3
- # exceeds maximum index
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][100])::text
- ----
- NULL
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][1][100])::text
- ----
- NULL
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][100][1])::text
- ----
- NULL
- # exceeds maximum layer
- query error cannot index into
- SELECT LIST [[1, 2, 3], [4, 5]][1][1][1]
- # 🔬🔬 list list slices
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][2:2])::text
- ----
- {{4,5}}
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][2:])::text
- ----
- {{4,5}}
- # end exceeds maximum index
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][:100][:])::text
- ----
- {{1,2,3},{4,5}}
- # 🔬🔬🔬 index + slice
- query T
- SELECT list[list[1,2], list[3,4]][2][2:2]::text;
- ----
- {4}
- query T
- SELECT list[[1,2], list[3,4]][2][2:]::text;
- ----
- {4}
- query T
- SELECT list[[1,2], list[3,4]][2][:2]::text;
- ----
- {3,4}
- # 🔬🔬🔬 slice + index
- query T
- SELECT list[list[1,2], list[3,4]][2:2][2]::text;
- ----
- NULL
- query T
- SELECT list[list[1,2], list[3,4]][:2][2]::text;
- ----
- {3,4}
- query T
- SELECT list[[1,2], list[3,4]][2:][2]::text;
- ----
- NULL
- # 🔬🔬🔬 layered list slices patterns, linear
- query T
- SELECT list[list[1,2], list[3,4]][1:2][2:2]::text;
- ----
- {{3,4}}
- query T
- SELECT list[list[1,2], list[3,4]][:2][2:2]::text;
- ----
- {{3,4}}
- query T
- SELECT list[list[1,2], list[3,4]][:2][2:]::text;
- ----
- {{3,4}}
- query T
- SELECT list[list[1,2], list[3,4]][:][2:]::text;
- ----
- {{3,4}}
- # 🔬🔬 list list slices + index
- query T
- SELECT (LIST [[1, 2, 3], [4, 5]][2:2])[1][2]::text
- ----
- 5
- # 🔬 list list list
- # 🔬🔬 list list list indexes
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1])::text
- ----
- {{1,2},{3,4,5}}
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1][2])::text
- ----
- {3,4,5}
- query R
- SELECT LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1][2][3]
- ----
- 5
- # exceeds maximum index
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][100])::text
- ----
- NULL
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1][100])::text
- ----
- NULL
- query R
- SELECT LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1][2][100]
- ----
- NULL
- query R
- SELECT LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][100][2][3]
- ----
- NULL
- query R
- SELECT LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1][100][3]
- ----
- NULL
- # exceeds maximum layer
- query error cannot index into
- SELECT LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1][2][3][1]
- # 🔬🔬 list list list slices
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1:2])::text
- ----
- {{{1,2},{3,4,5}},{{6}}}
- # start exceeds maximum index
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][100:100])::text
- ----
- {}
- # end exceeds maximum index
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][:100])::text
- ----
- {{{1,2},{3,4,5}},{{6}},{{7,8},{9}}}
- # 🔬🔬🔬 layered list repeated slices
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][2:3][:][2:2])::text
- ----
- {{{7,8},{9}}}
- # 🔬🔬 list list list slices + index
- query T
- SELECT (LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][2:3])[2]::text
- ----
- {{7,8},{9}}
- query T
- SELECT (LIST[1, 2, 3][NULL])::text
- ----
- NULL
- query T
- SELECT (LIST[1, 2, 3][NULL:NULL])::text
- ----
- NULL
- query T
- SELECT (LIST[1, 2, 3][1:NULL])::text
- ----
- NULL
- query T
- SELECT (LIST[1, 2, 3][NULL:1])::text
- ----
- NULL
- query T
- SELECT (LIST[1, 2, 3][NULL:])::text
- ----
- NULL
- query T
- SELECT (LIST[1, 2, 3][:NULL])::text
- ----
- NULL
- query T
- SELECT (LIST[NULL][:])::text
- ----
- {NULL}
- query T
- SELECT (LIST[1, NULL, 3][:NULL])::text
- ----
- NULL
- query T
- SELECT ((LIST [[1, NULL, 3], NULL, [4, NULL, 6]]::INT LIST LIST)[2:])::text
- ----
- {NULL,{4,NULL,6}}
- # 🔬🔬 Slices and NULLs
- # NULL literals are not touched by slice operations
- query T
- SELECT ((LIST[NULL]::INT LIST)[1:1])::text
- ----
- {NULL}
- # 🔬 Empty lists expressions
- query T
- SELECT ((LIST[]::INT LIST)[1])::text
- ----
- NULL
- query T
- SELECT ((LIST[]::INT LIST)[:])::text
- ----
- {}
- query T
- SELECT ((LIST[]::INT LIST)[1:1])::text
- ----
- {}
- # 🔬 Other subscript values
- # 🔬🔬 end > start
- query T
- SELECT (LIST[1, 2, 3][2:1])::text
- ----
- {}
- # 🔬🔬 Negative values
- query T
- SELECT (LIST[1, 2, 3][-100])::text
- ----
- NULL
- query T
- SELECT (LIST[1, 2, 3][-100:])::text
- ----
- {1,2,3}
- query T
- SELECT (LIST[1, 2, 3][-100:99])::text
- ----
- {1,2,3}
- query T
- SELECT (LIST[1, 2, 3][-100:-99])::text
- ----
- {}
- query T
- SELECT (LIST[1, 2, 3][-100:-101])::text
- ----
- {}
- query T
- SELECT (LIST[1, 2, 3][:-100])::text
- ----
- {}
- # 🔬🔬 min/max
- query R
- SELECT LIST[1][9223372036854775807::bigint]
- ----
- NULL
- query R
- SELECT LIST[1][-9223372036854775807::bigint]
- ----
- NULL
- query T
- SELECT (LIST[1][9223372036854775807::bigint:9223372036854775807::bigint])::text
- ----
- {}
- query T
- SELECT (LIST[1][9223372036854775807::bigint:-9223372036854775807::bigint])::text
- ----
- {}
- query T
- SELECT (LIST[1][-9223372036854775807::bigint:9223372036854775807::bigint])::text
- ----
- {1}
- query T
- SELECT (LIST[1][-9223372036854775807::bigint:-9223372036854775807::bigint])::text
- ----
- {}
- # 🔬 Non-int subscript values
- # 🔬🔬 Ok
- query R
- SELECT LIST[1,2,3][1.4]
- ----
- 1
- query R
- SELECT LIST[1,2,3][1.5]
- ----
- 2
- query R
- SELECT LIST[1,2,3][1.5::real]
- ----
- 2
- query R
- SELECT LIST[1,2,3][1.5::float]
- ----
- 2
- query R
- SELECT LIST[1,2,3][1.5 + 1.6]
- ----
- 3
- query T
- SELECT (LIST[1,2,3][0.1 * 2 : 0.5 + 1.6])::text
- ----
- {1,2}
- query T
- SELECT (LIST[1,2,3][LIST[1][2.0 / 2]])::text
- ----
- 1
- # 🔬🔬 Err
- query error invalid input syntax for type bigint: invalid digit found in string: "dog"
- SELECT LIST[1,2,3]['dog']
- query error subscripting does not support casting from date to bigint
- SELECT LIST [[1, 2, 3], [4, 5]][DATE '2001-01-01']
- query error subscripting does not support casting from timestamp without time zone to bigint
- SELECT LIST [[1, 2, 3], [4, 5]][TIMESTAMP '2001-01-01']
- query error invalid input syntax for type bigint: invalid digit found in string: "dog"
- SELECT (LIST[1,2,3][1:'dog'])::text
- query error subscripting does not support casting from date to bigint
- SELECT LIST [[1, 2, 3], [4, 5]][1:DATE '2001-01-01']
- query error subscripting does not support casting from timestamp without time zone to bigint
- SELECT LIST [[1, 2, 3], [4, 5]][1:TIMESTAMP '2001-01-01']
- # 🔬 Built-in functions
- # 🔬🔬 list_append
- # 🔬🔬🔬 list + element
- query T
- SELECT (list_append(LIST[1, 2], 3))::text
- ----
- {1,2,3}
- # 🔬🔬🔬 list list + list (list + element)
- query T
- SELECT (list_append(LIST[[1], [2]], LIST[3]))::text
- ----
- {{1},{2},{3}}
- # 🔬🔬🔬🔬 polymorphism
- query T
- SELECT pg_typeof(list_append(LIST[1::int2], 1::int8))
- ----
- bigint list
- query T
- SELECT pg_typeof(list_append(LIST[1::int8], 1::int2))
- ----
- bigint list
- # 🔬🔬🔬 NULL elements
- # 🔬🔬🔬🔬 list + element
- query T
- SELECT (list_append(LIST[1], NULL))::text
- ----
- {1,NULL}
- query T
- SELECT (list_append(NULL, 1))::text
- ----
- {1}
- query T
- SELECT (list_append(LIST[1], NULL))::text
- ----
- {1,NULL}
- query T
- SELECT (list_append(NULL, NULL::INT))::text
- ----
- {NULL}
- query T
- SELECT (list_append(NULL::INT LIST, NULL))::text
- ----
- {NULL}
- # 🔬🔬🔬🔬 list list + list (list + element)
- query T
- SELECT (list_append(LIST[[1]], NULL))::text
- ----
- {{1},NULL}
- query T
- SELECT (list_append(NULL, LIST[1]))::text
- ----
- {{1}}
- query T
- SELECT (list_append(NULL::INT LIST LIST, NULL))::text
- ----
- {NULL}
- query T
- SELECT (list_append(NULL, NULL::INT LIST))::text
- ----
- {NULL}
- # 🔬🔬🔬 errors
- query T
- SELECT list_append(NULL, NULL)::text
- ----
- {NULL}
- query error invalid input syntax for type integer
- SELECT list_append(LIST[1], 'a')::text
- query error db error: ERROR: function list_append\(integer list, integer list\) does not exist
- SELECT list_append(LIST[1], LIST[2])
- query error db error: ERROR: function list_append\(integer, integer list\) does not exist
- SELECT list_append(1, LIST[1])
- # 🔬🔬 list_cat
- # 🔬🔬🔬 list + list
- query T
- SELECT (list_cat(LIST[1, 2], LIST[3, 4]))::text
- ----
- {1,2,3,4}
- query T
- SELECT (list_cat(LIST[[1]], LIST[[2]]))::text
- ----
- {{1},{2}}
- # 🔬🔬🔬 NULL elements
- # 🔬🔬🔬🔬 list + list
- query T
- SELECT (list_cat(LIST[1], NULL))::text
- ----
- {1}
- query T
- SELECT (list_cat(LIST[1], NULL))::text
- ----
- {1}
- query T
- SELECT (list_cat(NULL, LIST[1]))::text
- ----
- {1}
- query T
- SELECT (list_cat(NULL::INT LIST, NULL))::text
- ----
- NULL
- query T
- SELECT (list_cat(NULL, NULL::INT LIST))::text
- ----
- NULL
- # 🔬🔬🔬🔬 polymorphism
- query T
- SELECT pg_typeof(list_cat(LIST[1::int2], LIST[1::int8]))
- ----
- bigint list
- query T
- SELECT pg_typeof(list_cat(LIST[1::int8], LIST[1::int2]))
- ----
- bigint list
- # 🔬🔬🔬 errors
- query error
- SELECT list_cat(NULL, NULL)
- query error
- SELECT list_cat('a', LIST[1])
- query error
- SELECT list_cat(LIST[1], LIST[[2]])
- # 🔬🔬 list_n_layers
- query R
- SELECT list_n_layers(LIST [1, 2, 3])
- ----
- 1
- query R
- SELECT list_n_layers(LIST []::INT LIST)
- ----
- 1
- query R
- SELECT list_n_layers(LIST[[1],[1]])
- ----
- 2
- query R
- SELECT list_n_layers(LIST [[[1], [1]], [[1]]])
- ----
- 3
- # 🔬🔬🔬 slices
- query R
- SELECT list_n_layers(LIST[[1],[1]][1:1])
- ----
- 2
- query R
- SELECT list_n_layers(LIST [[[1], [1]], [[1]]][1:2])
- ----
- 3
- # 🔬🔬🔬 interior lists
- query R
- SELECT list_n_layers(LIST[[1],[1]][1])
- ----
- 1
- query R
- SELECT list_n_layers(LIST [[[1], [1]], [[1]]][1])
- ----
- 2
- query R
- SELECT list_n_layers(LIST [[[1], [1]], [[1]]][1][1])
- ----
- 1
- # 🔬🔬🔬 NULL elements
- query R
- SELECT list_n_layers(LIST[NULL]::INT LIST)
- ----
- 1
- query R
- SELECT list_n_layers(LIST[NULL]::INT LIST LIST)
- ----
- 2
- query R
- SELECT list_n_layers(LIST[[1], NULL]::INT LIST LIST)
- ----
- 2
- query R
- SELECT list_n_layers((LIST[[1],NULL]::INT LIST LIST)[2])
- ----
- 1
- query error could not determine polymorphic type because input has type unknown
- SELECT list_n_layers(NULL)
- # 🔬🔬 list_length
- query R
- SELECT list_length(LIST [1])
- ----
- 1
- query R
- SELECT list_length(LIST [1, 1])
- ----
- 2
- query R
- SELECT list_length(LIST[[1],[1]])
- ----
- 2
- query R
- SELECT list_length(LIST [[[1], [1]], [[1]]])
- ----
- 2
- query R
- SELECT list_length(LIST []::INT LIST)
- ----
- 0
- # 🔬🔬🔬 slices
- query R
- SELECT list_length(LIST[[1],[1]][1:1])
- ----
- 1
- query R
- SELECT list_length(LIST [[[1, 2], [3, 4, 5]], [[6]], [[7, 8], [9]]][1:2])
- ----
- 2
- # 🔬🔬🔬 indexing operations
- query R
- SELECT list_length(LIST [[[1], [1]], [[1]]][1])
- ----
- 2
- query R
- SELECT list_length(LIST [[[1], [1]], [[1]]][1][1])
- ----
- 1
- # 🔬🔬🔬 NULL elements
- query R
- SELECT list_length(LIST[1, NULL]::INT LIST)
- ----
- 2
- query R
- SELECT list_length(LIST[[1],NULL]::INT LIST LIST)
- ----
- 2
- query R
- SELECT list_length((LIST[[1],NULL]::INT LIST LIST)[2])
- ----
- NULL
- query error could not determine polymorphic type because input has type unknown
- SELECT list_length(NULL)
- # 🔬🔬 list_length_max
- query R
- SELECT list_length_max(LIST [1, 2, 3], 1)
- ----
- 3
- query R
- SELECT list_length_max(LIST [1, 2, 3, 4], 1)
- ----
- 4
- query R
- SELECT list_length_max(LIST[[1],[2,3]], 2)
- ----
- 2
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]], 2)
- ----
- 2
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]], 3)
- ----
- 3
- query R
- SELECT list_length_max(LIST []::INT LIST, 1)
- ----
- 0
- query R
- SELECT list_length_max(LIST [[]]::INT LIST LIST, 2)
- ----
- 0
- # 🔬🔬🔬 slices
- query R
- SELECT list_length_max(LIST[[1], [2]][1:1], 1)
- ----
- 1
- query R
- SELECT list_length_max(LIST[[1], [2, 3]][2:2], 2)
- ----
- 2
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]][1:2], 1)
- ----
- 2
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]][1:1], 2)
- ----
- 2
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]][1:1], 3)
- ----
- 3
- # 🔬🔬🔬 indexing operations
- query R
- SELECT list_length_max(LIST[[1], [2, 3]][2], 1)
- ----
- 2
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]][1], 1)
- ----
- 2
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]][1], 2)
- ----
- 3
- query R
- SELECT list_length_max(LIST [[[1, 2, 3], [4]], [[5]]][1][2], 1)
- ----
- 1
- # 🔬🔬🔬 NULL elements
- query R
- SELECT list_length_max(NULL::INT LIST, 1)
- ----
- NULL
- query R
- SELECT list_length_max(LIST[1, NULL, 3]::INT LIST, 1)
- ----
- 3
- query R
- SELECT list_length_max(LIST[[1],NULL]::INT LIST LIST, 1)
- ----
- 2
- query R
- SELECT list_length_max((LIST[[1],NULL]::INT LIST LIST), 2)
- ----
- 1
- query T
- SELECT (list_length_max((LIST[NULL]::INT LIST LIST), 2))::text
- ----
- NULL
- # 🔬🔬🔬 errors
- query error invalid layer: 2; must use value within \[1, 1\]
- SELECT list_length_max((LIST[1]::INT LIST), 2)
- query error invalid layer: 2; must use value within \[1, 1\]
- SELECT list_length_max((LIST[NULL]::INT LIST), 2)
- query error invalid layer: 3; must use value within \[1, 2\]
- SELECT list_length_max((LIST[NULL]::INT LIST LIST), 3)
- query error invalid layer: 0; must use value within \[1, 1\]
- SELECT list_length_max((LIST[1]::INT LIST), 0)
- query error invalid layer: -1; must use value within \[1, 1\]
- SELECT list_length_max((LIST[1]::INT LIST), -1)
- query error invalid layer: -1; must use value within \[1, 1\]
- SELECT list_length_max((LIST[1]::INT LIST), LIST[-1][1])
- query error could not determine polymorphic type because input has type unknown
- SELECT list_length_max(NULL, 1)
- # 🔬🔬 list_prepend
- # 🔬🔬🔬 element + list
- query T
- SELECT (list_prepend(1, LIST[2, 3]))::text
- ----
- {1,2,3}
- # 🔬🔬🔬 list + list list (element + list)
- query T
- SELECT (list_prepend(LIST[1], LIST[[2], [3]]))::text
- ----
- {{1},{2},{3}}
- # 🔬🔬🔬🔬 polymorphism
- query T
- SELECT pg_typeof(list_prepend(1::int2, LIST[1::int8]))
- ----
- bigint list
- query T
- SELECT pg_typeof(list_prepend(1::int8, LIST[1::int2]))
- ----
- bigint list
- # 🔬🔬🔬 NULL elements
- # 🔬🔬🔬🔬 element + list
- query T
- SELECT (list_prepend(NULL, LIST[1]))::text
- ----
- {NULL,1}
- query T
- SELECT (list_prepend(NULL::INT, LIST[1]))::text
- ----
- {NULL,1}
- query T
- SELECT (list_prepend(1, NULL::INT LIST))::text
- ----
- {1}
- query T
- SELECT (list_prepend(NULL::INT, NULL::INT LIST))::text
- ----
- {NULL}
- # 🔬🔬🔬🔬 list + list list (element + list)
- query T
- SELECT (list_prepend(NULL, LIST[[1]]))::text
- ----
- {NULL,{1}}
- query T
- SELECT (list_prepend(LIST[1], NULL))::text
- ----
- {{1}}
- query T
- SELECT (list_prepend(NULL::INT LIST, NULL))::text
- ----
- {NULL}
- query T
- SELECT (list_prepend(NULL, NULL::INT LIST LIST))::text
- ----
- {NULL}
- # 🔬🔬🔬 errors
- query error
- SELECT list_prepend(NULL, NULL)
- query error
- SELECT list_prepend('a', LIST[1])
- query error
- SELECT list_prepend(LIST[1], LIST[2])
- query error
- SELECT list_prepend(LIST[1], 1)
- # 🔬🔬 unnest
- query I rowsort
- SELECT unnest FROM unnest(LIST[1,2,3])
- ----
- 1
- 2
- 3
- query T rowsort
- SELECT unnest::text FROM unnest(LIST[[1,2],[3]])
- ----
- {1,2}
- {3}
- query T
- SELECT unnest::text FROM unnest(LIST[NULL])
- ----
- NULL
- query I rowsort
- SELECT unnest FROM unnest(LIST[NULL,1])
- ----
- NULL
- 1
- query T
- SELECT unnest::text FROM unnest(NULL::int list)
- ----
- query error db error: ERROR: function unnest\(unknown\) is not unique
- SELECT * FROM unnest(NULL)
- # 🔬 List casts
- # 🔬🔬 Between lists
- # 🔬🔬🔬 Unlayered lists
- query T
- SELECT (LIST['1']::int list)::text
- ----
- {1}
- query T
- SELECT (LIST[NULL]::int list)::text
- ----
- {NULL}
- query T
- SELECT (LIST[NULL, '1']::int list)::text
- ----
- {NULL,1}
- query T
- SELECT (LIST[1.4, 1.5]::int list)::text
- ----
- {1,2}
- query T
- SELECT (LIST[1.4::float, -1.5::float]::int list)::text
- ----
- {1,-2}
- query T
- SELECT (NULL::int list)::text
- ----
- NULL
- # 🔬🔬🔬🔬 Errors
- query error invalid input syntax for type integer: invalid digit found in string: "dog"
- SELECT (LIST['1', 'dog']::int list)::text
- query error LIST could not convert type date to integer
- SELECT LIST[DATE '2008-02-01']::int list
- # 🔬🔬🔬 Layered and jagged lists
- query T
- SELECT (LIST[[1.4::float], [-1.5::float, 2.5::float]]::int list list)::text
- ----
- {{1},{-2,2}}
- query T
- SELECT (LIST[[1.4::float], [-1.5::float, 2.5::float], NULL::float list]::int list list)::text
- ----
- {{1},{-2,2},NULL}
- # 🔬🔬🔬 Non-numeric types
- query T
- SELECT (LIST[TIMESTAMP '2008-02-01 15:04:05', TIMESTAMP '2007-02-01 15:04:05']::date list)::text
- ----
- {2008-02-01,2007-02-01}
- query T
- SELECT (LIST[DATE '2008-02-01', DATE '2007-02-01']::timestamp list)::text
- ----
- {"2008-02-01 00:00:00","2007-02-01 00:00:00"}
- # 🔬🔬 list to text
- query T
- SELECT (LIST['1']::text)::text
- ----
- {1}
- query T
- SELECT (LIST[NULL]::text)::text
- ----
- {NULL}
- query T
- SELECT (LIST[NULL, '1']::text)::text
- ----
- {NULL,1}
- query T
- SELECT (LIST[NULL, 1]::text)::text
- ----
- {NULL,1}
- query T
- SELECT (LIST[NULL, '1']::text)::text
- ----
- {NULL,1}
- query T
- SELECT (LIST[NULL, 1]::text)::text
- ----
- {NULL,1}
- query T
- SELECT (LIST[1.4, -1.5]::text)::text
- ----
- {1.4,-1.5}
- query T
- SELECT (LIST[[1.4], [-1.5]]::text)::text
- ----
- {{1.4},{-1.5}}
- query T
- SELECT (LIST[[1.4::float], [-1.5::float, 2.5::float]]::text)::text
- ----
- {{1.4},{-1.5,2.5}}
- # Show that these are actually strings
- query I
- SELECT length(LIST['1','2']::text)
- ----
- 5
- query error db error: ERROR: function length\(text list\) does not exist
- SELECT length(LIST['1','2'])
- # 🔬🔬 text to list
- # 🔬🔬🔬 text to int list
- query I
- SELECT * FROM unnest('{1,2,3}'::int list)
- ----
- 1
- 2
- 3
- query T rowsort
- SELECT unnest::text FROM unnest('{{1,2},{3}}'::int list list)
- ----
- {1,2}
- {3}
- query T rowsort
- SELECT unnest::text FROM unnest('{{{1},{2}},{{3}}}'::int list list list)
- ----
- {{1},{2}}
- {{3}}
- query T
- SELECT ('{NULL}'::int list)::text
- ----
- {NULL}
- query T
- SELECT ('{}'::int list)::text
- ----
- {}
- # 🔬🔬🔬 text to text list
- query T
- SELECT ('{"a"," b","c ", d,e }'::text list)::text
- ----
- {a," b","c ",d,e}
- query T
- SELECT ('{{"a"," b","c "},{ d,e }}'::text list list)::text
- ----
- {{a," b","c "},{d,e}}
- # NULL-esque string handling
- query TI rowsort
- SELECT unnest, length(unnest) from unnest('{NULL,nUlL,"NULL"}'::text list) ORDER BY length
- ----
- NULL 4
- NULL NULL
- NULL NULL
- # Test some escape values
- query TI rowsort
- SELECT unnest, length(unnest) from unnest('{"a,b","\\","a\\b\"c\\d\""}'::text list) ORDER BY length
- ----
- \ 1
- a,b 3
- a\b"c\d" 8
- query T
- SELECT ('{NULL}'::text list)::text
- ----
- {NULL}
- query T
- SELECT ('{}'::text list)::text
- ----
- {}
- # 🔬🔬🔬🔬 Quote escapes
- # Preserves leading and trailing spaces within escape, but not outside of escape
- query T
- SELECT ('{ " a " }'::text list)::text
- ----
- {" a "}
- # Escapes content
- query T
- SELECT ('{"} \""}'::text list)::text
- ----
- {"} \""}
- query T
- SELECT ('{"{a}"}'::text list)::text
- ----
- {"{a}"}
- query T
- SELECT ('{"",""}'::text list)::text
- ----
- {"",""}
- # This demos that the double quotes from the input are actually stripped
- query TI
- SELECT unnest, length(unnest) FROM unnest('{"",""}'::text list)
- ----
- (empty) 0
- (empty) 0
- # Mixture of escape and non-escaped elements
- query T
- SELECT ('{"{",a}'::text list)::text
- ----
- {"{",a}
- # Escape gets reset after each element
- query T
- SELECT ('{"{",\\}'::text list)::text
- ----
- {"{","\\"}
- # Elements within double quotes gets unescaped before being cast
- query T
- SELECT ('{{a, "", "\""}, "{a, \"\", \"\\\"\"}"}'::text list list)::text
- ----
- {{a,"","\""},{a,"","\""}}
- # Unquoted elements cannot have special characters interleaved within them
- query error invalid input syntax for type list: malformed literal; must escape special character '"'
- SELECT ('{a"b"}'::text list)::text
- query error invalid input syntax for type list: malformed literal; must escape special character '\{'
- SELECT ('{a{b}'::text list)::text
- query error invalid input syntax for type list: malformed array literal; contains 'b' after terminal '\}'
- SELECT ('{a}b}'::text list)::text
- # No non-whitespace characters after the escape
- query error invalid input syntax for type list: expected ',' or '\}', got 'b'
- SELECT ('{"a"b}'::text list)::text
- query error invalid input syntax for type list: expected ',' or '\}', got '"'
- SELECT ('{""""}'::text list)::text
- query error invalid input syntax for type list: expected ',' or '\}', got '"'
- SELECT ('{"""}'::text list)::text
- # 🔬🔬🔬🔬 Unquoted escapes
- # Escapes work on special characters
- query T
- SELECT ('{\{, \}, \", \,}'::text list)::text
- ----
- {"{","}","\"",","}
- # Preserves escaped white space
- query T
- SELECT ('{\ a}'::text list)::text
- ----
- {" a"}
- query T
- SELECT ('{a \ }'::text list)::text
- ----
- {"a "}
- query T
- SELECT ('{\ a \ }'::text list)::text
- ----
- {" a "}
- query T
- SELECT ('{a \ \ }'::text list)::text
- ----
- {"a "}
- # list lists are only escaped once; if they were escaped at each level, they
- # would no longer escape leading or trailing whitespace
- query T
- SELECT ('{{\ a}}'::text list list)::text
- ----
- {{" a"}}
- query T
- SELECT ('{{a \ }}'::text list list)::text
- ----
- {{"a "}}
- query T
- SELECT ('{{\ a \ }}'::text list list)::text
- ----
- {{" a "}}
- query T
- SELECT ('{{a \ \ }}'::text list list)::text
- ----
- {{"a "}}
- # Unescaped space is trimmed
- query T
- SELECT ('{\ \ a , b \ }'::text list)::text
- ----
- {" a","b "}
- query T
- SELECT ('{ a \ \ , \ b }'::text list)::text
- ----
- {"a "," b"}
- query T
- SELECT ('{a \ \ , \ b }'::text list)::text
- ----
- {"a "," b"}
- query T
- SELECT ('{ { a \ } }'::text list list)::text
- ----
- {{"a "}}
- query T
- SELECT ('{ {a \ } }'::text list list)::text
- ----
- {{"a "}}
- query T
- SELECT ('{ \ a}'::text list)::text
- ----
- {" a"}
- # Leading/trailing escaped special characters are honored
- query T
- SELECT ('{\"a\"}'::text list)::text
- ----
- {"\"a\""}
- query T
- SELECT ('{\{a\}}'::text list)::text
- ----
- {"{a}"}
- # Escaping backslashes works
- query T
- SELECT ('{ \\\\a\\\\ }'::text list)::text
- ----
- {"\\\\a\\\\"}
- # Escaping a non-special character has no visible effect on the output; normal
- # whitespacing rules apply
- query T
- SELECT ('{ \a }'::text list)::text
- ----
- {a}
- # Escaping a character in NULL turns it into the string "NULL"
- query T
- SELECT ('{N\ULL}'::text list)::text
- ----
- {"NULL"}
- # Escaping terminal character means it isn't available to close the list
- query error invalid input syntax for type list: unterminated element
- SELECT ('{\}'::text list)::text
- query error invalid input syntax for type list: unexpected end of input
- SELECT ('{{\}}'::text list list)::text
- # 🔬🔬🔬 text to other lists
- query T
- SELECT ('{1y 2d 3h, "4y 5d 6h"}'::interval list)::text
- ----
- {"1 year 2 days 03:00:00","4 years 5 days 06:00:00"}
- query T
- SELECT ('{2001-02-03, "2004-05-06"}'::date list)::text
- ----
- {2001-02-03,2004-05-06}
- query T
- SELECT ('{NULL}'::date list)::text
- ----
- {NULL}
- # 🔬🔬🔬 misc. checks
- # Elements within double quotes have their double quotes before being cast to
- # their element type
- query T
- SELECT ('{"1"}'::int list)::text
- ----
- {1}
- query T
- SELECT ('{"1"}'::text list)::text
- ----
- {1}
- query T
- SELECT ('{"{}"}'::int list list)::text
- ----
- {{}}
- query T
- SELECT ('{"{}"}'::text list list)::text
- ----
- {{}}
- # Empty lists
- query T
- SELECT ('{ }'::text list)::text
- ----
- {}
- query T
- SELECT ('{ { } }'::text list list)::text
- ----
- {{}}
- # 🔬🔬🔬 errors
- # Empty string is invalid
- query error invalid input syntax for type list: expected '\{', found empty string: ""
- SELECT (''::text list)::text
- # Not a list
- query error invalid input syntax for type list: expected '\{', found 1: "1"
- SELECT ('1'::int list)::text
- # Invalid element
- query error invalid input syntax for type list: invalid input syntax for type integer: invalid digit found in string: "a": "\{a\}"
- SELECT ('{a}'::int list)::text
- # 'NULL' isn't a valid string for a list; just use unescaped NULL
- query error invalid input syntax for type list: expected '\{', found N: "NULL"
- SELECT ('NULL'::int list)::text
- # Too many leading brackets
- query error invalid input syntax for type list: unescaped '\{' at beginning of element
- SELECT ('{{1}}'::int list)::text
- # Too many leading brackets
- query error invalid input syntax for type list: unescaped '\{' at beginning of element
- SELECT ('{{1}'::int list)::text
- query error invalid input syntax for type list: unexpected end of input: "\{\{1\}"
- SELECT ('{{1}'::int list list)::text
- # Too many following brackets
- query error invalid input syntax for type list: malformed array literal; contains '\}' after terminal '\}': "\{1\}\}"
- SELECT ('{1}}'::int list)::text
- query error invalid input syntax for type list: invalid input syntax for type list: expected '\{', found 1: "1": "\{1\}\}"
- SELECT ('{1}}'::int list list)::text
- # Cannot have commas followed or preceded by empty elements
- query error invalid input syntax for type list: malformed literal; missing element: "\{a, \}"
- SELECT ('{a, }'::text list)::text
- query error invalid input syntax for type list: malformed literal; missing element: "\{ ,a\}"
- SELECT ('{ ,a}'::text list)::text
- # 🔬🔬🔬🔬 homogeneous text lists
- query error char list not yet supported
- SELECT (LIST['ab'::char, 'cd'::varchar, 'ef'::text])::text
- query T
- SELECT (LIST['cd'::varchar, 'ef'::text])::text
- ----
- {cd,ef}
- # 🔬🔬 char lists
- # ensures that the list type does not pick up an elements' typmod
- query error char list not yet supported
- SELECT LIST['abc'::char(1), 'abc'::char(2), 'abc'::char(3)]::text;
- query error char list not yet supported
- SELECT LIST['abc'::char(3), 'abc'::char(2), 'abc'::char(1)]::text;
- query error char list not yet supported
- SELECT pg_typeof(LIST['abc'::char(1), 'abc'::char(2), 'abc'::char(3)]);
- # 🔬🔬 varchar lists
- # ensures that the list type does not pick up an elements' typmod
- query T
- SELECT LIST['abc'::varchar(1), 'abc'::varchar(2), 'abc'::varchar(3)]::text;
- ----
- {a,ab,abc}
- query T
- SELECT LIST['abc'::varchar(3), 'abc'::varchar(2), 'abc'::varchar(1)]::text;
- ----
- {abc,ab,a}
- query T
- SELECT pg_typeof(LIST['abc'::varchar(1), 'abc'::varchar(2), 'abc'::varchar(3)]);
- ----
- character varying list
- # 🔬 Built-in operations
- # 🔬🔬 concatenation (||)
- # 🔬🔬🔬 list + list
- query T
- SELECT (LIST[1, 2] || LIST[3, 4])::text
- ----
- {1,2,3,4}
- query T
- SELECT (LIST[[1], [2]] || LIST[[3], [4]])::text
- ----
- {{1},{2},{3},{4}}
- # Concatenation properly casts text to appropriate list type
- query T
- SELECT (LIST[1] || '{2}')::text
- ----
- {1,2}
- # Differently scaled numerics are implicitly castable to one another
- query T
- SELECT ('{1.2}'::numeric(38,5) list || '{2.3}'::numeric(38,0) list)::text;
- ----
- {1.2,2}
- # ...including on multiple layers
- query T
- SELECT ('{{1.2}}'::numeric(38,5) list list || '{{2.3}}'::numeric(38,0) list list)::text;
- ----
- {{1.2},{2}}
- # Determining common list element type for numerics does not rescale values
- query T
- SELECT LIST[1.234::numeric(39,2), 2.345]::text;
- ----
- {1.23,2.345}
- query T
- SELECT LIST[1.234::numeric(39,2), 2.345]::numeric(39, 2) list::text;
- ----
- {1.23,2.35}
- # 🔬🔬🔬🔬 polymorphic
- query T
- SELECT pg_typeof(LIST[1::int2] || LIST[2::int8])
- ----
- bigint list
- query T
- SELECT pg_typeof(LIST[1::int8] || LIST[2::int2])
- ----
- bigint list
- # 🔬🔬🔬 list + element
- query T
- SELECT (LIST[1, 2] || 3)::text
- ----
- {1,2,3}
- query T
- SELECT ('{1.2}'::numeric(38,5) list || '2.3'::numeric(38,0))::text;
- ----
- {1.2,2}
- # 🔬🔬🔬🔬 polymorphic
- query T
- SELECT pg_typeof(LIST[1::int2] || 2::int8)
- ----
- bigint list
- query T
- SELECT pg_typeof(LIST[1::int8] || 2::int2)
- ----
- bigint list
- # 🔬🔬🔬 element + list
- query T
- SELECT (1 || LIST[2, 3])::text
- ----
- {1,2,3}
- query T
- SELECT ('1.2'::numeric(38,5) || '{2.3}'::numeric(38,0) list)::text;
- ----
- {1.2,2}
- # 🔬🔬🔬🔬 polymorphic
- query T
- SELECT pg_typeof(1::int2 || LIST[2::int8])
- ----
- bigint list
- query T
- SELECT pg_typeof(1::int8 || LIST[2::int2])
- ----
- bigint list
- # 🔬🔬🔬 list list + list (list + element)
- query T
- SELECT (LIST[[1], [2]] || LIST[3])::text
- ----
- {{1},{2},{3}}
- query T
- SELECT ('{{1.2}}'::numeric(38,5) list list || '{2.3}'::numeric(38,0) list)::text;
- ----
- {{1.2},{2}}
- # 🔬🔬🔬 list + list list (element + list)
- query T
- SELECT (LIST[1] || LIST[[2], [3]])::text
- ----
- {{1},{2},{3}}
- query T
- SELECT ('{1.2}'::numeric(38,5) list || '{{2.3}}'::numeric(38,0) list list)::text;
- ----
- {{1.2},{2}}
- # 🔬🔬🔬 NULL elements
- # 🔬🔬🔬🔬 list + list
- # Our type system resolves `list || NULL` as a form of `list || list`
- query T
- SELECT (LIST[1] || NULL)::text
- ----
- {1}
- query T
- SELECT (NULL || LIST[1])::text
- ----
- {1}
- query T
- SELECT (LIST[1] || NULL::INT LIST)::text
- ----
- {1}
- query T
- SELECT ( NULL::INT LIST || LIST[1])::text
- ----
- {1}
- query T
- SELECT (NULL::INT LIST || NULL::INT LIST)::text
- ----
- NULL
- # 🔬🔬🔬🔬 list + element
- query T
- SELECT (LIST[1] || NULL::INT)::text
- ----
- {1,NULL}
- query T
- SELECT (NULL::INT LIST || 1)::text
- ----
- {1}
- query T
- SELECT (NULL::INT LIST || NULL::INT)::text
- ----
- {NULL}
- # 🔬🔬🔬🔬 element + list
- query T
- SELECT (NULL::INT || LIST[1])::text
- ----
- {NULL,1}
- query T
- SELECT (1 || NULL::INT LIST)::text
- ----
- {1}
- query T
- SELECT (NULL::INT || NULL::INT LIST)::text
- ----
- {NULL}
- # 🔬🔬🔬🔬 list list + list (list + element)
- query T
- SELECT (LIST[[1]] || NULL::INT LIST)::text
- ----
- {{1},NULL}
- query T
- SELECT (NULL::INT LIST LIST || LIST[1])::text
- ----
- {{1}}
- query T
- SELECT (NULL::INT LIST LIST || NULL::INT LIST)::text
- ----
- {NULL}
- # 🔬🔬🔬🔬 list + list list (element + list)
- query T
- SELECT (NULL::INT LIST || LIST[[1]])::text
- ----
- {NULL,{1}}
- query T
- SELECT (LIST[1] || NULL::INT LIST LIST)::text
- ----
- {{1}}
- query T
- SELECT (NULL::INT LIST || NULL::INT LIST LIST)::text
- ----
- {NULL}
- # 🔬🔬🔬 errors
- query error no overload for int4 list || unknown: Cannot concatenate int4 list and string list
- SELECT LIST[1] || LIST['a']
- query error no overload for int4 list || unknown: Cannot concatenate int4 list and string
- SELECT LIST[1] || 'a'
- query error no overload for unknown || int4 list: Cannot concatenate string list and int4 list
- SELECT LIST[NULL] || LIST[1]
- query error no overload for unknown || int4 list: Cannot concatenate string list list and int4 list
- SELECT LIST[[NULL]] || LIST[1]
- query error no overload for int4 list list list || int4 list: Cannot concatenate int4 list list list and int4 list
- SELECT LIST[[[1]]] || LIST[2]
- # Literal text cannot be implicitly cast to list
- query error no overload for int4 list || string: arguments cannot be implicitly cast to any implementation's parameters; try providing explicit casts
- SELECT LIST[1] || '{2}'::text
- # Two lists containing implicitly castable element types are not implicitly castable to one another
- query error no overload for f32 list || f64 list: arguments cannot be implicitly cast to any implementation's parameters; try providing explicit casts
- SELECT '{1}'::float4 list || '{2}'::float8 list
- # 🔬🔬 equality (=)
- # 🔬🔬🔬 list = list
- query T
- SELECT LIST[1, 2] = LIST[1, 2]
- ----
- true
- query T
- SELECT LIST[1, 2] = LIST[1, 3]
- ----
- false
- query T
- SELECT LIST[[1], [2]] = LIST[[1], [2]]
- ----
- true
- query T
- SELECT LIST[[1], [2]] = LIST[[1], [3]]
- ----
- false
- # Equality properly casts text to appropriate list type
- query T
- SELECT LIST[1] = '{1}'
- ----
- true
- query T
- SELECT LIST[1] = '{2}'
- ----
- false
- # 🔬🔬🔬 errors
- query error db error: ERROR: operator does not exist: integer list = text list
- SELECT LIST[1] = LIST['a']
- query error db error: ERROR: operator does not exist: text list = integer list
- SELECT LIST[NULL] = LIST[1]
- query error db error: ERROR: operator does not exist: text list list = integer list
- SELECT LIST[[NULL]] = LIST[1]
- query error db error: ERROR: operator does not exist: integer list list list = integer list
- SELECT LIST[[[1]]] = LIST[2]
- # Literal text cannot be implicitly cast to list
- query error db error: ERROR: operator does not exist: integer list = text
- SELECT LIST[1] = '{2}'::text
- # Two lists containing implicitly castable element types are not implicitly castable to one another
- query error db error: ERROR: operator does not exist: real list = double precision list
- SELECT '{1}'::float4 list = '{2}'::float8 list
- # 🔬 CREATE TYPE .. AS LIST
- query error type "pg_enum" does not exist
- CREATE TYPE tbl_list AS LIST (ELEMENT TYPE=pg_enum)
- query error CREATE TYPE ... AS LIST option ELEMENT 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_list AS LIST (ELEMENT TYPE=int4 list)
- statement ok
- CREATE TYPE int4_list_c AS LIST (ELEMENT TYPE = int4);
- query T
- SELECT '{1,2}'::int4_list_c::text;
- ----
- {1,2}
- query T
- SELECT oid >= 20000 FROM pg_type WHERE typname = 'int4_list_c';
- ----
- true
- query T
- SELECT '{{1,2}}'::int4_list_c list::text
- ----
- {{1,2}}
- query T
- SELECT pg_typeof(NULL::int4_list_c);
- ----
- int4_list_c
- statement ok
- CREATE TYPE int4_list_list_c AS LIST (ELEMENT TYPE = int4_list_c);
- query T
- SELECT '{{1,2}}'::int4_list_list_c::text;
- ----
- {{1,2}}
- query error type "bool list" does not exist
- CREATE TYPE nested_list AS LIST (ELEMENT TYPE = "bool list")
- query error db error: ERROR: cannot reference pseudo type mz_catalog\.list
- CREATE TYPE nested_list AS LIST (ELEMENT TYPE = list)
- # 🔬🔬 Check each valid non-array element type
- statement ok
- CREATE TYPE bool_list_c AS LIST (ELEMENT TYPE=bool);
- query T
- SELECT '{true}'::bool_list_c::text
- ----
- {t}
- statement ok
- CREATE TYPE int8_list_c AS LIST (ELEMENT TYPE=int8);
- query T
- SELECT '{1,2}'::int8_list_c::text
- ----
- {1,2}
- query T
- SELECT '{1,2}'::int4_list_c::text
- ----
- {1,2}
- statement ok
- CREATE TYPE text_list_c AS LIST (ELEMENT TYPE=text);
- query T
- SELECT '{a,b}'::text_list_c::text
- ----
- {a,b}
- statement ok
- CREATE TYPE float4_list_c AS LIST (ELEMENT TYPE=float4);
- query T
- SELECT '{1.2,2.3}'::float4_list_c::text
- ----
- {1.2,2.3}
- statement ok
- CREATE TYPE float8_list_c AS LIST (ELEMENT TYPE=float8);
- query T
- SELECT '{1.2,2.3}'::float8_list_c::text
- ----
- {1.2,2.3}
- statement ok
- CREATE TYPE date_list_c AS LIST (ELEMENT TYPE=date);
- query T
- SELECT '{2001-01-01}'::date_list_c::text
- ----
- {2001-01-01}
- statement ok
- CREATE TYPE time_list_c AS LIST (ELEMENT TYPE=time);
- query T
- SELECT '{12:34:56}'::time_list_c::text
- ----
- {12:34:56}
- statement ok
- CREATE TYPE timestamp_list_c AS LIST (ELEMENT TYPE=timestamp);
- query T
- SELECT '{2001-01-01 12:34:56}'::timestamp_list_c::text
- ----
- {"2001-01-01 12:34:56"}
- statement ok
- CREATE TYPE timestamptz_list_c AS LIST (ELEMENT TYPE=timestamptz);
- query T
- SELECT '{2001-01-01 12:34:56}'::timestamptz_list_c::text
- ----
- {"2001-01-01 12:34:56+00"}
- statement ok
- CREATE TYPE interval_list_c AS LIST (ELEMENT TYPE=interval);
- query T
- SELECT '{1y 2d 3h 4m}'::interval_list_c::text
- ----
- {"1 year 2 days 03:04:00"}
- statement ok
- CREATE TYPE numeric_list_c AS LIST (ELEMENT TYPE=numeric);
- query T
- SELECT '{1.23,2.34}'::numeric_list_c::text
- ----
- {1.23,2.34}
- statement ok
- CREATE TYPE jsonb_list_c AS LIST (ELEMENT TYPE=jsonb);
- query T
- SELECT '{\{\"1\":2\}}'::jsonb_list_c::text;
- ----
- {"{\"1\":2}"}
- # 🔬🔬 Check custom type name resolution
- statement ok
- CREATE TYPE bool AS LIST (ELEMENT TYPE=int4)
- query error invalid input syntax for type boolean: "\{1,2\}"
- SELECT '{1,2}'::bool;
- query T
- SELECT '{1,2}'::public.bool::text;
- ----
- {1,2}
- # 🔬🔬 Check subtype resolution
- # Supports qualified subtypes
- statement ok
- CREATE TYPE qualified_int4_list AS LIST (ELEMENT TYPE=pg_catalog.int4)
- statement ok
- CREATE TYPE qualified_qualified_int4_list AS LIST (ELEMENT TYPE=public.qualified_int4_list)
- # Supports type aliases
- statement ok
- CREATE TYPE int_list AS MAP (KEY TYPE = pg_catalog.text, VALUE TYPE = int)
- # 🔬🔬 Built-in operations
- query T
- SELECT ('{1}'::int4_list_c || 2)::text;
- ----
- {1,2}
- query T
- SELECT (1 || '{2}'::int4_list_c)::text;
- ----
- {1,2}
- # 🔬 Explicit casts w/ custom types
- query T
- SELECT ('{1.2,2.3}'::numeric_list_c)::text;
- ----
- {1.2,2.3}
- query T
- SELECT ('{1.2,2.34567890}'::numeric_list_c::numeric(38,5) list)::text;
- ----
- {1.2,2.34568}
- query T
- SELECT ('{1.2,2.3}'::numeric(38,5) list::numeric_list_c)::text;
- ----
- {1.2,2.3}
- # 🔬 Implicit casts between custom types
- # 🔬🔬 1-D casts
- statement ok
- CREATE TYPE int4_list AS LIST (ELEMENT TYPE = int4)
- statement ok
- CREATE TYPE int4_list_too AS LIST (ELEMENT TYPE = int4)
- query T
- SELECT ('{1}'::int4_list || '{2}'::int list)::text;
- ----
- {1,2}
- query error
- SELECT '{1}'::int4_list || '{2}'::int4_list_too;
- # Anonymous type cast to custom type, which is not interoperable with a
- # different custom type
- query error
- SELECT '{1}'::int4_list || '{2}'::int list || '{3}'::int4_list_too
- query T
- SELECT ('{1}'::int4_list_too || '{2}'::int4_list::int4_list_too)::text;
- ----
- {1,2}
- query T
- SELECT ('{1}'::int4_list_too || '{2}'::int4_list::int list)::text;
- ----
- {1,2}
- query T
- SELECT ('{1}'::int4_list || 2)::text;
- ----
- {1,2}
- # 🔬🔬 2-D casts
- statement ok
- CREATE TYPE int4_list_list AS LIST (ELEMENT TYPE = int4_list)
- statement ok
- CREATE TYPE int4_list_list_too AS LIST (ELEMENT TYPE = int4_list_too)
- # Custom type interoperable with anonymous type
- query T
- SELECT ('{{1}}'::int4_list_list || '{{2}}'::int list list)::text;
- ----
- {{1},{2}}
- # Other custom types cast to same custom type
- query T
- SELECT ('{{1}}'::int4_list_list_too || '{{2}}'::int4_list_list::int4_list_list_too)::text;
- ----
- {{1},{2}}
- # Other custom type cast to anonymous type
- query T
- SELECT ('{{1}}'::int4_list_list_too || '{{2}}'::int4_list_list::int list list)::text;
- ----
- {{1},{2}}
- # Different custom types
- query error
- SELECT '{{1}}'::int4_list_list || '{{2}}'::int4_list_list_too;
- # Different custom types as element types
- query error
- SELECT '{{1}}'::int4_list list || '{{2}}'::int4_list_list_too list;
- # Custom element type
- query T
- SELECT ('{{1}}'::int4_list_list || '{2}'::int4_list)::text;
- ----
- {{1},{2}}
- # Anonymous element type
- query T
- SELECT ('{{1}}'::int4_list_list || '{2}'::int4 list)::text;
- ----
- {{1},{2}}
- # Non-matching element type
- query error
- SELECT '{{1}}'::int4_list_list || '{2}'::int4_list_too;
- query error
- SELECT '{1}'::int4_list_too || '{{2}}'::int4_list_list
- # Element types match, but "head" type does not
- query error
- SELECT '{{1}}'::int4_list_list || '{{2}}'::int4_list list
- query error
- SELECT '{{1}}'::int4_list list || '{{2}}'::int4_list_list
- # Custom element type w/ anonymous complex type
- query T
- SELECT ('{{1}}'::int4_list list || '{{2}}'::int4_list list)::text
- ----
- {{1},{2}}
- # Custom element exactly matches
- query T
- SELECT ('{{1}}'::int4_list list || '{2}'::int4_list)::text
- ----
- {{1},{2}}
- # Custom element + anonymous element
- query T
- SELECT ('{{1}}'::int4_list list || '{2}'::int4 list)::text
- ----
- {{1},{2}}
- # list_agg
- query T
- SELECT list_agg(a)::text FROM (SELECT 1 AS a WHERE false)
- ----
- NULL
- query T
- SELECT list_agg(1)::text
- ----
- {1}
- query T
- select list_agg(unnest)::text FROM (SELECT NULL) x JOIN LATERAL unnest(ARRAY[1,2,NULL]) ON true;
- ----
- {1,2,NULL}
- statement ok
- CREATE TABLE t1 (a int)
- statement ok
- INSERT INTO t1 VALUES (1), (2), (3), (NULL), (NULL)
- query T
- SELECT list_agg(a)::text FROM (select a from t1 where a IS NOT NULL)
- ----
- {1,2,3}
- query T
- SELECT list_agg(a)::text FROM (select a from t1 where a IS NULL)
- ----
- {NULL,NULL}
- query T
- SELECT list_agg(a)::text FROM t1
- ----
- {1,2,3,NULL,NULL}
- query T
- SELECT list_agg(a::text)::text FROM t1
- ----
- {1,2,3,NULL,NULL}
- query T
- SELECT (list_agg(a) FILTER (WHERE a IS NOT NULL))::text FROM t1
- ----
- {1,2,3}
- query T
- SELECT (list_agg(a) FILTER (WHERE a IS NULL))::text FROM t1
- ----
- {NULL,NULL}
- query error db error: ERROR: function list_agg\(integer, integer\) does not exist
- SELECT list_agg(1, 2)
- statement ok
- CREATE TABLE t2 (a int, b date)
- statement ok
- INSERT INTO t2 VALUES (1, date '2020-01-01'), (NULL, date '2020-01-02')
- query T
- SELECT list_agg((a, b))::text FROM t2
- ----
- {"(1,2020-01-01)","(,2020-01-02)"}
- query TTT
- SELECT list_agg((a, b))::text, list_agg(a)::text, list_agg(b)::text FROM t2
- ----
- {"(1,2020-01-01)","(,2020-01-02)"} {1,NULL} {2020-01-01,2020-01-02}
- query T
- SELECT list_agg(ARRAY[1])::text
- ----
- {{1}}
- query error list_agg on char
- SELECT list_agg('a'::char)::text
- query error list_agg on char
- SELECT list_agg('a'::char(2))::text
- query T
- SELECT list_agg(a)::text FROM (VALUES ('{1,2}'::int list), ('{3}'), (NULL)) v(a);
- ----
- {{1,2},{3},NULL}
- query T
- SELECT list_agg(a)::text FROM (VALUES (array[1,2]), (array[3]), (NULL)) v(a);
- ----
- {{1,2},{3},NULL}
- statement ok
- INSERT INTO t2 VALUES (3, date '2020-01-03')
- query T
- SELECT list_agg(a ORDER BY b)::text FROM t2
- ----
- {1,NULL,3}
- query T
- SELECT list_agg(a ORDER BY a DESC)::text FROM t2
- ----
- {NULL,3,1}
- query T
- SELECT list_agg(a ORDER BY a)::text FROM t2
- ----
- {1,3,NULL}
- query T
- SELECT (list_agg(a ORDER BY a) FILTER (WHERE b IS NOT NULL))::text FROM t2
- ----
- {1,3,NULL}
- query T
- SELECT (list_agg(a ORDER BY a) FILTER (WHERE b > '2050-01-01'))::text FROM t2
- ----
- {}
- query T
- SELECT list_agg(a ORDER BY b)::text FROM (VALUES (1, -1), (2, -2), (3, -3)) _ (a, b)
- ----
- {3,2,1}
- query T
- SELECT list_agg(a ORDER BY abs(b))::text FROM (VALUES (1, -1), (2, -2), (3, -3)) _ (a, b)
- ----
- {1,2,3}
- query T
- SELECT list_agg(a ORDER BY a > 10, -a)::text FROM (VALUES (1, -1), (2, -2), (3, -3)) _ (a, b)
- ----
- {3,2,1}
- query T
- SELECT list_agg(a ORDER BY (SELECT abs(-b)))::text FROM (VALUES (1, -1), (2, -2), (3, -3)) _ (a, b)
- ----
- {1,2,3}
- query T
- SELECT list_agg(a ORDER BY a+1 DESC)::text FROM (VALUES (1, -1), (2, -2), (3, -3)) _ (a, b)
- ----
- {3,2,1}
- query T
- SELECT list_agg(a ORDER BY -a DESC)::text FROM (VALUES (1, -1), (2, -2), (3, -3)) _ (a, b)
- ----
- {1,2,3}
- query error column "no_such_column" does not exist
- SELECT array_agg(a ORDER BY no_such_column)::text FROM (VALUES (1, -1)) AS a(a);
- query error division by zero
- SELECT array_agg(a ORDER BY a/0)::text FROM (VALUES (1, -1)) AS a(a);
- query error more than one record produced in subquery
- SELECT list_agg(a ORDER BY (SELECT 'a' FROM t2))::text FROM t2;
- query error Expected subselect to return 1 column, got 2 columns
- SELECT list_agg(a ORDER BY (SELECT * FROM t2)) FROM t2
- query T
- SELECT array_agg(column1 ORDER BY 1234)::text FROM (VALUES (1)) _;
- ----
- {1}
- # Test that a function that does not support ORDER BY is correct.
- query T
- SELECT sum(a ORDER BY b) FROM t2
- ----
- 4
- # list_remove
- query T
- SELECT list_remove(LIST[1,2,3,2], 2)::text
- ----
- {1,3}
- query T
- SELECT list_remove(LIST[1,2,3,2], 5)::text
- ----
- {1,2,3,2}
- query T
- SELECT list_remove(LIST[1,2,3,NULL::INT], NULL::INT)::text
- ----
- {1,2,3}
- query T
- SELECT list_remove(LIST[1,NULL::INT,2,3,NULL::INT], NULL::INT)::text
- ----
- {1,2,3}
- query T
- SELECT list_remove(NULL::integer list, NULL::INT)::text
- ----
- NULL
- query T
- SELECT list_remove(NULL::integer list, 1)::text
- ----
- NULL
- query T
- SELECT list_remove(LIST[1,1,1], 1)::text
- ----
- {}
- query T
- SELECT list_remove(LIST[[1,2],[1],[1,2,3], LIST[1]], LIST[1])::text
- ----
- {{1,2},{1,2,3}}
- query T
- SELECT list_remove(LIST[[1,2],[1],[1,2,3],LIST[1]], LIST[1,2,3])::text
- ----
- {{1,2},{1},{1}}
- ## polymorphism
- query T
- SELECT pg_typeof(list_remove(LIST[1::int8,2,3,2], 2::int2))
- ----
- bigint list
- query T
- SELECT pg_typeof(list_remove(LIST[1::int2,2,3,2], 2::int8))
- ----
- bigint list
- # array to list
- query T
- SELECT '{1,2,3}'::int[]::int list::text;
- ----
- {1,2,3}
- query T
- SELECT pg_typeof('{1,2,3}'::int[]::int list);
- ----
- integer list
- query T
- SELECT '{}'::int[]::int list::text;
- ----
- {}
- query T
- SELECT pg_typeof('{1,2,3}'::int[]::int list);
- ----
- integer list
- query T
- SELECT NULL::int[]::int list::text;
- ----
- NULL
- query T
- SELECT pg_typeof(NULL::int[]::int list);
- ----
- integer list
- query error casting multi-dimensional array to list; got array with 2 dimensions not yet supported
- SELECT '{{1},{2},{3}}'::int[]::int list::text;
- # Verify nested lists
- statement ok
- CREATE TABLE users (id int not null, other_field int not null)
- statement ok
- CREATE TABLE customer (id int not null, first_name string not null, last_name string not null, zip string not null)
- statement ok
- INSERT INTO users VALUES (1, 10), (2, 5), (3, 8);
- statement ok
- INSERT INTO customer VALUES (1, 'alice', 'lasta', '10003'::text), (2, 'bob', 'lastb', '10013'::text), (3, 'charlie', 'lastc', '11217'::text);
- query error LIST could not convert type integer list to text list
- SELECT LIST[LIST[customer.first_name, customer.last_name], LIST[customer.zip], LIST[customer.id]]::text FROM customer JOIN users ON customer.id = users.id ORDER BY users.other_field DESC LIMIT 2
- query T
- SELECT LIST[LIST[customer.first_name, customer.last_name], LIST[customer.zip], LIST[customer.id::text]]::text FROM customer JOIN users ON customer.id = users.id ORDER BY users.other_field DESC LIMIT 2
- ----
- {{alice,lasta},{10003},{1}}
- {{charlie,lastc},{11217},{3}}
- ## Optimization: Reducing ListIndex(ListCreate, literal) and multidimensional variations
- # Most of these tests could also be in src/expr/tests/testdata/reduce, but writing these big ListCreate expressions is a
- # bit cumbersome in that format.
- statement ok
- CREATE TABLE t3(f1 int, f2 int, f3 int, f4 int, f5 int, f6 int, f7 int, f8 int, n int, m int, l int list)
- statement ok
- CREATE VIEW m3 AS SELECT * FROM t3
- statement ok
- CREATE DEFAULT INDEX ON m3
- statement ok
- INSERT INTO t3 VALUES (1, 2, 3, 4, 5, 6, 7, 8, 1, 2, list[42, 43])
- statement ok
- INSERT INTO t3 VALUES (11, 12, 13, 14, 15, 16, 17, 18, 11, 12, list[82, 83])
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[f1, f2, f3, f4, f5][3] from m3
- ----
- Explained Query (fast path):
- Project (#2{f3})
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[f1, f2, f3, f4, f5][3] from m3
- ----
- 3
- 13
- # Reducing multidimensional ListIndex when all indexes are literals
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[[f1, f2], [f3, f4]][2][1] from m3
- ----
- Explained Query (fast path):
- Project (#2{f3})
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[f1, f2], [f3, f4]][2][1] from m3
- ----
- 3
- 13
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [2][1][2] from m3
- ----
- Explained Query (fast path):
- Project (#5{f6})
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [2][1][2] from m3
- ----
- 6
- 16
- # Reducing multidimensional ListIndex when some of the indexes are not literals, and therefore can't be removed.
- # We use `types, no fast path` to be able to check that the type is not changing.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations, types, no fast path) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f7, f8, f3, f4]], [[f5, f6], [f7, f8]]] [n][m][n] from m3
- ----
- Explained Query:
- Project (#12) // { arity: 1, types: "(integer?)" }
- Map (integer_to_bigint(#8{n}), list_index(list[list[list[#0{f1}, #1{f2}], list[#6{f7}, #7{f8}, #2{f3}, #3{f4}]], list[list[#4{f5}, #5{f6}], list[#6{f7}, #7{f8}]]], #11, integer_to_bigint(#9{m}), #11)) // { arity: 13, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?, bigint?, integer?)" }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?)" }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f7, f8, f3, f4]], [[f5, f6], [f7, f8]]] [n][m][n] from m3
- ----
- 7
- NULL
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations, types, no fast path) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [n][m][1] from m3
- ----
- Explained Query:
- Project (#11) // { arity: 1, types: "(integer?)" }
- Map (list_index(list[list[#0{f1}, #2{f3}], list[#4{f5}, #6{f7}]], integer_to_bigint(#8{n}), integer_to_bigint(#9{m}))) // { arity: 12, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?, integer?)" }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?)" }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [n][m][1] from m3
- ----
- 3
- NULL
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations, types, no fast path) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [n][2][m] from m3
- ----
- Explained Query:
- Project (#11) // { arity: 1, types: "(integer?)" }
- Map (list_index(list[list[#2{f3}, #3{f4}], list[#6{f7}, #7{f8}]], integer_to_bigint(#8{n}), integer_to_bigint(#9{m}))) // { arity: 12, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?, integer?)" }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?)" }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [n][2][m] from m3
- ----
- 4
- NULL
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations, types, no fast path) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [1][n][m] from m3
- ----
- Explained Query:
- Project (#11) // { arity: 1, types: "(integer?)" }
- Map (list_index(list[list[#0{f1}, #1{f2}], list[#2{f3}, #3{f4}]], integer_to_bigint(#8{n}), integer_to_bigint(#9{m}))) // { arity: 12, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?, integer?)" }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?)" }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [1][n][m] from m3
- ----
- 2
- NULL
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations, types, no fast path) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [2][1][n] from m3
- ----
- Explained Query:
- Project (#11) // { arity: 1, types: "(integer?)" }
- Map (list_index(list[#4{f5}, #5{f6}], integer_to_bigint(#8{n}))) // { arity: 12, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?, integer?)" }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?)" }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [2][1][n] from m3
- ----
- 5
- NULL
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations, types, no fast path) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [2][n][2] from m3
- ----
- Explained Query:
- Project (#11) // { arity: 1, types: "(integer?)" }
- Map (list_index(list[#5{f6}, #7{f8}], integer_to_bigint(#8{n}))) // { arity: 12, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?, integer?)" }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?)" }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [2][n][2] from m3
- ----
- 6
- NULL
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations, types, no fast path) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [n][2][2] from m3
- ----
- Explained Query:
- Project (#11) // { arity: 1, types: "(integer?)" }
- Map (list_index(list[#3{f4}, #7{f8}], integer_to_bigint(#8{n}))) // { arity: 12, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?, integer?)" }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11, types: "(integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer?, integer list?)" }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [[f5, f6], [f7, f8]]] [n][2][2] from m3
- ----
- 4
- NULL
- # Reducing ListIndex when a literal index is out of bounds
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[f1, f2, f3, f4, f5][6] from m3
- ----
- Explained Query (fast path):
- Project (#11)
- Map (null)
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[f1, f2, f3, f4, f5][0] from m3
- ----
- Explained Query (fast path):
- Project (#11)
- Map (null)
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[f1, f2, f3, f4, f5][-1] from m3
- ----
- Explained Query (fast path):
- Project (#11)
- Map (null)
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query T
- SELECT LIST[f1, f2, f3, f4, f5][6] from m3
- ----
- NULL
- NULL
- # Reducing multidimensional ListIndex when a literal index is out of bounds.
- # Also, one of the indexes is `1+1`, which must be evaluated to make it a literal, and then the reduction can take place.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [l, [f7, f8]]] [1+1][-1][2] from m3;
- ----
- Explained Query (fast path):
- Project (#11)
- Map (null)
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- # Reducing multidimensional ListIndex when the list doesn't have enough complete layers,
- # but has a NULL instead of a ListCreate.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [NULL, [f7, f8]]] [1+1][1][2] from m3
- ----
- Explained Query (fast path):
- Project (#11)
- Map (null)
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- # Reducing multidimensional ListIndex when the list doesn't have enough complete layers,
- # but has a column reference instead of a ListCreate.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT LIST[[[f1, f2], [f3, f4]], [l, [f7, f8]]] [1+1][1][2] from m3
- ----
- Explained Query (fast path):
- Project (#11)
- Map (list_index(#10{l}, 2))
- ReadIndex on=materialize.public.m3 m3_primary_idx=[*** full scan ***]
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT LIST[[[f1, f2], [f3, f4]], [l, [f7, f8]]] [1+1][1][2] from m3
- ----
- 43
- 83
- # Reducing ListIndex(ListCreate, literal) when this pattern appears after some other optimization (reduce_elision)
- # already took place.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT row_number() over () from (select f1 from m3 limit 1)
- ----
- Explained Query:
- Project (#2) // { arity: 1 }
- Map (record_get[0](#1)) // { arity: 3 }
- FlatMap unnest_list(#0) // { arity: 2 }
- Project (#1) // { arity: 1 }
- Map (list[row(1, row(#0{f1}))]) // { arity: 2 }
- TopK limit=1 // { arity: 1 }
- Project (#0{f1}) // { arity: 1 }
- ReadIndex on=m3 m3_primary_idx=[*** full scan ***] // { arity: 11 }
- Used Indexes:
- - materialize.public.m3_primary_idx (*** full scan ***)
- Target cluster: quickstart
- EOF
- query T
- SELECT LIST[1,4,3] @> LIST[3,1] AS contains
- ----
- true
- query T
- SELECT LIST[1,4,3] <@ LIST[3,1] AS contains
- ----
- false
- # array containment in Postgres does NOT account for duplicates
- query T
- SELECT LIST[1,4,3] @> LIST[3,1,1,1,1,1,1,1,1,1,1,1,3,3,1,3,3,3,3,3,1,1,3,3,3] AS contains
- ----
- true
- query T
- SELECT LIST[1,4,3] @> LIST[]::INT LIST AS contains
- ----
- true
- query T
- SELECT LIST[2,7] <@ LIST[1,7,4,2,6] AS is_contained_by
- ----
- true
- query T
- SELECT LIST[2,7] @> LIST[1,7,4,2,6] AS is_contained_by
- ----
- false
- query T
- SELECT '{}'::numeric list @> '{}'::numeric list;
- ----
- true
- query T
- SELECT '{1,2}'::numeric list @> '{}'::numeric list;
- ----
- true
- query T
- SELECT '{}'::numeric list @> '{1,2}'::numeric list;
- ----
- false
- query T
- SELECT '{NULL}'::numeric list @> '{NULL}'::numeric list;
- ----
- false
- query T
- SELECT '{NULL, 1}'::numeric list @> '{1}'::numeric list;
- ----
- true
- query T
- SELECT '{1}'::numeric list @> '{1, NULL}'::numeric list;
- ----
- false
- query T
- SELECT '{1, 2, 3, NULL}'::numeric list @> '{1, NULL}'::numeric list;
- ----
- false
- query T
- SELECT LIST[1,3,7,NULL] @> LIST[1,3,7,NULL] AS contains;
- ----
- false
- # Make sure we can index into a CAST-ed list.
- statement ok
- CREATE TABLE jsons (payload jsonb, random_index int, random_id uuid);
- statement ok
- CREATE MATERIALIZED VIEW json_mv AS (
- SELECT * FROM jsons WHERE random_id = CAST(payload->>'my_field' AS uuid list)[random_index]
- )
|