1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014 |
- # 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.
- # This test may seem simple, but it is surprisingly good at verifying that
- # logical timestamp handling for internal inputs is sane.
- mode cockroach
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a'), ('b'), ('c');
- statement error db error: ERROR: window function pg_catalog\.row_number requires an OVER clause
- SELECT row_number()
- FROM t;
- statement error db error: ERROR: window function pg_catalog\.row_number requires an OVER clause
- SELECT *
- FROM t
- ORDER BY row_number();
- statement error db error: ERROR: window function pg_catalog\.row_number requires an OVER clause
- SELECT *
- FROM t
- QUALIFY row_number();
- statement error db error: ERROR: OVER clause not allowed on pg_catalog\.int8range\. The OVER clause can only be used with window functions \(including aggregations\)\.
- SELECT int8range(1, 1, '') OVER (PARTITION BY 1 ORDER BY 1);
- query IT
- SELECT row_number() OVER (ORDER BY x), x FROM t
- ORDER BY row_number
- ----
- 1 a
- 2 b
- 3 c
- query IT
- SELECT row_number() OVER (ORDER BY x DESC), x FROM t
- ORDER BY row_number
- ----
- 1 c
- 2 b
- 3 a
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 98), ('b', 99), ('c', 98);
- query IT
- SELECT row_number() OVER (PARTITION BY y ORDER BY x), x FROM t
- ORDER BY row_number, x
- ----
- 1 a
- 1 b
- 2 c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 1), ('b', 2), ('c', 1);
- query IT
- SELECT row_number() OVER (PARTITION BY y ORDER BY x DESC), x FROM t
- ORDER BY row_number, x
- ----
- 1 b
- 1 c
- 2 a
- query IT
- SELECT row_number() OVER (PARTITION BY x ORDER BY x), x FROM t
- ORDER BY row_number, x
- ----
- 1 a
- 1 b
- 1 c
- query IT
- SELECT row_number() OVER (PARTITION BY NULL ORDER BY 10000) AS q, a1.x
- FROM t AS a1, t AS a2
- ORDER BY q DESC
- ----
- 9 c
- 8 c
- 7 c
- 6 b
- 5 b
- 4 b
- 3 a
- 2 a
- 1 a
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a');
- # Make sure a non-column expression following the window function is correctly
- # handled.
- query ITT
- SELECT row_number() OVER (PARTITION BY NULL) AS q, x, 'b'
- FROM t
- ----
- 1 a b
- # Regression test for database-issues#2730
- query II
- SELECT row_number() OVER (), row_number() OVER ()
- ----
- 1 1
- statement ok
- INSERT INTO t VALUES ('b');
- query II
- SELECT row_number() OVER (), row_number() OVER () from t
- ----
- 1 1
- 2 2
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 1), ('b', 2), ('c', 1);
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT row_number() OVER (PARTITION BY x ORDER BY x), x FROM t
- ORDER BY row_number, x
- ----
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last] output=[#0, #1]
- Project (#2, #0)
- Map (row_number() over (partition by [#0{x}] order by [#0{x} asc nulls_last]))
- Get materialize.public.t
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN DECORRELATED PLAN WITH(arity) FOR
- SELECT row_number() OVER (PARTITION BY x ORDER BY x), x FROM t
- ORDER BY row_number, x
- ----
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last] output=[#0, #1]
- Project (#3, #0) // { arity: 2 }
- Map (#2) // { arity: 4 }
- Project (#3..=#5) // { arity: 3 }
- Map (record_get[0](record_get[1](#2)), record_get[1](record_get[1](#2)), record_get[0](#2)) // { arity: 6 }
- FlatMap unnest_list(#1) // { arity: 3 }
- Reduce group_by=[#0] aggregates=[row_number[order_by=[#0 asc nulls_last]](row(list[row(#0, #1)], #0{x}))] // { arity: 2 }
- CrossJoin // { arity: 2 }
- Constant // { arity: 0 }
- - ()
- Get materialize.public.t // { arity: 2 }
- Target cluster: quickstart
- EOF
- #
- # Regression test for database-issues#2760
- #
- statement ok
- CREATE TABLE t1 (f1 INTEGER, f2 INTEGER);
- ----
- statement ok
- ----
- INSERT INTO t1 VALUES (1, 1), (2, 2), (4, 4);
- statement ok
- CREATE TABLE t2 (f1 INTEGER, f2 INTEGER);
- ----
- statement ok
- INSERT INTO t2 VALUES (1, 1), (1, 2), (2, 2);
- ----
- query I
- SELECT f1 FROM t1
- WHERE f1 IN (SELECT ROW_NUMBER() OVER () FROM t2);
- ----
- 1
- 2
- query T multiline
- EXPLAIN DECORRELATED PLAN WITH(arity) FOR SELECT f1 FROM t1
- WHERE f1 IN (SELECT ROW_NUMBER() OVER () FROM t2);
- ----
- With
- cte l0 =
- CrossJoin // { arity: 2 }
- Constant // { arity: 0 }
- - ()
- Get materialize.public.t1 // { arity: 2 }
- cte l1 =
- Distinct project=[#0] // { arity: 1 }
- Get l0 // { arity: 2 }
- cte l2 =
- Map (true) // { arity: 2 }
- Distinct project=[#0] // { arity: 1 }
- Filter (integer_to_bigint(#0{f1}) = #1{right_col0_0}) // { arity: 2 }
- Project (#0, #4) // { arity: 2 }
- Map (#3) // { arity: 5 }
- Project (#3..=#6) // { arity: 4 }
- Map (record_get[0](record_get[1](#2)), record_get[1](record_get[1](#2)), record_get[2](record_get[1](#2)), record_get[0](#2)) // { arity: 7 }
- FlatMap unnest_list(#1) // { arity: 3 }
- Reduce group_by=[#0] aggregates=[row_number[order_by=[]](row(list[row(#0, #1, #2)]))] // { arity: 2 }
- CrossJoin // { arity: 3 }
- Get l1 // { arity: 1 }
- Get materialize.public.t2 // { arity: 2 }
- Return // { arity: 1 }
- Project (#0) // { arity: 1 }
- Filter #2 // { arity: 3 }
- Project (#0, #1, #3) // { arity: 3 }
- Join on=(#0 = #2) // { arity: 4 }
- Get l0 // { arity: 2 }
- Union // { arity: 2 }
- Get l2 // { arity: 2 }
- CrossJoin // { arity: 2 }
- Project (#0) // { arity: 1 }
- Join on=(#0 = #1) // { arity: 2 }
- Union // { arity: 1 }
- Negate // { arity: 1 }
- Distinct project=[#0] // { arity: 1 }
- Get l2 // { arity: 2 }
- Distinct project=[#0] // { arity: 1 }
- Get l1 // { arity: 1 }
- Get l1 // { arity: 1 }
- Constant // { arity: 1 }
- - (false)
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(humanized expressions, arity, join implementations) AS VERBOSE TEXT FOR SELECT f1 FROM t1
- WHERE f1 IN (SELECT ROW_NUMBER() OVER () FROM t2);
- ----
- Explained Query:
- With
- cte l0 =
- Project (#0{f1}) // { arity: 1 }
- ReadStorage materialize.public.t1 // { arity: 2 }
- Return // { arity: 1 }
- Project (#0{f1}) // { arity: 1 }
- Join on=(#0{f1} = #1) type=differential // { arity: 2 }
- implementation
- %1[#0]UKA » %0:l0[#0]K
- ArrangeBy keys=[[#0{f1}]] // { arity: 1 }
- Get l0 // { arity: 1 }
- ArrangeBy keys=[[#0]] // { arity: 1 }
- Distinct project=[record_get[0](record_get[1](#0))] // { arity: 1 }
- Project (#1) // { arity: 1 }
- Filter (integer_to_bigint(record_get[0](record_get[1](#1))) = record_get[0](#1)) // { arity: 2 }
- FlatMap unnest_list(#0{row_number}) // { arity: 2 }
- Project (#1{row_number}) // { arity: 1 }
- Reduce group_by=[#0{f1}] aggregates=[row_number[order_by=[]](row(list[row(#0{f1}, #1{f1}, #2{f2})]))] // { arity: 2 }
- CrossJoin type=differential // { arity: 3 }
- implementation
- %0[×] » %1:t2[×]
- ArrangeBy keys=[[]] // { arity: 1 }
- Distinct project=[#0{f1}] // { arity: 1 }
- Get l0 // { arity: 1 }
- ArrangeBy keys=[[]] // { arity: 2 }
- ReadStorage materialize.public.t2 // { arity: 2 }
- Source materialize.public.t1
- Source materialize.public.t2
- Target cluster: quickstart
- EOF
- query IIIII
- SELECT * FROM t1, LATERAL(SELECT t2.*, ROW_NUMBER() OVER() FROM t2 WHERE t1.f1 = t2.f1) AS foo;
- ----
- 1 1 1 1 1
- 1 1 1 2 2
- 2 2 2 2 1
- query IIIII
- SELECT * FROM t1, LATERAL(SELECT t2.*, ROW_NUMBER() OVER() FROM t2 WHERE t1.f1 = t2.f1 AND t1.f2 = t2.f2) AS foo;
- ----
- 1 1 1 1 1
- 2 2 2 2 1
- query IIIII
- SELECT * FROM t1, LATERAL(SELECT t2.*, ROW_NUMBER() OVER() FROM t2 WHERE t1.f2 = t2.f2) AS foo;
- ----
- 1 1 1 1 1
- 2 2 1 2 1
- 2 2 2 2 2
- query IIIII rowsort
- SELECT * FROM t2, LATERAL(SELECT t1.*, ROW_NUMBER() OVER() FROM t1 WHERE t1.f1 = t2.f1) AS foo;
- ----
- 1 1 1 1 1
- 1 2 1 1 1
- 2 2 2 2 1
- query IIIII
- SELECT * FROM t2, LATERAL(SELECT t1.*, ROW_NUMBER() OVER() FROM t1 WHERE t1.f1 = t2.f1 AND t1.f2 = t2.f2) AS foo;
- ----
- 1 1 1 1 1
- 2 2 2 2 1
- query IIIII rowsort
- SELECT * FROM t2, LATERAL(SELECT t1.*, ROW_NUMBER() OVER() FROM t1 WHERE t1.f2 = t2.f2) AS foo;
- ----
- 1 1 1 1 1
- 1 2 2 2 1
- 2 2 2 2 1
- # Check that the partition key comes after the outer columns in the grouping key
- query T multiline
- EXPLAIN DECORRELATED PLAN WITH(arity) FOR SELECT * FROM t2, LATERAL(SELECT t1.*, ROW_NUMBER() OVER() FROM t1 WHERE t1.f2 = t2.f2) AS foo;
- ----
- With
- cte l0 =
- CrossJoin // { arity: 2 }
- Constant // { arity: 0 }
- - ()
- Get materialize.public.t2 // { arity: 2 }
- Return // { arity: 5 }
- Project (#0, #1, #3..=#5) // { arity: 5 }
- Join on=(#1 = #2) // { arity: 6 }
- Get l0 // { arity: 2 }
- Project (#0..=#2, #4) // { arity: 4 }
- Map (#3) // { arity: 5 }
- Project (#3..=#6) // { arity: 4 }
- Map (record_get[0](record_get[1](#2)), record_get[1](record_get[1](#2)), record_get[2](record_get[1](#2)), record_get[0](#2)) // { arity: 7 }
- FlatMap unnest_list(#1) // { arity: 3 }
- Reduce group_by=[#0] aggregates=[row_number[order_by=[]](row(list[row(#0, #1, #2)]))] // { arity: 2 }
- Filter (#2{f2} = #0{f2}) // { arity: 3 }
- CrossJoin // { arity: 3 }
- Distinct project=[#1] // { arity: 1 }
- Get l0 // { arity: 2 }
- Get materialize.public.t1 // { arity: 2 }
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN DECORRELATED PLAN WITH(arity) FOR SELECT * FROM t2, LATERAL(SELECT t1.*, ROW_NUMBER() OVER(PARTITION BY f1) FROM t1 WHERE t1.f2 = t2.f2) AS foo;
- ----
- With
- cte l0 =
- CrossJoin // { arity: 2 }
- Constant // { arity: 0 }
- - ()
- Get materialize.public.t2 // { arity: 2 }
- Return // { arity: 5 }
- Project (#0, #1, #3..=#5) // { arity: 5 }
- Join on=(#1 = #2) // { arity: 6 }
- Get l0 // { arity: 2 }
- Project (#0..=#2, #4) // { arity: 4 }
- Map (#3) // { arity: 5 }
- Project (#4..=#7) // { arity: 4 }
- Map (record_get[0](record_get[1](#3)), record_get[1](record_get[1](#3)), record_get[2](record_get[1](#3)), record_get[0](#3)) // { arity: 8 }
- FlatMap unnest_list(#2) // { arity: 4 }
- Reduce group_by=[#0, #1] aggregates=[row_number[order_by=[]](row(list[row(#0, #1, #2)]))] // { arity: 3 }
- Filter (#2{f2} = #0{f2}) // { arity: 3 }
- CrossJoin // { arity: 3 }
- Distinct project=[#1] // { arity: 1 }
- Get l0 // { arity: 2 }
- Get materialize.public.t1 // { arity: 2 }
- Target cluster: quickstart
- EOF
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a'), ('b'), ('c');
- # Regression for database-issues#2962
- query error window functions are not allowed in ON
- SELECT * FROM t AS v JOIN t ON row_number() over () > 1;
- query error window functions are not allowed in WHERE
- SELECT * FROM t
- WHERE row_number() over () > 1;
- statement ok
- CREATE TABLE not_allowed_tests (
- v INT,
- w INT,
- k INT
- );
- query error window functions are not allowed in GROUP BY
- SELECT * FROM not_allowed_tests GROUP BY v, count(w) OVER ();
- query error window functions are not allowed in GROUP BY
- SELECT count(w) OVER () FROM not_allowed_tests GROUP BY 1;
- query error window functions are not allowed in RETURNING
- INSERT INTO not_allowed_tests (k, v) VALUES (99, 100) RETURNING sum(v) OVER ();
- query error window functions are not allowed in LIMIT
- SELECT sum(v) FROM not_allowed_tests GROUP BY k LIMIT sum(v) OVER ();
- query error db error: ERROR: window functions are not allowed in OFFSET \(function pg_catalog\.sum\)
- SELECT sum(v) FROM not_allowed_tests GROUP BY k LIMIT 1 OFFSET sum(v) OVER ();
- query error window functions are not allowed in VALUES
- INSERT INTO not_allowed_tests (k, v) VALUES (99, count(1) OVER ());
- query error window functions are not allowed in WHERE
- SELECT k FROM not_allowed_tests WHERE avg(k) OVER () > 1;
- query error window functions are not allowed in HAVING
- SELECT 1 FROM not_allowed_tests GROUP BY 1 HAVING sum(1) OVER (PARTITION BY 1) > 1;
- query T
- SELECT DISTINCT ON (row_number() OVER ()) *
- FROM t
- ORDER BY row_number() OVER ()
- ----
- a
- b
- c
- # rank and dense_rank
- query error db error: ERROR: function rank has 0 parameters, but was called with 1
- SELECT rank(x) OVER (ORDER BY x), dense_rank() OVER (ORDER BY x), x FROM t
- ORDER BY dense_rank;
- query IT
- SELECT dense_rank() OVER (ORDER BY x), x FROM t
- ORDER BY dense_rank
- ----
- 1 a
- 2 b
- 3 c
- statement ok
- INSERT INTO t VALUES ('b');
- query IT
- SELECT dense_rank() OVER (ORDER BY x), x FROM t
- ORDER BY dense_rank
- ----
- 1 a
- 2 b
- 2 b
- 3 c
- statement ok
- INSERT INTO t VALUES ('c');
- query IT
- SELECT dense_rank() OVER (ORDER BY x), x FROM t
- ORDER BY dense_rank
- ----
- 1 a
- 2 b
- 2 b
- 3 c
- 3 c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a'), ('b'), ('c');
- query IT
- SELECT dense_rank() OVER (ORDER BY x DESC), x FROM t
- ORDER BY dense_rank
- ----
- 1 c
- 2 b
- 3 a
- query IIT rowsort
- SELECT rank() OVER (ORDER BY x), dense_rank() OVER (ORDER BY x), x FROM t
- ----
- 1 1 a
- 2 2 b
- 3 3 c
- query IIT
- SELECT rank() OVER (ORDER BY x DESC), dense_rank() OVER (ORDER BY x DESC), x FROM t
- ORDER BY dense_rank
- ----
- 1 1 c
- 2 2 b
- 3 3 a
- statement ok
- INSERT INTO t VALUES ('b');
- query IT
- SELECT dense_rank() OVER (ORDER BY x DESC), x FROM t
- ORDER BY dense_rank
- ----
- 1 c
- 2 b
- 2 b
- 3 a
- query IIT
- SELECT rank() OVER (ORDER BY x), dense_rank() OVER (ORDER BY x), x FROM t
- ----
- 1 1 a
- 2 2 b
- 2 2 b
- 4 3 c
- query IIT
- SELECT rank() OVER (ORDER BY x DESC), dense_rank() OVER (ORDER BY x DESC), x FROM t
- ORDER BY dense_rank
- ----
- 1 1 c
- 2 2 b
- 2 2 b
- 4 3 a
- statement ok
- INSERT INTO t VALUES ('c');
- query IT
- SELECT dense_rank() OVER (ORDER BY x DESC), x FROM t
- ORDER BY dense_rank
- ----
- 1 c
- 1 c
- 2 b
- 2 b
- 3 a
- query IIT
- SELECT rank() OVER (ORDER BY x DESC), dense_rank() OVER (ORDER BY x DESC), x FROM t
- ORDER BY dense_rank
- ----
- 1 1 c
- 1 1 c
- 3 2 b
- 3 2 b
- 5 3 a
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 98), ('b', 99), ('c', 98);
- query IIT rowsort
- SELECT rank() OVER (PARTITION BY y ORDER BY x), dense_rank() OVER (PARTITION BY y ORDER BY x), x FROM t;
- ----
- 1 1 a
- 1 1 b
- 2 2 c
- query IT
- SELECT dense_rank() OVER (PARTITION BY y ORDER BY x), x FROM t
- ORDER BY dense_rank, x;
- ----
- 1 a
- 1 b
- 2 c
- statement ok
- INSERT INTO t VALUES ('a', 98), ('a', 99);
- query IIT
- SELECT rank() OVER (PARTITION BY y ORDER BY x), dense_rank() OVER (PARTITION BY y ORDER BY x), x FROM t;
- ----
- 1 1 a
- 1 1 a
- 1 1 a
- 2 2 b
- 3 2 c
- query IT
- SELECT dense_rank() OVER (PARTITION BY y ORDER BY x), x FROM t
- ORDER BY dense_rank, x;
- ----
- 1 a
- 1 a
- 1 a
- 2 b
- 2 c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 1), ('b', 2), ('c', 1);
- query IIT
- SELECT rank() OVER (PARTITION BY y ORDER BY x DESC), dense_rank() OVER (PARTITION BY y ORDER BY x DESC), x FROM t;
- ----
- 1 1 b
- 1 1 c
- 2 2 a
- query IT
- SELECT dense_rank() OVER (PARTITION BY y ORDER BY x DESC), x FROM t
- ORDER BY dense_rank, x;
- ----
- 1 b
- 1 c
- 2 a
- query IIT rowsort
- SELECT rank() OVER (PARTITION BY x ORDER BY x), dense_rank() OVER (PARTITION BY x ORDER BY x), x FROM t;
- ----
- 1 1 a
- 1 1 b
- 1 1 c
- query IT
- SELECT dense_rank() OVER (PARTITION BY x ORDER BY x), x FROM t
- ORDER BY dense_rank, x;
- ----
- 1 a
- 1 b
- 1 c
- query IIT rowsort
- SELECT rank() OVER (PARTITION BY NULL ORDER BY 10000), dense_rank() OVER (PARTITION BY NULL ORDER BY 10000) AS q, a1.x
- FROM t AS a1, t AS a2;
- ----
- 1 1 a
- 1 1 a
- 1 1 a
- 1 1 b
- 1 1 b
- 1 1 b
- 1 1 c
- 1 1 c
- 1 1 c
- query IT
- SELECT dense_rank() OVER (PARTITION BY NULL ORDER BY 10000) AS q, a1.x
- FROM t AS a1, t AS a2
- ORDER BY q DESC, a1.x DESC;
- ----
- 1 c
- 1 c
- 1 c
- 1 b
- 1 b
- 1 b
- 1 a
- 1 a
- 1 a
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a');
- # Make sure a non-column expression following the window function is correctly
- # handled.
- query IITT
- SELECT rank() OVER (PARTITION BY NULL), dense_rank() OVER (PARTITION BY NULL) AS q, x, 'b'
- FROM t;
- ----
- 1 1 a b
- query ITT
- SELECT dense_rank() OVER (PARTITION BY NULL) AS q, x, 'b'
- FROM t;
- ----
- 1 a b
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x int, y string, z numeric);
- statement ok
- INSERT INTO t VALUES (1, 'a', 1.0), (2, 'a', 1.0), (2, 'a', 1.0), (3, 'a', 1.0), (4, 'b', 0), (4, 'b', 1), (1, 'c', 'NaN'), (2, 'c', 'NaN'), (3, 'c', 1.0);
- query IIITT
- SELECT rank() OVER (PARTITION BY y ORDER BY x DESC, z), dense_rank() OVER (PARTITION BY y ORDER BY x DESC, z), x, y, z
- FROM t;
- ----
- 1 1 3 a 1
- 1 1 3 c 1
- 1 1 4 b 0
- 2 2 2 a 1
- 2 2 2 a 1
- 2 2 2 c NaN
- 2 2 4 b 1
- 3 3 1 c NaN
- 4 3 1 a 1
- query IITT
- SELECT dense_rank() OVER (PARTITION BY y ORDER BY x DESC, z), x, y, z
- FROM t
- ORDER BY y, x DESC, z;
- ----
- 1 3 a 1
- 2 2 a 1
- 2 2 a 1
- 3 1 a 1
- 1 4 b 0
- 2 4 b 1
- 1 3 c 1
- 2 2 c NaN
- 3 1 c NaN
- # NaNs have the same rank
- query IIITT
- WITH t (x, y, z) AS (VALUES (1, 'a', 1.0), (2, 'a', 1.0), (2, 'a', 1.0), (3, 'a', 1.0), (4, 'b', 0), (4, 'b', 1), (1, 'c', 'NaN'), (2, 'c', 'NaN'), (3, 'c', 1.0))
- SELECT rank() OVER (PARTITION BY y ORDER BY z DESC), dense_rank() OVER (PARTITION BY y ORDER BY z DESC), x, y, z
- FROM t;
- ----
- 1 1 1 a 1
- 1 1 1 c NaN
- 1 1 2 a 1
- 1 1 2 a 1
- 1 1 2 c NaN
- 1 1 3 a 1
- 1 1 4 b 1
- 2 2 4 b 0
- 3 2 3 c 1
- query IITT
- SELECT dense_rank() OVER (PARTITION BY y ORDER BY z DESC), x, y, z
- FROM t
- ORDER BY y, z DESC, x;
- ----
- 1 1 a 1
- 1 2 a 1
- 1 2 a 1
- 1 3 a 1
- 1 4 b 1
- 2 4 b 0
- 1 1 c NaN
- 1 2 c NaN
- 2 3 c 1
- ## lag
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a'), ('b'), ('c');
- # Simple cases
- query TT
- SELECT lag(x) OVER (ORDER BY x), x FROM t
- ORDER BY x, lag
- ----
- NULL a
- a b
- b c
- statement ok
- INSERT INTO t VALUES ('b');
- query TT
- SELECT lag(x) OVER (ORDER BY x), x FROM t
- ORDER BY x, lag
- ----
- NULL a
- a b
- b b
- b c
- statement ok
- INSERT INTO t VALUES ('c');
- query TT
- SELECT lag(x) OVER (ORDER BY x), x FROM t
- ORDER BY x, lag
- ----
- NULL a
- a b
- b b
- b c
- c c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a'), ('b'), ('c');
- query TT
- SELECT lag(x) OVER (ORDER BY x DESC), x FROM t
- ORDER BY x, lag
- ----
- b a
- c b
- NULL c
- statement ok
- INSERT INTO t VALUES ('b');
- query TT
- SELECT lag(x) OVER (ORDER BY x DESC), x FROM t
- ORDER BY x, lag
- ----
- b a
- b b
- c b
- NULL c
- statement ok
- INSERT INTO t VALUES ('c');
- query TT
- SELECT lag(x) OVER (ORDER BY x DESC), x FROM t
- ORDER BY x, lag
- ----
- b a
- b b
- c b
- c c
- NULL c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 98), ('b', 99), ('c', 98);
- query TT
- SELECT lag(x) OVER (PARTITION BY y ORDER BY x), x FROM t
- ORDER BY x, lag
- ----
- NULL a
- NULL b
- a c
- statement ok
- INSERT INTO t VALUES ('a', 98), ('a', 99);
- query TT
- SELECT lag(x) OVER (PARTITION BY y ORDER BY x), x FROM t
- ORDER BY x, lag
- ----
- a a
- NULL a
- NULL a
- a b
- a c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 1), ('b', 2), ('c', 1);
- query TT
- SELECT lag(x) OVER (PARTITION BY y ORDER BY x DESC), x FROM t
- ORDER BY x, lag
- ----
- c a
- NULL b
- NULL c
- query TT
- SELECT lag(x) OVER (PARTITION BY x ORDER BY x), x FROM t
- ORDER BY x, lag
- ----
- NULL a
- NULL b
- NULL c
- query TT
- SELECT lag(a1.x) OVER (PARTITION BY NULL ORDER BY 10000) AS q, a1.x
- FROM t AS a1, t AS a2
- ORDER BY q DESC, a1.x DESC
- ----
- NULL a
- c c
- c c
- b c
- b b
- b b
- a b
- a a
- a a
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(f1 int, f2 string, f3 numeric);
- statement ok
- INSERT INTO t VALUES (1, 'a', 1.0), (2, 'a', 1.0), (2, 'a', 1.0), (3, 'a', 1.0), (4, 'b', 0), (4, 'b', 1), (1, 'c', 'NaN'), (2, 'c', 'NaN'), (3, 'c', 1.0), (7, 'd', -5.0);
- query ITTT
- SELECT f1, f2, f3, lag(f1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN 1
- 3 c 1 2
- 4 b 1 NULL
- 4 b 0 4
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- query ITTT
- SELECT f1, f2, f3, lag(f1, 1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN 1
- 3 c 1 2
- 4 b 1 NULL
- 4 b 0 4
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- query ITTT
- SELECT f1, f2, f3, lag(f1, 1, NULL) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN 1
- 3 c 1 2
- 4 b 1 NULL
- 4 b 0 4
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- # With default value
- query ITTT
- SELECT f1, f2, f3, lag(f1, 1, -1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 -1
- 1 c NaN -1
- 2 c NaN 1
- 3 c 1 2
- 4 b 1 -1
- 4 b 0 4
- 1 a 1 -1
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- # Complex expressions
- query ITTT
- SELECT f1, f2, f3, lag(f1 + coalesce(nullif(f3, 'NaN'), -10)) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN -9
- 3 c 1 -8
- 4 b 1 NULL
- 4 b 0 5
- 1 a 1 NULL
- 2 a 1 2
- 2 a 1 3
- 3 a 1 3
- # Nulls in the first argument
- query ITTT
- SELECT f1, f2, f3, lag(NULL::int) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(nullif(f1, 4)) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN 1
- 3 c 1 2
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- # Nulls in the first argument with a default value in the third argument
- query ITTT
- SELECT f1, f2, f3, lag(NULL::int, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- # Zero offset
- query ITTT
- SELECT f1, f2, f3, lag(f1, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 7
- 1 c NaN 1
- 2 c NaN 2
- 3 c 1 3
- 4 b 1 4
- 4 b 0 4
- 1 a 1 1
- 2 a 1 2
- 2 a 1 2
- 3 a 1 3
- query ITTT
- SELECT f1, f2, f3, lag(f1 + f3, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 2
- 1 c NaN NaN
- 2 c NaN NaN
- 3 c 1 4
- 4 b 1 5
- 4 b 0 4
- 1 a 1 2
- 2 a 1 3
- 2 a 1 3
- 3 a 1 4
- # Positive offsets
- query ITTT
- SELECT f1, f2, f3, lag(f1, 2) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 1
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 NULL
- 3 a 1 2
- query ITTT
- SELECT f1, f2, f3, lag(f1 + f3, 2) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NaN
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 2
- 2 a 1 NULL
- 3 a 1 3
- # Out of range positive offsets
- query ITTT
- SELECT f1, f2, f3, lag(f1, 10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(f1 + f3, 10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(f1 + f3, 10, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 0
- 1 c NaN 0
- 2 c NaN 0
- 3 c 1 0
- 4 b 1 0
- 4 b 0 0
- 1 a 1 0
- 2 a 1 0
- 2 a 1 0
- 3 a 1 0
- # Negative offsets
- query ITTT
- SELECT f1, f2, f3, lag(f1, -1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN 2
- 2 c NaN 3
- 3 c 1 NULL
- 4 b 1 4
- 4 b 0 NULL
- 1 a 1 2
- 2 a 1 2
- 2 a 1 3
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(f1 + f3, -1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NaN
- 2 c NaN 4
- 3 c 1 NULL
- 4 b 1 4
- 4 b 0 NULL
- 1 a 1 3
- 2 a 1 3
- 2 a 1 4
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(f1 + f3, -2) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN 4
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 3
- 2 a 1 4
- 2 a 1 NULL
- 3 a 1 NULL
- # Out of range negative offsets
- query ITTT
- SELECT f1, f2, f3, lag(f1, -10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(f1 + f3, -10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(f1, -10, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 0
- 1 c NaN 0
- 2 c NaN 0
- 3 c 1 0
- 4 b 1 0
- 4 b 0 0
- 1 a 1 0
- 2 a 1 0
- 2 a 1 0
- 3 a 1 0
- # Variable per row offsets
- query ITTT
- SELECT f1, f2, f3, lag(f1, f1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 NULL
- 3 a 1 1
- query ITTT
- SELECT f1, f2, f3, lag(f1, f1 - 1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN 1
- 2 c NaN 1
- 3 c 1 1
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 1
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- # Null offsets
- query ITTT
- SELECT f1, f2, f3, lag(f1, NULL) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lag(f1, nullif(f1, 1)) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 NULL
- 3 a 1 1
- # Null offset with default value
- query ITTT
- SELECT f1, f2, f3, lag(f1, NULL, -10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- # Variable per row default value
- query ITTT
- SELECT f1, f2, f3, lag(f1, 1, f3) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lag
- ----
- 7 d -5 -5
- 1 c NaN NaN
- 2 c NaN 1
- 3 c 1 2
- 4 b 1 1
- 4 b 0 4
- 1 a 1 1
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(f1 int, f2 int);
- statement ok
- INSERT INTO t VALUES (1, 2), (1, 2), (3, 4);
- # reduce_elision code path
- # Default offset
- query II
- SELECT f1, lag(f1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 NULL
- 3 NULL
- query II
- SELECT f1, lag(f1, 1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 NULL
- 3 NULL
- # Zero offset
- query II
- SELECT f1, lag(f1, 0) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 1
- 3 3
- # Negative offset
- query II
- SELECT f1, lag(f1, -1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 NULL
- 3 NULL
- # Default value with offset 1
- query II
- SELECT f1, lag(f1, 1, 10) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 10
- 3 10
- # Default value with offset 0
- query II
- SELECT f1, lag(f1, 0, 10) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 1
- 3 3
- # Complex expression
- query II
- SELECT f1, lag(f1 * f2, 0, 10) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 2
- 3 12
- query II
- SELECT f1, lag(f1 * f2, 1, f1 * f2 + 1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 3
- 3 13
- # Complex offset
- query II
- SELECT f1, lag(f1 * f2, f1 - f1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 2
- 3 12
- query II rowsort
- SELECT f1, lag(f1 * f2, f1 - 1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 3 NULL
- 1 2
- query II
- SELECT f1, lag(f1 * f2, f2 - 2 * f1, f2) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 2
- 3 4
- # Complex default value
- query II
- SELECT f1, lag(f1, 0, f1 * f2) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 1
- 3 3
- query II
- SELECT f1, lag(f1, 1, f1 * f2) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ----
- 1 2
- 3 12
- # Null value in input relation
- # This was caused by a bug in the reduce elision logic
- statement ok
- CREATE TABLE t3 (f1 INTEGER)
- ----
- statement ok
- INSERT INTO t3 VALUES (NULL)
- ----
- query II
- SELECT f1, lag(0, f1 , 0) OVER (PARTITION BY f1 ORDER BY f1) FROM t3 GROUP BY f1 ORDER BY 1
- ----
- NULL NULL
- ## lead
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a'), ('b'), ('c');
- # Simple cases
- query TT
- SELECT lead(x) OVER (ORDER BY x), x FROM t
- ORDER BY x, lead
- ----
- b a
- c b
- NULL c
- statement ok
- INSERT INTO t VALUES ('b');
- query TT
- SELECT lead(x) OVER (ORDER BY x), x FROM t
- ORDER BY x, lead
- ----
- b a
- b b
- c b
- NULL c
- statement ok
- INSERT INTO t VALUES ('c');
- query TT
- SELECT lead(x) OVER (ORDER BY x), x FROM t
- ORDER BY x, lead
- ----
- b a
- b b
- c b
- c c
- NULL c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string);
- statement ok
- INSERT INTO t VALUES ('a'), ('b'), ('c');
- query TT
- SELECT lead(x) OVER (ORDER BY x DESC), x FROM t
- ORDER BY x, lead
- ----
- NULL a
- a b
- b c
- statement ok
- INSERT INTO t VALUES ('b');
- query TT
- SELECT lead(x) OVER (ORDER BY x DESC), x FROM t
- ORDER BY x, lead
- ----
- NULL a
- a b
- b b
- b c
- statement ok
- INSERT INTO t VALUES ('c');
- query TT
- SELECT lead(x) OVER (ORDER BY x DESC), x FROM t
- ORDER BY x, lead
- ----
- NULL a
- a b
- b b
- b c
- c c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 98), ('b', 99), ('c', 98);
- query TT
- SELECT lead(x) OVER (PARTITION BY y ORDER BY x), x FROM t
- ORDER BY x, lead
- ----
- c a
- NULL b
- NULL c
- statement ok
- INSERT INTO t VALUES ('a', 98), ('a', 99);
- query TT
- SELECT lead(x) OVER (PARTITION BY y ORDER BY x), x FROM t
- ORDER BY x, lead
- ----
- a a
- b a
- c a
- NULL b
- NULL c
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(x string, y int);
- statement ok
- INSERT INTO t VALUES ('a', 1), ('b', 2), ('c', 1);
- query TT
- SELECT lead(x) OVER (PARTITION BY y ORDER BY x DESC), x FROM t
- ORDER BY x, lead
- ----
- NULL a
- NULL b
- a c
- query TT
- SELECT lead(x) OVER (PARTITION BY x ORDER BY x), x FROM t
- ORDER BY x, lead
- ----
- NULL a
- NULL b
- NULL c
- query TT
- SELECT lead(a1.x) OVER (PARTITION BY NULL ORDER BY 10000) AS q, a1.x
- FROM t AS a1, t AS a2
- ORDER BY q DESC, a1.x DESC
- ----
- NULL c
- c c
- c c
- c b
- b b
- b b
- b a
- a a
- a a
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(f1 int, f2 string, f3 numeric);
- statement ok
- INSERT INTO t VALUES (1, 'a', 1.0), (2, 'a', 1.0), (2, 'a', 1.0), (3, 'a', 1.0), (4, 'b', 0), (4, 'b', 1), (1, 'c', 'NaN'), (2, 'c', 'NaN'), (3, 'c', 1.0), (7, 'd', -5.0);
- query ITTT
- SELECT f1, f2, f3, lead(f1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 2
- 2 c NaN 3
- 3 c 1 NULL
- 4 b 1 4
- 4 b 0 NULL
- 1 a 1 2
- 2 a 1 2
- 2 a 1 3
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1, 1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 2
- 2 c NaN 3
- 3 c 1 NULL
- 4 b 1 4
- 4 b 0 NULL
- 1 a 1 2
- 2 a 1 2
- 2 a 1 3
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1, 1, NULL) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 2
- 2 c NaN 3
- 3 c 1 NULL
- 4 b 1 4
- 4 b 0 NULL
- 1 a 1 2
- 2 a 1 2
- 2 a 1 3
- 3 a 1 NULL
- # With default value
- query ITTT
- SELECT f1, f2, f3, lead(f1, 1, -1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 -1
- 1 c NaN 2
- 2 c NaN 3
- 3 c 1 -1
- 4 b 1 4
- 4 b 0 -1
- 1 a 1 2
- 2 a 1 2
- 2 a 1 3
- 3 a 1 -1
- # Complex expressions
- query ITTT
- SELECT f1, f2, f3, lead(f1 + coalesce(nullif(f3, 'NaN'), -10)) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN -8
- 2 c NaN 4
- 3 c 1 NULL
- 4 b 1 4
- 4 b 0 NULL
- 1 a 1 3
- 2 a 1 3
- 2 a 1 4
- 3 a 1 NULL
- # Nulls in the first argument
- query ITTT
- SELECT f1, f2, f3, lead(NULL::int) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(nullif(f1, 4)) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 2
- 2 c NaN 3
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 2
- 2 a 1 2
- 2 a 1 3
- 3 a 1 NULL
- # Nulls in the first argument with a default value in the third argument
- query ITTT
- SELECT f1, f2, f3, lead(NULL::int, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- # Zero offset
- query ITTT
- SELECT f1, f2, f3, lead(f1, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 7
- 1 c NaN 1
- 2 c NaN 2
- 3 c 1 3
- 4 b 1 4
- 4 b 0 4
- 1 a 1 1
- 2 a 1 2
- 2 a 1 2
- 3 a 1 3
- query ITTT
- SELECT f1, f2, f3, lead(f1 + f3, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 2
- 1 c NaN NaN
- 2 c NaN NaN
- 3 c 1 4
- 4 b 1 5
- 4 b 0 4
- 1 a 1 2
- 2 a 1 3
- 2 a 1 3
- 3 a 1 4
- # Positive offsets
- query ITTT
- SELECT f1, f2, f3, lead(f1, 2) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 3
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 2
- 2 a 1 3
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1 + f3, 2) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 4
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 3
- 2 a 1 4
- 2 a 1 NULL
- 3 a 1 NULL
- # Out of range positive offsets
- query ITTT
- SELECT f1, f2, f3, lead(f1, 10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1 + f3, 10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1 + f3, 10, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 0
- 1 c NaN 0
- 2 c NaN 0
- 3 c 1 0
- 4 b 1 0
- 4 b 0 0
- 1 a 1 0
- 2 a 1 0
- 2 a 1 0
- 3 a 1 0
- # Negative offsets
- query ITTT
- SELECT f1, f2, f3, lead(f1, -1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN 1
- 3 c 1 2
- 4 b 1 NULL
- 4 b 0 4
- 1 a 1 NULL
- 2 a 1 1
- 2 a 1 2
- 3 a 1 2
- query ITTT
- SELECT f1, f2, f3, lead(f1 + f3, -1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NaN
- 3 c 1 NaN
- 4 b 1 NULL
- 4 b 0 5
- 1 a 1 NULL
- 2 a 1 2
- 2 a 1 3
- 3 a 1 3
- query ITTT
- SELECT f1, f2, f3, lead(f1 + f3, -2) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NaN
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 2
- 2 a 1 NULL
- 3 a 1 3
- # Out of range negative offsets
- query ITTT
- SELECT f1, f2, f3, lead(f1, -10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1 + f3, -10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1, -10, 0) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 0
- 1 c NaN 0
- 2 c NaN 0
- 3 c 1 0
- 4 b 1 0
- 4 b 0 0
- 1 a 1 0
- 2 a 1 0
- 2 a 1 0
- 3 a 1 0
- # Variable per row offsets
- query ITTT
- SELECT f1, f2, f3, lead(f1, f1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 2
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 2
- 2 a 1 3
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1, f1 - 1) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN 1
- 2 c NaN 3
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 1
- 2 a 1 2
- 2 a 1 3
- 3 a 1 NULL
- # Null offsets
- query ITTT
- SELECT f1, f2, f3, lead(f1, NULL) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- query ITTT
- SELECT f1, f2, f3, lead(f1, nullif(f1, 1)) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 3
- 2 a 1 NULL
- 3 a 1 NULL
- # Null offset with default value
- query ITTT
- SELECT f1, f2, f3, lead(f1, NULL, -10) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 NULL
- 1 c NaN NULL
- 2 c NaN NULL
- 3 c 1 NULL
- 4 b 1 NULL
- 4 b 0 NULL
- 1 a 1 NULL
- 2 a 1 NULL
- 2 a 1 NULL
- 3 a 1 NULL
- # Variable per row default value
- query ITTT
- SELECT f1, f2, f3, lead(f1, 1, f3) OVER (PARTITION BY f2 ORDER BY f3 DESC, f1)
- FROM t
- ORDER BY f2 DESC, f3 DESC, f1, lead
- ----
- 7 d -5 -5
- 1 c NaN 2
- 2 c NaN 3
- 3 c 1 1
- 4 b 1 4
- 4 b 0 0
- 1 a 1 2
- 2 a 1 2
- 2 a 1 3
- 3 a 1 1
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(f1 int, f2 int);
- statement ok
- INSERT INTO t VALUES (1, 2), (1, 2), (3, 4);
- # reduce_elision code path
- # Default offset
- query II
- SELECT f1, lead(f1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 NULL
- 3 NULL
- query II
- SELECT f1, lead(f1, 1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 NULL
- 3 NULL
- # Zero offset
- query II
- SELECT f1, lead(f1, 0) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 1
- 3 3
- # Negative offset
- query II
- SELECT f1, lead(f1, -1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 NULL
- 3 NULL
- # Default value with offset 1
- query II
- SELECT f1, lead(f1, 1, 10) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 10
- 3 10
- # Default value with offset 0
- query II
- SELECT f1, lead(f1, 0, 10) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 1
- 3 3
- # Complex expression
- query II
- SELECT f1, lead(f1 * f2, 0, 10) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 2
- 3 12
- query II
- SELECT f1, lead(f1 * f2, 1, f1 * f2 + 1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 3
- 3 13
- # Complex offset
- query II
- SELECT f1, lead(f1 * f2, f1 - f1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 2
- 3 12
- query II
- SELECT f1, lead(f1 * f2, f1 - 1) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 2
- 3 NULL
- query II
- SELECT f1, lead(f1 * f2, f2 - 2 * f1, f2) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 2
- 3 4
- # Complex default value
- query II
- SELECT f1, lead(f1, 0, f1 * f2) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 1
- 3 3
- query II
- SELECT f1, lead(f1, 1, f1 * f2) OVER (PARTITION BY f1, f2)
- FROM (SELECT DISTINCT f1, f2 FROM t) q
- ORDER BY 1, 2
- ----
- 1 2
- 3 12
- # Null value in input relation
- # This was caused by a bug in the reduce elision logic
- statement ok
- CREATE TABLE t4 (f1 INTEGER)
- ----
- statement ok
- INSERT INTO t4 VALUES (NULL)
- ----
- query II
- SELECT f1, lead(0, f1 , 0) OVER (PARTITION BY f1 ORDER BY f1) FROM t4 GROUP BY f1 ORDER BY 1
- ----
- NULL NULL
- ## lag/lead ignore nulls
- statement ok
- create table t6(x int, y int);
- statement ok
- insert into t6 values (1,2), (3,null), (5,6), (7,8), (9, null), (11, null), (13, 14), (15, 16), (17, 18);
- query IIIIIIIIIIIIIIIIIIII
- select
- x,
- y,
- lag(y) over (order by x) as lag1,
- lag(y) respect nulls over (order by x) as lag1_resp,
- lag(y) ignore nulls over (order by x) as lag1_ign,
- lead(y) over (order by x) as lead1,
- lead(y) ignore nulls over (order by x) as lead1_ign,
- lag(y, 2) over (order by x) as lag2,
- lag(y, 2) ignore nulls over (order by x) as lag2_ign,
- lead(y, 2) over (order by x) as lead2,
- lead(y, 2) ignore nulls over (order by x) as lead2_ign,
- lag(y, 2, -1) ignore nulls over (order by x) as lag2_ign_def,
- lead(y, 2, -1) ignore nulls over (order by x) as lead2_ign_def,
- lag(y, 2, 16) ignore nulls over (order by x) as lag2_ign_def16,
- lead(y, 2, 16) ignore nulls over (order by x) as lead2_ign_def16,
- lag(y, -1, 100) ignore nulls over (order by x) as lag_neg_offset,
- lead(y, -2, 100) ignore nulls over (order by x) as lead_neg_offset,
- lag(y, y/5+1) ignore nulls over (order by x) as lag_dynamic_offset,
- lead(y, y/5+1) ignore nulls over (order by x) as lead_dynamic_offset,
- lag(y, null) ignore nulls over (order by x) as lag_literal_null_offset
- from t6
- order by x;
- ----
- 1 2 NULL NULL NULL NULL 6 NULL NULL 6 8 -1 8 16 8 6 100 NULL 6 NULL
- 3 NULL 2 2 2 6 6 NULL NULL 8 8 -1 8 16 8 6 100 NULL NULL NULL
- 5 6 NULL NULL 2 8 8 2 NULL NULL 14 -1 14 16 14 8 100 NULL 14 NULL
- 7 8 6 6 6 NULL 14 NULL 2 NULL 16 2 16 2 16 14 2 2 16 NULL
- 9 NULL 8 8 8 NULL 14 6 6 14 16 6 16 6 16 14 6 NULL NULL NULL
- 11 NULL NULL NULL 8 14 14 8 6 16 16 6 16 6 16 14 6 NULL NULL NULL
- 13 14 NULL NULL 8 16 16 NULL 6 18 18 6 18 6 18 16 6 2 NULL NULL
- 15 16 14 14 14 18 18 NULL 8 NULL NULL 8 -1 8 16 18 8 2 NULL NULL
- 17 18 16 16 16 NULL NULL 14 14 NULL NULL 14 -1 14 16 100 14 6 NULL NULL
- # Same as above, but with a `partition by`
- query IIIIIIIIIIIIIIIIIIII
- select
- x,
- y,
- lag(y) over (partition by x%4 order by x) as lag1,
- lag(y) respect nulls over (partition by x%4 order by x) as lag1_resp,
- lag(y) ignore nulls over (partition by x%4 order by x) as lag1_ign,
- lead(y) over (partition by x%4 order by x) as lead1,
- lead(y) ignore nulls over (partition by x%4 order by x) as lead1_ign,
- lag(y, 2) over (partition by x%4 order by x) as lag2,
- lag(y, 2) ignore nulls over (partition by x%4 order by x) as lag2_ign,
- lead(y, 2) over (partition by x%4 order by x) as lead2,
- lead(y, 2) ignore nulls over (partition by x%4 order by x) as lead2_ign,
- lag(y, 2, -1) ignore nulls over (partition by x%4 order by x) as lag2_ign_def,
- lead(y, 2, -1) ignore nulls over (partition by x%4 order by x) as lead2_ign_def,
- lag(y, 2, 16) ignore nulls over (partition by x%4 order by x) as lag2_ign_def16,
- lead(y, 2, 16) ignore nulls over (partition by x%4 order by x) as lead2_ign_def16,
- lag(y, -1, 100) ignore nulls over (partition by x%4 order by x) as lag_neg_offset,
- lead(y, -2, 100) ignore nulls over (partition by x%4 order by x) as lead_neg_offset,
- lag(y, y/5+1) ignore nulls over (partition by x%4 order by x) as lag_dynamic_offset,
- lead(y, y/5+1) ignore nulls over (partition by x%4 order by x) as lead_dynamic_offset,
- lag(y, null) ignore nulls over (partition by x%4 order by x) as lag_literal_null_offset
- from t6
- order by x%4, x;
- ----
- 1 2 NULL NULL NULL 6 6 NULL NULL NULL 14 -1 14 16 14 6 100 NULL 6 NULL
- 5 6 2 2 2 NULL 14 NULL NULL 14 18 -1 18 16 18 14 100 NULL 18 NULL
- 9 NULL 6 6 6 14 14 2 2 18 18 2 18 2 18 14 2 NULL NULL NULL
- 13 14 NULL NULL 6 18 18 6 2 NULL NULL 2 -1 2 16 18 2 NULL NULL NULL
- 17 18 14 14 14 NULL NULL NULL 6 NULL NULL 6 -1 6 16 100 6 NULL NULL NULL
- 3 NULL NULL NULL NULL 8 8 NULL NULL NULL 16 -1 16 16 16 8 100 NULL NULL NULL
- 7 8 NULL NULL NULL NULL 16 NULL NULL 16 NULL -1 -1 16 16 16 100 NULL NULL NULL
- 11 NULL 8 8 8 16 16 NULL NULL NULL NULL -1 -1 16 16 16 100 NULL NULL NULL
- 15 16 NULL NULL 8 NULL NULL 8 NULL NULL NULL -1 -1 16 16 100 100 NULL NULL NULL
- statement ok
- CREATE VIEW t6_more_nulls AS
- SELECT
- x,
- CASE WHEN y < 15 AND y > 7 THEN null ELSE y END AS y
- FROM t6;
- query IIIIIIII
- select
- x,
- y,
- lag(y) ignore nulls over (order by x) as lag1,
- lag(y,2) ignore nulls over (order by x) as lag2,
- lag(y,3) ignore nulls over (order by x) as lag3,
- lead(y) ignore nulls over (order by x) as lead1,
- lead(y,2) ignore nulls over (order by x) as lead2,
- lead(y,3) ignore nulls over (order by x) as lead3
- from t6_more_nulls
- order by x;
- ----
- 1 2 NULL NULL NULL 6 16 18
- 3 NULL 2 NULL NULL 6 16 18
- 5 6 2 NULL NULL 16 18 NULL
- 7 NULL 6 2 NULL 16 18 NULL
- 9 NULL 6 2 NULL 16 18 NULL
- 11 NULL 6 2 NULL 16 18 NULL
- 13 NULL 6 2 NULL 16 18 NULL
- 15 16 6 2 NULL 18 NULL NULL
- 17 18 16 6 2 NULL NULL NULL
- # Test the `offset = 0` code path. This currently doesn't work with nulls if IGNORE NULLS is specified,
- # so we just filter out nulls for now.
- # See https://materializeinc.slack.com/archives/C063H5S7NKE/p1724962369706729
- # Also tests negative dynamic offsets.
- statement ok
- CREATE VIEW t6_no_nulls AS
- SELECT
- x,
- COALESCE(y,-11) AS y
- FROM t6;
- query IIIIIII
- SELECT
- x,
- y,
- y/10,
- lag(y, y/10) OVER (ORDER BY x),
- lag(y, y/10) IGNORE NULLS OVER (ORDER BY x),
- lead(y, y/10) OVER (ORDER BY x),
- lead(y, y/10) IGNORE NULLS OVER (ORDER BY x)
- FROM t6_no_nulls
- ORDER BY x;
- ----
- 1 2 0 2 2 2 2
- 3 -11 -1 6 6 2 2
- 5 6 0 6 6 6 6
- 7 8 0 8 8 8 8
- 9 -11 -1 -11 -11 8 8
- 11 -11 -1 14 14 -11 -11
- 13 14 1 -11 -11 16 16
- 15 16 1 14 14 18 18
- 17 18 1 16 16 NULL NULL
- query error db error: ERROR: IGNORE NULLS and RESPECT NULLS options for functions other than LAG and LEAD not yet supported
- select first_value(x) ignore nulls over() from t6;
- query error db error: ERROR: IGNORE NULLS and RESPECT NULLS options for functions other than LAG and LEAD not yet supported
- select row_number() ignore nulls over();
- query error db error: ERROR: Both IGNORE NULLS and RESPECT NULLS were given\.
- select row_number() ignore nulls respect nulls over();
- ## window frames
- # Invalid frame start
- query error frame start cannot be UNBOUNDED FOLLOWING
- SELECT row_number() OVER (ROWS UNBOUNDED FOLLOWING)
- # Invalid frame end
- query error frame end cannot be UNBOUNDED PRECEDING
- SELECT row_number() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED PRECEDING)
- # End frame can't be of a type that comes before the start bound
- query error frame starting from current row cannot have preceding rows
- SELECT row_number() OVER (ROWS BETWEEN CURRENT ROW AND 1 PRECEDING)
- query error frame starting from following row cannot have preceding rows
- SELECT row_number() OVER (ROWS BETWEEN 1 FOLLOWING AND 1 PRECEDING)
- query error frame starting from following row cannot have preceding rows
- SELECT row_number() OVER (ROWS BETWEEN 1 FOLLOWING AND CURRENT ROW)
- # But end offsets can come before start offsets
- query I
- SELECT row_number() OVER (ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING)
- ----
- 1
- query I
- SELECT row_number() OVER (ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
- ----
- 1
- # Negative offsets are not allowed
- # Our error message is different from Postgres, so it's not checked here
- query error
- SELECT row_number() OVER (ROWS -1 PRECEDING)
- query error
- SELECT row_number() OVER (ROWS -1 FOLLOWING)
- # Current implementation restrictions
- # RANGE is not supported outside of the default frame
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN 1 PRECEDING AND CURRENT ROW)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN CURRENT ROW AND 1 FOLLOWING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
- query error RANGE in non-default window frames not yet supported
- SELECT row_number() OVER (RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
- # Default window frame works fine
- query I
- SELECT row_number() OVER ()
- ----
- 1
- query I
- SELECT row_number() OVER (RANGE UNBOUNDED PRECEDING)
- ----
- 1
- query I
- SELECT row_number() OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- ----
- 1
- # GROUPS is not supported at all
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN 1 PRECEDING AND 1 PRECEDING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN 1 PRECEDING AND CURRENT ROW)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN CURRENT ROW AND CURRENT ROW)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
- query error GROUPS in window frames not yet supported
- SELECT row_number() OVER (GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
- ## first_value
- statement ok
- DROP TABLE t;
- statement ok
- CREATE TABLE t(f1 int, f2 string, f3 int);
- statement ok
- INSERT INTO t VALUES (1, 'a', 1), (2, 'a', 2), (2, 'a', 3), (3, 'a', 4), (4, 'b', 5), (4, 'b', 6), (1, 'c', 7), (2, 'c', 8), (3, 'c', 9), (7, 'd', 10);
- # Default frame (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN UNBOUNDED PRECEDING AND x PRECEDING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 NULL
- 4 b 6 4
- 1 c 7 NULL
- 2 c 8 1
- 3 c 9 1
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 1
- 3 a 4 1
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 1
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 10 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN UNBOUNDED PRECEDING AND x FOLLOWING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN 0 PRECEDING AND x PRECEDING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND 10 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN x PRECEDING AND 0 PRECEDING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN x PRECEDING AND y PRECEDING, where x < y
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN x PRECEDING AND y PRECEDING, where x > y
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 NULL
- 4 b 6 4
- 1 c 7 NULL
- 2 c 8 1
- 3 c 9 1
- 7 d 10 NULL
- # ROWS BETWEEN x PRECEDING AND y PRECEDING, where x == y
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 NULL
- 4 b 6 4
- 1 c 7 NULL
- 2 c 8 1
- 3 c 9 2
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 1
- 3 a 4 2
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 1
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 PRECEDING AND 10 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN x PRECEDING AND CURRENT ROW
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN x PRECEDING AND x FOLLOWING
- # Equivalent to ROWS BETWEEN x PRECEDING AND CURRENT ROW for first_value
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 PRECEDING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN x PRECEDING AND UNBOUNDED FOLLOWING
- # Equivalent to ROWS BETWEEN x PRECEDING AND CURRENT ROW for first_value
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN CURRENT ROW AND CURRENT ROW
- # Always returns current row
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN CURRENT ROW AND x FOLLOWING
- # Always returns current row
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN CURRENT ROW AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN CURRENT ROW AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- # Always returns current row
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN 0 FOLLOWING AND x FOLLOWING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 FOLLOWING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 FOLLOWING AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN x FOLLOWING AND 0 FOLLOWING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN x FOLLOWING AND y FOLLOWING, where x < y
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 2
- 2 a 2 2
- 2 a 3 3
- 3 a 4 NULL
- 4 b 5 4
- 4 b 6 NULL
- 1 c 7 2
- 2 c 8 3
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN x FOLLOWING AND y FOLLOWING, where x > y
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN x FOLLOWING AND y FOLLOWING, where x == y
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 2
- 2 a 2 2
- 2 a 3 3
- 3 a 4 NULL
- 4 b 5 4
- 4 b 6 NULL
- 1 c 7 2
- 2 c 8 3
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 FOLLOWING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 2
- 2 a 2 3
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 3
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 FOLLOWING AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN x FOLLOWING AND UNBOUNDED FOLLOWING
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 0 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 2
- 2 a 2 2
- 2 a 3 3
- 3 a 4 NULL
- 4 b 5 4
- 4 b 6 NULL
- 1 c 7 2
- 2 c 8 3
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 2 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 2
- 2 a 2 3
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 3
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 10 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # Test offset limits
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 100 FOLLOWING AND 1000001 FOLLOWING)
- # Test near-overflow behavior on offsets
- # u64::MAX FOLLOWING
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 18446744073709551615 FOLLOWING AND 18446744073709551615 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1000001 PRECEDING AND 100 FOLLOWING)
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 18446744073709551614 FOLLOWING AND 18446744073709551615 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- query error Expected literal unsigned integer, found operator "\-"
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 PRECEDING AND -1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- # u64::MAX PRECEDING
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 18446744073709551615 PRECEDING AND 18446744073709551615 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 18446744073709551615 PRECEDING AND 18446744073709551614 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1000 PRECEDING AND 1000 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, first_value(f1) OVER (PARTITION BY f2 ORDER BY f1, f3 ROWS BETWEEN 1000 PRECEDING AND 999 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, first_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # reduce_elision code path
- statement ok
- CREATE TABLE t5 (f1 INTEGER)
- ----
- statement ok
- INSERT INTO t5 VALUES (1)
- ----
- # Default frame, includes current row
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame starting at UNBOUNDED PRECEDING
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame starting at 1 PRECEDING
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame starting at 0 PRECEDING
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame starting at CURRENT ROW
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame starting at 0 FOLLOWING
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 FOLLOWING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame starting at 1 FOLLOWING
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 FOLLOWING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, first_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- ## last_value
- # Default frame (RANGE BETWEEN UNBOUNDED FOLLOWING AND CURRENT ROW)
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # Default frame with large peer group
- # Note: there are multiple valid results of this query (because the default frame is up through the current row's last
- # ORDER BY peer, and the ordering among ORDER BY peers is unspecified), but we make the result stable by internally
- # always adding all remaining columns into our orderings.
- query ITII
- SELECT f1, f2, f3, last_value(f3) OVER (PARTITION BY f2 ORDER BY f1)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 3
- 2 a 3 3
- 3 a 4 4
- 4 b 5 6
- 4 b 6 6
- 1 c 7 7
- 2 c 8 8
- 3 c 9 9
- 7 d 10 10
- # ROWS BETWEEN x FOLLOWING AND UNBOUNDED FOLLOWING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 NULL
- 4 b 6 4
- 1 c 7 NULL
- 2 c 8 1
- 3 c 9 1
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 1
- 3 a 4 1
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 1
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN x PRECEDING AND UNBOUNDED FOLLOWING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN x FOLLOWING AND 0 FOLLOWING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN 0 FOLLOWING AND x FOLLOWING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 FOLLOWING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 FOLLOWING AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN y FOLLOWING AND x FOLLOWING, where x < y
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN y FOLLOWING AND x FOLLOWING, where x > y
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 NULL
- 4 b 6 4
- 1 c 7 NULL
- 2 c 8 1
- 3 c 9 1
- 7 d 10 NULL
- # ROWS BETWEEN x FOLLOWING AND y FOLLOWING, where x == y
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 NULL
- 4 b 6 4
- 1 c 7 NULL
- 2 c 8 1
- 3 c 9 2
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 FOLLOWING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 1
- 3 a 4 2
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 1
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 FOLLOWING AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN CURRENT ROW AND x FOLLOWING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN CURRENT ROW AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN CURRENT ROW AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN x PRECEDING AND x FOLLOWING
- # Equivalent to ROWS BETWEEN CURRENT ROW AND x FOLLOWING for last_value
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN UNBOUNDED PRECEDING AND x FOLLOWING
- # Equivalent to ROWS BETWEEN CURRENT ROW AND x FOLLOWING for last_value
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 2
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 2
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 2
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 1
- 2 a 3 1
- 3 a 4 1
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 1
- 3 c 9 1
- 7 d 10 7
- # ROWS BETWEEN CURRENT ROW AND CURRENT ROW
- # Always returns current row
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN x PRECEDING AND CURRENT ROW
- # Always returns current row
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- # Always returns current row
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN x PRECEDING AND 0 PRECEDING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- # ROWS BETWEEN 0 PRECEDING AND x PRECEDING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 PRECEDING AND 10 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN y PRECEDING AND x PRECEDING, where x < y
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 2
- 2 a 2 2
- 2 a 3 3
- 3 a 4 NULL
- 4 b 5 4
- 4 b 6 NULL
- 1 c 7 2
- 2 c 8 3
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN y PRECEDING AND x PRECEDING, where x > y
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN y PRECEDING AND x PRECEDING, where x == y
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 2
- 2 a 2 2
- 2 a 3 3
- 3 a 4 NULL
- 4 b 5 4
- 4 b 6 NULL
- 1 c 7 2
- 2 c 8 3
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 2
- 2 a 2 3
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 3
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 10 PRECEDING AND 10 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # ROWS BETWEEN UNBOUNDED PRECEDING AND x PRECEDING
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 1
- 2 a 2 2
- 2 a 3 2
- 3 a 4 3
- 4 b 5 4
- 4 b 6 4
- 1 c 7 1
- 2 c 8 2
- 3 c 9 3
- 7 d 10 7
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 2
- 2 a 2 2
- 2 a 3 3
- 3 a 4 NULL
- 4 b 5 4
- 4 b 6 NULL
- 1 c 7 2
- 2 c 8 3
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 2 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 2
- 2 a 2 3
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 3
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 10 PRECEDING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # Test near-overflow behavior on offsets
- # u64::MAX FOLLOWING
- # u64::MAX PRECEDING
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 18446744073709551615 FOLLOWING AND 18446744073709551615 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- query error db error: ERROR: Window frame offsets greater than 1000000 are currently not supported
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 18446744073709551614 FOLLOWING AND 18446744073709551615 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1000 FOLLOWING AND 1000 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- query ITII
- SELECT f1, f2, f3, last_value(f1) OVER (PARTITION BY f2 ORDER BY f1 DESC, f3 DESC ROWS BETWEEN 1000 FOLLOWING AND 1001 FOLLOWING)
- FROM t
- ORDER BY f2, f3, f1, last_value
- ----
- 1 a 1 NULL
- 2 a 2 NULL
- 2 a 3 NULL
- 3 a 4 NULL
- 4 b 5 NULL
- 4 b 6 NULL
- 1 c 7 NULL
- 2 c 8 NULL
- 3 c 9 NULL
- 7 d 10 NULL
- # reduce_elision code path
- # Using the same table as first_value
- # Default frame, includes current row
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame ending at UNBOUNDED FOLLOWING
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame ending at 1 FOLLOWING
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 FOLLOWING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame ending at 0 FOLLOWING
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 FOLLOWING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame ending at CURRENT ROW
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame ending at 0 PRECEDING
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 1
- # Frame ending at 1 PRECEDING
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- query II
- SELECT f1, last_value(f1) OVER (PARTITION BY f1 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
- FROM t5
- GROUP BY f1
- ----
- 1 NULL
- # Check some HIR plans to verify that the lifting of window functions to the top of Maps is actually happening.
- statement ok
- CREATE TABLE foo (
- a int,
- b text
- );
- statement ok
- INSERT INTO foo (a, b) VALUES (0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three');
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT 3 + lag(a) OVER (ORDER BY a) + 5 + 27
- FROM foo;
- ----
- Project (#3)
- Map (lag(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), (((3 + #2{?column?}) + 5) + 27))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT -lag(10*right_a+3) OVER (ORDER BY right_a NULLS FIRST), -sum(foo.a), b
- FROM foo LEFT JOIN (SELECT a AS right_a FROM foo WHERE a<2) ON foo.a = right_a
- GROUP BY b, right_a;
- ----
- Project (#4, #5, #0)
- Map (lag(row(((10 * #1{right_a}) + 3), 1, null)) over (order by [#1{right_a} asc nulls_first]), -(#3{?column?}), -(#2{?column?}))
- Reduce group_by=[#3, #4] aggregates=[sum(#0{a})]
- Map (#1{b}, #2{right_a})
- LeftOuterJoin (#0{a} = #2{right_a})
- Get materialize.public.foo
- Project (#0)
- Filter (#0{a} < 2)
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT 3 + lag(a) OVER (ORDER BY a) AS o
- FROM foo
- ORDER BY o;
- ----
- Finish order_by=[#0 asc nulls_last] output=[#0]
- Project (#3)
- Map (lag(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), (3 + #2{?column?}))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT
- a,
- 3 + lag(a) OVER (ORDER BY a),
- 3 + lag(a) OVER (ORDER BY a),
- lag(a) OVER (ORDER BY a),
- lead(a) OVER (ORDER BY a),
- 5 + lag(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- Finish order_by=[#0 asc nulls_last] output=[#0..=#5]
- Project (#0, #4, #4, #2, #3, #5)
- Map (lag(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), lead(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), (3 + #2{?column?}), (5 + #2{?column?}))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- query IIIIII nosort
- SELECT
- a,
- 3 + lag(a) OVER (ORDER BY a),
- 3 + lag(a) OVER (ORDER BY a),
- lag(a) OVER (ORDER BY a),
- lead(a) OVER (ORDER BY a),
- 5 + lag(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 NULL NULL NULL 1 NULL
- 1 3 3 0 2 5
- 2 4 4 1 3 6
- 3 5 5 2 NULL 7
- # Two window function calls in the same HirScalarExpr, but both calls are the same
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT a, b, lag(a) OVER (ORDER BY a) + lag(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- Finish order_by=[#0 asc nulls_last] output=[#0..=#2]
- Project (#0, #1, #3)
- Map (lag(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), (#2{?column?} + #2{?column?}))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- query ITI nosort
- SELECT a, b, lag(a) OVER (ORDER BY a) + lag(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL
- 1 one 0
- 2 two 2
- 3 three 4
- # Two window function calls in the same HirScalarExpr, and they are different
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT a, b, lag(a) OVER (ORDER BY a) + lead(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- Finish order_by=[#0 asc nulls_last] output=[#0..=#2]
- Project (#0, #1, #4)
- Map (lead(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), lag(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), (#3{?column?} + #2{?column?}))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- query ITI nosort
- SELECT a, b, lag(a) OVER (ORDER BY a) + lead(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL
- 1 one 2
- 2 two 4
- 3 three NULL
- # Window function in DISTINCT ON
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT DISTINCT ON(1 + lag(a, 1, 0) OVER (ORDER BY a)) *
- FROM foo;
- ----
- Project (#0, #1)
- TopK group_by=[#3] limit=1
- Map (lag(row(#0{a}, 1, 0)) over (order by [#0{a} asc nulls_last]), (1 + #2{?column?}))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- query IIT
- SELECT 1 + lag(a, 1, 0) OVER (ORDER BY a), *
- FROM foo
- ORDER BY a;
- ----
- 1 0 zero
- 1 1 one
- 2 2 two
- 3 3 three
- query IT
- SELECT DISTINCT ON(1 + lag(a, 1, 0) OVER (ORDER BY a)) *
- FROM foo
- ORDER BY 1 + lag(a, 1, 0) OVER (ORDER BY a);
- ----
- 0 zero
- 2 two
- 3 three
- query IIT nosort
- SELECT 1 + lag(a, 1, 0) OVER (ORDER BY a), *
- FROM foo
- ORDER BY 1 + lag(a, 1, 0) OVER (ORDER BY a), a ASC;
- ----
- 1 0 zero
- 1 1 one
- 2 2 two
- 3 3 three
- query IT nosort
- SELECT DISTINCT ON(1 + lag(a, 1, 0) OVER (ORDER BY a)) *
- FROM foo
- ORDER BY 1 + lag(a, 1, 0) OVER (ORDER BY a), a ASC;
- ----
- 0 zero
- 2 two
- 3 three
- query error db error: ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
- SELECT DISTINCT ON(1 + lag(a, 1, 0) OVER (ORDER BY a)) *
- FROM foo
- ORDER BY lag(a, 1, 0) OVER (ORDER BY a), a DESC;
- query IIIT nosort
- SELECT 1 + lag(a, 1, 0) OVER (ORDER BY a), lead(a) OVER (ORDER BY b) AS o, a, b
- FROM foo
- ORDER BY 1 + lag(a, 1, 0) OVER (ORDER BY a), o DESC;
- ----
- 1 NULL 0 zero
- 1 3 1 one
- 2 0 2 two
- 3 2 3 three
- query IIT nosort
- SELECT DISTINCT ON(1 + lag(a, 1, 0) OVER (ORDER BY a)) lead(a) OVER (ORDER BY b) AS o, a, b
- FROM foo
- ORDER BY 1 + lag(a, 1, 0) OVER (ORDER BY a), o DESC;
- ----
- NULL 0 zero
- 0 2 two
- 2 3 three
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT DISTINCT ON(5 + lag(a) OVER (ORDER BY a)) lead(a) OVER (ORDER BY b) AS o
- FROM foo
- ORDER BY 5 + lag(a) OVER (ORDER BY a), o;
- ----
- Finish order_by=[#4 asc nulls_last, #3 asc nulls_last] output=[#3]
- TopK group_by=[#4] order_by=[#3 asc nulls_last] limit=1
- Map (lag(row(#0{a}, 1, null)) over (order by [#0{a} asc nulls_last]), lead(row(#0{a}, 1, null)) over (order by [#1{b} asc nulls_last]), (5 + #2{?column?}))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- # Nested window function call in the argument of a window function call (Postgres doesn't allow this, but we do)
- query ITI nosort
- SELECT a, b, lag(lag(a) OVER (ORDER BY a)) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL
- 1 one NULL
- 2 two 0
- 3 three 1
- query ITI nosort
- SELECT a, b, lag(lag(a) OVER (PARTITION BY length(b) ORDER BY a)) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL
- 1 one NULL
- 2 two NULL
- 3 three 1
- # The inner window function call also appears outside
- query ITII nosort
- SELECT a, b, lag(lag(a) OVER (ORDER BY a)) OVER (ORDER BY a), lag(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL NULL
- 1 one NULL 0
- 2 two 0 1
- 3 three 1 2
- query ITII nosort
- SELECT a, b, lag(a) OVER (ORDER BY a), lag(lag(a) OVER (ORDER BY a)) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL NULL
- 1 one 0 NULL
- 2 two 1 0
- 3 three 2 1
- # Nested window function call in the PARTITION BY of a window function call (Postgres doesn't allow this, but we do)
- query ITII nosort
- SELECT a, b, lag(a) OVER (PARTITION BY lag(length(b)) OVER (ORDER BY a) ORDER BY a), lag(length(b)) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL NULL
- 1 one NULL 4
- 2 two NULL 3
- 3 three 2 3
- query ITI nosort
- SELECT a, b, lag(a) OVER (PARTITION BY lag(length(b)) OVER (ORDER BY a) ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL
- 1 one NULL
- 2 two NULL
- 3 three 2
- query ITII nosort
- SELECT a, b, row_number() OVER (PARTITION BY lag(length(b)) OVER (ORDER BY a) ORDER BY a), lag(length(b)) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero 1 NULL
- 1 one 1 4
- 2 two 1 3
- 3 three 2 3
- # Nested window function calls in both the argument and the PARTITION BY of a window function call (Postgres doesn't
- # allow this, but we do)
- query ITI nosort
- SELECT a, b, lead(lag(a) OVER (PARTITION BY lag(length(b)) OVER (ORDER BY a) ORDER BY a), 1, -5) OVER (ORDER BY a)
- FROM foo
- ORDER BY a;
- ----
- 0 zero NULL
- 1 one NULL
- 2 two 2
- 3 three -5
- # Nested window function calls in the ORDER BY of a window function call (Postgres doesn't allow this, but we do)
- query ITII nosort
- SELECT a, b, lag(a) OVER (ORDER BY lag(a) OVER (ORDER BY a)), lag(a) OVER (ORDER BY a)
- FROM foo
- ORDER BY lag(a) OVER (ORDER BY a);
- ----
- 1 one NULL 0
- 2 two 1 1
- 3 three 2 2
- 0 zero 3 NULL
- query ITI
- SELECT a, b, lag(a) OVER (ORDER BY lag(a) OVER (ORDER BY a))
- FROM foo
- ORDER BY a;
- ----
- 0 zero 3
- 1 one NULL
- 2 two 1
- 3 three 2
- # Window function inside CASE WHEN
- # Regression test for https://github.com/MaterializeInc/database-issues/issues/6250
- statement ok
- CREATE TABLE bools(cond bool, x int);
- statement ok
- INSERT INTO bools VALUES (true, 0), (false, 1), (false, 2);
- # The window function call should be lifted outside of the If
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT
- cond,
- x,
- CASE
- WHEN cond THEN
- first_value(x) OVER (ORDER BY x DESC)
- ELSE
- 42
- END
- FROM bools;
- ----
- Project (#0, #1, #3)
- Map (first_value(#1{x}) over (order by [#1{x} desc nulls_first]), case when #0{cond} then #2{?column?} else 42 end)
- Get materialize.public.bools
- Target cluster: quickstart
- EOF
- query TII
- SELECT
- cond,
- x,
- CASE
- WHEN cond THEN
- first_value(x) OVER (ORDER BY x DESC)
- ELSE
- 42
- END
- FROM bools
- ORDER BY x;
- ----
- true 0 2
- false 1 42
- false 2 42
- statement ok
- CREATE TABLE tcm(
- chat_id int,
- chat_message_id int,
- message_tstamp date,
- xxx_id int,
- first_xxx_id int,
- user_id int,
- boolean_flag bool
- );
- statement ok
- INSERT INTO tcm VALUES
- (
- 5814889,
- 78687406,
- '2023-08-04'::DATE,
- 11111111,
- null,
- 22222221,
- true
- ),
- (
- 5814889,
- 78707836,
- '2023-08-05'::DATE,
- 11111112,
- 923095,
- 22222222,
- false
- ),
- (
- 5814889,
- 78708445,
- '2023-08-06'::DATE,
- 11111113,
- 743482,
- 22222223,
- false
- ),
- (
- 581488900,
- 78687406,
- '2023-08-04'::DATE,
- 11111111,
- null,
- 22222221,
- true
- ),
- (
- 581488900,
- 78707836,
- '2023-08-05'::DATE,
- 11111112,
- 923095,
- 22222222,
- false
- ),
- (
- 581488900,
- 78708445,
- '2023-08-06'::DATE,
- 11111113,
- 743482,
- 22222223,
- true
- );
- query IITIIIIT nosort
- SELECT
- tcm.chat_id AS chat_id,
- tcm.chat_message_id AS chat_message_id,
- tcm.message_tstamp AS message_tstamp,
- tcm.first_xxx_id AS first_xxx_id,
- lead(tcm.first_xxx_id) ignore nulls over (partition by tcm.chat_id order by tcm.message_tstamp) AS _lead,
- lag(tcm.first_xxx_id) ignore nulls over (partition by tcm.chat_id order by tcm.message_tstamp) AS _lag,
- CASE
- WHEN tcm.boolean_flag THEN
- coalesce(
- lead(tcm.first_xxx_id) ignore nulls over (partition by tcm.chat_id order by tcm.message_tstamp),
- lag(tcm.first_xxx_id) ignore nulls over (partition by tcm.chat_id order by tcm.message_tstamp),
- tcm.xxx_id
- )
- ELSE tcm.user_id end AS xxx_id,
- tcm.boolean_flag AS boolean_flag
- FROM tcm
- ORDER BY chat_id, message_tstamp;
- ----
- 5814889 78687406 2023-08-04 NULL 923095 NULL 923095 true
- 5814889 78707836 2023-08-05 923095 743482 NULL 22222222 false
- 5814889 78708445 2023-08-06 743482 NULL 923095 22222223 false
- 581488900 78687406 2023-08-04 NULL 923095 NULL 923095 true
- 581488900 78707836 2023-08-05 923095 743482 NULL 22222222 false
- 581488900 78708445 2023-08-06 743482 NULL 923095 923095 true
- query IITIIT nosort
- SELECT
- tcm.chat_id AS chat_id,
- tcm.chat_message_id AS chat_message_id,
- tcm.message_tstamp AS message_tstamp,
- tcm.first_xxx_id AS first_xxx_id,
- CASE
- WHEN tcm.boolean_flag THEN
- coalesce(
- lead(tcm.first_xxx_id) ignore nulls over (partition by tcm.chat_id order by tcm.message_tstamp),
- lag(tcm.first_xxx_id) ignore nulls over (partition by tcm.chat_id order by tcm.message_tstamp),
- tcm.xxx_id
- )
- ELSE tcm.user_id end AS xxx_id,
- tcm.boolean_flag AS boolean_flag
- FROM tcm
- ORDER BY chat_id, message_tstamp;
- ----
- 5814889 78687406 2023-08-04 NULL 923095 true
- 5814889 78707836 2023-08-05 923095 22222222 false
- 5814889 78708445 2023-08-06 743482 22222223 false
- 581488900 78687406 2023-08-04 NULL 923095 true
- 581488900 78707836 2023-08-05 923095 22222222 false
- 581488900 78708445 2023-08-06 743482 923095 true
- # Window func with (non-windowed) aggregations
- query error db error: ERROR: window functions are not allowed in aggregate function \(function pg_catalog\.lag\)
- EXPLAIN RAW PLAN FOR
- SELECT sum(lag(a) OVER ())
- FROM foo;
- query III nosort
- SELECT length(b), sum(a), lag(sum(a)) OVER (ORDER BY sum(a))
- FROM foo
- GROUP BY length(b)
- ORDER BY sum(a), length(b);
- ----
- 4 0 NULL
- 3 3 0
- 5 3 3
- query III nosort
- SELECT length(b), sum(a), lag(sum(a)) OVER (ORDER BY length(b))
- FROM foo
- GROUP BY length(b)
- ORDER BY length(b);
- ----
- 3 3 NULL
- 4 0 3
- 5 3 0
- query III
- SELECT * FROM
- ((SELECT length(b), sum(a), lag(sum(a)) OVER (ORDER BY sum(a))
- FROM foo
- GROUP BY length(b))
- UNION
- (SELECT length(b), sum(a), lag(sum(a)) OVER (ORDER BY length(b))
- FROM foo
- GROUP BY length(b))) r(x, y, z)
- ORDER BY x, y, z;
- ----
- 3 3 0
- 3 3 NULL
- 4 0 3
- 4 0 NULL
- 5 3 0
- 5 3 3
- query IIII nosort
- SELECT *, row_number() OVER (PARTITION BY len ORDER BY sum DESC, lag NULLS FIRST) as row_num FROM (
- (SELECT length(b) AS len, sum(a) AS sum, lag(sum(a)) OVER (ORDER BY sum(a)) AS lag
- FROM foo
- GROUP BY length(b))
- UNION
- (SELECT length(b), -1 + sum(a) + row_number() OVER (ORDER BY length(b)), lag(sum(a)) OVER (ORDER BY length(b))
- FROM foo
- GROUP BY length(b))
- ) AS sq
- ORDER BY len, row_num;
- ----
- 3 3 NULL 1
- 3 3 0 2
- 4 1 3 1
- 4 0 NULL 2
- 5 5 0 1
- 5 3 3 2
- ## Subqueries
- # Correlated scalar subquery in the 2nd argument of lag
- query ITI nosort
- SELECT *,
- lag(
- outer_a,
- (SELECT count(*) FROM foo WHERE length(b) = length(outer_b))::integer
- ) OVER (ORDER BY outer_a)
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY outer_a;
- ----
- 0 zero NULL
- 1 one NULL
- 2 two 0
- 3 three 2
- # Add a correlated IN subquery at the 3rd argument of lag
- query ITI nosort
- SELECT *,
- lag(
- outer_a,
- (SELECT count(*) FROM foo WHERE length(b) = length(outer_b))::integer,
- CASE WHEN outer_a - 1 IN (SELECT a FrOM foo) THEN 100 ELSE 500 END
- ) OVER (ORDER BY outer_a)
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY outer_a;
- ----
- 0 zero 500
- 1 one 100
- 2 two 0
- 3 three 2
- # Correlated subquery in the PARTITION BY.
- # The same subquery is also present in the SELECT to make the output more human-friendly.
- query IITI nosort
- SELECT (SELECT count(*) FROM foo WHERE length(b) = length(outer_b)) as part, *,
- lag(outer_a) OVER (
- PARTITION BY (SELECT count(*) FROM foo WHERE length(b) = length(outer_b))
- ORDER BY outer_a
- )
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY part, outer_a;
- ----
- 1 0 zero NULL
- 1 3 three 0
- 2 1 one NULL
- 2 2 two 1
- # Same query as the previous, but the subquery is not present in the SELECT
- query ITI nosort
- SELECT *,
- lag(outer_a) OVER (
- PARTITION BY (SELECT count(*) FROM foo WHERE length(b) = length(outer_b))
- ORDER BY outer_a
- )
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY outer_a;
- ----
- 0 zero NULL
- 1 one NULL
- 2 two 1
- 3 three 0
- # Correlated subquery in the ORDER BY of a window function.
- # The same subquery is also present in the SELECT to make the output more human-friendly.
- query IITI nosort
- SELECT (SELECT count(*) FROM foo WHERE length(outer_b) > a + 2) as ord, *,
- lag(outer_a) OVER (
- ORDER BY (SELECT count(*) FROM foo WHERE length(outer_b) > a + 2), outer_a
- )
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY ord, outer_a;
- ----
- 1 1 one NULL
- 1 2 two 1
- 2 0 zero 2
- 3 3 three 0
- # Same query as the previous, but the subquery is not present in the SELECT
- query ITI nosort
- SELECT *,
- lag(outer_a) OVER (
- ORDER BY (SELECT count(*) FROM foo WHERE length(outer_b) > a + 2), outer_a
- )
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY outer_a;
- ----
- 0 zero 2
- 1 one NULL
- 2 two 1
- 3 three 0
- # Window func in a correlated subquery, but the correlating column reference is outside the window function
- query ITI nosort
- SELECT *,
- (
- SELECT sum(lead_a)
- FROM (
- SELECT lead(a) OVER (ORDER BY a) AS lead_a
- FROM foo
- WHERE a <= outer_a AND a < 3
- ) as fsq2
- )
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY outer_a;
- ----
- 0 zero NULL
- 1 one 1
- 2 two 3
- 3 three 3
- # Similar to the previous one, but more window functions and aggregations
- query ITI nosort
- SELECT *,
- (
- SELECT sum(2 * w) + max(w)
- FROM (
- SELECT lead(a) OVER (ORDER BY a) + row_number() OVER (ORDER BY a) AS w
- FROM foo
- WHERE a <= outer_a AND a < 3
- ) as fsq2
- )
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY outer_a;
- ----
- 0 zero NULL
- 1 one 6
- 2 two 16
- 3 three 16
- # Window func in a correlated subquery, and the window function argument refers to the outer query
- query ITI nosort
- SELECT *,
- (
- SELECT sum(lead_a)
- FROM (
- SELECT lead(outer_a + a) OVER (ORDER BY a) AS lead_a
- FROM foo
- ) as fsq2
- )
- FROM (
- SELECT a AS outer_a, b AS outer_b
- FROM foo
- ) as fsq
- ORDER BY outer_a;
- ----
- 0 zero 6
- 1 one 9
- 2 two 12
- 3 three 15
- # Window func in a correlated subquery, and the window function's PARTITION BY refers to the outer query
- query ITI
- SELECT *,
- (
- SELECT sum(lead_a)
- FROM (
- SELECT 3 + lead(a) OVER (PARTITION BY 4 * a / (outer_a + length(outer_b)) ORDER BY a) AS lead_a
- FROM foo
- ) as fsq2
- )
- FROM (
- (SELECT a AS outer_a, b AS outer_b
- FROM foo)
- UNION
- (SELECT a + 2 AS outer_a, b AS outer_b
- FROM foo)
- UNION
- (SELECT a + 5 AS outer_a, b AS outer_b
- FROM foo)
- ) as fsq
- ORDER BY outer_a, outer_b;
- ----
- 0 zero NULL
- 1 one NULL
- 2 two 4
- 2 zero 4
- 3 one 4
- 3 three 10
- 4 two 10
- 5 three 9
- 5 zero 9
- 6 one 9
- 7 two 9
- 8 three 15
- # Let's check the HIR plan for the above query to see if the window function is lifted out from behind the `3 +`
- query T multiline
- EXPLAIN RAW PLAN FOR
- SELECT *,
- (
- SELECT sum(lead_a)
- FROM (
- SELECT 3 + lead(a) OVER (PARTITION BY 4 * a / (outer_a + length(outer_b)) ORDER BY a) AS lead_a
- FROM foo
- ) as fsq2
- )
- FROM (
- (SELECT a AS outer_a, b AS outer_b
- FROM foo)
- UNION
- (SELECT a + 2 AS outer_a, b AS outer_b
- FROM foo)
- UNION
- (SELECT a + 5 AS outer_a, b AS outer_b
- FROM foo)
- ) as fsq
- ORDER BY outer_a, outer_b;
- ----
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last] output=[#0..=#2]
- With
- cte [l1 as subquery-1] =
- Reduce aggregates=[sum(#0{lead_a})]
- Project (#3)
- Map (lead(row(#0{a}, 1, null)) over (partition by [((4 * #0{a}) / (#^0{outer_a} + char_length(#^1{outer_b})))] order by [#0{a} asc nulls_last]), (3 + #2{?column?}))
- Get materialize.public.foo
- Return
- Map (select(Get l1))
- Distinct
- Union
- Distinct
- Union
- Get materialize.public.foo
- Project (#2, #1)
- Map ((#0{a} + 2))
- Get materialize.public.foo
- Project (#2, #1)
- Map ((#0{a} + 5))
- Get materialize.public.foo
- Target cluster: quickstart
- EOF
- ##################################
- ## Window aggregations
- ##################################
- statement ok
- CREATE TABLE t7(x INT, y INT);
- # Plans
- query T multiline
- EXPLAIN DECORRELATED PLAN FOR
- SELECT
- sum(y-3) OVER (PARTITION BY 2*x, 3*y ORDER BY x+1, y+2 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t7
- ORDER BY x;
- ----
- Finish order_by=[#0 asc nulls_last] output=[#2]
- Project (#0, #1, #3)
- Map (#2)
- Project (#4..=#6)
- Map (record_get[0](record_get[1](#3)), record_get[1](record_get[1](#3)), record_get[0](#3))
- FlatMap unnest_list(#2)
- Reduce group_by=[#2, #3] aggregates=[window_agg[sum order_by=[#0 asc nulls_last, #1 asc nulls_last] rows between unbounded preceding and current row](row(row(row(#0, #1), (#1{y} - 3)), (#0{x} + 1), (#1{y} + 2)))]
- Map ((2 * #0{x}), (3 * #1{y}))
- CrossJoin
- Constant
- - ()
- Get materialize.public.t7
- Target cluster: quickstart
- EOF
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- sum(y-3) OVER (PARTITION BY 2*x, 3*y ORDER BY x+1, y+2 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t7
- ORDER BY x;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last] output=[#2]
- Project (#3..=#5)
- Map (record_get[1](#1), record_get[0](#2), record_get[1](#2), record_get[0](#1))
- FlatMap unnest_list(#0{window_agg})
- Project (#2{window_agg})
- Reduce group_by=[(2 * #0{x}), (3 * #1{y})] aggregates=[window_agg[sum order_by=[#0{x} asc nulls_last, #1{y} asc nulls_last] rows between unbounded preceding and current row](row(row(row(#0{x}, #1{y}), (#1{y} - 3)), (#0{x} + 1), (#1{y} + 2)))]
- ReadStorage materialize.public.t7
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- # Empty aggregations
- query IIIIIT
- SELECT
- x,
- y,
- sum(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
- max(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
- min(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
- array_agg(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t7
- ORDER BY x;
- ----
- query IIIIIT
- SELECT
- x,
- y,
- sum(y) OVER (ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),
- max(y) OVER (ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),
- min(y) OVER (ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),
- jsonb_agg(y) OVER (ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
- FROM t7
- ORDER BY x;
- ----
- query IIIIIT
- SELECT
- x,
- y,
- sum(y) OVER (ORDER BY x ROWS BETWEEN 2 FOLLOWING AND 5 FOLLOWING),
- max(y) OVER (ORDER BY x ROWS BETWEEN 2 FOLLOWING AND 5 FOLLOWING),
- min(y) OVER (ORDER BY x ROWS BETWEEN 2 FOLLOWING AND 5 FOLLOWING),
- list_agg(y) OVER (ORDER BY x ROWS BETWEEN 2 FOLLOWING AND 5 FOLLOWING)[1]
- FROM t7
- ORDER BY x;
- ----
- statement ok
- INSERT INTO t7 VALUES (1,2), (3,null), (5,6), (7,8), (9, null), (11, null), (13, 14), (15, 16), (17, 18), (10, -40), (10, -50);
- # Test various nestings
- # Postgres also doesn't support this.
- query error db error: ERROR: window functions are not allowed in aggregate function \(function pg_catalog\.sum\)
- SELECT sum(sum(x) OVER ()) FROM t7;
- # Other way around: grouped aggregate inside a window aggregate.
- # What this query is asking us to do is to
- # 1. First, perform the inner sum (with its GROUP BY), and then
- # 2. the outer sum (with its OVER clause).
- # (Postgres handles this the same.)
- query I
- SELECT sum(sum(x)) OVER (ORDER BY y) FROM t7 GROUP BY y;
- ----
- 10
- 20
- 21
- 26
- 33
- 46
- 61
- 78
- 101
- # Window aggregation inside a window aggregation. We support this, and queries like this might actually make sense in
- # some cases. (I think we already had a customer with some other window functions nested inside each other.)
- # (Postgres doesn't support this.)
- query I
- SELECT sum(sum(x) OVER ()) OVER () FROM t7;
- ----
- 1111
- 1111
- 1111
- 1111
- 1111
- 1111
- 1111
- 1111
- 1111
- 1111
- 1111
- query III
- SELECT
- x,
- sum(x) OVER (ORDER BY x),
- sum(sum(x) OVER (ORDER BY x)) OVER (ORDER BY x)
- FROM (SELECT DISTINCT ON(x) * FROM t7);
- ----
- 1 1 1
- 3 4 5
- 5 9 14
- 7 16 30
- 9 25 55
- 10 35 90
- 11 46 136
- 13 59 195
- 15 74 269
- 17 91 360
- # Lots of different aggregation functions. This covers
- # - basic, hierarchical, accumulable aggregations
- # - count's null handling
- # - count(*)
- # - FILTER clause
- # - Aggregation functions that are transformed away by `transform_ast.rs`: bool_and, bool_or.
- # These are all supported by Postgres, and the output should be identical.
- query IIIIIITIIIITT
- SELECT
- x-y,
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- max(x*y+1) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- min(x*y+1) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- array_agg(2*x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- count(2*x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- count(CASE WHEN x%3 != 0 THEN x ELSE null END) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- count(*) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- sum(x) FILTER (WHERE x%3 != 0) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- bool_and(x%3 != 0) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- bool_or(x%3 = 0) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x-y, x;
- ----
- -1 1 2 116 307 3 {2,10,14,26,30,34} 6 5 6 43 false true
- -1 5 6 114 307 31 {10,14,26,30,34} 5 4 5 42 false true
- -1 7 8 104 307 57 {14,26,30,34} 4 3 4 37 false true
- -1 13 14 90 307 183 {26,30,34} 3 2 3 30 false true
- -1 15 16 64 307 241 {30,34} 2 1 2 17 false true
- -1 17 18 34 307 307 {34} 1 1 1 17 true false
- 50 10 -40 20 -399 -399 {20} 1 1 1 10 true false
- 60 10 -50 20 -499 -499 {20} 1 1 1 10 true false
- NULL 3 NULL 46 NULL NULL {6,18,22} 3 1 3 11 false true
- NULL 9 NULL 40 NULL NULL {18,22} 2 1 2 11 false true
- NULL 11 NULL 22 NULL NULL {22} 1 1 1 11 true false
- # Also supported by Postgres, but output text formatting is a bit different, so putting this in a separate test.
- # avg, variance, var_pop, stddev, stddev_pop are transformed away by `transform_ast.rs`.
- query IIITRRRRR
- SELECT
- x-y,
- x,
- y,
- jsonb_agg(2*x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- avg(x+y) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- variance(x+y) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- var_pop(x+y) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- stddev(x+y) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- stddev_pop(x+y) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x-y, x;
- ----
- -1 1 2 [2,10,14,26,30,34] 20.3333333333333333333333333333333333333 157.866666666666666666666666666666666666 131.555555555555555555555555555555555555 12.5645002553490628940078294328743895394 11.469767022723502362305964713399618176
- -1 5 6 [10,14,26,30,34] 23.8 107.2 85.76 10.3537432844358276565421773235938072887 9.26066952223218037884464808956388302968
- -1 7 8 [14,26,30,34] 27 74.6666666666666666666666666666666666667 56 8.64098759787714697462128991478399554361 7.48331477354788277116749746463309860351
- -1 13 14 [26,30,34] 31 16 10.6666666666666666666666666666666666667 4 3.26598632371090413092971209960785518929
- -1 15 16 [30,34] 33 8 4 2.82842712474619009760337744841939615714 2
- -1 17 18 [34] 35 NULL 0 NULL 0
- 50 10 -40 [20] -30 NULL 0 NULL 0
- 60 10 -50 [20] -40 NULL 0 NULL 0
- NULL 3 NULL [6,18,22] NULL NULL NULL NULL NULL
- NULL 9 NULL [18,22] NULL NULL NULL NULL NULL
- NULL 11 NULL [22] NULL NULL NULL NULL NULL
- # These are not supported by Postgres.
- # - ORDER BY in aggr
- # - list indexing after the OVER clause
- query IIITTI
- SELECT
- x-y,
- x,
- y,
- array_agg(x ORDER BY CASE WHEN y IS NOT NULL THEN y ELSE x%5 END DESC) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- array_agg(2*x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- list_agg(2*x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)[2]
- FROM t7
- ORDER BY x-y, x;
- ----
- -1 1 2 {17,15,13,7,5,1} {2,10,14,26,30,34} 10
- -1 5 6 {17,15,13,7,5} {10,14,26,30,34} 14
- -1 7 8 {17,15,13,7} {14,26,30,34} 26
- -1 13 14 {17,15,13} {26,30,34} 30
- -1 15 16 {17,15} {30,34} 34
- -1 17 18 {17} {34} NULL
- 50 10 -40 {10} {20} NULL
- 60 10 -50 {10} {20} NULL
- NULL 3 NULL {9,3,11} {6,18,22} 18
- NULL 9 NULL {9,11} {18,22} 22
- NULL 11 NULL {11} {22} NULL
- # https://github.com/MaterializeInc/database-issues/issues/6626
- query error db error: ERROR: DISTINCT in window aggregates not yet supported
- SELECT
- x-y,
- x,
- y,
- array_agg(x/10) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- count(DISTINCT x/10) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x-y, x;
- # No ORDER BY in OVER clause.
- query IIIIITTTT
- SELECT
- x,
- y,
- sum(y) OVER (),
- max(y) OVER (),
- min(y) OVER (),
- array_agg(y ORDER BY y) OVER (),
- array_agg(y ORDER BY y NULLS LAST) OVER (),
- array_agg(y ORDER BY y NULLS FIRST) OVER (),
- bool_and(x%3 != 0) OVER ()
- FROM t7
- ORDER BY x;
- ----
- 1 2 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 3 NULL -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 5 6 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 7 8 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 9 NULL -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 10 -50 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 10 -40 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 11 NULL -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 13 14 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 15 16 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- 17 18 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL} {NULL,NULL,NULL,-50,-40,2,6,8,14,16,18} false
- query IIIIIIT
- SELECT
- x-y+x/10,
- x,
- y,
- sum(y) OVER (PARTITION BY x-y+x/10),
- max(y) OVER (PARTITION BY x-y+x/10),
- min(y) OVER (PARTITION BY x-y+x/10),
- array_agg(y) OVER (PARTITION BY x-y+x/10)
- FROM t7
- ORDER BY x-y+x/10;
- ----
- -1 1 2 16 8 2 {2,6,8}
- -1 5 6 16 8 2 {2,6,8}
- -1 7 8 16 8 2 {2,6,8}
- 0 13 14 48 18 14 {14,16,18}
- 0 15 16 48 18 14 {14,16,18}
- 0 17 18 48 18 14 {14,16,18}
- 51 10 -40 -40 -40 -40 {-40}
- 61 10 -50 -50 -50 -50 {-50}
- NULL 3 NULL NULL NULL NULL {NULL,NULL,NULL}
- NULL 9 NULL NULL NULL NULL {NULL,NULL,NULL}
- NULL 11 NULL NULL NULL NULL {NULL,NULL,NULL}
- # Test the situation when we don't have an ORDER BY, but we have a frame that doesn't include the current row.
- # This verifies that the `order_by.is_empty()` if condition also includes `window_frame.includes_current_row()`.
- query IIIIITR
- SELECT
- x-y+x/10,
- x,
- y,
- sum(y) OVER (PARTITION BY x-y+x/10 ROWS BETWEEN 200 PRECEDING AND 100 PRECEDING),
- count(y) OVER (PARTITION BY x-y+x/10 ROWS BETWEEN 200 PRECEDING AND 100 PRECEDING),
- array_agg(y) OVER (PARTITION BY x-y+x/10 ROWS BETWEEN 200 PRECEDING AND 100 PRECEDING),
- avg(y) OVER (PARTITION BY x-y+x/10 ROWS BETWEEN 200 PRECEDING AND 100 PRECEDING)
- FROM t7
- ORDER BY x, y;
- ----
- -1 1 2 NULL 0 NULL NULL
- NULL 3 NULL NULL 0 NULL NULL
- -1 5 6 NULL 0 NULL NULL
- -1 7 8 NULL 0 NULL NULL
- NULL 9 NULL NULL 0 NULL NULL
- 61 10 -50 NULL 0 NULL NULL
- 51 10 -40 NULL 0 NULL NULL
- NULL 11 NULL NULL 0 NULL NULL
- 0 13 14 NULL 0 NULL NULL
- 0 15 16 NULL 0 NULL NULL
- 0 17 18 NULL 0 NULL NULL
- # ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- query IIIIIT
- SELECT
- x,
- y,
- sum(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
- max(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
- min(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
- array_agg(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t7
- ORDER BY x;
- ----
- 1 2 2 2 2 {2}
- 3 NULL 2 2 2 {2,NULL}
- 5 6 8 6 2 {2,6,NULL}
- 7 8 16 8 2 {2,6,8,NULL}
- 9 NULL 16 8 2 {2,6,8,NULL,NULL}
- 10 -50 -34 8 -50 {-50,2,6,8,NULL,NULL}
- 10 -40 -74 8 -50 {-50,-40,2,6,8,NULL,NULL}
- 11 NULL -74 8 -50 {-50,-40,2,6,8,NULL,NULL,NULL}
- 13 14 -60 14 -50 {-50,-40,2,6,8,14,NULL,NULL,NULL}
- 15 16 -44 16 -50 {-50,-40,2,6,8,14,16,NULL,NULL,NULL}
- 17 18 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL}
- statement ok
- CREATE TABLE t8(o1 INT, o2 INT, v INT);
- statement ok
- INSERT INTO t8 VALUES (1,1,-2), (1,1,-3), (1,2,-4), (1,3,-7), (1,3,-8), (2,1,-10), (2,2,-1000), (2,2,-1000), (2,2,-1000), (3,0,-100);
- # Default frame, i.e. RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- query IIIIIIT
- SELECT
- o1,
- o2,
- v,
- sum(v) OVER (ORDER BY o1, o2),
- max(v) OVER (ORDER BY o1, o2),
- min(v) OVER (ORDER BY o1, o2),
- array_agg(v) OVER (ORDER BY o1, o2 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t8
- ORDER BY o1, o2;
- ----
- 1 1 -3 -5 -2 -3 {-3,-2}
- 1 1 -2 -5 -2 -3 {-3,-2}
- 1 2 -4 -9 -2 -4 {-4,-3,-2}
- 1 3 -8 -24 -2 -8 {-8,-7,-4,-3,-2}
- 1 3 -7 -24 -2 -8 {-8,-7,-4,-3,-2}
- 2 1 -10 -34 -2 -10 {-10,-8,-7,-4,-3,-2}
- 2 2 -1000 -3034 -2 -1000 {-1000,-1000,-1000,-10,-8,-7,-4,-3,-2}
- 2 2 -1000 -3034 -2 -1000 {-1000,-1000,-1000,-10,-8,-7,-4,-3,-2}
- 2 2 -1000 -3034 -2 -1000 {-1000,-1000,-1000,-10,-8,-7,-4,-3,-2}
- 3 0 -100 -3134 -2 -1000 {-1000,-1000,-1000,-100,-10,-8,-7,-4,-3,-2}
- query IIIIIIT
- SELECT
- o1,
- o2,
- v,
- sum(v) OVER (PARTITION BY o1 ORDER BY o2),
- max(v) OVER (PARTITION BY o1 ORDER BY o2),
- min(v) OVER (PARTITION BY o1 ORDER BY o2),
- array_agg(v) OVER (PARTITION BY o1 ORDER BY o2 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- FROM t8
- ORDER BY o1, o2;
- ----
- 1 1 -3 -5 -2 -3 {-3,-2}
- 1 1 -2 -5 -2 -3 {-3,-2}
- 1 2 -4 -9 -2 -4 {-4,-3,-2}
- 1 3 -8 -24 -2 -8 {-8,-7,-4,-3,-2}
- 1 3 -7 -24 -2 -8 {-8,-7,-4,-3,-2}
- 2 1 -10 -10 -10 -10 {-10}
- 2 2 -1000 -3010 -10 -1000 {-1000,-1000,-1000,-10}
- 2 2 -1000 -3010 -10 -1000 {-1000,-1000,-1000,-10}
- 2 2 -1000 -3010 -10 -1000 {-1000,-1000,-1000,-10}
- 3 0 -100 -100 -100 -100 {-100}
- # ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- # Note that x=10 occurs twice. This means that the ordering of these rows is undefined, so it can change between
- # Materialize versions.
- query IIIIIT
- SELECT
- x,
- y,
- sum(y) OVER (ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- max(y) OVER (ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- min(y) OVER (ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- array_agg(y) OVER (ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x;
- ----
- 1 2 -26 18 -50 {-50,-40,2,6,8,14,16,18,NULL,NULL,NULL}
- 3 NULL -28 18 -50 {-50,-40,6,8,14,16,18,NULL,NULL,NULL}
- 5 6 -28 18 -50 {-50,-40,6,8,14,16,18,NULL,NULL}
- 7 8 -34 18 -50 {-50,-40,8,14,16,18,NULL,NULL}
- 9 NULL -42 18 -50 {-50,-40,14,16,18,NULL,NULL}
- 10 -40 8 18 -40 {-40,14,16,18,NULL}
- 10 -50 -42 18 -50 {-50,-40,14,16,18,NULL}
- 11 NULL 48 18 14 {14,16,18,NULL}
- 13 14 48 18 14 {14,16,18}
- 15 16 34 18 16 {16,18}
- 17 18 18 18 18 {18}
- # RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- # TODO: Actually, we already have the rendering code for this. So, we just need to either hack planning a bit to add an
- # exception for window aggregations, or add rendering support also for other window functions.
- query error RANGE in non-default window frames not yet supported
- SELECT
- x,
- y,
- sum(y) OVER (ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- max(y) OVER (ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- min(y) OVER (ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- array_agg(y) OVER (ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x;
- # PARTITION BY
- # ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- # Here, x=10 occurring twice does NOT mean that the result for these rows would be undefined.
- query IIIIIIT
- SELECT
- x-y,
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- max(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- min(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x-y, x;
- ----
- -1 1 2 116 34 2 {2,10,14,26,30,34}
- -1 5 6 114 34 10 {10,14,26,30,34}
- -1 7 8 104 34 14 {14,26,30,34}
- -1 13 14 90 34 26 {26,30,34}
- -1 15 16 64 34 30 {30,34}
- -1 17 18 34 34 34 {34}
- 50 10 -40 20 20 20 {20}
- 60 10 -50 20 20 20 {20}
- NULL 3 NULL 46 22 6 {6,18,22}
- NULL 9 NULL 40 22 18 {18,22}
- NULL 11 NULL 22 22 22 {22}
- query IIIIIT
- SELECT
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- max(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- min(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-y ORDER BY x ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x-y, x;
- ----
- 1 2 116 34 2 {2,10,14,26,30,34}
- 5 6 114 34 10 {10,14,26,30,34}
- 7 8 104 34 14 {14,26,30,34}
- 13 14 90 34 26 {26,30,34}
- 15 16 64 34 30 {30,34}
- 17 18 34 34 34 {34}
- 10 -40 20 20 20 {20}
- 10 -50 20 20 20 {20}
- 3 NULL 46 22 6 {6,18,22}
- 9 NULL 40 22 18 {18,22}
- 11 NULL 22 22 22 {22}
- # PARTITION BY
- # RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- query error RANGE in non-default window frames not yet supported
- SELECT
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- max(x+x) OVER (PARTITION BY x-y ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- min(x+x) OVER (PARTITION BY x-y ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-y ORDER BY x RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
- FROM t7
- ORDER BY x-y, x;
- # ROWS BETWEEN offset PRECEDING AND offset FOLLOWING
- query IIIIIT
- SELECT
- x,
- y,
- sum(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING),
- max(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING),
- min(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING),
- array_agg(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
- FROM t7
- ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END;
- ----
- 10 -50 20 10 10 {10,10}
- 10 -40 21 10 1 {1,10,10}
- 1 2 24 10 1 {1,3,10,10}
- 3 NULL 23 10 1 {1,3,9,10}
- 9 NULL 24 11 1 {1,3,9,11}
- 11 NULL 28 11 3 {3,5,9,11}
- 5 6 32 11 5 {5,7,9,11}
- 7 8 36 13 5 {5,7,11,13}
- 13 14 40 15 5 {5,7,13,15}
- 15 16 52 17 7 {7,13,15,17}
- 17 18 45 17 13 {13,15,17}
- query IIIIIT
- SELECT
- x,
- y,
- sum(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING),
- max(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING),
- min(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING),
- array_agg(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING)
- FROM t7
- ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END;
- ----
- 10 -50 20 10 10 {10,10}
- 10 -40 11 10 1 {1,10}
- 1 2 4 3 1 {1,3}
- 3 NULL 12 9 3 {3,9}
- 9 NULL 20 11 9 {9,11}
- 11 NULL 16 11 5 {5,11}
- 5 6 12 7 5 {5,7}
- 7 8 20 13 7 {7,13}
- 13 14 28 15 13 {13,15}
- 15 16 32 17 15 {15,17}
- 17 18 17 17 17 {17}
- query IIIIIT
- SELECT
- x,
- y,
- sum(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING),
- max(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING),
- min(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING),
- array_agg(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING)
- FROM t7
- ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END;
- ----
- 10 -50 10 10 10 {10}
- 10 -40 10 10 10 {10}
- 1 2 1 1 1 {1}
- 3 NULL 3 3 3 {3}
- 9 NULL 9 9 9 {9}
- 11 NULL 11 11 11 {11}
- 5 6 5 5 5 {5}
- 7 8 7 7 7 {7}
- 13 14 13 13 13 {13}
- 15 16 15 15 15 {15}
- 17 18 17 17 17 {17}
- # mixed UNBOUNDED - OFFSET frames
- query error db error: ERROR: mixed unbounded \- offset frames not yet supported
- SELECT
- sum(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND 2 PRECEDING)
- FROM t7;
- query error db error: ERROR: mixed unbounded \- offset frames not yet supported
- SELECT
- sum(y) OVER (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING)
- FROM t7;
- query error db error: ERROR: mixed unbounded \- offset frames not yet supported
- SELECT
- sum(y) OVER (ORDER BY x ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING)
- FROM t7;
- query error db error: ERROR: mixed unbounded \- offset frames not yet supported
- SELECT
- sum(y) OVER (ORDER BY x ROWS BETWEEN 3 FOLLOWING AND UNBOUNDED FOLLOWING)
- FROM t7;
- # And a parse error as a bonus
- query error Expected PRECEDING or FOLLOWING, found UNBOUNDED
- SELECT
- sum(y) OVER (ORDER BY x ROWS BETWEEN 3 FOLLOWING AND 2 UNBOUNDED FOLLOWING)
- FROM t7;
- # ROWS BETWEEN offset PRECEDING AND offset PRECEDING
- query IIIIIT
- SELECT
- x,
- y,
- sum(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING),
- max(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING),
- min(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING),
- array_agg(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING)
- FROM t7
- ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END;
- ----
- 10 -50 NULL NULL NULL NULL
- 10 -40 10 10 10 {10}
- 1 2 20 10 10 {10,10}
- 3 NULL 21 10 1 {1,10,10}
- 9 NULL 14 10 1 {1,3,10}
- 11 NULL 13 9 1 {1,3,9}
- 5 6 23 11 3 {3,9,11}
- 7 8 25 11 5 {5,9,11}
- 13 14 23 11 5 {5,7,11}
- 15 16 25 13 5 {5,7,13}
- 17 18 35 15 7 {7,13,15}
- # ROWS BETWEEN offset FOLLOWING AND offset FOLLOWING
- query IIIIIT
- SELECT
- x,
- y,
- sum(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING),
- max(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING),
- min(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING),
- array_agg(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING)
- FROM t7
- ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END;
- ----
- 10 -50 13 9 1 {1,3,9}
- 10 -40 23 11 3 {3,9,11}
- 1 2 25 11 5 {5,9,11}
- 3 NULL 23 11 5 {5,7,11}
- 9 NULL 25 13 5 {5,7,13}
- 11 NULL 35 15 7 {7,13,15}
- 5 6 45 17 13 {13,15,17}
- 7 8 32 17 15 {15,17}
- 13 14 17 17 17 {17}
- 15 16 NULL NULL NULL NULL
- 17 18 NULL NULL NULL NULL
- # Frame end is later than frame start. All frames are empty.
- query IIIIIT
- SELECT
- x,
- y,
- sum(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 30 FOLLOWING AND 1 FOLLOWING),
- max(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 30 FOLLOWING AND 1 FOLLOWING),
- min(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 30 FOLLOWING AND 1 FOLLOWING),
- array_agg(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 30 FOLLOWING AND 1 FOLLOWING)
- FROM t7
- ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END;
- ----
- 10 -50 NULL NULL NULL NULL
- 10 -40 NULL NULL NULL NULL
- 1 2 NULL NULL NULL NULL
- 3 NULL NULL NULL NULL NULL
- 9 NULL NULL NULL NULL NULL
- 11 NULL NULL NULL NULL NULL
- 5 6 NULL NULL NULL NULL
- 7 8 NULL NULL NULL NULL
- 13 14 NULL NULL NULL NULL
- 15 16 NULL NULL NULL NULL
- 17 18 NULL NULL NULL NULL
- query IIIIIT
- SELECT
- x,
- y,
- sum(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING),
- max(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING),
- min(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING),
- array_agg(x) OVER (ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
- FROM t7
- ORDER BY CASE WHEN y IS NOT NULL THEN x*y ELSE x END;
- ----
- 10 -50 NULL NULL NULL NULL
- 10 -40 NULL NULL NULL NULL
- 1 2 NULL NULL NULL NULL
- 3 NULL NULL NULL NULL NULL
- 9 NULL NULL NULL NULL NULL
- 11 NULL NULL NULL NULL NULL
- 5 6 NULL NULL NULL NULL
- 7 8 NULL NULL NULL NULL
- 13 14 NULL NULL NULL NULL
- 15 16 NULL NULL NULL NULL
- 17 18 NULL NULL NULL NULL
- # ROWS BETWEEN offset PRECEDING AND offset FOLLOWING
- query IIIIIIT
- SELECT
- x-y+x/10,
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
- max(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
- min(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- FROM t7
- ORDER BY x-y+x/10, x;
- ----
- -1 1 2 12 10 2 {2,10}
- -1 5 6 26 14 2 {2,10,14}
- -1 7 8 24 14 10 {10,14}
- 0 13 14 56 30 26 {26,30}
- 0 15 16 90 34 26 {26,30,34}
- 0 17 18 64 34 30 {30,34}
- 51 10 -40 20 20 20 {20}
- 61 10 -50 20 20 20 {20}
- NULL 3 NULL 24 18 6 {6,18}
- NULL 9 NULL 46 22 6 {6,18,22}
- NULL 11 NULL 40 22 18 {18,22}
- query IIIIIIT
- SELECT
- x-y+x/10,
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1000000 PRECEDING AND 1000000 FOLLOWING),
- max(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1000000 PRECEDING AND 1000000 FOLLOWING),
- min(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1000000 PRECEDING AND 1000000 FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 1000000 PRECEDING AND 1000000 FOLLOWING)
- FROM t7
- ORDER BY x-y+x/10, x;
- ----
- -1 1 2 26 14 2 {2,10,14}
- -1 5 6 26 14 2 {2,10,14}
- -1 7 8 26 14 2 {2,10,14}
- 0 13 14 90 34 26 {26,30,34}
- 0 15 16 90 34 26 {26,30,34}
- 0 17 18 90 34 26 {26,30,34}
- 51 10 -40 20 20 20 {20}
- 61 10 -50 20 20 20 {20}
- NULL 3 NULL 46 22 6 {6,18,22}
- NULL 9 NULL 46 22 6 {6,18,22}
- NULL 11 NULL 46 22 6 {6,18,22}
- query IIIIIIT
- SELECT
- x-row_number() OVER (ORDER BY x+y),
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
- max(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
- min(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
- FROM t7
- ORDER BY x-row_number() OVER (ORDER BY x+y), x;
- ----
- -6 3 NULL 6 6 6 {6}
- -2 1 2 2 2 2 {2}
- -1 9 NULL 18 18 18 {18}
- 0 11 NULL 22 22 22 {22}
- 1 5 6 10 10 10 {10}
- 2 7 8 14 14 14 {14}
- 7 13 14 26 26 26 {26}
- 8 10 -40 50 30 20 {20,30}
- 8 15 16 50 30 20 {20,30}
- 9 10 -50 54 34 20 {20,34}
- 9 17 18 54 34 20 {20,34}
- # Offset has to be a literal
- query error Expected literal unsigned integer, found identifier "row_number"
- SELECT
- x-row_number() OVER (ORDER BY x+y),
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN row_number() OVER (ORDER BY x+y) PRECEDING AND 0 FOLLOWING),
- max(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN row_number() OVER (ORDER BY x+y) PRECEDING AND 0 FOLLOWING),
- min(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN row_number() OVER (ORDER BY x+y) PRECEDING AND 0 FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-row_number() OVER (ORDER BY x+y) ORDER BY x ROWS BETWEEN row_number() OVER (ORDER BY x+y) PRECEDING AND 0 FOLLOWING)
- FROM t7
- ORDER BY x-row_number() OVER (ORDER BY x+y), x;
- # ROWS BETWEEN offset PRECEDING AND CURRENT ROW
- query IIIIIIT
- SELECT
- x-y+x/10,
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),
- max(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),
- min(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),
- array_agg(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
- FROM t7
- ORDER BY x-y+x/10, x;
- ----
- -1 1 2 2 2 2 {2}
- -1 5 6 12 10 2 {2,10}
- -1 7 8 26 14 2 {2,10,14}
- 0 13 14 26 26 26 {26}
- 0 15 16 56 30 26 {26,30}
- 0 17 18 90 34 26 {26,30,34}
- 51 10 -40 20 20 20 {20}
- 61 10 -50 20 20 20 {20}
- NULL 3 NULL 6 6 6 {6}
- NULL 9 NULL 24 18 6 {6,18}
- NULL 11 NULL 46 22 6 {6,18,22}
- # ROWS BETWEEN CURRENT ROW AND offset FOLLOWING
- query IIIIIIT
- SELECT
- x-y+x/10,
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),
- max(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),
- min(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),
- array_agg(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
- FROM t7
- ORDER BY x-y+x/10, x;
- ----
- -1 1 2 12 10 2 {2,10}
- -1 5 6 24 14 10 {10,14}
- -1 7 8 14 14 14 {14}
- 0 13 14 56 30 26 {26,30}
- 0 15 16 64 34 30 {30,34}
- 0 17 18 34 34 34 {34}
- 51 10 -40 20 20 20 {20}
- 61 10 -50 20 20 20 {20}
- NULL 3 NULL 24 18 6 {6,18}
- NULL 9 NULL 40 22 18 {18,22}
- NULL 11 NULL 22 22 22 {22}
- # ROWS BETWEEN CURRENT ROW AND CURRENT ROW
- query IIIIIIT
- SELECT
- x-y+x/10,
- x,
- y,
- sum(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND CURRENT ROW),
- max(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND CURRENT ROW),
- min(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND CURRENT ROW),
- array_agg(x+x) OVER (PARTITION BY x-y+x/10 ORDER BY x ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
- FROM t7
- ORDER BY x-y+x/10, x;
- ----
- -1 1 2 2 2 2 {2}
- -1 5 6 10 10 10 {10}
- -1 7 8 14 14 14 {14}
- 0 13 14 26 26 26 {26}
- 0 15 16 30 30 30 {30}
- 0 17 18 34 34 34 {34}
- 51 10 -40 20 20 20 {20}
- 61 10 -50 20 20 20 {20}
- NULL 3 NULL 6 6 6 {6}
- NULL 9 NULL 18 18 18 {18}
- NULL 11 NULL 22 22 22 {22}
- ## Tests for `AggregateExpr::on_unique`
- # In the next several tests, the global aggregates make the input column to the window aggregate a key, so
- # `ReduceElision` invokes `on_unique`.
- #
- # First, let's see that `ReduceElision` indeed kicks in, by observing that the Reduce of the window aggregation is not
- # present in the plan. (There is 1 Reduce present from the global aggregation.)
- #
- # Note that in these tests that rely on the window function's PARTITION BY being a key, we unfortunately can't test more
- # than one window function call in one test, because we currently forget the key information after a window function
- # call (even when `ReduceElision` simplifies the window function call).
- # TODO: Add an optimization that eliminates a Map-FlatMap pair where the Map is just creating a 1-element list on which
- # the FlatMap is immediately calling `unnest_list`.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(keys, humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- sum(sum(x)) OVER ()
- FROM t7;
- ----
- Explained Query:
- With
- cte l0 =
- Reduce aggregates=[sum(#0{x})] // { keys: "([])" }
- Project (#0{x}) // { keys: "()" }
- ReadStorage materialize.public.t7 // { keys: "()" }
- Return // { keys: "()" }
- Project (#2) // { keys: "()" }
- Map (record_get[0](#1)) // { keys: "()" }
- FlatMap unnest_list(#0) // { keys: "()" }
- Project (#1) // { keys: "([])" }
- Map (list[row(bigint_to_numeric(#0{sum_x}), row(#0{sum_x}))]) // { keys: "([])" }
- Union // { keys: "([])" }
- Get l0 // { keys: "([])" }
- Map (null) // { keys: "()" }
- Union // { keys: "()" }
- Negate // { keys: "()" }
- Project () // { keys: "([])" }
- Get l0 // { keys: "([])" }
- Constant // { keys: "([])" }
- - ()
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- query I
- SELECT
- sum(sum(x)) OVER ()
- FROM t7;
- ----
- 101
- query I
- SELECT
- min(count(x)) OVER ()
- FROM t7;
- ----
- 11
- query I
- SELECT
- count(min(x)) OVER ()
- FROM t7;
- ----
- 1
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET unsafe_enable_table_keys = true
- ----
- COMPLETE 0
- statement ok
- CREATE TABLE t9(x INT UNIQUE, y INT);
- statement ok
- INSERT INTO t9 VALUES (1,2), (3,null), (5,6), (7,8), (9, null), (11, null), (13, 14), (15, 16), (17, 18);
- # Still testing `AggregateExpr::on_unique`. Here, the uniqueness constraint on the table makes `ReduceElision` call
- # `on_unique`. There should be 0 Reduce operations in the plan.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH(keys, humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- sum(y) OVER (PARTITION BY x)
- FROM t9
- ORDER BY x;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last] output=[#2]
- Project (#3..=#5) // { keys: "()" }
- Map (record_get[1](#1), record_get[0](#2), record_get[1](#2), record_get[0](#1)) // { keys: "()" }
- FlatMap unnest_list(#0) // { keys: "()" }
- Project (#2) // { keys: "()" }
- Map (list[row(integer_to_bigint(#1{y}), row(#0{x}, #1{y}))]) // { keys: "([0])" }
- ReadStorage materialize.public.t9 // { keys: "([0])" }
- Source materialize.public.t9
- Target cluster: quickstart
- EOF
- query I
- SELECT
- sum(y) OVER (PARTITION BY x)
- FROM t9
- ORDER BY x;
- ----
- 2
- NULL
- 6
- 8
- NULL
- NULL
- 14
- 16
- 18
- query I
- SELECT
- min(y) OVER (PARTITION BY x)
- FROM t9
- ORDER BY x;
- ----
- 2
- NULL
- 6
- 8
- NULL
- NULL
- 14
- 16
- 18
- query I
- SELECT
- count(y) OVER (PARTITION BY x)
- FROM t9
- ORDER BY x;
- ----
- 1
- 0
- 1
- 1
- 0
- 0
- 1
- 1
- 1
- query I
- SELECT
- count(*) OVER (PARTITION BY x)
- FROM t9
- ORDER BY x;
- ----
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- query T
- SELECT
- array_agg(y) OVER (PARTITION BY x)
- FROM t9
- ORDER BY x;
- ----
- {2}
- {NULL}
- {6}
- {8}
- {NULL}
- {NULL}
- {14}
- {16}
- {18}
- query R
- SELECT
- avg(y+y) OVER (PARTITION BY x)
- FROM t9
- ORDER BY x;
- ----
- 4
- NULL
- 12
- 16
- NULL
- NULL
- 28
- 32
- 36
- # Test that, for window aggregations, `on_unique` is properly calling `wrapped_aggregate.default()` when the frame is
- # empty (and not just returns null as the other window function cases in `on_unique`).
- query I
- SELECT
- count(y) OVER (PARTITION BY x ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING)
- FROM t9
- ORDER BY x;
- ----
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- query I
- SELECT
- sum(y) OVER (PARTITION BY x ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING)
- FROM t9
- ORDER BY x;
- ----
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- query II
- SELECT
- count(y) OVER (PARTITION BY x ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING),
- sum(y) OVER (PARTITION BY x ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING)
- FROM t9
- ORDER BY x;
- ----
- 0 NULL
- 0 NULL
- 0 NULL
- 0 NULL
- 0 NULL
- 0 NULL
- 0 NULL
- 0 NULL
- 0 NULL
- query T
- SELECT
- array_agg(y) OVER (PARTITION BY x ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING)
- FROM t9
- ORDER BY x;
- ----
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- query R
- SELECT
- avg(y+y) OVER (PARTITION BY x ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING)
- FROM t9
- ORDER BY x;
- ----
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- NULL
- # Test `on_unique` for lag/lead
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- lag(x,y,100) OVER (PARTITION BY x ORDER BY y+y)
- FROM t9;
- ----
- Explained Query:
- Project (#2)
- Map (record_get[0](#1))
- FlatMap unnest_list(#0)
- Project (#2)
- Map (list[row(case when (#1{y}) IS NULL then null else case when (#1{y} = 0) then #0{x} else 100 end end, row(#0{x}, #1{y}))])
- ReadStorage materialize.public.t9
- Source materialize.public.t9
- Target cluster: quickstart
- EOF
- query I rowsort
- SELECT
- lag(x,y,100) OVER (PARTITION BY x ORDER BY y+y)
- FROM t9;
- ----
- NULL
- NULL
- NULL
- 100
- 100
- 100
- 100
- 100
- 100
- query I rowsort
- SELECT
- lead(x,y-2,120) OVER (PARTITION BY x ORDER BY x)
- FROM t9;
- ----
- NULL
- NULL
- NULL
- 1
- 120
- 120
- 120
- 120
- 120
- # Test `on_unique` for `FusedValueWindowFunc`. There should be NO window function call in the following plan.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- x,
- y,
- lag(x,y,100) OVER (PARTITION BY x ORDER BY y+y),
- lag(x,y,110) OVER (PARTITION BY x ORDER BY y+y),
- lag(x,y,100) OVER (PARTITION BY x ORDER BY y+y),
- first_value(y) OVER (PARTITION BY x ORDER BY y+y),
- last_value(y) OVER (PARTITION BY x ORDER BY y+y),
- lead(x,y-2,120) OVER (PARTITION BY x ORDER BY y+y)
- FROM t9
- ORDER BY x;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last] output=[#0..=#7]
- Project (#3, #4, #9, #10, #9, #8, #7, #6)
- Map (record_get[1](#1), record_get[0](#2), record_get[1](#2), record_get[0](#1), record_get[0](#5), record_get[1](#5), record_get[2](#5), record_get[3](#5), record_get[4](#5))
- FlatMap unnest_list(#0)
- Project (#3)
- Map ((#1{y}) IS NULL, list[row(row(case when #2 then null else case when (0 = (#1{y} - 2)) then #0{x} else 120 end end, #1{y}, #1{y}, case when #2 then null else case when (#1{y} = 0) then #0{x} else 100 end end, case when #2 then null else case when (#1{y} = 0) then #0{x} else 110 end end), row(#0{x}, #1{y}))])
- ReadStorage materialize.public.t9
- Source materialize.public.t9
- Target cluster: quickstart
- EOF
- query IIIIIIII
- SELECT
- x,
- y,
- lag(x,y,100) OVER (PARTITION BY x ORDER BY y+y),
- lag(x,y,110) OVER (PARTITION BY x ORDER BY y+y),
- lag(x,y,100) OVER (PARTITION BY x ORDER BY y+y),
- first_value(y) OVER (PARTITION BY x ORDER BY y+y),
- last_value(y) OVER (PARTITION BY x ORDER BY y+y),
- lead(x,y-2,120) OVER (PARTITION BY x ORDER BY y+y)
- FROM t9
- ORDER BY x;
- ----
- 1 2 100 110 100 2 2 1
- 3 NULL NULL NULL NULL NULL NULL NULL
- 5 6 100 110 100 6 6 120
- 7 8 100 110 100 8 8 120
- 9 NULL NULL NULL NULL NULL NULL NULL
- 11 NULL NULL NULL NULL NULL NULL NULL
- 13 14 100 110 100 14 14 120
- 15 16 100 110 100 16 16 120
- 17 18 100 110 100 18 18 120
- ## Complex tests with array_agg and then unnesting the array
- query R
- SELECT avg(u)
- FROM (
- SELECT x, unnest(l) AS u
- FROM (
- SELECT x, array_agg(y) OVER (PARTITION BY x%5) AS l
- FROM t7
- ) AS ff1
- ) AS ff2
- GROUP BY x%5
- ORDER BY x%5;
- ----
- -17
- 2
- 13
- 14
- NULL
- query IBRR
- WITH
- array_agg_unnest_grouped_agg AS (
- SELECT x%5 AS k1, avg(u) AS avg1
- FROM (
- SELECT x, unnest(l) AS u
- FROM (
- SELECT x, array_agg(y) OVER (PARTITION BY x%5) AS l
- FROM t7
- ) AS ff1
- ) AS ff2
- GROUP BY x%5
- ),
- grouped_agg AS (
- SELECT x%5 AS k2, avg(y) AS avg2
- FROM t7
- GROUP BY x%5
- )
- SELECT k1, avg1 = avg2, avg1, avg2
- FROM array_agg_unnest_grouped_agg, grouped_agg
- WHERE k1 = k2 AND avg1 IS NOT NULL
- ORDER BY k1;
- ----
- 0 true -17 -17
- 1 true 2 2
- 2 true 13 13
- 3 true 14 14
- query I
- WITH
- array_agg AS (
- SELECT x%5, array_agg(y) OVER (PARTITION BY x%5) AS l
- FROM t7
- )
- SELECT s
- FROM
- array_agg,
- LATERAL (
- SELECT sum(ul) AS s
- FROM (SELECT unnest(l) AS ul FROM array_agg) AS sq1
- ) AS sq2;
- ----
- -188
- -188
- -188
- -188
- -188
- -188
- -188
- -188
- -188
- -188
- -188
- query IRRB
- WITH
- simple AS (
- SELECT
- x%5 AS x5_simple,
- avg(y) OVER (PARTITION BY x%5) AS avg_simple
- FROM t7
- ),
- complicated AS ( -- array_agg, then do an unnest and global agg in a subquery in a SELECT
- WITH
- array_agg AS (
- SELECT
- x%5 AS x5,
- array_agg(y) OVER (PARTITION BY x%5) AS l
- FROM t7
- )
- SELECT
- x5 AS x5_complicated,
- (
- SELECT avg(uy)
- FROM unnest(l) AS uy
- ) AS avg_complicated
- FROM array_agg
- )
- SELECT DISTINCT
- x5_simple,
- avg_simple,
- avg_complicated,
- avg_simple = avg_complicated
- FROM simple, complicated
- WHERE x5_simple = x5_complicated
- ORDER BY x5_simple;
- ----
- 0 -17 -17 true
- 1 2 2 true
- 2 13 13 true
- 3 14 14 true
- 4 NULL NULL NULL
- # Regression test for https://github.com/MaterializeInc/materialize/pull/22270#issuecomment-1761432124
- statement ok
- SET cluster_replica = r1
- statement error db error: ERROR: Evaluation error: "4294967295 \* 2" uint4 out of range
- select max(1) over (partition by 1 order by 1, 1)
- from
- (select
- subq_2."c9" as c0
- from
- (select
- subq_1."c0" as c0,
- subq_1."c2" as c1,
- subq_1."c4" as c2,
- subq_1."c2" as c3,
- subq_1."c1" as c4,
- subq_1."c0" as c5,
- subq_1."c5" as c6,
- subq_1."c0" as c7,
- subq_1."c5" as c8,
- subq_1."c1" as c9,
- subq_1."c2" as c10,
- 87 as c11,
- subq_1."c1" as c12
- from
- (select
- subq_0."c1" as c0,
- subq_0."c0" as c1,
- subq_0."c1" as c2,
- subq_0."c0" as c3,
- subq_0."c1" as c4,
- subq_0."c0" as c5
- from
- (select
- ref_0."form_of_use" as c0,
- ref_0."default_collate_schema" as c1
- from
- information_schema.character_sets as ref_0
- ) as subq_0
- ) as subq_1
- ) as subq_2
- ) as subq_3
- where (case when (((select "collection_timestamp" from mz_internal.mz_storage_usage_by_shard limit 1 offset 4)
- ) < ((select pg_catalog.min("occurred_at") from mz_internal.mz_source_status_history)
- ))
- and ((case when subq_3."c0" is NULL then TIMESTAMPTZ '2023-01-01 01:23:45+06' else TIMESTAMPTZ '2023-01-01 01:23:45+06' end
- ) <> (pg_catalog.now())) then case when (((select pg_catalog.sum("connection_id") from mz_internal.mz_sessions)
- ) - (0::uint8)) >= ((select "worker_id" from mz_introspection.mz_arrangement_sharing_per_worker limit 1 offset 3)
- ) then numrange(0,0) else numrange(0,0) end
- else case when (((select pg_catalog.sum("connection_id") from mz_internal.mz_sessions)
- ) - (0::uint8)) >= ((select "worker_id" from mz_introspection.mz_arrangement_sharing_per_worker limit 1 offset 3)
- ) then numrange(0,0) else numrange(0,0) end
- end
- ) >= (case when (0::uint4) > (pg_catalog.mod(
- CAST((select 1 from mz_internal.mz_subscriptions limit 1 offset 2)
- as uint4),
- CAST((4294967295::uint4) * (2::uint4) as uint4))) then case when (mz_catalog.map_length(
- mz_internal.mz_role_oid_memberships())) = ((select pg_catalog.min("rolconnlimit") from pg_catalog.pg_roles)
- ) then case when (null::uint4) = (null::uint4) then numrange(0,0) else numrange(0,0) end
- else case when (null::uint4) = (null::uint4) then numrange(0,0) else numrange(0,0) end
- end
- else case when (mz_catalog.map_length(
- mz_internal.mz_role_oid_memberships())) = ((select pg_catalog.min("rolconnlimit") from pg_catalog.pg_roles)
- ) then case when (null::uint4) = (null::uint4) then numrange(0,0) else numrange(0,0) end
- else case when (null::uint4) = (null::uint4) then numrange(0,0) else numrange(0,0) end
- end
- end
- );
- ## Tests for window function fusion
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- *,
- lag(x) OVER (ORDER BY x),
- first_value(x) OVER (ORDER BY x),
- last_value(x) OVER (ORDER BY x),
- x*y,
- lag(y) OVER (ORDER BY x),
- lag(x+x,1,null) OVER (PARTITION BY x ORDER BY y),
- lead(x,2,null) OVER (PARTITION BY x ORDER BY -y NULLS FIRST),
- lead(x,2,null) OVER (PARTITION BY x ORDER BY -y NULLS LAST),
- x+y,
- lag(x+x,2,null) OVER (PARTITION BY x ORDER BY y),
- sum(x) OVER (ORDER BY x),
- min(x) OVER (ORDER BY x),
- max(x) OVER (ORDER BY y)
- FROM t7
- ORDER BY x,y;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last] output=[#0..=#14]
- Project (#3, #4, #16, #15, #14, #17, #13, #9, #11, #10, #18, #8, #7, #6, #5)
- Map (record_get[1](#1), record_get[0](#2), record_get[1](#2), record_get[2](#2), record_get[4](#2), record_get[5](#2), record_get[7](#2), record_get[8](#2), record_get[10](#2), record_get[12](#2), record_get[0](#1), record_get[0](#12), record_get[1](#12), record_get[2](#12), record_get[3](#12), (#3{x} * #4{y}), (#3{x} + #4{y}))
- FlatMap unnest_list(#0{fused_value_window_func})
- Reduce aggregates=[fused_value_window_func[lag[order_by=[#0 asc nulls_last]], last_value[order_by=[#0 asc nulls_last]], first_value[order_by=[#0 asc nulls_last]], lag[order_by=[#0 asc nulls_last]] order_by=[#0 asc nulls_last]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[2](record_get[1](#0)), record_get[3](record_get[1](#0)), record_get[4](record_get[1](#0)), record_get[5](record_get[1](#0)), record_get[6](record_get[1](#0)), record_get[7](record_get[1](#0)), record_get[8](record_get[1](#0)), record_get[9](record_get[1](#0)), record_get[10](record_get[1](#0)), record_get[0](#0), record_get[0](#0)), row(row(record_get[1](record_get[1](#0)), 1, null), record_get[0](record_get[1](#0)), record_get[0](record_get[1](#0)), row(record_get[0](record_get[1](#0)), 1, null))), record_get[0](record_get[1](#0))))]
- Project (#1)
- FlatMap unnest_list(#0{lead})
- Project (#1{lead})
- Reduce group_by=[record_get[0](record_get[1](#0))] aggregates=[lead[order_by=[#0 asc nulls_first]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[2](record_get[1](#0)), record_get[3](record_get[1](#0)), record_get[4](record_get[1](#0)), record_get[5](record_get[1](#0)), record_get[6](record_get[1](#0)), record_get[7](record_get[1](#0)), record_get[8](record_get[1](#0)), record_get[0](#0), record_get[0](#0)), row(record_get[0](record_get[1](#0)), 2, null)), -(record_get[1](record_get[1](#0)))))]
- Project (#1)
- FlatMap unnest_list(#0{lead})
- Project (#1{lead})
- Reduce group_by=[record_get[0](record_get[1](#0))] aggregates=[lead[order_by=[#0 asc nulls_last]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[2](record_get[1](#0)), record_get[3](record_get[1](#0)), record_get[4](record_get[1](#0)), record_get[5](record_get[1](#0)), record_get[0](#0), record_get[0](record_get[0](#0)), record_get[1](record_get[0](#0))), row(record_get[0](record_get[1](#0)), 2, null)), -(record_get[1](record_get[1](#0)))))]
- Project (#1)
- FlatMap unnest_list(#0{fused_value_window_func})
- Project (#1{fused_value_window_func})
- Reduce group_by=[record_get[0](record_get[1](#0))] aggregates=[fused_value_window_func[lag[order_by=[#0 asc nulls_last]], lag[order_by=[#0 asc nulls_last]] order_by=[#0 asc nulls_last]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[3](record_get[1](#0)), record_get[0](#0), record_get[0](record_get[0](#0)), record_get[1](record_get[0](#0))), row(row((record_get[0](record_get[1](#0)) + record_get[0](record_get[1](#0))), 2, null), row((record_get[0](record_get[1](#0)) + record_get[0](record_get[1](#0))), 1, null))), record_get[1](record_get[1](#0))))]
- Project (#1)
- FlatMap unnest_list(#0{fused_window_agg})
- Reduce aggregates=[fused_window_agg(row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[0](#0), record_get[0](#0)), row(record_get[0](record_get[1](#0)), record_get[0](record_get[1](#0)))), record_get[0](record_get[1](#0))))]
- Project (#1)
- FlatMap unnest_list(#0{window_agg})
- Reduce aggregates=[window_agg[max order_by=[#0{x} asc nulls_last]](row(row(row(#0{x}, #1{y}), #0{x}), #1{y}))]
- ReadStorage materialize.public.t7
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- query IIIIIIIIIIIIIII
- SELECT
- *,
- lag(x) OVER (ORDER BY x),
- first_value(x) OVER (ORDER BY x),
- last_value(x) OVER (ORDER BY x),
- x*y,
- lag(y) OVER (ORDER BY x),
- lag(x+x,1,null) OVER (PARTITION BY x ORDER BY y),
- lead(x,2,null) OVER (PARTITION BY x ORDER BY -y NULLS FIRST),
- lead(x,2,null) OVER (PARTITION BY x ORDER BY -y NULLS LAST),
- x+y,
- lag(x+x,2,null) OVER (PARTITION BY x ORDER BY y),
- sum(x) OVER (ORDER BY x),
- min(x) OVER (ORDER BY x),
- max(x) OVER (ORDER BY y)
- FROM t7
- ORDER BY x,y;
- ----
- 1 2 NULL 1 1 2 NULL NULL NULL NULL 3 NULL 1 1 10
- 3 NULL 1 1 3 NULL 2 NULL NULL NULL NULL NULL 4 1 17
- 5 6 3 1 5 30 NULL NULL NULL NULL 11 NULL 9 1 10
- 7 8 5 1 7 56 6 NULL NULL NULL 15 NULL 16 1 10
- 9 NULL 7 1 9 NULL 8 NULL NULL NULL NULL NULL 25 1 17
- 10 -50 9 1 10 -500 NULL NULL NULL NULL -40 NULL 45 1 10
- 10 -40 10 1 10 -400 -50 20 NULL NULL -30 NULL 45 1 10
- 11 NULL 10 1 11 NULL -40 NULL NULL NULL NULL NULL 56 1 17
- 13 14 11 1 13 182 NULL NULL NULL NULL 27 NULL 69 1 13
- 15 16 13 1 15 240 14 NULL NULL NULL 31 NULL 84 1 15
- 17 18 15 1 17 306 16 NULL NULL NULL 35 NULL 101 1 17
- # In the following query, currently we only fuse the two inner `lag`s.
- # In theory, we could also fuse the two `last_value`s.
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- *,
- first_value(
- lag(x*x,y,1111) OVER (PARTITION BY x ORDER BY y)
- ) OVER (PARTITION BY x ORDER BY y),
- x*y,
- last_value(
- lag(x*x,y,2222) OVER (PARTITION BY x ORDER BY y)
- ) OVER (PARTITION BY x ORDER BY y+y),
- last_value(x+y) OVER (PARTITION BY x ORDER BY y+y),
- lag(y) OVER (ORDER BY x),
- x+y
- FROM t7
- ORDER BY x,y;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last] output=[#0..=#7]
- Project (#3, #4, #8, #9, #7, #6, #5, #10)
- Map (record_get[1](#1), record_get[0](#2), record_get[1](#2), record_get[2](#2), record_get[3](#2), record_get[8](#2), record_get[0](#1), (#3{x} * #4{y}), (#3{x} + #4{y}))
- FlatMap unnest_list(#0{first_value})
- Project (#1{first_value})
- Reduce group_by=[record_get[0](record_get[1](#0))] aggregates=[first_value[order_by=[#0 asc nulls_last]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[2](record_get[1](#0)), record_get[3](record_get[1](#0)), record_get[4](record_get[1](#0)), record_get[5](record_get[1](#0)), record_get[6](record_get[1](#0)), record_get[0](#0), record_get[0](#0)), record_get[6](record_get[1](#0))), record_get[1](record_get[1](#0))))]
- Project (#1)
- FlatMap unnest_list(#0{last_value})
- Project (#1{last_value})
- Reduce group_by=[record_get[0](record_get[1](#0))] aggregates=[last_value[order_by=[#0 asc nulls_last]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[3](record_get[1](#0)), record_get[5](record_get[1](#0)), record_get[0](#0), record_get[0](record_get[0](#0)), record_get[1](record_get[0](#0))), record_get[0](record_get[0](#0))), (record_get[1](record_get[1](#0)) + record_get[1](record_get[1](#0)))))]
- Project (#1)
- FlatMap unnest_list(#0{fused_value_window_func})
- Project (#1{fused_value_window_func})
- Reduce group_by=[record_get[0](record_get[1](#0))] aggregates=[fused_value_window_func[lag[order_by=[#0 asc nulls_last]], lag[order_by=[#0 asc nulls_last]] order_by=[#0 asc nulls_last]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[2](record_get[1](#0)), record_get[3](record_get[1](#0)), record_get[0](#0), record_get[0](#0)), row(row((record_get[0](record_get[1](#0)) * record_get[0](record_get[1](#0))), record_get[1](record_get[1](#0)), 2222), row((record_get[0](record_get[1](#0)) * record_get[0](record_get[1](#0))), record_get[1](record_get[1](#0)), 1111))), record_get[1](record_get[1](#0))))]
- Project (#1)
- FlatMap unnest_list(#0{last_value})
- Project (#1{last_value})
- Reduce group_by=[record_get[0](record_get[1](#0))] aggregates=[last_value[order_by=[#0 asc nulls_last]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[0](#0), record_get[0](#0)), (record_get[0](record_get[1](#0)) + record_get[1](record_get[1](#0)))), (record_get[1](record_get[1](#0)) + record_get[1](record_get[1](#0)))))]
- Project (#1)
- FlatMap unnest_list(#0{lag})
- Reduce aggregates=[lag[order_by=[#0{x} asc nulls_last]](row(row(row(#0{x}, #1{y}), row(#1{y}, 1, null)), #0{x}))]
- ReadStorage materialize.public.t7
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- query IIIIIIII
- SELECT
- *,
- first_value(
- lag(x*x,y,1111) OVER (PARTITION BY x ORDER BY y)
- ) OVER (PARTITION BY x ORDER BY y),
- x*y,
- last_value(
- lag(x*x,y,2222) OVER (PARTITION BY x ORDER BY y)
- ) OVER (PARTITION BY x ORDER BY y+y),
- last_value(x+y) OVER (PARTITION BY x ORDER BY y+y),
- lag(y) OVER (ORDER BY x),
- x+y
- FROM t7
- ORDER BY x,y;
- ----
- 1 2 1111 2 2222 3 NULL 3
- 3 NULL NULL NULL NULL NULL 2 NULL
- 5 6 1111 30 2222 11 NULL 11
- 7 8 1111 56 2222 15 6 15
- 9 NULL NULL NULL NULL NULL 8 NULL
- 10 -50 1111 -500 2222 -40 NULL -40
- 10 -40 1111 -400 2222 -30 -50 -30
- 11 NULL NULL NULL NULL NULL -40 NULL
- 13 14 1111 182 2222 27 NULL 27
- 15 16 1111 240 2222 31 14 31
- 17 18 1111 306 2222 35 16 35
- query T multiline
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR
- SELECT
- *,
- lag(x) OVER (),
- lag(y) OVER (),
- sum(x) OVER (),
- min(x) OVER ()
- FROM t7
- ORDER BY x,y;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last] output=[#0..=#5]
- Project (#3, #4, #9, #8, #6, #5)
- Map (record_get[1](#1), record_get[0](#2), record_get[1](#2), record_get[3](#2), record_get[4](#2), record_get[0](#1), record_get[0](#7), record_get[1](#7))
- FlatMap unnest_list(#0{fused_value_window_func})
- Reduce aggregates=[fused_value_window_func[lag[order_by=[]], lag[order_by=[]] order_by=[]](row(row(row(record_get[0](record_get[1](#0)), record_get[1](record_get[1](#0)), record_get[0](#0), record_get[0](record_get[0](#0)), record_get[1](record_get[0](#0))), row(row(record_get[1](record_get[1](#0)), 1, null), row(record_get[0](record_get[1](#0)), 1, null)))))]
- Project (#1)
- FlatMap unnest_list(#0{fused_window_agg})
- Reduce aggregates=[fused_window_agg(row(row(row(#0{x}, #1{y}), row(#0{x}, #0{x}))))]
- ReadStorage materialize.public.t7
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- # Test the situation when the MFP above is fused into the Reduce, and the MFP can error.
- query III
- SELECT *
- FROM (
- SELECT *, lag(x) OVER (ORDER BY x) AS l
- FROM t7
- )
- WHERE l/2 < 7
- ORDER BY x,y,l;
- ----
- 3 NULL 1
- 5 6 3
- 7 8 5
- 9 NULL 7
- 10 -50 9
- 10 -40 10
- 11 NULL 10
- 13 14 11
- 15 16 13
- # Test the situation when the MFP above is fused into the Reduce, but the MFP can't error.
- query III
- SELECT *
- FROM (
- SELECT *, lag(x) OVER (ORDER BY x) AS l
- FROM t7
- )
- WHERE l < 14
- ORDER BY x,y,l;
- ----
- 3 NULL 1
- 5 6 3
- 7 8 5
- 9 NULL 7
- 10 -50 9
- 10 -40 10
- 11 NULL 10
- 13 14 11
- 15 16 13
- ## Check some LIR plans that the optimization of fusing `Reduce` with `FlatMap UnnestList` happens.
- ## https://github.com/MaterializeInc/materialize/pull/29554
- ## These should show `fused_unnest_list=true`.
- # Simple situation
- query T multiline
- EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
- SELECT
- lead(x,y-2,120) OVER (ORDER BY x)
- FROM t9;
- ----
- Explained Query:
- Mfp
- project=(#1)
- map=(record_get[0](#0))
- input_key=
- Reduce::Basic
- aggr=(0, lead[order_by=[#0 asc nulls_last]](row(row(row(#0, #1), row(#0{x}, (#1{y} - 2), 120)), #0{x})), fused_unnest_list=true)
- val_plan
- project=(#2)
- map=(row(row(row(#0, #1), row(#0{x}, (#1{y} - 2), 120)), #0{x}))
- key_plan
- project=()
- Get::PassArrangements materialize.public.t9
- raw=true
- Source materialize.public.t9
- Target cluster: quickstart
- EOF
- # PARTITION BY
- query T multiline
- EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
- SELECT
- lead(x,y-2,120) OVER (PARTITION BY x/2 ORDER BY x)
- FROM t9;
- ----
- Explained Query:
- Mfp
- project=(#2)
- map=(record_get[0](#1))
- input_key=#0
- Reduce::Basic
- aggr=(0, lead[order_by=[#0 asc nulls_last]](row(row(row(#0, #1), row(#0{x}, (#1{y} - 2), 120)), #0{x})), fused_unnest_list=true)
- val_plan
- project=(#2)
- map=(row(row(row(#0, #1), row(#0{x}, (#1{y} - 2), 120)), #0{x}))
- key_plan
- project=(#2)
- map=((#0{x} / 2))
- Get::PassArrangements materialize.public.t9
- raw=true
- Source materialize.public.t9
- Target cluster: quickstart
- EOF
- # PARTITION BY multiple columns
- query T multiline
- EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
- SELECT
- lead(x,y-2,120) OVER (PARTITION BY x/2, y ORDER BY x)
- FROM t9;
- ----
- Explained Query:
- Mfp
- project=(#3)
- map=(record_get[0](#2))
- input_key=#0, #1
- Reduce::Basic
- aggr=(0, lead[order_by=[#0 asc nulls_last]](row(row(row(#0, #1), row(#0{x}, (#1{y} - 2), 120)), #0{x})), fused_unnest_list=true)
- val_plan
- project=(#2)
- map=(row(row(row(#0, #1), row(#0{x}, (#1{y} - 2), 120)), #0{x}))
- key_plan
- project=(#2, #1)
- map=((#0{x} / 2))
- Get::PassArrangements materialize.public.t9
- raw=true
- Source materialize.public.t9
- Target cluster: quickstart
- EOF
- # row_number()
- query T multiline
- EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
- SELECT
- row_number() OVER (ORDER BY x),
- x
- FROM t7
- ORDER BY row_number
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last] output=[#0, #1]
- Mfp
- project=(#2, #1)
- map=(record_get[0](record_get[1](#0)), record_get[0](#0))
- input_key=
- Reduce::Basic
- aggr=(0, row_number[order_by=[#0 asc nulls_last]](row(list[row(#0, #1)], #0{x})), fused_unnest_list=true)
- val_plan
- project=(#2)
- map=(row(list[row(#0, #1)], #0{x}))
- key_plan
- project=()
- Get::PassArrangements materialize.public.t7
- raw=true
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- # MFP after is fused into the Reduce
- query T multiline
- EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
- SELECT *
- FROM (
- SELECT *, lag(x) OVER (ORDER BY x) AS l
- FROM t7
- )
- WHERE l < 14
- ORDER BY x,y,l;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last, #2 asc nulls_last] output=[#0..=#2]
- Mfp
- project=(#3, #4, #1)
- map=(record_get[0](#0), record_get[1](#0), record_get[0](#2), record_get[1](#2))
- input_key=
- Reduce::Basic
- aggr=(0, lag[order_by=[#0 asc nulls_last]](row(row(row(#0, #1), row(#0{x}, 1, null)), #0{x})), fused_unnest_list=true)
- val_plan
- project=(#2)
- map=(row(row(row(#0, #1), row(#0{x}, 1, null)), #0{x}))
- key_plan
- project=()
- mfp_after
- filter=((record_get[0](#0) < 14))
- Get::PassArrangements materialize.public.t7
- raw=true
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- # Two lags fused with each other + Reduce-FlatMap fusion.
- query T multiline
- EXPLAIN PHYSICAL PLAN AS VERBOSE TEXT FOR
- SELECT
- *,
- lag(x) OVER (),
- lag(y) OVER ()
- FROM t7
- ORDER BY x,y;
- ----
- Explained Query:
- Finish order_by=[#0 asc nulls_last, #1 asc nulls_last] output=[#0..=#3]
- Mfp
- project=(#2, #3, #6, #5)
- map=(record_get[1](#0), record_get[0](#1), record_get[1](#1), record_get[0](#0), record_get[0](#4), record_get[1](#4))
- input_key=
- Reduce::Basic
- aggr=(0, fused_value_window_func[lag[order_by=[]], lag[order_by=[]] order_by=[]](row(row(row(#0, #1), row(row(#1{y}, 1, null), row(#0{x}, 1, null))))), fused_unnest_list=true)
- val_plan
- project=(#2)
- map=(row(row(row(#0, #1), row(row(#1{y}, 1, null), row(#0{x}, 1, null)))))
- key_plan
- project=()
- Get::PassArrangements materialize.public.t7
- raw=true
- Source materialize.public.t7
- Target cluster: quickstart
- EOF
- ## Window functions on big relations.
- statement ok
- CREATE TABLE t10(t timestamptz, d1 int, d2 text, d3 int, d4 uint8, d5 int, d6 text);
- statement ok
- INSERT INTO t10
- SELECT generate_series(1,1000)::mz_timestamp::timestamptz, 5, 'aaa', 7, 8, 9, 'bbb';
- statement ok
- CREATE VIEW v1 AS
- SELECT t, d1, d2, EXTRACT(MILLISECOND FROM t) * 91 % 1223 AS d3, d4, d5, d6
- FROM t10;
- statement ok
- CREATE MATERIALIZED VIEW mv1 AS
- SELECT t, d1, d2, d3, d4, d6, lag(d1) OVER (ORDER BY t) - d1 AS r
- FROM v1;
- query I
- SELECT sum(r)
- FROM mv1;
- ----
- 0
- statement ok
- CREATE MATERIALIZED VIEW mv2 AS
- SELECT *, row_number() OVER (ORDER BY t) AS rn
- FROM mv1;
- query I
- SELECT sum(r)
- FROM (
- SELECT rn - lag(rn) OVER (ORDER BY t) AS r
- FROM mv2
- );
- ----
- 999
- query I
- SELECT sum(lv)
- FROM (
- SELECT last_value(rn) OVER () AS lv
- FROM mv2
- );
- ----
- 1000000
- statement ok
- DELETE FROM t10
- statement ok
- INSERT INTO t10
- SELECT generate_series(1,70000)::mz_timestamp::timestamptz, 5, 'aaa', 7, 8, 9, 'bbb';
- query I
- SELECT sum(r)
- FROM mv1;
- ----
- 0
- query I
- SELECT sum(r)
- FROM (
- SELECT rn - lag(rn) OVER (ORDER BY t) AS r
- FROM mv2
- );
- ----
- 69999
- ## QUALIFY
- query II
- SELECT *
- FROM t6
- QUALIFY row_number() OVER (PARTITION BY x%3 ORDER BY y) = 1;
- ----
- 1 2
- 5 6
- 15 16
- query IIII rowsort
- SELECT *, x%3, row_number() OVER (PARTITION BY x%3 ORDER BY y)
- FROM t6
- QUALIFY row_number() OVER (PARTITION BY x%3 ORDER BY y) = 1;
- ----
- 15 16 0 1
- 1 2 1 1
- 5 6 2 1
- query II
- SELECT *
- FROM t6
- QUALIFY sum(x) OVER (ORDER BY y) = 26;
- ----
- 13 14
- query II
- SELECT *
- FROM (SELECT * FROM t6 UNION ALL SELECT * FROM t6)
- QUALIFY sum(x) OVER (ORDER BY y) = 26;
- ----
- 7 8
- 7 8
- query I
- SELECT avg(u)
- FROM (
- SELECT x, unnest(l) AS u
- FROM (
- SELECT x, array_agg(y) OVER (PARTITION BY x%5) AS l
- FROM t7
- ) AS ff1
- ) AS ff2
- GROUP BY x%5
- QUALIFY sum(avg(u)) OVER (ORDER BY x%5) = -15
- ORDER BY x%5;
- ----
- 2
- query II
- SELECT *
- FROM (
- SELECT x, unnest(l) AS u
- FROM (
- SELECT x, array_agg(y) OVER (PARTITION BY x%5) AS l
- FROM t7
- ) AS ff1
- )
- QUALIFY x-lag(x) OVER (ORDER BY x) = 0 AND lag(x) OVER (ORDER BY x) - lag(lag(x) OVER (ORDER BY x)) OVER (ORDER BY x) = 0
- ORDER BY x,u;
- ----
- 5 6
- 5 16
- 10 -40
- 10 -40
- 10 6
- 10 6
- 10 16
- 10 16
- 15 6
- 15 16
- query III
- SELECT *, sum(x-9) OVER (ORDER BY x, u)
- FROM
- (
- SELECT DISTINCT *
- FROM (
- SELECT x, unnest(l) AS u
- FROM (
- SELECT x, array_agg(y) OVER (PARTITION BY x%5) AS l
- FROM t7
- ) AS ff1
- )
- QUALIFY x-lag(x) OVER (ORDER BY x) = 0 AND lag(x) OVER (ORDER BY x) - lag(lag(x) OVER (ORDER BY x)) OVER (ORDER BY x) = 0
- )
- QUALIFY sum(x-9) OVER (ORDER BY x, u) > -6
- ORDER BY x,u;
- ----
- 5 6 -4
- 10 16 -5
- 15 6 1
- 15 16 7
|