pg_sql.cpp 224 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469
  1. #include "../../parser/pg_wrapper/pg_compat.h"
  2. #ifdef _WIN32
  3. #define __restrict
  4. #endif
  5. #define TypeName PG_TypeName
  6. #define SortBy PG_SortBy
  7. #undef SIZEOF_SIZE_T
  8. extern "C" {
  9. #include "postgres.h"
  10. #include "nodes/pg_list.h"
  11. #include "nodes/parsenodes.h"
  12. #include "nodes/value.h"
  13. #undef Min
  14. #undef Max
  15. #undef TypeName
  16. #undef SortBy
  17. #undef TRACE
  18. #undef INFO
  19. #undef WARNING
  20. #undef ERROR
  21. #undef FATAL
  22. #undef NOTICE
  23. }
  24. #include "util/charset/utf8.h"
  25. #include "utils.h"
  26. #include <yql/essentials/ast/yql_expr.h>
  27. #include <yql/essentials/sql/settings/partitioning.h>
  28. #include <yql/essentials/sql/settings/translator.h>
  29. #include <yql/essentials/parser/pg_wrapper/interface/config.h>
  30. #include <yql/essentials/parser/pg_wrapper/interface/parser.h>
  31. #include <yql/essentials/parser/pg_wrapper/interface/utils.h>
  32. #include <yql/essentials/parser/pg_wrapper/interface/raw_parser.h>
  33. #include <yql/essentials/parser/pg_wrapper/postgresql/src/backend/catalog/pg_type_d.h>
  34. #include <yql/essentials/parser/pg_catalog/catalog.h>
  35. #include <yql/essentials/providers/common/provider/yql_provider_names.h>
  36. #include <yql/essentials/minikql/mkql_type_builder.h>
  37. #include <yql/essentials/core/issue/yql_issue.h>
  38. #include <yql/essentials/core/sql_types/yql_callable_names.h>
  39. #include <yql/essentials/parser/pg_catalog/catalog.h>
  40. #include <yql/essentials/utils/log/log_level.h>
  41. #include <yql/essentials/utils/log/log.h>
  42. #include <util/string/builder.h>
  43. #include <util/string/cast.h>
  44. #include <util/string/join.h>
  45. #include <util/string/split.h>
  46. #include <util/generic/scope.h>
  47. #include <util/generic/stack.h>
  48. #include <util/generic/hash_set.h>
  49. constexpr auto PREPARED_PARAM_PREFIX = "$p";
  50. constexpr auto AUTO_PARAM_PREFIX = "a";
  51. constexpr auto DEFAULT_PARAM_TYPE = "unknown";
  52. namespace NSQLTranslationPG {
  53. using namespace NYql;
  54. static const THashSet<TString> SystemColumns = { "tableoid", "xmin", "cmin", "xmax", "cmax", "ctid" };
  55. template <typename T>
  56. const T* CastNode(const void* nodeptr, int tag) {
  57. Y_ENSURE(nodeTag(nodeptr) == tag);
  58. return static_cast<const T*>(nodeptr);
  59. }
  60. const Node* Expr2Node(const Expr* e) {
  61. return reinterpret_cast<const Node*>(e);
  62. }
  63. int NodeTag(const Node* node) {
  64. return nodeTag(node);
  65. }
  66. int NodeTag(const ValUnion& val) {
  67. return NodeTag(&val.node);
  68. }
  69. int IntVal(const ValUnion& val) {
  70. Y_ENSURE(val.node.type == T_Integer);
  71. return intVal(&val.node);
  72. }
  73. bool BoolVal(const ValUnion& val) {
  74. Y_ENSURE(val.node.type == T_Boolean);
  75. return boolVal(&val.node);
  76. }
  77. const char* StrFloatVal(const ValUnion& val) {
  78. Y_ENSURE(val.node.type == T_Float);
  79. return strVal(&val.node);
  80. }
  81. const char* StrVal(const ValUnion& val) {
  82. Y_ENSURE(val.node.type == T_String || val.node.type == T_BitString);
  83. return strVal(&val.node);
  84. }
  85. int BoolVal(const Node* node) {
  86. Y_ENSURE(node->type == T_Boolean);
  87. return boolVal(node);
  88. }
  89. int IntVal(const Node* node) {
  90. Y_ENSURE(node->type == T_Integer);
  91. return intVal(node);
  92. }
  93. double FloatVal(const Node* node) {
  94. Y_ENSURE(node->type == T_Float);
  95. return floatVal(node);
  96. }
  97. const char* StrFloatVal(const Node* node) {
  98. Y_ENSURE(node->type == T_Float);
  99. return strVal(node);
  100. }
  101. const char* StrVal(const Node* node) {
  102. Y_ENSURE(node->type == T_String || node->type == T_BitString);
  103. return strVal(node);
  104. }
  105. bool ValueAsString(const ValUnion& val, bool isNull, TString& ret) {
  106. if (isNull) {
  107. ret = "NULL";
  108. return true;
  109. }
  110. switch (NodeTag(val)) {
  111. case T_Boolean: {
  112. ret = BoolVal(val) ? "t" : "f";
  113. return true;
  114. }
  115. case T_Integer: {
  116. ret = ToString(IntVal(val));
  117. return true;
  118. }
  119. case T_Float: {
  120. ret = StrFloatVal(val);
  121. return true;
  122. }
  123. case T_String:
  124. case T_BitString: {
  125. ret = StrVal(val);
  126. return true;
  127. }
  128. default:
  129. return false;
  130. }
  131. }
  132. int ListLength(const List* list) {
  133. return list_length(list);
  134. }
  135. int StrLength(const char* s) {
  136. return s ? strlen(s) : 0;
  137. }
  138. int StrCompare(const char* s1, const char* s2) {
  139. return strcmp(s1 ? s1 : "", s2 ? s2 : "");
  140. }
  141. int StrICompare(const char* s1, const char* s2) {
  142. return stricmp(s1 ? s1 : "", s2 ? s2 : "");
  143. }
  144. std::shared_ptr<List> ListMake1(void* cell) {
  145. return std::shared_ptr<List>(list_make1(cell), list_free);
  146. }
  147. #define CAST_NODE(nodeType, nodeptr) CastNode<nodeType>(nodeptr, T_##nodeType)
  148. #define CAST_NODE_EXT(nodeType, tag, nodeptr) CastNode<nodeType>(nodeptr, tag)
  149. #define LIST_CAST_NTH(nodeType, list, index) CAST_NODE(nodeType, list_nth(list, index))
  150. #define LIST_CAST_EXT_NTH(nodeType, tag, list, index) CAST_NODE_EXT(nodeType, tag, list_nth(list, i))
  151. const Node* ListNodeNth(const List* list, int index) {
  152. return static_cast<const Node*>(list_nth(list, index));
  153. }
  154. const IndexElem* IndexElement(const Node* node) {
  155. Y_ENSURE(node->type == T_IndexElem);
  156. return ((const IndexElem*)node);
  157. }
  158. #define AT_LOCATION(node) \
  159. TLocationGuard guard(this, node->location);
  160. #define AT_LOCATION_EX(node, field) \
  161. TLocationGuard guard(this, node->field);
  162. std::tuple<TStringBuf, TStringBuf> getSchemaAndObjectName(const List* nameList) {
  163. switch (ListLength(nameList)) {
  164. case 2: {
  165. const auto clusterName = StrVal(ListNodeNth(nameList, 0));
  166. const auto tableName = StrVal(ListNodeNth(nameList, 1));
  167. return {clusterName, tableName};
  168. }
  169. case 1: {
  170. const auto tableName = StrVal(ListNodeNth(nameList, 0));
  171. return {"", tableName};
  172. }
  173. default: {
  174. return {"", ""};
  175. }
  176. }
  177. }
  178. struct TPgConst {
  179. TMaybe<TString> value;
  180. enum class Type {
  181. boolean,
  182. int4,
  183. int8,
  184. numeric,
  185. text,
  186. unknown,
  187. bit,
  188. nil,
  189. };
  190. static TString ToString(const TPgConst::Type& type) {
  191. switch (type) {
  192. case TPgConst::Type::boolean:
  193. return "bool";
  194. case TPgConst::Type::int4:
  195. return "int4";
  196. case TPgConst::Type::int8:
  197. return "int8";
  198. case TPgConst::Type::numeric:
  199. return "numeric";
  200. case TPgConst::Type::text:
  201. return "text";
  202. case TPgConst::Type::unknown:
  203. return "unknown";
  204. case TPgConst::Type::bit:
  205. return "bit";
  206. case TPgConst::Type::nil:
  207. return "unknown";
  208. }
  209. }
  210. Type type;
  211. };
  212. TMaybe<TPgConst> GetValueNType(const A_Const* value) {
  213. TPgConst pgConst;
  214. if (value->isnull) {
  215. pgConst.type = TPgConst::Type::nil;
  216. return pgConst;
  217. }
  218. const auto& val = value->val;
  219. switch (NodeTag(val)) {
  220. case T_Boolean: {
  221. pgConst.value = BoolVal(val) ? "t" : "f";
  222. pgConst.type = TPgConst::Type::boolean;
  223. return pgConst;
  224. }
  225. case T_Integer: {
  226. pgConst.value = ToString(IntVal(val));
  227. pgConst.type = TPgConst::Type::int4;
  228. return pgConst;
  229. }
  230. case T_Float: {
  231. auto s = StrFloatVal(val);
  232. i64 v;
  233. const bool isInt8 = TryFromString<i64>(s, v);
  234. pgConst.value = ToString(s);
  235. pgConst.type = isInt8 ? TPgConst::Type::int8 : TPgConst::Type::numeric;
  236. return pgConst;
  237. }
  238. case T_String: {
  239. pgConst.value = ToString(StrVal(val));
  240. pgConst.type = TPgConst::Type::unknown; // to support implicit casts
  241. return pgConst;
  242. }
  243. case T_BitString: {
  244. pgConst.value = ToString(StrVal(val));
  245. pgConst.type = TPgConst::Type::bit;
  246. return pgConst;
  247. }
  248. default: {
  249. return {};
  250. }
  251. }
  252. }
  253. class TConverter : public IPGParseEvents {
  254. friend class TLocationGuard;
  255. private:
  256. class TLocationGuard {
  257. private:
  258. TConverter* Owner;
  259. public:
  260. TLocationGuard(TConverter* owner, int location)
  261. : Owner(owner)
  262. {
  263. Owner->PushPosition(location);
  264. }
  265. ~TLocationGuard() {
  266. Owner->PopPosition();
  267. }
  268. };
  269. public:
  270. struct TFromDesc {
  271. TAstNode* Source = nullptr;
  272. TString Alias;
  273. TVector<TString> ColNames;
  274. bool InjectRead = false;
  275. };
  276. struct TReadWriteKeyExprs {
  277. TAstNode* SinkOrSource = nullptr;
  278. TAstNode* Key = nullptr;
  279. };
  280. struct TExprSettings {
  281. bool AllowColumns = false;
  282. bool AllowAggregates = false;
  283. bool AllowOver = false;
  284. bool AllowReturnSet = false;
  285. bool AllowSubLinks = false;
  286. bool AutoParametrizeEnabled = true;
  287. TVector<TAstNode*>* WindowItems = nullptr;
  288. TString Scope;
  289. };
  290. struct TView {
  291. TString Name;
  292. TVector<TString> ColNames;
  293. TAstNode* Source = nullptr;
  294. };
  295. using TViews = THashMap<TString, TView>;
  296. struct TState {
  297. TMaybe<TString> ApplicationName;
  298. TString CostBasedOptimizer;
  299. TVector<TAstNode*> Statements;
  300. ui32 ReadIndex = 0;
  301. TViews Views;
  302. TVector<TViews> CTE;
  303. const TView* CurrentRecursiveView = nullptr;
  304. TVector<NYql::TPosition> Positions = {NYql::TPosition()};
  305. THashMap<TString, TString> ParamNameToPgTypeName;
  306. NYql::IAutoParamBuilderPtr AutoParamValues;
  307. };
  308. TConverter(TVector<TAstParseResult>& astParseResults, const NSQLTranslation::TTranslationSettings& settings,
  309. const TString& query, TVector<TStmtParseInfo>* stmtParseInfo, bool perStatementResult,
  310. TMaybe<ui32> sqlProcArgsCount)
  311. : AstParseResults(astParseResults)
  312. , Settings(settings)
  313. , DqEngineEnabled(Settings.DqDefaultAuto->Allow())
  314. , BlockEngineEnabled(Settings.BlockDefaultAuto->Allow())
  315. , StmtParseInfo(stmtParseInfo)
  316. , PerStatementResult(perStatementResult)
  317. , SqlProcArgsCount(sqlProcArgsCount)
  318. {
  319. Y_ENSURE(settings.Mode == NSQLTranslation::ESqlMode::QUERY || settings.Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW);
  320. Y_ENSURE(settings.Mode != NSQLTranslation::ESqlMode::LIMITED_VIEW || !perStatementResult);
  321. State.ApplicationName = Settings.ApplicationName;
  322. AstParseResults.push_back({});
  323. if (StmtParseInfo) {
  324. StmtParseInfo->push_back({});
  325. }
  326. ScanRows(query);
  327. for (auto& flag : Settings.Flags) {
  328. if (flag == "DqEngineEnable") {
  329. DqEngineEnabled = true;
  330. } else if (flag == "DqEngineForce") {
  331. DqEngineForce = true;
  332. } else if (flag == "BlockEngineEnable") {
  333. BlockEngineEnabled = true;
  334. } else if (flag == "BlockEngineForce") {
  335. BlockEngineForce = true;
  336. } if (flag == "UnorderedResult") {
  337. UnorderedResult = true;
  338. }
  339. }
  340. if (Settings.PathPrefix) {
  341. TablePathPrefix = Settings.PathPrefix + "/";
  342. }
  343. for (const auto& [cluster, provider] : Settings.ClusterMapping) {
  344. if (provider != PgProviderName) {
  345. Provider = provider;
  346. break;
  347. }
  348. }
  349. if (!Provider) {
  350. Provider = PgProviderName;
  351. }
  352. Y_ENSURE(!Provider.empty());
  353. for (size_t i = 0; i < Settings.PgParameterTypeOids.size(); ++i) {
  354. const auto paramName = PREPARED_PARAM_PREFIX + ToString(i + 1);
  355. const auto typeOid = Settings.PgParameterTypeOids[i];
  356. const auto& typeName =
  357. typeOid != UNKNOWNOID ? NPg::LookupType(typeOid).Name : DEFAULT_PARAM_TYPE;
  358. State.ParamNameToPgTypeName[paramName] = typeName;
  359. }
  360. }
  361. void OnResult(const List* raw) {
  362. if (!PerStatementResult) {
  363. AstParseResults[StatementId].Pool = std::make_unique<TMemoryPool>(4096);
  364. AstParseResults[StatementId].Root = ParseResult(raw);
  365. AstParseResults[StatementId].PgAutoParamValues = State.AutoParamValues;
  366. return;
  367. }
  368. AstParseResults.resize(ListLength(raw));
  369. if (StmtParseInfo) {
  370. StmtParseInfo->resize(AstParseResults.size());
  371. }
  372. for (; StatementId < AstParseResults.size(); ++StatementId) {
  373. AstParseResults[StatementId].Pool = std::make_unique<TMemoryPool>(4096);
  374. AstParseResults[StatementId].Root = ParseResult(raw, StatementId);
  375. AstParseResults[StatementId].PgAutoParamValues = State.AutoParamValues;
  376. State = {};
  377. }
  378. }
  379. void OnError(const TIssue& issue) {
  380. AstParseResults[StatementId].Issues.AddIssue(issue);
  381. }
  382. void PrepareStatements() {
  383. auto configSource = L(A("DataSource"), QA(TString(NYql::ConfigProviderName)));
  384. State.Statements.push_back(L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource,
  385. QA("OrderedColumns"))));
  386. }
  387. TAstNode* ParseResult(const List* raw, const TMaybe<ui32> statementId = Nothing()) {
  388. PrepareStatements();
  389. auto configSource = L(A("DataSource"), QA(TString(NYql::ConfigProviderName)));
  390. ui32 blockEnginePgmPos = State.Statements.size();
  391. State.Statements.push_back(configSource);
  392. ui32 costBasedOptimizerPos = State.Statements.size();
  393. State.Statements.push_back(configSource);
  394. ui32 dqEnginePgmPos = State.Statements.size();
  395. State.Statements.push_back(configSource);
  396. if (statementId) {
  397. if (!ParseRawStmt(LIST_CAST_NTH(RawStmt, raw, *statementId))) {
  398. return nullptr;
  399. }
  400. } else {
  401. for (int i = 0; i < ListLength(raw); ++i) {
  402. if (!ParseRawStmt(LIST_CAST_NTH(RawStmt, raw, i))) {
  403. return nullptr;
  404. }
  405. }
  406. }
  407. if (!State.Views.empty()) {
  408. AddError("Not all views have been dropped");
  409. return nullptr;
  410. }
  411. if (Settings.EndOfQueryCommit && Settings.Mode != NSQLTranslation::ESqlMode::LIMITED_VIEW) {
  412. State.Statements.push_back(L(A("let"), A("world"), L(A("CommitAll!"),
  413. A("world"))));
  414. }
  415. AddVariableDeclarations();
  416. if (Settings.Mode != NSQLTranslation::ESqlMode::LIMITED_VIEW) {
  417. State.Statements.push_back(L(A("return"), A("world")));
  418. }
  419. if (DqEngineEnabled) {
  420. State.Statements[dqEnginePgmPos] = L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource,
  421. QA("DqEngine"), QA(DqEngineForce ? "force" : "auto")));
  422. } else {
  423. State.Statements.erase(State.Statements.begin() + dqEnginePgmPos);
  424. }
  425. if (State.CostBasedOptimizer) {
  426. State.Statements[costBasedOptimizerPos] = L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource,
  427. QA("CostBasedOptimizer"), QA(State.CostBasedOptimizer)));
  428. } else {
  429. State.Statements.erase(State.Statements.begin() + costBasedOptimizerPos);
  430. }
  431. if (BlockEngineEnabled) {
  432. State.Statements[blockEnginePgmPos] = L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource,
  433. QA("BlockEngine"), QA(BlockEngineForce ? "force" : "auto")));
  434. } else {
  435. State.Statements.erase(State.Statements.begin() + blockEnginePgmPos);
  436. }
  437. return FinishStatements();
  438. }
  439. TAstNode* FinishStatements() {
  440. return VL(State.Statements.data(), State.Statements.size());
  441. }
  442. [[nodiscard]]
  443. bool ParseRawStmt(const RawStmt* value) {
  444. AT_LOCATION_EX(value, stmt_location);
  445. auto node = value->stmt;
  446. if (Settings.Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
  447. if (NodeTag(node) != T_SelectStmt && NodeTag(node) != T_VariableSetStmt) {
  448. AddError("Unsupported statement in LIMITED_VIEW mode");
  449. return false;
  450. }
  451. }
  452. if (StmtParseInfo) {
  453. (*StmtParseInfo)[StatementId].CommandTagName = GetCommandName(node);
  454. }
  455. switch (NodeTag(node)) {
  456. case T_SelectStmt:
  457. return ParseSelectStmt(CAST_NODE(SelectStmt, node), {.Inner = false}) != nullptr;
  458. case T_InsertStmt:
  459. return ParseInsertStmt(CAST_NODE(InsertStmt, node)) != nullptr;
  460. case T_UpdateStmt:
  461. return ParseUpdateStmt(CAST_NODE(UpdateStmt, node)) != nullptr;
  462. case T_ViewStmt:
  463. return ParseViewStmt(CAST_NODE(ViewStmt, node)) != nullptr;
  464. case T_CreateStmt:
  465. return ParseCreateStmt(CAST_NODE(CreateStmt, node)) != nullptr;
  466. case T_DropStmt:
  467. return ParseDropStmt(CAST_NODE(DropStmt, node)) != nullptr;
  468. case T_VariableSetStmt:
  469. {
  470. // YQL-16284
  471. const char* node_name = CAST_NODE(VariableSetStmt, node)->name;
  472. const char* skip_statements[] = {
  473. "extra_float_digits", // jdbc
  474. "application_name", // jdbc
  475. "statement_timeout", // pg_dump
  476. "lock_timeout", // pg_dump
  477. "idle_in_transaction_session_timeout", // pg_dump
  478. "client_encoding", // pg_dump
  479. "standard_conforming_strings", // pg_dump
  480. "check_function_bodies", // pg_dump
  481. "xmloption", // pg_dump
  482. "client_min_messages", // pg_dump
  483. "row_security", // pg_dump
  484. "escape_string_warning", // zabbix
  485. "bytea_output", // zabbix
  486. "datestyle", // pgadmin 4
  487. "timezone", // mediawiki
  488. NULL,
  489. };
  490. for (int i = 0; skip_statements[i] != NULL; i++){
  491. const char *skip_name = skip_statements[i];
  492. if (stricmp(node_name, skip_name) == 0){
  493. return true;
  494. }
  495. };
  496. };
  497. return ParseVariableSetStmt(CAST_NODE(VariableSetStmt, node)) != nullptr;
  498. case T_DeleteStmt:
  499. return ParseDeleteStmt(CAST_NODE(DeleteStmt, node)) != nullptr;
  500. case T_VariableShowStmt:
  501. return ParseVariableShowStmt(CAST_NODE(VariableShowStmt, node)) != nullptr;
  502. case T_TransactionStmt:
  503. return ParseTransactionStmt(CAST_NODE(TransactionStmt, node));
  504. case T_IndexStmt:
  505. return ParseIndexStmt(CAST_NODE(IndexStmt, node)) != nullptr;
  506. case T_CreateSeqStmt:
  507. return ParseCreateSeqStmt(CAST_NODE(CreateSeqStmt, node)) != nullptr;
  508. case T_AlterSeqStmt:
  509. return ParseAlterSeqStmt(CAST_NODE(AlterSeqStmt, node)) != nullptr;
  510. case T_AlterTableStmt:
  511. return ParseAlterTableStmt(CAST_NODE(AlterTableStmt, node)) != nullptr;
  512. default:
  513. NodeNotImplemented(value, node);
  514. return false;
  515. }
  516. }
  517. [[nodiscard]]
  518. bool ExtractPgConstsForAutoParam(List* rawValuesLists, TVector<TPgConst>& pgConsts) {
  519. YQL_LOG_CTX_SCOPE(TStringBuf("PgSql Autoparametrize"), __FUNCTION__);
  520. Y_ABORT_UNLESS(rawValuesLists);
  521. size_t rows = ListLength(rawValuesLists);
  522. if (rows == 0 || !Settings.AutoParametrizeEnabled || !Settings.AutoParametrizeValuesStmt) {
  523. return false;
  524. }
  525. size_t cols = ListLength(CAST_NODE(List, ListNodeNth(rawValuesLists, 0)));
  526. pgConsts.reserve(rows * cols);
  527. for (int rowIdx = 0; rowIdx < ListLength(rawValuesLists); ++rowIdx) {
  528. const auto rawRow = CAST_NODE(List, ListNodeNth(rawValuesLists, rowIdx));
  529. for (int colIdx = 0; colIdx < ListLength(rawRow); ++colIdx) {
  530. const auto rawCell = ListNodeNth(rawRow, colIdx);
  531. if (NodeTag(rawCell) != T_A_Const) {
  532. YQL_CLOG(INFO, Default) << "Auto parametrization of " << NodeTag(rawCell) << " is not supported";
  533. return false;
  534. }
  535. auto pgConst = GetValueNType(CAST_NODE(A_Const, rawCell));
  536. if (!pgConst) {
  537. return false;
  538. }
  539. pgConsts.push_back(std::move(pgConst.GetRef()));
  540. }
  541. }
  542. return true;
  543. }
  544. TMaybe<TVector<TPgConst::Type>> InferColumnTypesForValuesStmt(const TVector<TPgConst>& values, size_t cols) {
  545. Y_ABORT_UNLESS((values.size() % cols == 0), "wrong amount of columns for auto param values vector");
  546. TVector<TMaybe<TPgConst::Type>> maybeColumnTypes(cols);
  547. for (size_t i = 0; i < values.size(); ++i) {
  548. const auto& value = values[i];
  549. size_t col = i % cols;
  550. auto& columnType = maybeColumnTypes[col];
  551. if (!columnType || columnType.GetRef() == TPgConst::Type::unknown || columnType.GetRef() == TPgConst::Type::nil) {
  552. columnType = value.type;
  553. continue;
  554. }
  555. // should we allow compatible types here?
  556. if (columnType.GetRef() != value.type && columnType.GetRef() != TPgConst::Type::unknown && columnType.GetRef() != TPgConst::Type::nil) {
  557. YQL_CLOG(INFO, Default)
  558. << "Failed to auto parametrize: different types: "
  559. << TPgConst::ToString(columnType.GetRef()) << " and " << TPgConst::ToString(value.type)
  560. << " in col " << col;
  561. return {};
  562. }
  563. }
  564. TVector<TPgConst::Type> columnTypes;
  565. for (auto& maybeColumnType: maybeColumnTypes) {
  566. if (maybeColumnType.Empty()) {
  567. YQL_CLOG(INFO, Default) << "Failed to auto parametrize: can't infer PgType for column";
  568. return {};
  569. }
  570. columnTypes.emplace_back(maybeColumnType.GetRef());
  571. }
  572. return columnTypes;
  573. }
  574. TString AddSimpleAutoParam(TPgConst&& valueNType) {
  575. if (!State.AutoParamValues) {
  576. Y_ENSURE(Settings.AutoParamBuilderFactory);
  577. State.AutoParamValues = Settings.AutoParamBuilderFactory->MakeBuilder();
  578. }
  579. auto nextName = TString(AUTO_PARAM_PREFIX) + ToString(State.AutoParamValues->Size());
  580. auto& type = State.AutoParamValues->Add(nextName);
  581. type.Pg(TPgConst::ToString(valueNType.type));
  582. auto& data = type.FinishType();
  583. data.Pg(valueNType.value);
  584. data.FinishData();
  585. return nextName;
  586. }
  587. TString AddValuesAutoParam(TVector<TPgConst>&& values, TVector<TPgConst::Type>&& columnTypes) {
  588. if (!State.AutoParamValues) {
  589. Y_ENSURE(Settings.AutoParamBuilderFactory);
  590. State.AutoParamValues = Settings.AutoParamBuilderFactory->MakeBuilder();
  591. }
  592. auto nextName = TString(AUTO_PARAM_PREFIX) + ToString(State.AutoParamValues->Size());
  593. auto& type = State.AutoParamValues->Add(nextName);
  594. type.BeginList();
  595. type.BeginTuple();
  596. for (const auto& t : columnTypes) {
  597. type.BeforeItem();
  598. type.Pg(TPgConst::ToString(t));
  599. type.AfterItem();
  600. }
  601. type.EndTuple();
  602. type.EndList();
  603. auto& data = type.FinishType();
  604. data.BeginList();
  605. size_t cols = columnTypes.size();
  606. for (size_t idx = 0; idx < values.size(); idx += cols){
  607. data.BeforeItem();
  608. data.BeginTuple();
  609. for (size_t delta = 0; delta < cols; ++delta) {
  610. data.BeforeItem();
  611. data.Pg(values[idx + delta].value);
  612. data.AfterItem();
  613. }
  614. data.EndTuple();
  615. data.AfterItem();
  616. }
  617. data.EndList();
  618. data.FinishData();
  619. return nextName;
  620. }
  621. TAstNode* MakeValuesStmtAutoParam(TVector<TPgConst>&& values, TVector<TPgConst::Type>&& columnTypes) {
  622. TVector<TAstNode*> autoParamTupleType;
  623. autoParamTupleType.reserve(columnTypes.size());
  624. autoParamTupleType.push_back(A("TupleType"));
  625. for (const auto& type : columnTypes) {
  626. auto pgType = L(A("PgType"), QA(TPgConst::ToString(type)));
  627. autoParamTupleType.push_back(pgType);
  628. }
  629. const auto paramType = L(A("ListType"), VL(autoParamTupleType));
  630. const auto paramName = AddValuesAutoParam(std::move(values), std::move(columnTypes));
  631. State.Statements.push_back(L(A("declare"), A(paramName), paramType));
  632. YQL_CLOG(INFO, Default) << "Successfully autoparametrized VALUES at" << State.Positions.back();
  633. return A(paramName);
  634. }
  635. [[nodiscard]]
  636. TAstNode* ParseValuesList(List* valuesLists, bool buildCommonType) {
  637. TVector<TAstNode*> valNames;
  638. uint64 colIdx = 0;
  639. TExprSettings settings;
  640. settings.AllowColumns = false;
  641. settings.Scope = "VALUES";
  642. for (int valueIndex = 0; valueIndex < ListLength(valuesLists); ++valueIndex) {
  643. auto node = ListNodeNth(valuesLists, valueIndex);
  644. if (NodeTag(node) != T_List) {
  645. NodeNotImplemented(node);
  646. return nullptr;
  647. }
  648. auto lst = CAST_NODE(List, node);
  649. if (valueIndex == 0) {
  650. for (int item = 0; item < ListLength(lst); ++item) {
  651. valNames.push_back(QA("column" + ToString(colIdx++)));
  652. }
  653. } else {
  654. if (ListLength(lst) != (int)valNames.size()) {
  655. AddError("VALUES lists must all be the same length");
  656. return nullptr;
  657. }
  658. }
  659. }
  660. TVector<TPgConst> pgConsts;
  661. bool canAutoparametrize = ExtractPgConstsForAutoParam(valuesLists, pgConsts);
  662. if (canAutoparametrize) {
  663. auto maybeColumnTypes = InferColumnTypesForValuesStmt(pgConsts, valNames.size());
  664. if (maybeColumnTypes) {
  665. auto valuesNode = MakeValuesStmtAutoParam(std::move(pgConsts), std::move(maybeColumnTypes.GetRef()));
  666. return QL(QA("values"), QVL(valNames.data(), valNames.size()), valuesNode);
  667. }
  668. }
  669. TVector<TAstNode*> valueRows;
  670. valueRows.reserve(ListLength(valuesLists));
  671. valueRows.push_back(A(buildCommonType ? "PgValuesList" : "AsList"));
  672. for (int valueIndex = 0; valueIndex < ListLength(valuesLists); ++valueIndex) {
  673. auto node = ListNodeNth(valuesLists, valueIndex);
  674. if (NodeTag(node) != T_List) {
  675. NodeNotImplemented(node);
  676. return nullptr;
  677. }
  678. auto lst = CAST_NODE(List, node);
  679. TVector<TAstNode*> row;
  680. for (int item = 0; item < ListLength(lst); ++item) {
  681. auto cell = ParseExpr(ListNodeNth(lst, item), settings);
  682. if (!cell) {
  683. return nullptr;
  684. }
  685. row.push_back(cell);
  686. }
  687. valueRows.push_back(QVL(row.data(), row.size()));
  688. }
  689. return QL(QA("values"), QVL(valNames.data(), valNames.size()), VL(valueRows));
  690. }
  691. TAstNode* ParseSetConfig(const FuncCall* value) {
  692. auto length = ListLength(value->args);
  693. if (length != 3) {
  694. AddError(TStringBuilder() << "Expected 3 arguments, but got: " << length);
  695. return nullptr;
  696. }
  697. VariableSetStmt config;
  698. config.kind = VAR_SET_VALUE;
  699. auto arg0 = ListNodeNth(value->args, 0);
  700. auto arg1 = ListNodeNth(value->args, 1);
  701. auto arg2 = ListNodeNth(value->args, 2);
  702. if (NodeTag(arg2) != T_A_Const) {
  703. AddError(TStringBuilder() << "Expected AConst node as is_local arg, but got node with tag: " << NodeTag(arg2));
  704. return nullptr;
  705. }
  706. auto isLocalConst = CAST_NODE(A_Const, arg2);
  707. if (isLocalConst->isnull) {
  708. AddError(TStringBuilder() << "Expected t/f, but got null");
  709. return nullptr;
  710. }
  711. if (NodeTag(isLocalConst->val) != T_Boolean) {
  712. AddError(TStringBuilder() << "Expected bool in const, but got something wrong: " << NodeTag(isLocalConst->val));
  713. return nullptr;
  714. }
  715. config.is_local = BoolVal(isLocalConst->val);
  716. if (NodeTag(arg0) != T_A_Const || NodeTag(arg1) != T_A_Const) {
  717. AddError(TStringBuilder() << "Expected const with string, but got something else: " << NodeTag(arg0));
  718. return nullptr;
  719. }
  720. if (CAST_NODE(A_Const, arg0)->isnull || CAST_NODE(A_Const, arg1)->isnull) {
  721. AddError(TStringBuilder() << "Expected string const as name arg, but got null");
  722. return nullptr;
  723. }
  724. auto name = CAST_NODE(A_Const, arg0)->val;
  725. auto val = CAST_NODE(A_Const, arg1)->val;
  726. if (NodeTag(name) != T_String || NodeTag(val) != T_String) {
  727. AddError(TStringBuilder() << "Expected string const as name arg, but got something else: " << NodeTag(name));
  728. return nullptr;
  729. }
  730. config.name = (char*)StrVal(name);
  731. config.args = list_make1((void*)arg1);
  732. return ParseVariableSetStmt(&config, true);
  733. }
  734. using TTraverseSelectStack = TStack<std::pair<const SelectStmt*, bool>>;
  735. using TTraverseNodeStack = TStack<std::pair<const Node*, bool>>;
  736. struct TSelectStmtSettings {
  737. bool Inner = true;
  738. mutable TVector<TAstNode*> TargetColumns;
  739. bool AllowEmptyResSet = false;
  740. bool EmitPgStar = false;
  741. bool FillTargetColumns = false;
  742. bool UnknownsAllowed = false;
  743. const TView* Recursive = nullptr;
  744. };
  745. [[nodiscard]]
  746. TAstNode* ParseSelectStmt(
  747. const SelectStmt* value,
  748. const TSelectStmtSettings& selectSettings
  749. ) {
  750. if (Settings.Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
  751. if (HasSelectInLimitedView) {
  752. AddError("Expected exactly one SELECT in LIMITED_VIEW mode");
  753. return nullptr;
  754. }
  755. HasSelectInLimitedView = true;
  756. }
  757. bool isValuesClauseOfInsertStmt = selectSettings.FillTargetColumns;
  758. State.CTE.emplace_back();
  759. auto prevRecursiveView = State.CurrentRecursiveView;
  760. State.CurrentRecursiveView = selectSettings.Recursive;
  761. Y_DEFER {
  762. State.CTE.pop_back();
  763. State.CurrentRecursiveView = prevRecursiveView;
  764. };
  765. if (value->withClause) {
  766. if (!ParseWithClause(CAST_NODE(WithClause, value->withClause))) {
  767. return nullptr;
  768. }
  769. }
  770. TTraverseSelectStack traverseSelectStack;
  771. traverseSelectStack.push({ value, false });
  772. TVector<const SelectStmt*> setItems;
  773. TVector<TAstNode*> setOpsNodes;
  774. while (!traverseSelectStack.empty()) {
  775. auto& top = traverseSelectStack.top();
  776. if (top.first->op == SETOP_NONE) {
  777. // leaf
  778. setItems.push_back(top.first);
  779. setOpsNodes.push_back(QA("push"));
  780. traverseSelectStack.pop();
  781. } else {
  782. if (!top.first->larg || !top.first->rarg) {
  783. AddError("SelectStmt: expected larg and rarg");
  784. return nullptr;
  785. }
  786. if (!top.second) {
  787. traverseSelectStack.push({ top.first->rarg, false });
  788. traverseSelectStack.push({ top.first->larg, false });
  789. top.second = true;
  790. } else {
  791. TString op;
  792. switch (top.first->op) {
  793. case SETOP_UNION:
  794. op = "union"; break;
  795. case SETOP_INTERSECT:
  796. op = "intersect"; break;
  797. case SETOP_EXCEPT:
  798. op = "except"; break;
  799. default:
  800. AddError(TStringBuilder() << "SetOperation unsupported value: " << (int)top.first->op);
  801. return nullptr;
  802. }
  803. if (top.first->all) {
  804. op += "_all";
  805. }
  806. setOpsNodes.push_back(QA(op));
  807. traverseSelectStack.pop();
  808. }
  809. }
  810. }
  811. bool hasCombiningQueries = (1 < setItems.size());
  812. TAstNode* sort = nullptr;
  813. if (ListLength(value->sortClause) > 0) {
  814. TVector<TAstNode*> sortItems;
  815. for (int i = 0; i < ListLength(value->sortClause); ++i) {
  816. auto node = ListNodeNth(value->sortClause, i);
  817. if (NodeTag(node) != T_SortBy) {
  818. NodeNotImplemented(value, node);
  819. return nullptr;
  820. }
  821. auto sort = ParseSortBy(CAST_NODE_EXT(PG_SortBy, T_SortBy, node), !hasCombiningQueries, true);
  822. if (!sort) {
  823. return nullptr;
  824. }
  825. sortItems.push_back(sort);
  826. }
  827. sort = QVL(sortItems.data(), sortItems.size());
  828. }
  829. TVector<TAstNode*> setItemNodes;
  830. for (size_t id = 0; id < setItems.size(); ++id) {
  831. const auto& x = setItems[id];
  832. bool hasDistinctAll = false;
  833. TVector<TAstNode*> distinctOnItems;
  834. if (x->distinctClause) {
  835. if (linitial(x->distinctClause) == NULL) {
  836. hasDistinctAll = true;
  837. } else {
  838. for (int i = 0; i < ListLength(x->distinctClause); ++i) {
  839. auto node = ListNodeNth(x->distinctClause, i);
  840. TAstNode* expr;
  841. if (NodeTag(node) == T_A_Const && (NodeTag(CAST_NODE(A_Const, node)->val) == T_Integer)) {
  842. expr = MakeProjectionRef("DISTINCT ON", CAST_NODE(A_Const, node));
  843. } else {
  844. TExprSettings settings;
  845. settings.AllowColumns = true;
  846. settings.Scope = "DISTINCT ON";
  847. expr = ParseExpr(node, settings);
  848. }
  849. if (!expr) {
  850. return nullptr;
  851. }
  852. auto lambda = L(A("lambda"), QL(), expr);
  853. distinctOnItems.push_back(L(A("PgGroup"), L(A("Void")), lambda));
  854. }
  855. }
  856. }
  857. if (x->intoClause) {
  858. AddError("SelectStmt: not supported intoClause");
  859. return nullptr;
  860. }
  861. TVector<TAstNode*> fromList;
  862. TVector<TAstNode*> joinOps;
  863. for (int i = 0; i < ListLength(x->fromClause); ++i) {
  864. auto node = ListNodeNth(x->fromClause, i);
  865. if (NodeTag(node) != T_JoinExpr) {
  866. auto p = ParseFromClause(node);
  867. if (!p) {
  868. return nullptr;
  869. }
  870. AddFrom(*p, fromList);
  871. joinOps.push_back(QL(QL(QA("push"))));
  872. } else {
  873. TTraverseNodeStack traverseNodeStack;
  874. traverseNodeStack.push({ node, false });
  875. TVector<TAstNode*> oneJoinGroup;
  876. while (!traverseNodeStack.empty()) {
  877. auto& top = traverseNodeStack.top();
  878. if (NodeTag(top.first) != T_JoinExpr) {
  879. // leaf
  880. auto p = ParseFromClause(top.first);
  881. if (!p) {
  882. return nullptr;
  883. }
  884. AddFrom(*p, fromList);
  885. traverseNodeStack.pop();
  886. oneJoinGroup.push_back(QL(QA("push")));
  887. } else {
  888. auto join = CAST_NODE(JoinExpr, top.first);
  889. if (!join->larg || !join->rarg) {
  890. AddError("JoinExpr: expected larg and rarg");
  891. return nullptr;
  892. }
  893. if (join->alias) {
  894. AddError("JoinExpr: unsupported alias");
  895. return nullptr;
  896. }
  897. if (join->isNatural) {
  898. AddError("JoinExpr: unsupported isNatural");
  899. return nullptr;
  900. }
  901. if (!top.second) {
  902. traverseNodeStack.push({ join->rarg, false });
  903. traverseNodeStack.push({ join->larg, false });
  904. top.second = true;
  905. } else {
  906. TString op;
  907. switch (join->jointype) {
  908. case JOIN_INNER:
  909. op = join->quals ? "inner" : "cross"; break;
  910. case JOIN_LEFT:
  911. op = "left"; break;
  912. case JOIN_FULL:
  913. op = "full"; break;
  914. case JOIN_RIGHT:
  915. op = "right"; break;
  916. default:
  917. AddError(TStringBuilder() << "jointype unsupported value: " << (int)join->jointype);
  918. return nullptr;
  919. }
  920. if (ListLength(join->usingClause) > 0) {
  921. if (join->join_using_alias) {
  922. AddError(TStringBuilder() << "join USING: unsupported AS");
  923. return nullptr;
  924. }
  925. if (op == "cross") {
  926. op = "inner";
  927. }
  928. auto len = ListLength(join->usingClause);
  929. TVector<TAstNode*> fields(len);
  930. THashSet<TString> present;
  931. for (decltype(len) i = 0; i < len; ++i) {
  932. auto node = ListNodeNth(join->usingClause, i);
  933. if (NodeTag(node) != T_String) {
  934. AddError("JoinExpr: unexpected non-string constant");
  935. return nullptr;
  936. }
  937. if (present.contains(StrVal(node))) {
  938. AddError(TStringBuilder() << "USING clause: duplicated column " << StrVal(node));
  939. return nullptr;
  940. }
  941. fields[i] = QAX(StrVal(node));
  942. }
  943. oneJoinGroup.push_back(QL(QA(op), QA("using"), QVL(fields)));
  944. } else {
  945. if (op != "cross" && !join->quals) {
  946. AddError("join_expr: expected quals for non-cross join");
  947. return nullptr;
  948. }
  949. if (op == "cross") {
  950. oneJoinGroup.push_back(QL(QA(op)));
  951. } else {
  952. TExprSettings settings;
  953. settings.AllowColumns = true;
  954. settings.Scope = "JOIN ON";
  955. auto quals = ParseExpr(join->quals, settings);
  956. if (!quals) {
  957. return nullptr;
  958. }
  959. auto lambda = L(A("lambda"), QL(), quals);
  960. oneJoinGroup.push_back(QL(QA(op), L(A("PgWhere"), L(A("Void")), lambda)));
  961. }
  962. }
  963. traverseNodeStack.pop();
  964. }
  965. }
  966. }
  967. joinOps.push_back(QVL(oneJoinGroup.data(), oneJoinGroup.size()));
  968. }
  969. }
  970. TAstNode* whereFilter = nullptr;
  971. if (x->whereClause) {
  972. TExprSettings settings;
  973. settings.AllowColumns = true;
  974. settings.AllowSubLinks = true;
  975. settings.Scope = "WHERE";
  976. whereFilter = ParseExpr(x->whereClause, settings);
  977. if (!whereFilter) {
  978. return nullptr;
  979. }
  980. }
  981. TAstNode* groupBy = nullptr;
  982. if (ListLength(x->groupClause) > 0) {
  983. TVector<TAstNode*> groupByItems;
  984. for (int i = 0; i < ListLength(x->groupClause); ++i) {
  985. auto node = ListNodeNth(x->groupClause, i);
  986. TAstNode* expr;
  987. if (NodeTag(node) == T_A_Const && (NodeTag(CAST_NODE(A_Const, node)->val) == T_Integer)) {
  988. expr = MakeProjectionRef("GROUP BY", CAST_NODE(A_Const, node));
  989. } else {
  990. TExprSettings settings;
  991. settings.AllowColumns = true;
  992. settings.Scope = "GROUP BY";
  993. if (NodeTag(node) == T_GroupingSet) {
  994. expr = ParseGroupingSet(CAST_NODE(GroupingSet, node), settings);
  995. } else {
  996. expr = ParseExpr(node, settings);
  997. }
  998. }
  999. if (!expr) {
  1000. return nullptr;
  1001. }
  1002. auto lambda = L(A("lambda"), QL(), expr);
  1003. groupByItems.push_back(L(A("PgGroup"), L(A("Void")), lambda));
  1004. }
  1005. groupBy = QVL(groupByItems.data(), groupByItems.size());
  1006. }
  1007. TAstNode* having = nullptr;
  1008. if (x->havingClause) {
  1009. TExprSettings settings;
  1010. settings.AllowColumns = true;
  1011. settings.Scope = "HAVING";
  1012. settings.AllowAggregates = true;
  1013. settings.AllowSubLinks = true;
  1014. having = ParseExpr(x->havingClause, settings);
  1015. if (!having) {
  1016. return nullptr;
  1017. }
  1018. }
  1019. TVector<TAstNode*> windowItems;
  1020. if (ListLength(x->windowClause) > 0) {
  1021. for (int i = 0; i < ListLength(x->windowClause); ++i) {
  1022. auto node = ListNodeNth(x->windowClause, i);
  1023. if (NodeTag(node) != T_WindowDef) {
  1024. NodeNotImplemented(x, node);
  1025. return nullptr;
  1026. }
  1027. auto win = ParseWindowDef(CAST_NODE(WindowDef, node));
  1028. if (!win) {
  1029. return nullptr;
  1030. }
  1031. windowItems.push_back(win);
  1032. }
  1033. }
  1034. if (ListLength(x->valuesLists) && ListLength(x->fromClause)) {
  1035. AddError("SelectStmt: values_lists isn't compatible to from_clause");
  1036. return nullptr;
  1037. }
  1038. if (!selectSettings.AllowEmptyResSet && (ListLength(x->valuesLists) == 0) && (ListLength(x->targetList) == 0)) {
  1039. AddError("SelectStmt: both values_list and target_list are not allowed to be empty");
  1040. return nullptr;
  1041. }
  1042. if (x != value && ListLength(x->sortClause) > 0) {
  1043. AddError("SelectStmt: sortClause should be used only on top");
  1044. return nullptr;
  1045. }
  1046. if (x != value) {
  1047. if (x->limitOption == LIMIT_OPTION_COUNT || x->limitOption == LIMIT_OPTION_DEFAULT) {
  1048. if (x->limitCount || x->limitOffset) {
  1049. AddError("SelectStmt: limit should be used only on top");
  1050. return nullptr;
  1051. }
  1052. } else {
  1053. AddError(TStringBuilder() << "LimitOption unsupported value: " << (int)x->limitOption);
  1054. return nullptr;
  1055. }
  1056. if (ListLength(x->lockingClause) > 0) {
  1057. AddWarning(TIssuesIds::PG_NO_LOCKING_SUPPORT, "SelectStmt: lockingClause is ignored");
  1058. }
  1059. }
  1060. TVector<TAstNode*> res;
  1061. ui32 i = 0;
  1062. if (selectSettings.EmitPgStar && id + 1 == setItems.size()) {
  1063. res.emplace_back(CreatePgStarResultItem());
  1064. i++;
  1065. }
  1066. bool maybeSelectWithJustSetConfig = !selectSettings.Inner && !sort && windowItems.empty() && !having && !groupBy && !whereFilter && !x->distinctClause && ListLength(x->targetList) == 1;
  1067. if (maybeSelectWithJustSetConfig) {
  1068. auto node = ListNodeNth(x->targetList, 0);
  1069. if (NodeTag(node) != T_ResTarget) {
  1070. NodeNotImplemented(x, node);
  1071. return nullptr;
  1072. }
  1073. auto r = CAST_NODE(ResTarget, node);
  1074. if (!r->val) {
  1075. AddError("SelectStmt: expected val");
  1076. return nullptr;
  1077. }
  1078. auto call = r->val;
  1079. if (NodeTag(call) == T_FuncCall) {
  1080. auto fn = CAST_NODE(FuncCall, call);
  1081. if (ListLength(fn->funcname) == 1) {
  1082. auto nameNode = ListNodeNth(fn->funcname, 0);
  1083. if (NodeTag(nameNode) != T_String) {
  1084. AddError("Function name must be string");
  1085. return nullptr;
  1086. }
  1087. auto name = to_lower(TString(StrVal(ListNodeNth(fn->funcname, 0))));
  1088. if (name == "set_config") {
  1089. return ParseSetConfig(fn);
  1090. }
  1091. }
  1092. }
  1093. }
  1094. for (int targetIndex = 0; targetIndex < ListLength(x->targetList); ++targetIndex) {
  1095. auto node = ListNodeNth(x->targetList, targetIndex);
  1096. if (NodeTag(node) != T_ResTarget) {
  1097. NodeNotImplemented(x, node);
  1098. return nullptr;
  1099. }
  1100. auto r = CAST_NODE(ResTarget, node);
  1101. if (!r->val) {
  1102. AddError("SelectStmt: expected val");
  1103. return nullptr;
  1104. }
  1105. TExprSettings settings;
  1106. settings.AllowColumns = true;
  1107. settings.AllowAggregates = true;
  1108. settings.AllowOver = true;
  1109. settings.AllowSubLinks = true;
  1110. settings.WindowItems = &windowItems;
  1111. settings.Scope = "SELECT";
  1112. auto x = ParseExpr(r->val, settings);
  1113. if (!x) {
  1114. return nullptr;
  1115. }
  1116. res.push_back(CreatePgResultItem(r, x, i));
  1117. }
  1118. TVector<TAstNode*> setItemOptions;
  1119. if (selectSettings.EmitPgStar) {
  1120. setItemOptions.push_back(QL(QA("emit_pg_star")));
  1121. }
  1122. if (!selectSettings.TargetColumns.empty()) {
  1123. setItemOptions.push_back(QL(QA("target_columns"), QVL(selectSettings.TargetColumns.data(), selectSettings.TargetColumns.size())));
  1124. }
  1125. if (selectSettings.FillTargetColumns) {
  1126. setItemOptions.push_back(QL(QA("fill_target_columns")));
  1127. }
  1128. if (ListLength(x->targetList) > 0) {
  1129. setItemOptions.push_back(QL(QA("result"), QVL(res.data(), res.size())));
  1130. } else {
  1131. auto valuesList = ParseValuesList(x->valuesLists, /*buildCommonType=*/!isValuesClauseOfInsertStmt);
  1132. if (!valuesList) {
  1133. return nullptr;
  1134. }
  1135. setItemOptions.push_back(valuesList);
  1136. }
  1137. if (!fromList.empty()) {
  1138. setItemOptions.push_back(QL(QA("from"), QVL(fromList.data(), fromList.size())));
  1139. setItemOptions.push_back(QL(QA("join_ops"), QVL(joinOps.data(), joinOps.size())));
  1140. }
  1141. if (whereFilter) {
  1142. auto lambda = L(A("lambda"), QL(), whereFilter);
  1143. setItemOptions.push_back(QL(QA("where"), L(A("PgWhere"), L(A("Void")), lambda)));
  1144. }
  1145. if (groupBy) {
  1146. setItemOptions.push_back(QL(QA("group_by"), groupBy));
  1147. }
  1148. if (windowItems.size()) {
  1149. auto window = QVL(windowItems.data(), windowItems.size());
  1150. setItemOptions.push_back(QL(QA("window"), window));
  1151. }
  1152. if (having) {
  1153. auto lambda = L(A("lambda"), QL(), having);
  1154. setItemOptions.push_back(QL(QA("having"), L(A("PgWhere"), L(A("Void")), lambda)));
  1155. }
  1156. if (hasDistinctAll) {
  1157. setItemOptions.push_back(QL(QA("distinct_all")));
  1158. } else if (!distinctOnItems.empty()) {
  1159. auto distinctOn = QVL(distinctOnItems.data(), distinctOnItems.size());
  1160. setItemOptions.push_back(QL(QA("distinct_on"), distinctOn));
  1161. }
  1162. if (!hasCombiningQueries && sort) {
  1163. setItemOptions.push_back(QL(QA("sort"), sort));
  1164. }
  1165. if (selectSettings.UnknownsAllowed || hasCombiningQueries) {
  1166. setItemOptions.push_back(QL(QA("unknowns_allowed")));
  1167. }
  1168. auto setItem = L(A("PgSetItem"), QVL(setItemOptions.data(), setItemOptions.size()));
  1169. setItemNodes.push_back(setItem);
  1170. }
  1171. if (value->intoClause) {
  1172. AddError("SelectStmt: not supported intoClause");
  1173. return nullptr;
  1174. }
  1175. if (ListLength(value->lockingClause) > 0) {
  1176. AddWarning(TIssuesIds::PG_NO_LOCKING_SUPPORT, "SelectStmt: lockingClause is ignored");
  1177. }
  1178. TAstNode* limit = nullptr;
  1179. TAstNode* offset = nullptr;
  1180. if (value->limitOption == LIMIT_OPTION_COUNT || value->limitOption == LIMIT_OPTION_DEFAULT) {
  1181. if (value->limitCount) {
  1182. TExprSettings settings;
  1183. settings.AllowColumns = false;
  1184. settings.AllowSubLinks = true;
  1185. settings.Scope = "LIMIT";
  1186. limit = ParseExpr(value->limitCount, settings);
  1187. if (!limit) {
  1188. return nullptr;
  1189. }
  1190. }
  1191. if (value->limitOffset) {
  1192. TExprSettings settings;
  1193. settings.AllowColumns = false;
  1194. settings.AllowSubLinks = true;
  1195. settings.Scope = "OFFSET";
  1196. offset = ParseExpr(value->limitOffset, settings);
  1197. if (!offset) {
  1198. return nullptr;
  1199. }
  1200. }
  1201. } else {
  1202. AddError(TStringBuilder() << "LimitOption unsupported value: " << (int)value->limitOption);
  1203. return nullptr;
  1204. }
  1205. TVector<TAstNode*> selectOptions;
  1206. selectOptions.push_back(QL(QA("set_items"), QVL(setItemNodes.data(), setItemNodes.size())));
  1207. selectOptions.push_back(QL(QA("set_ops"), QVL(setOpsNodes.data(), setOpsNodes.size())));
  1208. if (hasCombiningQueries && sort) {
  1209. selectOptions.push_back(QL(QA("sort"), sort));
  1210. }
  1211. if (limit) {
  1212. selectOptions.push_back(QL(QA("limit"), limit));
  1213. }
  1214. if (offset) {
  1215. selectOptions.push_back(QL(QA("offset"), offset));
  1216. }
  1217. auto output = L(A("PgSelect"), QVL(selectOptions.data(), selectOptions.size()));
  1218. if (selectSettings.Inner) {
  1219. return output;
  1220. }
  1221. if (Settings.Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
  1222. State.Statements.push_back(L(A("return"), L(A("Right!"), L(A("Cons!"), A("world"), output))));
  1223. return State.Statements.back();
  1224. }
  1225. auto resOptions = BuildResultOptions(!sort);
  1226. State.Statements.push_back(L(A("let"), A("output"), output));
  1227. State.Statements.push_back(L(A("let"), A("result_sink"), L(A("DataSink"), QA(TString(NYql::ResultProviderName)))));
  1228. State.Statements.push_back(L(A("let"), A("world"), L(A("Write!"),
  1229. A("world"), A("result_sink"), L(A("Key")), A("output"), resOptions)));
  1230. State.Statements.push_back(L(A("let"), A("world"), L(A("Commit!"),
  1231. A("world"), A("result_sink"))));
  1232. return State.Statements.back();
  1233. }
  1234. TAstNode* BuildResultOptions(bool unordered) {
  1235. TVector<TAstNode*> options;
  1236. options.push_back(QL(QA("type")));
  1237. options.push_back(QL(QA("autoref")));
  1238. if (unordered && UnorderedResult) {
  1239. options.push_back(QL(QA("unordered")));
  1240. }
  1241. return QVL(options.data(), options.size());
  1242. }
  1243. [[nodiscard]]
  1244. bool ParseWithClause(const WithClause* value) {
  1245. AT_LOCATION(value);
  1246. for (int i = 0; i < ListLength(value->ctes); ++i) {
  1247. auto object = ListNodeNth(value->ctes, i);
  1248. if (NodeTag(object) != T_CommonTableExpr) {
  1249. NodeNotImplemented(value, object);
  1250. return false;
  1251. }
  1252. if (!ParseCTE(CAST_NODE(CommonTableExpr, object), value->recursive)) {
  1253. return false;
  1254. }
  1255. }
  1256. return true;
  1257. }
  1258. [[nodiscard]]
  1259. bool ParseCTE(const CommonTableExpr* value, bool recursive) {
  1260. AT_LOCATION(value);
  1261. TView view;
  1262. view.Name = value->ctename;
  1263. for (int i = 0; i < ListLength(value->aliascolnames); ++i) {
  1264. auto node = ListNodeNth(value->aliascolnames, i);
  1265. if (NodeTag(node) != T_String) {
  1266. NodeNotImplemented(value, node);
  1267. return false;
  1268. }
  1269. view.ColNames.push_back(StrVal(node));
  1270. }
  1271. if (NodeTag(value->ctequery) != T_SelectStmt) {
  1272. AddError("Expected Select statement as CTE query");
  1273. return false;
  1274. }
  1275. view.Source = ParseSelectStmt(CAST_NODE(SelectStmt, value->ctequery), {
  1276. .Inner = true,
  1277. .Recursive = recursive ? &view : nullptr
  1278. });
  1279. if (!view.Source) {
  1280. return false;
  1281. }
  1282. auto& currentCTEs = State.CTE.back();
  1283. if (currentCTEs.find(view.Name) != currentCTEs.end()) {
  1284. AddError(TStringBuilder() << "CTE already exists: '" << view.Name << "'");
  1285. return false;
  1286. }
  1287. currentCTEs[view.Name] = view;
  1288. return true;
  1289. }
  1290. [[nodiscard]]
  1291. TAstNode* AsScalarContext(TAstNode* subquery) {
  1292. return L(A("SingleMember"), L(A("Head"), L(A("Take"), subquery, L(A("Uint64"), QA("1")))));
  1293. }
  1294. [[nodiscard]]
  1295. TAstNode* MakeLambda(TVector<TAstNode*> args, TAstNode* body) {
  1296. return L(A("lambda"), QVL(args), body);
  1297. }
  1298. [[nodiscard]]
  1299. TAstNode* CreatePgStarResultItem() {
  1300. TAstNode* starLambda = L(A("lambda"), QL(), L(A("PgStar")));
  1301. return L(A("PgResultItem"), QAX(""), L(A("Void")), starLambda);
  1302. }
  1303. [[nodiscard]]
  1304. TAstNode* CreatePgResultItem(const ResTarget* r, TAstNode* x, ui32& columnIndex) {
  1305. bool isStar = false;
  1306. if (NodeTag(r->val) == T_ColumnRef) {
  1307. auto ref = CAST_NODE(ColumnRef, r->val);
  1308. for (int fieldNo = 0; fieldNo < ListLength(ref->fields); ++fieldNo) {
  1309. if (NodeTag(ListNodeNth(ref->fields, fieldNo)) == T_A_Star) {
  1310. isStar = true;
  1311. break;
  1312. }
  1313. }
  1314. }
  1315. TString name;
  1316. if (!isStar) {
  1317. name = r->name;
  1318. if (name.empty()) {
  1319. if (NodeTag(r->val) == T_ColumnRef) {
  1320. auto ref = CAST_NODE(ColumnRef, r->val);
  1321. auto field = ListNodeNth(ref->fields, ListLength(ref->fields) - 1);
  1322. if (NodeTag(field) == T_String) {
  1323. name = StrVal(field);
  1324. }
  1325. } else if (NodeTag(r->val) == T_FuncCall) {
  1326. auto func = CAST_NODE(FuncCall, r->val);
  1327. if (!ExtractFuncName(func, name, nullptr)) {
  1328. return nullptr;
  1329. }
  1330. }
  1331. }
  1332. if (name.empty()) {
  1333. name = "column" + ToString(columnIndex++);
  1334. }
  1335. }
  1336. const auto lambda = L(A("lambda"), QL(), x);
  1337. const auto columnName = QAX(name);
  1338. return L(A("PgResultItem"), columnName, L(A("Void")), lambda);
  1339. }
  1340. [[nodiscard]]
  1341. std::optional<TVector<TAstNode*>> ParseReturningList(const List* returningList) {
  1342. TVector <TAstNode*> list;
  1343. if (ListLength(returningList) == 0) {
  1344. return {};
  1345. }
  1346. ui32 index = 0;
  1347. for (int i = 0; i < ListLength(returningList); i++) {
  1348. auto node = ListNodeNth(returningList, i);
  1349. if (NodeTag(node) != T_ResTarget) {
  1350. NodeNotImplemented(returningList, node);
  1351. return std::nullopt;
  1352. }
  1353. auto r = CAST_NODE(ResTarget, node);
  1354. if (!r->val) {
  1355. AddError("SelectStmt: expected value");
  1356. return std::nullopt;
  1357. }
  1358. if (NodeTag(r->val) != T_ColumnRef) {
  1359. NodeNotImplemented(r, r->val);
  1360. return std::nullopt;
  1361. }
  1362. TExprSettings settings;
  1363. settings.AllowColumns = true;
  1364. auto columnRef = ParseColumnRef(CAST_NODE(ColumnRef, r->val), settings);
  1365. if (!columnRef) {
  1366. return std::nullopt;
  1367. }
  1368. list.emplace_back(CreatePgResultItem(r, columnRef, index));
  1369. }
  1370. return list;
  1371. }
  1372. [[nodiscard]]
  1373. TAstNode* ParseInsertStmt(const InsertStmt* value) {
  1374. if (value->onConflictClause) {
  1375. AddError("InsertStmt: not supported onConflictClause");
  1376. return nullptr;
  1377. }
  1378. TVector <TAstNode*> returningList;
  1379. if (value->returningList) {
  1380. auto list = ParseReturningList(value->returningList);
  1381. if (list.has_value()) {
  1382. returningList = list.value();
  1383. } else {
  1384. return nullptr;
  1385. }
  1386. }
  1387. if (value->withClause) {
  1388. AddError("InsertStmt: not supported withClause");
  1389. return nullptr;
  1390. }
  1391. const auto [sink, key] = ParseWriteRangeVar(value->relation);
  1392. if (!sink || !key) {
  1393. return nullptr;
  1394. }
  1395. TVector <TAstNode*> targetColumns;
  1396. if (value->cols) {
  1397. for (int i = 0; i < ListLength(value->cols); i++) {
  1398. auto node = ListNodeNth(value->cols, i);
  1399. if (NodeTag(node) != T_ResTarget) {
  1400. NodeNotImplemented(value, node);
  1401. return nullptr;
  1402. }
  1403. auto r = CAST_NODE(ResTarget, node);
  1404. if (!r->name) {
  1405. AddError("SelectStmt: expected name");
  1406. return nullptr;
  1407. }
  1408. targetColumns.push_back(QA(r->name));
  1409. }
  1410. }
  1411. const auto select = (value->selectStmt)
  1412. ? ParseSelectStmt(
  1413. CAST_NODE(SelectStmt, value->selectStmt),
  1414. {
  1415. .Inner = true,
  1416. .TargetColumns = targetColumns,
  1417. .AllowEmptyResSet = false,
  1418. .EmitPgStar = false,
  1419. .FillTargetColumns = true,
  1420. .UnknownsAllowed = true
  1421. })
  1422. : L(A("Void"));
  1423. if (!select) {
  1424. return nullptr;
  1425. }
  1426. const auto writeOptions = BuildWriteOptions(value, std::move(returningList));
  1427. State.Statements.push_back(L(
  1428. A("let"),
  1429. A("world"),
  1430. L(
  1431. A("Write!"),
  1432. A("world"),
  1433. sink,
  1434. key,
  1435. select,
  1436. writeOptions
  1437. )
  1438. ));
  1439. return State.Statements.back();
  1440. }
  1441. [[nodiscard]]
  1442. TAstNode* ParseUpdateStmt(const UpdateStmt* value) {
  1443. const auto fromClause = value->fromClause ? value->fromClause : ListMake1(value->relation).get();
  1444. SelectStmt selectStmt {
  1445. .type = T_SelectStmt,
  1446. .targetList = value->targetList,
  1447. .fromClause = fromClause,
  1448. .whereClause = value->whereClause,
  1449. .withClause = value->withClause,
  1450. };
  1451. const auto select = ParseSelectStmt(
  1452. &selectStmt,
  1453. {
  1454. .Inner = true,
  1455. .AllowEmptyResSet = true,
  1456. .EmitPgStar = true,
  1457. .FillTargetColumns = false,
  1458. .UnknownsAllowed = true
  1459. }
  1460. );
  1461. if (!select) {
  1462. return nullptr;
  1463. }
  1464. const auto [sink, key] = ParseWriteRangeVar(value->relation);
  1465. if (!sink || !key) {
  1466. return nullptr;
  1467. }
  1468. TVector<TAstNode*> returningList;
  1469. if (value->returningList) {
  1470. auto list = ParseReturningList(value->returningList);
  1471. if (list.has_value()) {
  1472. returningList = list.value();
  1473. } else {
  1474. return nullptr;
  1475. }
  1476. }
  1477. TVector<TAstNode*> options;
  1478. options.push_back(QL(QA("pg_update"), A("update_select")));
  1479. options.push_back(QL(QA("mode"), QA("update")));
  1480. if (!returningList.empty()) {
  1481. options.push_back(QL(QA("returning"), QVL(returningList.data(), returningList.size())));
  1482. }
  1483. const auto writeUpdate = L(A("block"), QL(
  1484. L(A("let"), A("update_select"), select),
  1485. L(A("let"), A("sink"), sink),
  1486. L(A("let"), A("key"), key),
  1487. L(A("return"), L(
  1488. A("Write!"),
  1489. A("world"),
  1490. A("sink"),
  1491. A("key"),
  1492. L(A("Void")),
  1493. QVL(options.data(), options.size())))
  1494. ));
  1495. State.Statements.push_back(L(
  1496. A("let"),
  1497. A("world"),
  1498. writeUpdate
  1499. ));
  1500. return State.Statements.back();
  1501. }
  1502. [[nodiscard]]
  1503. TAstNode* ParseViewStmt(const ViewStmt* value) {
  1504. if (ListLength(value->options) > 0) {
  1505. AddError("Create view: not supported options");
  1506. return nullptr;
  1507. }
  1508. TView view;
  1509. if (StrLength(value->view->catalogname) > 0) {
  1510. AddError("catalogname is not supported");
  1511. return nullptr;
  1512. }
  1513. if (StrLength(value->view->schemaname) > 0) {
  1514. AddError("schemaname is not supported");
  1515. return nullptr;
  1516. }
  1517. if (StrLength(value->view->relname) == 0) {
  1518. AddError("relname should be specified");
  1519. return nullptr;
  1520. }
  1521. view.Name = value->view->relname;
  1522. if (value->view->alias) {
  1523. AddError("alias is not supported");
  1524. return nullptr;
  1525. }
  1526. if (ListLength(value->aliases) == 0) {
  1527. AddError("expected at least one target column");
  1528. return nullptr;
  1529. }
  1530. for (int i = 0; i < ListLength(value->aliases); ++i) {
  1531. auto node = ListNodeNth(value->aliases, i);
  1532. if (NodeTag(node) != T_String) {
  1533. NodeNotImplemented(value, node);
  1534. return nullptr;
  1535. }
  1536. view.ColNames.push_back(StrVal(node));
  1537. }
  1538. if (value->withCheckOption != NO_CHECK_OPTION) {
  1539. AddError("Create view: not supported options");
  1540. return nullptr;
  1541. }
  1542. view.Source = ParseSelectStmt(CAST_NODE(SelectStmt, value->query), { .Inner = true });
  1543. if (!view.Source) {
  1544. return nullptr;
  1545. }
  1546. auto it = State.Views.find(view.Name);
  1547. if (it != State.Views.end() && !value->replace) {
  1548. AddError(TStringBuilder() << "View already exists: '" << view.Name << "'");
  1549. return nullptr;
  1550. }
  1551. State.Views[view.Name] = view;
  1552. return State.Statements.back();
  1553. }
  1554. #pragma region CreateTable
  1555. private:
  1556. struct TColumnInfo {
  1557. TString Name;
  1558. TString Type;
  1559. bool Serial = false;
  1560. bool NotNull = false;
  1561. TAstNode* Default = nullptr;
  1562. };
  1563. struct TCreateTableCtx {
  1564. std::unordered_map<TString, TColumnInfo> ColumnsSet;
  1565. std::vector<TString> ColumnOrder;
  1566. std::vector<TAstNode*> PrimaryKey;
  1567. std::vector<std::vector<TAstNode*>> UniqConstr;
  1568. bool isTemporary;
  1569. bool ifNotExists;
  1570. };
  1571. bool CheckConstraintSupported(const Constraint* pk) {
  1572. bool isSupported = true;
  1573. if (pk->deferrable) {
  1574. AddError("DEFERRABLE constraints not supported");
  1575. isSupported = false;
  1576. }
  1577. if (pk->initdeferred) {
  1578. AddError("INITIALLY DEFERRED constraints not supported");
  1579. isSupported = false;
  1580. }
  1581. if (0 < ListLength(pk->including)) {
  1582. AddError("INCLUDING columns not supported");
  1583. isSupported = false;
  1584. }
  1585. if (0 < ListLength(pk->options)) {
  1586. AddError("WITH options not supported");
  1587. isSupported = false;
  1588. }
  1589. if (pk->indexname) {
  1590. AddError("INDEX name not supported");
  1591. isSupported = false;
  1592. }
  1593. if (pk->indexspace) {
  1594. AddError("USING INDEX TABLESPACE not supported");
  1595. isSupported = false;
  1596. }
  1597. return isSupported;
  1598. }
  1599. bool FillPrimaryKeyColumns(TCreateTableCtx& ctx, const Constraint* pk) {
  1600. if (!CheckConstraintSupported(pk))
  1601. return false;
  1602. for (int i = 0; i < ListLength(pk->keys); ++i) {
  1603. auto node = ListNodeNth(pk->keys, i);
  1604. auto nodeName = StrVal(node);
  1605. auto it = ctx.ColumnsSet.find(nodeName);
  1606. if (it == ctx.ColumnsSet.end()) {
  1607. AddError("PK column does not belong to table");
  1608. return false;
  1609. }
  1610. it->second.NotNull = true;
  1611. ctx.PrimaryKey.push_back(QA(StrVal(node)));
  1612. }
  1613. Y_ENSURE(0 < ctx.PrimaryKey.size());
  1614. return true;
  1615. }
  1616. bool FillUniqueConstraint(TCreateTableCtx& ctx, const Constraint* constr) {
  1617. if (!CheckConstraintSupported(constr))
  1618. return false;
  1619. const auto length = ListLength(constr->keys);
  1620. std::vector<TAstNode*> uniq;
  1621. uniq.reserve(length);
  1622. for (auto i = 0; i < length; ++i) {
  1623. auto node = ListNodeNth(constr->keys, i);
  1624. auto nodeName = StrVal(node);
  1625. if (!ctx.ColumnsSet.contains(nodeName)) {
  1626. AddError("UNIQUE column does not belong to table");
  1627. return false;
  1628. }
  1629. uniq.push_back(QA(nodeName));
  1630. }
  1631. Y_ENSURE(0 < uniq.size());
  1632. ctx.UniqConstr.emplace_back(std::move(uniq));
  1633. return true;
  1634. }
  1635. const TString& FindColumnTypeAlias(const TString& colType, bool& isTypeSerial) {
  1636. const static std::unordered_map<TString, TString> aliasMap {
  1637. {"smallserial", "int2"},
  1638. {"serial2", "int2"},
  1639. {"serial", "int4"},
  1640. {"serial4", "int4"},
  1641. {"bigserial", "int8"},
  1642. {"serial8", "int8"},
  1643. };
  1644. const auto aliasIt = aliasMap.find(to_lower(colType));
  1645. if (aliasIt == aliasMap.end()) {
  1646. isTypeSerial = false;
  1647. return colType;
  1648. }
  1649. isTypeSerial = true;
  1650. return aliasIt->second;
  1651. }
  1652. bool AddColumn(TCreateTableCtx& ctx, const ColumnDef* node) {
  1653. TColumnInfo cinfo{.Name = node->colname};
  1654. if (SystemColumns.contains(to_lower(cinfo.Name))) {
  1655. AddError(TStringBuilder() << "system column can't be used: " << node->colname);
  1656. return false;
  1657. }
  1658. if (node->constraints) {
  1659. for (int i = 0; i < ListLength(node->constraints); ++i) {
  1660. auto constraintNode =
  1661. CAST_NODE(Constraint, ListNodeNth(node->constraints, i));
  1662. switch (constraintNode->contype) {
  1663. case CONSTR_NOTNULL:
  1664. cinfo.NotNull = true;
  1665. break;
  1666. case CONSTR_PRIMARY: {
  1667. if (!ctx.PrimaryKey.empty()) {
  1668. AddError("Only a single PK is allowed per table");
  1669. return false;
  1670. }
  1671. cinfo.NotNull = true;
  1672. ctx.PrimaryKey.push_back(QA(node->colname));
  1673. } break;
  1674. case CONSTR_UNIQUE: {
  1675. ctx.UniqConstr.push_back({QA(node->colname)});
  1676. } break;
  1677. case CONSTR_DEFAULT: {
  1678. TExprSettings settings;
  1679. settings.AllowColumns = false;
  1680. settings.Scope = "DEFAULT";
  1681. settings.AutoParametrizeEnabled = false;
  1682. cinfo.Default = ParseExpr(constraintNode->raw_expr, settings);
  1683. if (!cinfo.Default) {
  1684. return false;
  1685. }
  1686. } break;
  1687. default:
  1688. AddError("column constraint not supported");
  1689. return false;
  1690. }
  1691. }
  1692. }
  1693. // for now we pass just the last part of the type name
  1694. auto colTypeVal = StrVal( ListNodeNth(node->typeName->names,
  1695. ListLength(node->typeName->names) - 1));
  1696. cinfo.Type = FindColumnTypeAlias(colTypeVal, cinfo.Serial);
  1697. auto [it, inserted] = ctx.ColumnsSet.emplace(node->colname, cinfo);
  1698. if (!inserted) {
  1699. AddError("duplicated column names found");
  1700. return false;
  1701. }
  1702. ctx.ColumnOrder.push_back(node->colname);
  1703. return true;
  1704. }
  1705. bool AddConstraint(TCreateTableCtx& ctx, const Constraint* node) {
  1706. switch (node->contype) {
  1707. case CONSTR_PRIMARY: {
  1708. if (!ctx.PrimaryKey.empty()) {
  1709. AddError("Only a single PK is allowed per table");
  1710. return false;
  1711. }
  1712. if (!FillPrimaryKeyColumns(ctx, node)) {
  1713. return false;
  1714. }
  1715. } break;
  1716. case CONSTR_UNIQUE: {
  1717. if (!FillUniqueConstraint(ctx, node)) {
  1718. return false;
  1719. }
  1720. } break;
  1721. // TODO: support table-level not null constraints like:
  1722. // CHECK (col1 is not null [OR col2 is not null])
  1723. default:
  1724. AddError("table constraint not supported");
  1725. return false;
  1726. }
  1727. return true;
  1728. }
  1729. TAstNode* BuildColumnsOptions(TCreateTableCtx& ctx) {
  1730. std::vector<TAstNode*> columns;
  1731. for(const auto& name: ctx.ColumnOrder) {
  1732. auto it = ctx.ColumnsSet.find(name);
  1733. Y_ENSURE(it != ctx.ColumnsSet.end());
  1734. const auto& cinfo = it->second;
  1735. std::vector<TAstNode*> constraints;
  1736. if (cinfo.Serial) {
  1737. constraints.push_back(QL(QA("serial")));
  1738. }
  1739. if (cinfo.NotNull) {
  1740. constraints.push_back(QL(QA("not_null")));
  1741. }
  1742. if (cinfo.Default) {
  1743. constraints.push_back(QL(QA("default"), cinfo.Default));
  1744. }
  1745. columns.push_back(QL(QA(cinfo.Name), L(A("PgType"), QA(cinfo.Type)), QL(QA("columnConstraints"), QVL(constraints.data(), constraints.size()))));
  1746. }
  1747. return QVL(columns.data(), columns.size());
  1748. }
  1749. TAstNode* BuildCreateTableOptions(TCreateTableCtx& ctx) {
  1750. std::vector<TAstNode*> options;
  1751. TString mode = (ctx.ifNotExists) ? "create_if_not_exists" : "create";
  1752. options.push_back(QL(QA("mode"), QA(mode)));
  1753. options.push_back(QL(QA("columns"), BuildColumnsOptions(ctx)));
  1754. if (!ctx.PrimaryKey.empty()) {
  1755. options.push_back(QL(QA("primarykey"), QVL(ctx.PrimaryKey.data(), ctx.PrimaryKey.size())));
  1756. }
  1757. for (auto& uniq : ctx.UniqConstr) {
  1758. auto columns = QVL(uniq.data(), uniq.size());
  1759. options.push_back(QL(QA("index"), QL(
  1760. QL(QA("indexName")),
  1761. QL(QA("indexType"), QA("syncGlobalUnique")),
  1762. QL(QA("dataColumns"), QL()),
  1763. QL(QA("indexColumns"), columns))));
  1764. }
  1765. if (ctx.isTemporary) {
  1766. options.push_back(QL(QA("temporary")));
  1767. }
  1768. return QVL(options.data(), options.size());
  1769. }
  1770. TAstNode* BuildWriteOptions(const InsertStmt* value, TVector<TAstNode*> returningList = {}) {
  1771. std::vector<TAstNode*> options;
  1772. const auto insertMode = (ProviderToInsertModeMap.contains(Provider))
  1773. ? ProviderToInsertModeMap.at(Provider)
  1774. : "append";
  1775. options.push_back(QL(QA("mode"), QA(insertMode)));
  1776. if (!returningList.empty()) {
  1777. options.push_back(QL(QA("returning"), QVL(returningList.data(), returningList.size())));
  1778. }
  1779. if (!value->selectStmt) {
  1780. options.push_back(QL(QA("default_values")));
  1781. }
  1782. return QVL(options.data(), options.size());
  1783. }
  1784. public:
  1785. [[nodiscard]]
  1786. TAstNode* ParseCreateStmt(const CreateStmt* value) {
  1787. // See also transformCreateStmt() in parse_utilcmd.c
  1788. if (0 < ListLength(value->inhRelations)) {
  1789. AddError("table inheritance not supported");
  1790. return nullptr;
  1791. }
  1792. if (value->partspec) {
  1793. AddError("PARTITION BY clause not supported");
  1794. return nullptr;
  1795. }
  1796. if (value->partbound) {
  1797. AddError("FOR VALUES clause not supported");
  1798. return nullptr;
  1799. }
  1800. // if we ever support typed tables, check transformOfType() in parse_utilcmd.c
  1801. if (value->ofTypename) {
  1802. AddError("typed tables not supported");
  1803. return nullptr;
  1804. }
  1805. if (0 < ListLength(value->options)) {
  1806. AddError("table options not supported");
  1807. return nullptr;
  1808. }
  1809. if (value->oncommit != ONCOMMIT_NOOP && value->oncommit != ONCOMMIT_PRESERVE_ROWS) {
  1810. AddError("ON COMMIT actions not supported");
  1811. return nullptr;
  1812. }
  1813. if (value->tablespacename) {
  1814. AddError("TABLESPACE not supported");
  1815. return nullptr;
  1816. }
  1817. if (value->accessMethod) {
  1818. AddError("USING not supported");
  1819. return nullptr;
  1820. }
  1821. TCreateTableCtx ctx {};
  1822. if (value->if_not_exists) {
  1823. ctx.ifNotExists = true;
  1824. }
  1825. const auto relPersistence = static_cast<NPg::ERelPersistence>(value->relation->relpersistence);
  1826. switch (relPersistence) {
  1827. case NPg::ERelPersistence::Temp:
  1828. ctx.isTemporary = true;
  1829. break;
  1830. case NPg::ERelPersistence::Unlogged:
  1831. AddError("UNLOGGED tables not supported");
  1832. return nullptr;
  1833. break;
  1834. case NPg::ERelPersistence::Permanent:
  1835. break;
  1836. }
  1837. auto [sink, key] = ParseWriteRangeVar(value->relation, true);
  1838. if (!sink || !key) {
  1839. return nullptr;
  1840. }
  1841. for (int i = 0; i < ListLength(value->tableElts); ++i) {
  1842. auto rawNode = ListNodeNth(value->tableElts, i);
  1843. switch (NodeTag(rawNode)) {
  1844. case T_ColumnDef:
  1845. if (!AddColumn(ctx, CAST_NODE(ColumnDef, rawNode))) {
  1846. return nullptr;
  1847. }
  1848. break;
  1849. case T_Constraint:
  1850. if (!AddConstraint(ctx, CAST_NODE(Constraint, rawNode))) {
  1851. return nullptr;
  1852. }
  1853. break;
  1854. default:
  1855. NodeNotImplemented(value, rawNode);
  1856. return nullptr;
  1857. }
  1858. }
  1859. State.Statements.push_back(
  1860. L(A("let"), A("world"),
  1861. L(A("Write!"), A("world"), sink, key, L(A("Void")),
  1862. BuildCreateTableOptions(ctx))));
  1863. return State.Statements.back();
  1864. }
  1865. #pragma endregion CreateTable
  1866. [[nodiscard]]
  1867. TAstNode* ParseDropStmt(const DropStmt* value) {
  1868. TVector<const List*> nameListNodes;
  1869. for (int i = 0; i < ListLength(value->objects); ++i) {
  1870. auto object = ListNodeNth(value->objects, i);
  1871. if (NodeTag(object) != T_List) {
  1872. NodeNotImplemented(value, object);
  1873. return nullptr;
  1874. }
  1875. auto nameListNode = CAST_NODE(List, object);
  1876. nameListNodes.push_back(nameListNode);
  1877. }
  1878. switch (value->removeType) {
  1879. case OBJECT_VIEW: {
  1880. return ParseDropViewStmt(value, nameListNodes);
  1881. }
  1882. case OBJECT_TABLE: {
  1883. return ParseDropTableStmt(value, nameListNodes);
  1884. }
  1885. case OBJECT_INDEX: {
  1886. return ParseDropIndexStmt(value, nameListNodes);
  1887. }
  1888. case OBJECT_SEQUENCE: {
  1889. return ParseDropSequenceStmt(value, nameListNodes);
  1890. }
  1891. default: {
  1892. AddError("Not supported object type for DROP");
  1893. return nullptr;
  1894. }
  1895. }
  1896. }
  1897. TAstNode* ParseDropViewStmt(const DropStmt* value, const TVector<const List*>& names) {
  1898. // behavior and concurrent don't matter here
  1899. for (const auto& nameList : names) {
  1900. if (ListLength(nameList) != 1) {
  1901. AddError("Expected view name");
  1902. }
  1903. const auto nameNode = ListNodeNth(nameList, 0);
  1904. if (NodeTag(nameNode) != T_String) {
  1905. NodeNotImplemented(value, nameNode);
  1906. return nullptr;
  1907. }
  1908. const auto name = StrVal(nameNode);
  1909. auto it = State.Views.find(name);
  1910. if (!value->missing_ok && it == State.Views.end()) {
  1911. AddError(TStringBuilder() << "View not found: '" << name << "'");
  1912. return nullptr;
  1913. }
  1914. if (it != State.Views.end()) {
  1915. State.Views.erase(it);
  1916. }
  1917. }
  1918. return State.Statements.back();
  1919. }
  1920. TAstNode* ParseDropTableStmt(const DropStmt* value, const TVector<const List*>& names) {
  1921. if (value->behavior == DROP_CASCADE) {
  1922. AddError("CASCADE is not implemented");
  1923. return nullptr;
  1924. }
  1925. for (const auto& nameList : names) {
  1926. const auto [clusterName, tableName] = getSchemaAndObjectName(nameList);
  1927. const auto [sink, key] = ParseQualifiedRelationName(
  1928. /* catalogName */ "",
  1929. clusterName,
  1930. tableName,
  1931. /* isSink */ true,
  1932. /* isScheme */ true
  1933. );
  1934. if (sink == nullptr) {
  1935. return nullptr;
  1936. }
  1937. TString mode = (value->missing_ok) ? "drop_if_exists" : "drop";
  1938. State.Statements.push_back(L(
  1939. A("let"),
  1940. A("world"),
  1941. L(
  1942. A("Write!"),
  1943. A("world"),
  1944. sink,
  1945. key,
  1946. L(A("Void")),
  1947. QL(
  1948. QL(QA("mode"), QA(mode))
  1949. )
  1950. )
  1951. ));
  1952. }
  1953. return State.Statements.back();
  1954. }
  1955. TAstNode* ParseDropIndexStmt(const DropStmt* value, const TVector<const List*>& names) {
  1956. if (value->behavior == DROP_CASCADE) {
  1957. AddError("CASCADE is not implemented");
  1958. return nullptr;
  1959. }
  1960. if (names.size() != 1) {
  1961. AddError("DROP INDEX requires exactly one index");
  1962. return nullptr;
  1963. }
  1964. for (const auto& nameList : names) {
  1965. const auto [clusterName, indexName] = getSchemaAndObjectName(nameList);
  1966. const auto [sink, key] = ParseQualifiedPgObjectName(
  1967. /* catalogName */ "",
  1968. clusterName,
  1969. indexName,
  1970. "pgIndex"
  1971. );
  1972. TString missingOk = (value->missing_ok) ? "true" : "false";
  1973. State.Statements.push_back(L(
  1974. A("let"),
  1975. A("world"),
  1976. L(
  1977. A("Write!"),
  1978. A("world"),
  1979. sink,
  1980. key,
  1981. L(A("Void")),
  1982. QL(
  1983. QL(QA("mode"), QA("dropIndex")),
  1984. QL(QA("ifExists"), QA(missingOk))
  1985. )
  1986. )
  1987. ));
  1988. }
  1989. return State.Statements.back();
  1990. }
  1991. TAstNode* ParseDropSequenceStmt(const DropStmt* value, const TVector<const List*>& names) {
  1992. if (value->behavior == DROP_CASCADE) {
  1993. AddError("CASCADE is not implemented");
  1994. return nullptr;
  1995. }
  1996. if (names.size() != 1) {
  1997. AddError("DROP SEQUENCE requires exactly one sequence");
  1998. return nullptr;
  1999. }
  2000. for (const auto& nameList : names) {
  2001. const auto [clusterName, indexName] = getSchemaAndObjectName(nameList);
  2002. const auto [sink, key] = ParseQualifiedPgObjectName(
  2003. /* catalogName */ "",
  2004. clusterName,
  2005. indexName,
  2006. "pgSequence"
  2007. );
  2008. TString mode = (value->missing_ok) ? "drop_if_exists" : "drop";
  2009. State.Statements.push_back(L(
  2010. A("let"),
  2011. A("world"),
  2012. L(
  2013. A("Write!"),
  2014. A("world"),
  2015. sink,
  2016. key,
  2017. L(A("Void")),
  2018. QL(
  2019. QL(QA("mode"), QA(mode))
  2020. )
  2021. )
  2022. ));
  2023. }
  2024. return State.Statements.back();
  2025. }
  2026. [[nodiscard]]
  2027. TAstNode* ParseVariableSetStmt(const VariableSetStmt* value, bool isSetConfig = false) {
  2028. if (value->kind != VAR_SET_VALUE) {
  2029. AddError(TStringBuilder() << "VariableSetStmt, not supported kind: " << (int)value->kind);
  2030. return nullptr;
  2031. }
  2032. auto name = to_lower(TString(value->name));
  2033. if (name == "search_path") {
  2034. THashSet<TString> visitedValues;
  2035. TVector<TString> values;
  2036. for (int i = 0; i < ListLength(value->args); ++i) {
  2037. auto val = ListNodeNth(value->args, i);
  2038. if (NodeTag(val) != T_A_Const || CAST_NODE(A_Const, val)->isnull || NodeTag(CAST_NODE(A_Const, val)->val) != T_String) {
  2039. AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option");
  2040. return nullptr;
  2041. }
  2042. TString rawStr = to_lower(TString(StrVal(CAST_NODE(A_Const, val)->val)));
  2043. if (visitedValues.emplace(rawStr).second) {
  2044. values.emplace_back(rawStr);
  2045. }
  2046. }
  2047. if (values.size() != 1) {
  2048. AddError(TStringBuilder() << "VariableSetStmt, expected 1 unique scheme, but got: " << values.size());
  2049. return nullptr;
  2050. }
  2051. auto rawStr = values[0];
  2052. if (rawStr != "pg_catalog" && rawStr != "public" && rawStr != "" && rawStr != "information_schema") {
  2053. AddError(TStringBuilder() << "VariableSetStmt, search path supports only 'information_schema', 'public', 'pg_catalog', '' but got: '" << rawStr << "'");
  2054. return nullptr;
  2055. }
  2056. if (Settings.GUCSettings) {
  2057. Settings.GUCSettings->Set(name, rawStr, value->is_local);
  2058. if (StmtParseInfo) {
  2059. (*StmtParseInfo)[StatementId].KeepInCache = false;
  2060. }
  2061. }
  2062. return State.Statements.back();
  2063. }
  2064. if (isSetConfig) {
  2065. if (name != "search_path") {
  2066. AddError(TStringBuilder() << "VariableSetStmt, set_config doesn't support that option:" << name);
  2067. return nullptr;
  2068. }
  2069. }
  2070. if (name == "useblocks" || name == "emitaggapply" || name == "unorderedresult") {
  2071. if (ListLength(value->args) != 1) {
  2072. AddError(TStringBuilder() << "VariableSetStmt, expected 1 arg, but got: " << ListLength(value->args));
  2073. return nullptr;
  2074. }
  2075. auto arg = ListNodeNth(value->args, 0);
  2076. if (NodeTag(arg) == T_A_Const && (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String)) {
  2077. TString rawStr = StrVal(CAST_NODE(A_Const, arg)->val);
  2078. if (name == "unorderedresult") {
  2079. UnorderedResult = (rawStr == "true");
  2080. } else {
  2081. auto configSource = L(A("DataSource"), QA(TString(NYql::ConfigProviderName)));
  2082. State.Statements.push_back(L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), configSource,
  2083. QA(TString(rawStr == "true" ? "" : "Disable") + TString((name == "useblocks") ? "UseBlocks" : "PgEmitAggApply")))));
  2084. }
  2085. } else {
  2086. AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option");
  2087. return nullptr;
  2088. }
  2089. } else if (name == "dqengine" || name == "blockengine") {
  2090. if (ListLength(value->args) != 1) {
  2091. AddError(TStringBuilder() << "VariableSetStmt, expected 1 arg, but got: " << ListLength(value->args));
  2092. return nullptr;
  2093. }
  2094. auto arg = ListNodeNth(value->args, 0);
  2095. if (NodeTag(arg) == T_A_Const && (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String)) {
  2096. auto rawStr = StrVal(CAST_NODE(A_Const, arg)->val);
  2097. auto str = to_lower(TString(rawStr));
  2098. const bool isDqEngine = name == "dqengine";
  2099. auto& enable = isDqEngine ? DqEngineEnabled : BlockEngineEnabled;
  2100. auto& force = isDqEngine ? DqEngineForce : BlockEngineForce;
  2101. if (str == "auto") {
  2102. enable = true;
  2103. force = false;
  2104. } else if (str == "force") {
  2105. enable = true;
  2106. force = true;
  2107. } else if (str == "disable") {
  2108. enable = false;
  2109. force = false;
  2110. } else {
  2111. AddError(TStringBuilder() << "VariableSetStmt, not supported " << value->name << " option value: " << rawStr);
  2112. return nullptr;
  2113. }
  2114. } else {
  2115. AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option");
  2116. return nullptr;
  2117. }
  2118. } else if (name.StartsWith("dq.") || name.StartsWith("yt.") || name.StartsWith("s3.") || name.StartsWith("ydb.")) {
  2119. if (ListLength(value->args) != 1) {
  2120. AddError(TStringBuilder() << "VariableSetStmt, expected 1 arg, but got: " << ListLength(value->args));
  2121. return nullptr;
  2122. }
  2123. auto arg = ListNodeNth(value->args, 0);
  2124. if (NodeTag(arg) == T_A_Const && (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String)) {
  2125. auto dotPos = name.find('.');
  2126. auto provider = name.substr(0, dotPos);
  2127. TString providerName;
  2128. if (name.StartsWith("dq.")) {
  2129. providerName = NYql::DqProviderName;
  2130. } else if (name.StartsWith("yt.")) {
  2131. providerName = NYql::YtProviderName;
  2132. } else if (name.StartsWith("s3.")) {
  2133. providerName = NYql::S3ProviderName;
  2134. } else if (name.StartsWith("ydb.")) {
  2135. providerName = NYql::YdbProviderName;
  2136. } else {
  2137. Y_ASSERT(0);
  2138. }
  2139. auto providerSource = L(A("DataSource"), QA(providerName), QA("$all"));
  2140. auto rawStr = StrVal(CAST_NODE(A_Const, arg)->val);
  2141. State.Statements.push_back(L(A("let"), A("world"), L(A(TString(NYql::ConfigureName)), A("world"), providerSource,
  2142. QA("Attr"), QAX(name.substr(dotPos + 1)), QAX(rawStr))));
  2143. } else {
  2144. AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option");
  2145. return nullptr;
  2146. }
  2147. } else if (name == "tablepathprefix") {
  2148. if (ListLength(value->args) != 1) {
  2149. AddError(TStringBuilder() << "VariableSetStmt, expected 1 arg, but got: " << ListLength(value->args));
  2150. return nullptr;
  2151. }
  2152. auto arg = ListNodeNth(value->args, 0);
  2153. if (NodeTag(arg) == T_A_Const && (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String)) {
  2154. auto rawStr = StrVal(CAST_NODE(A_Const, arg)->val);
  2155. TablePathPrefix = rawStr;
  2156. } else {
  2157. AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option");
  2158. return nullptr;
  2159. }
  2160. } else if (name == "costbasedoptimizer") {
  2161. if (ListLength(value->args) != 1) {
  2162. AddError(TStringBuilder() << "VariableSetStmt, expected 1 arg, but got: " << ListLength(value->args));
  2163. return nullptr;
  2164. }
  2165. auto arg = ListNodeNth(value->args, 0);
  2166. if (NodeTag(arg) == T_A_Const && (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String)) {
  2167. auto rawStr = StrVal(CAST_NODE(A_Const, arg)->val);
  2168. auto str = to_lower(TString(rawStr));
  2169. if (!(str == "disable" || str == "pg" || str == "native")) {
  2170. AddError(TStringBuilder() << "VariableSetStmt, not supported CostBasedOptimizer option value: " << rawStr);
  2171. return nullptr;
  2172. }
  2173. State.CostBasedOptimizer = str;
  2174. } else {
  2175. AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option");
  2176. return nullptr;
  2177. }
  2178. } else if (name == "applicationname") {
  2179. if (ListLength(value->args) != 1) {
  2180. AddError(TStringBuilder() << "VariableSetStmt, expected 1 arg, but got: " << ListLength(value->args));
  2181. return nullptr;
  2182. }
  2183. auto arg = ListNodeNth(value->args, 0);
  2184. if (NodeTag(arg) == T_A_Const && (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String)) {
  2185. auto rawStr = StrVal(CAST_NODE(A_Const, arg)->val);
  2186. State.ApplicationName = rawStr;
  2187. } else {
  2188. AddError(TStringBuilder() << "VariableSetStmt, expected string literal for " << value->name << " option");
  2189. return nullptr;
  2190. }
  2191. } else {
  2192. AddError(TStringBuilder() << "VariableSetStmt, not supported name: " << value->name);
  2193. return nullptr;
  2194. }
  2195. return State.Statements.back();
  2196. }
  2197. [[nodiscard]]
  2198. TAstNode* ParseDeleteStmt(const DeleteStmt* value) {
  2199. if (value->usingClause) {
  2200. AddError("using is not supported");
  2201. return nullptr;
  2202. }
  2203. TVector <TAstNode*> returningList;
  2204. if (value->returningList) {
  2205. auto list = ParseReturningList(value->returningList);
  2206. if (list.has_value()) {
  2207. returningList = list.value();
  2208. } else {
  2209. return nullptr;
  2210. }
  2211. }
  2212. if (value->withClause) {
  2213. AddError("with is not supported");
  2214. return nullptr;
  2215. }
  2216. if (!value->relation) {
  2217. AddError("DeleteStmt: expected relation");
  2218. return nullptr;
  2219. }
  2220. TVector<TAstNode*> fromList;
  2221. auto p = ParseRangeVar(value->relation);
  2222. if (!p) {
  2223. return nullptr;
  2224. }
  2225. AddFrom(*p, fromList);
  2226. TAstNode* whereFilter = nullptr;
  2227. if (value->whereClause) {
  2228. TExprSettings settings;
  2229. settings.AllowColumns = true;
  2230. settings.AllowSubLinks = true;
  2231. settings.Scope = "WHERE";
  2232. whereFilter = ParseExpr(value->whereClause, settings);
  2233. if (!whereFilter) {
  2234. return nullptr;
  2235. }
  2236. }
  2237. TVector<TAstNode*> setItemOptions;
  2238. setItemOptions.push_back(QL(QA("result"), QVL(CreatePgStarResultItem())));
  2239. setItemOptions.push_back(QL(QA("from"), QVL(fromList.data(), fromList.size())));
  2240. setItemOptions.push_back(QL(QA("join_ops"), QVL(QL(QL(QA("push"))))));
  2241. NYql::TAstNode* lambda = nullptr;
  2242. if (whereFilter) {
  2243. lambda = L(A("lambda"), QL(), whereFilter);
  2244. setItemOptions.push_back(QL(QA("where"), L(A("PgWhere"), L(A("Void")), lambda)));
  2245. }
  2246. auto setItemNode = L(A("PgSetItem"), QVL(setItemOptions.data(), setItemOptions.size()));
  2247. TVector<TAstNode*> selectOptions;
  2248. selectOptions.push_back(QL(QA("set_items"), QVL(setItemNode)));
  2249. selectOptions.push_back(QL(QA("set_ops"), QVL(QA("push"))));
  2250. auto select = L(A("PgSelect"), QVL(selectOptions.data(), selectOptions.size()));
  2251. auto [sink, key] = ParseWriteRangeVar(value->relation);
  2252. if (!sink || !key) {
  2253. return nullptr;
  2254. }
  2255. std::vector<TAstNode*> options;
  2256. options.push_back(QL(QA("pg_delete"), select));
  2257. options.push_back(QL(QA("mode"), QA("delete")));
  2258. if (!returningList.empty()) {
  2259. options.push_back(QL(QA("returning"), QVL(returningList.data(), returningList.size())));
  2260. }
  2261. State.Statements.push_back(L(
  2262. A("let"),
  2263. A("world"),
  2264. L(
  2265. A("Write!"),
  2266. A("world"),
  2267. sink,
  2268. key,
  2269. L(A("Void")),
  2270. QVL(options.data(), options.size())
  2271. )
  2272. ));
  2273. return State.Statements.back();
  2274. }
  2275. TMaybe<TString> GetConfigVariable(const TString& varName) {
  2276. if (varName == "server_version") {
  2277. return GetPostgresServerVersionStr();
  2278. }
  2279. if (varName == "server_version_num") {
  2280. return GetPostgresServerVersionNum();
  2281. }
  2282. if (varName == "standard_conforming_strings"){
  2283. return "on";
  2284. }
  2285. if (varName == "search_path"){
  2286. auto searchPath = Settings.GUCSettings->Get("search_path");
  2287. return searchPath ? *searchPath : "public";
  2288. }
  2289. if (varName == "default_transaction_read_only"){
  2290. return "off"; // mediawiki
  2291. }
  2292. if (varName == "transaction_isolation"){
  2293. return "serializable";
  2294. }
  2295. return {};
  2296. }
  2297. TMaybe<std::vector<TAstNode*>> ParseIndexElements(List* list) {
  2298. const auto length = ListLength(list);
  2299. std::vector<TAstNode*> columns;
  2300. columns.reserve(length);
  2301. for (auto i = 0; i < length; ++i) {
  2302. auto node = ListNodeNth(list, i);
  2303. auto indexElem = IndexElement(node);
  2304. if (indexElem->expr || indexElem->indexcolname) {
  2305. AddError("index expression is not supported yet");
  2306. return {};
  2307. }
  2308. columns.push_back(QA(indexElem->name));
  2309. }
  2310. return columns;
  2311. }
  2312. [[nodiscard]]
  2313. TAstNode* ParseVariableShowStmt(const VariableShowStmt* value) {
  2314. const auto varName = to_lower(TString(value->name));
  2315. const auto varValue = GetConfigVariable(varName);
  2316. if (!varValue) {
  2317. AddError("unrecognized configuration parameter \"" + varName + "\"");
  2318. return nullptr;
  2319. }
  2320. const auto columnName = QAX(varName);
  2321. const auto varValueNode =
  2322. L(A("PgConst"), QAX(*varValue), L(A("PgType"), QA("text")));
  2323. const auto lambda = L(A("lambda"), QL(), varValueNode);
  2324. const auto res = QL(L(A("PgResultItem"), columnName, L(A("Void")), lambda));
  2325. const auto setItem = L(A("PgSetItem"), QL(QL(QA("result"), res)));
  2326. const auto setItems = QL(QA("set_items"), QL(setItem));
  2327. const auto setOps = QL(QA("set_ops"), QVL(QA("push")));
  2328. const auto selectOptions = QL(setItems, setOps);
  2329. const auto output = L(A("PgSelect"), selectOptions);
  2330. State.Statements.push_back(L(A("let"), A("output"), output));
  2331. State.Statements.push_back(L(A("let"), A("result_sink"), L(A("DataSink"), QA(TString(NYql::ResultProviderName)))));
  2332. const auto resOptions = BuildResultOptions(true);
  2333. State.Statements.push_back(L(A("let"), A("world"), L(A("Write!"),
  2334. A("world"), A("result_sink"), L(A("Key")), A("output"), resOptions)));
  2335. State.Statements.push_back(L(A("let"), A("world"), L(A("Commit!"),
  2336. A("world"), A("result_sink"))));
  2337. return State.Statements.back();
  2338. }
  2339. [[nodiscard]]
  2340. bool ParseTransactionStmt(const TransactionStmt* value) {
  2341. switch (value->kind) {
  2342. case TRANS_STMT_BEGIN:
  2343. case TRANS_STMT_START:
  2344. case TRANS_STMT_SAVEPOINT:
  2345. case TRANS_STMT_RELEASE:
  2346. case TRANS_STMT_ROLLBACK_TO:
  2347. return true;
  2348. case TRANS_STMT_COMMIT:
  2349. State.Statements.push_back(L(A("let"), A("world"), L(A("CommitAll!"),
  2350. A("world"))));
  2351. if (Settings.GUCSettings) {
  2352. Settings.GUCSettings->Commit();
  2353. }
  2354. return true;
  2355. case TRANS_STMT_ROLLBACK:
  2356. State.Statements.push_back(L(A("let"), A("world"), L(A("CommitAll!"),
  2357. A("world"), QL(QL(QA("mode"), QA("rollback"))))));
  2358. if (Settings.GUCSettings) {
  2359. Settings.GUCSettings->RollBack();
  2360. }
  2361. return true;
  2362. default:
  2363. AddError(TStringBuilder() << "TransactionStmt: kind is not supported: " << (int)value->kind);
  2364. return false;
  2365. }
  2366. }
  2367. [[nodiscard]]
  2368. TAstNode* ParseIndexStmt(const IndexStmt* value) {
  2369. if (value->unique) {
  2370. AddError("unique index creation is not supported yet");
  2371. return nullptr;
  2372. }
  2373. if (value->primary) {
  2374. AddError("primary key creation is not supported yet");
  2375. return nullptr;
  2376. }
  2377. if (value->isconstraint || value->deferrable || value->initdeferred) {
  2378. AddError("constraint modification is not supported yet");
  2379. return nullptr;
  2380. }
  2381. if (value->whereClause) {
  2382. AddError("partial index is not supported yet");
  2383. return nullptr;
  2384. }
  2385. if (value->options) {
  2386. AddError("storage parameters for index is not supported yet");
  2387. return nullptr;
  2388. }
  2389. auto columns = ParseIndexElements(value->indexParams);
  2390. if (!columns)
  2391. return nullptr;
  2392. auto coverColumns = ParseIndexElements(value->indexIncludingParams);
  2393. if (!coverColumns)
  2394. return nullptr;
  2395. const auto [sink, key] = ParseWriteRangeVar(value->relation, true);
  2396. if (!sink || !key) {
  2397. return nullptr;
  2398. }
  2399. std::vector<TAstNode*> flags;
  2400. flags.emplace_back(QA("pg"));
  2401. if (value->if_not_exists) {
  2402. flags.emplace_back(QA("ifNotExists"));
  2403. }
  2404. std::vector<TAstNode*> desc;
  2405. auto indexNameAtom = QA("indexName");
  2406. if (value->idxname) {
  2407. desc.emplace_back(QL(indexNameAtom, QA(value->idxname)));
  2408. } else {
  2409. desc.emplace_back(QL(indexNameAtom));
  2410. }
  2411. desc.emplace_back(QL(QA("indexType"), QA(value->unique ? "syncGlobalUnique" : "syncGlobal")));
  2412. desc.emplace_back(QL(QA("indexColumns"), QVL(columns->data(), columns->size())));
  2413. desc.emplace_back(QL(QA("dataColumns"), QVL(coverColumns->data(), coverColumns->size())));
  2414. desc.emplace_back(QL(QA("flags"), QVL(flags.data(), flags.size())));
  2415. State.Statements.push_back(L(
  2416. A("let"),
  2417. A("world"),
  2418. L(
  2419. A("Write!"),
  2420. A("world"),
  2421. sink,
  2422. key,
  2423. L(A("Void")),
  2424. QL(
  2425. QL(QA("mode"), QA("alter")),
  2426. QL(QA("actions"), QL(QL(QA("addIndex"), QVL(desc.data(), desc.size()))))
  2427. )
  2428. )
  2429. ));
  2430. return State.Statements.back();
  2431. }
  2432. [[nodiscard]]
  2433. TAstNode* ParseCreateSeqStmt(const CreateSeqStmt* value) {
  2434. std::vector<TAstNode*> options;
  2435. TString mode = (value->if_not_exists) ? "create_if_not_exists" : "create";
  2436. options.push_back(QL(QA("mode"), QA(mode)));
  2437. auto [sink, key] = ParseQualifiedPgObjectName(
  2438. value->sequence->catalogname,
  2439. value->sequence->schemaname,
  2440. value->sequence->relname,
  2441. "pgSequence"
  2442. );
  2443. if (!sink || !key) {
  2444. return nullptr;
  2445. }
  2446. const auto relPersistence = static_cast<NPg::ERelPersistence>(value->sequence->relpersistence);
  2447. switch (relPersistence) {
  2448. case NPg::ERelPersistence::Temp:
  2449. options.push_back(QL(QA("temporary")));
  2450. break;
  2451. case NPg::ERelPersistence::Unlogged:
  2452. AddError("UNLOGGED sequence not supported");
  2453. return nullptr;
  2454. break;
  2455. case NPg::ERelPersistence::Permanent:
  2456. break;
  2457. }
  2458. for (int i = 0; i < ListLength(value->options); ++i) {
  2459. auto rawNode = ListNodeNth(value->options, i);
  2460. switch (NodeTag(rawNode)) {
  2461. case T_DefElem: {
  2462. const auto* defElem = CAST_NODE(DefElem, rawNode);
  2463. TString nameElem = defElem->defname;
  2464. if (defElem->arg) {
  2465. switch (NodeTag(defElem->arg))
  2466. {
  2467. case T_Boolean:
  2468. options.emplace_back(QL(QAX(nameElem), QA(ToString(boolVal(defElem->arg)))));
  2469. break;
  2470. case T_Integer:
  2471. options.emplace_back(QL(QAX(nameElem), QA(ToString(intVal(defElem->arg)))));
  2472. break;
  2473. case T_Float:
  2474. options.emplace_back(QL(QAX(nameElem), QA(strVal(defElem->arg))));
  2475. break;
  2476. case T_TypeName: {
  2477. const auto* typeName = CAST_NODE_EXT(PG_TypeName, T_TypeName, defElem->arg);
  2478. if (ListLength(typeName->names) > 0) {
  2479. options.emplace_back(QL(QAX(nameElem),
  2480. QAX(StrVal(ListNodeNth(typeName->names, ListLength(typeName->names) - 1)))));
  2481. }
  2482. break;
  2483. }
  2484. default:
  2485. NodeNotImplemented(defElem->arg);
  2486. return nullptr;
  2487. }
  2488. }
  2489. break;
  2490. }
  2491. default:
  2492. NodeNotImplemented(rawNode);
  2493. return nullptr;
  2494. }
  2495. }
  2496. if (value->for_identity) {
  2497. options.push_back(QL(QA("for_identity")));
  2498. }
  2499. if (value->ownerId != InvalidOid) {
  2500. options.push_back(QL(QA("owner_id"), QA(ToString(value->ownerId))));
  2501. }
  2502. State.Statements.push_back(
  2503. L(A("let"), A("world"),
  2504. L(A("Write!"), A("world"), sink, key, L(A("Void")),
  2505. QVL(options.data(), options.size()))));
  2506. return State.Statements.back();
  2507. }
  2508. [[nodiscard]]
  2509. TAstNode* ParseAlterSeqStmt(const AlterSeqStmt* value) {
  2510. std::vector<TAstNode*> options;
  2511. TString mode = (value->missing_ok) ? "alter_if_exists" : "alter";
  2512. options.push_back(QL(QA("mode"), QA(mode)));
  2513. auto [sink, key] = ParseQualifiedPgObjectName(
  2514. value->sequence->catalogname,
  2515. value->sequence->schemaname,
  2516. value->sequence->relname,
  2517. "pgSequence"
  2518. );
  2519. if (!sink || !key) {
  2520. return nullptr;
  2521. }
  2522. for (int i = 0; i < ListLength(value->options); ++i) {
  2523. auto rawNode = ListNodeNth(value->options, i);
  2524. switch (NodeTag(rawNode)) {
  2525. case T_DefElem: {
  2526. const auto* defElem = CAST_NODE(DefElem, rawNode);
  2527. TString nameElem = defElem->defname;
  2528. if (defElem->arg) {
  2529. switch (NodeTag(defElem->arg))
  2530. {
  2531. case T_Boolean:
  2532. options.emplace_back(QL(QAX(nameElem), QA(ToString(boolVal(defElem->arg)))));
  2533. break;
  2534. case T_Integer:
  2535. options.emplace_back(QL(QAX(nameElem), QA(ToString(intVal(defElem->arg)))));
  2536. break;
  2537. case T_Float:
  2538. options.emplace_back(QL(QAX(nameElem), QA(strVal(defElem->arg))));
  2539. break;
  2540. case T_TypeName: {
  2541. const auto* typeName = CAST_NODE_EXT(PG_TypeName, T_TypeName, defElem->arg);
  2542. if (ListLength(typeName->names) > 0) {
  2543. options.emplace_back(QL(QAX(nameElem),
  2544. QAX(StrVal(ListNodeNth(typeName->names, ListLength(typeName->names) - 1)))));
  2545. }
  2546. break;
  2547. }
  2548. default:
  2549. NodeNotImplemented(defElem->arg);
  2550. return nullptr;
  2551. }
  2552. } else {
  2553. if (nameElem == "restart") {
  2554. options.emplace_back(QL(QAX(nameElem), QA(TString())));
  2555. }
  2556. }
  2557. break;
  2558. }
  2559. default:
  2560. NodeNotImplemented(rawNode);
  2561. return nullptr;
  2562. }
  2563. }
  2564. if (value->for_identity) {
  2565. options.push_back(QL(QA("for_identity")));
  2566. }
  2567. State.Statements.push_back(
  2568. L(A("let"), A("world"),
  2569. L(A("Write!"), A("world"), sink, key, L(A("Void")),
  2570. QVL(options.data(), options.size()))));
  2571. return State.Statements.back();
  2572. }
  2573. [[nodiscard]]
  2574. TAstNode* ParseAlterTableStmt(const AlterTableStmt* value) {
  2575. std::vector<TAstNode*> options;
  2576. TString mode = (value->missing_ok) ? "alter_if_exists" : "alter";
  2577. options.push_back(QL(QA("mode"), QA(mode)));
  2578. const auto [sink, key] = ParseWriteRangeVar(value->relation, true);
  2579. if (!sink || !key) {
  2580. return nullptr;
  2581. }
  2582. std::vector<TAstNode*> alterColumns;
  2583. for (int i = 0; i < ListLength(value->cmds); ++i) {
  2584. auto rawNode = ListNodeNth(value->cmds, i);
  2585. const auto* cmd = CAST_NODE(AlterTableCmd, rawNode);
  2586. switch (cmd->subtype) {
  2587. case AT_ColumnDefault: { /* ALTER COLUMN DEFAULT */
  2588. const auto* def = cmd->def;
  2589. const auto* colName = cmd->name;
  2590. if (def == nullptr) {
  2591. alterColumns.push_back(QL(QAX(colName), QL(QA("setDefault"), QL(QA("Null")))));
  2592. break;
  2593. }
  2594. switch (NodeTag(def)) {
  2595. case T_FuncCall: {
  2596. const auto* newDefault = CAST_NODE(FuncCall, def);
  2597. const auto* funcName = ListNodeNth(newDefault->funcname, 0);
  2598. if (NodeTag(funcName) != T_String) {
  2599. NodeNotImplemented(newDefault, funcName);
  2600. return nullptr;
  2601. }
  2602. auto strFuncName = StrVal(funcName);
  2603. if (strcmp(strFuncName, "nextval") != 0) {
  2604. NodeNotImplemented(newDefault, funcName);
  2605. return nullptr;
  2606. }
  2607. const auto* rawArg = ListNodeNth(newDefault->args, 0);
  2608. if (NodeTag(rawArg) != T_TypeCast && NodeTag(rawArg) != T_A_Const) {
  2609. AddError(TStringBuilder() << "Expected type cast node or a_const, but got something wrong: " << NodeTag(rawArg));
  2610. return nullptr;
  2611. }
  2612. const A_Const* localConst = nullptr;
  2613. if (NodeTag(rawArg) == T_TypeCast) {
  2614. auto localCast = CAST_NODE(TypeCast, rawArg)->arg;
  2615. if (NodeTag(localCast) != T_A_Const) {
  2616. AddError(TStringBuilder() << "Expected a_const in cast, but got something wrong: " << NodeTag(localCast));
  2617. return nullptr;
  2618. }
  2619. localConst = CAST_NODE(A_Const, localCast);
  2620. } else {
  2621. localConst = CAST_NODE(A_Const, rawArg);
  2622. }
  2623. if (NodeTag(localConst->val) != T_String) {
  2624. AddError(TStringBuilder() << "Expected string in const, but got something wrong: " << NodeTag(localConst->val));
  2625. return nullptr;
  2626. }
  2627. auto seqName = StrVal(localConst->val);
  2628. TVector<TString> seqNameList;
  2629. Split(seqName, ".", seqNameList);
  2630. if (seqNameList.size() != 2 && seqNameList.size() != 1) {
  2631. AddError(TStringBuilder() << "Expected list size is 1 or 2, but there are " << seqNameList.size());
  2632. return nullptr;
  2633. }
  2634. alterColumns.push_back(QL(QAX(colName), QL(QA("setDefault"), QL(QA("nextval"), QA(seqNameList.back())))));
  2635. break;
  2636. }
  2637. default:
  2638. NodeNotImplemented(def);
  2639. return nullptr;
  2640. }
  2641. break;
  2642. }
  2643. default:
  2644. NodeNotImplemented(rawNode);
  2645. return nullptr;
  2646. }
  2647. }
  2648. std::vector<TAstNode*> actions { QL(QA("alterColumns"), QVL(alterColumns.data(), alterColumns.size())) };
  2649. options.push_back(
  2650. QL(QA("actions"),
  2651. QVL(actions.data(), actions.size())
  2652. )
  2653. );
  2654. State.Statements.push_back(
  2655. L(A("let"), A("world"),
  2656. L(A("Write!"), A("world"), sink, key, L(A("Void")),
  2657. QVL(options.data(), options.size()))));
  2658. return State.Statements.back();
  2659. }
  2660. TMaybe<TFromDesc> ParseFromClause(const Node* node) {
  2661. switch (NodeTag(node)) {
  2662. case T_RangeVar:
  2663. return ParseRangeVar(CAST_NODE(RangeVar, node));
  2664. case T_RangeSubselect:
  2665. return ParseRangeSubselect(CAST_NODE(RangeSubselect, node));
  2666. case T_RangeFunction:
  2667. return ParseRangeFunction(CAST_NODE(RangeFunction, node));
  2668. default:
  2669. NodeNotImplementedImpl<SelectStmt>(node);
  2670. return {};
  2671. }
  2672. }
  2673. void AddFrom(const TFromDesc& p, TVector<TAstNode*>& fromList) {
  2674. auto aliasNode = QAX(p.Alias);
  2675. TVector<TAstNode*> colNamesNodes;
  2676. for (const auto& c : p.ColNames) {
  2677. colNamesNodes.push_back(QAX(c));
  2678. }
  2679. auto colNamesTuple = QVL(colNamesNodes.data(), colNamesNodes.size());
  2680. if (p.InjectRead) {
  2681. auto label = "read" + ToString(State.ReadIndex);
  2682. State.Statements.push_back(L(A("let"), A(label), p.Source));
  2683. State.Statements.push_back(L(A("let"), A("world"), L(A("Left!"), A(label))));
  2684. fromList.push_back(QL(L(A("Right!"), A(label)), aliasNode, colNamesTuple));
  2685. ++State.ReadIndex;
  2686. } else {
  2687. auto source = p.Source;
  2688. if (!source) {
  2689. source = L(A("PgSelf"));
  2690. }
  2691. fromList.push_back(QL(source, aliasNode, colNamesTuple));
  2692. }
  2693. }
  2694. bool ParseAlias(const Alias* alias, TString& res, TVector<TString>& colnames) {
  2695. for (int i = 0; i < ListLength(alias->colnames); ++i) {
  2696. auto node = ListNodeNth(alias->colnames, i);
  2697. if (NodeTag(node) != T_String) {
  2698. NodeNotImplemented(alias, node);
  2699. return false;
  2700. }
  2701. colnames.push_back(StrVal(node));
  2702. }
  2703. res = alias->aliasname;
  2704. return true;
  2705. }
  2706. TString ResolveCluster(const TStringBuf schemaname, TString name) {
  2707. if (NYql::NPg::GetStaticColumns().contains(NPg::TTableInfoKey{"pg_catalog", name})) {
  2708. return "pg_catalog";
  2709. }
  2710. if (schemaname == "public") {
  2711. return Settings.DefaultCluster;;
  2712. }
  2713. if (schemaname == "" && Settings.GUCSettings) {
  2714. auto search_path = Settings.GUCSettings->Get("search_path");
  2715. if (!search_path || *search_path == "public" || search_path->empty()) {
  2716. return Settings.DefaultCluster;
  2717. }
  2718. return TString(*search_path);
  2719. }
  2720. return TString(schemaname);
  2721. }
  2722. TAstNode* BuildClusterSinkOrSourceExpression(
  2723. bool isSink, const TStringBuf schemaname) {
  2724. TString usedCluster(schemaname);
  2725. auto p = Settings.ClusterMapping.FindPtr(usedCluster);
  2726. if (!p) {
  2727. usedCluster = to_lower(usedCluster);
  2728. p = Settings.ClusterMapping.FindPtr(usedCluster);
  2729. }
  2730. if (!p) {
  2731. AddError(TStringBuilder() << "Unknown cluster: " << schemaname);
  2732. return nullptr;
  2733. }
  2734. return L(isSink ? A("DataSink") : A("DataSource"), QAX(*p), QAX(usedCluster));
  2735. }
  2736. TAstNode* BuildTableKeyExpression(const TStringBuf relname,
  2737. const TStringBuf cluster, bool isScheme = false
  2738. ) {
  2739. auto lowerCluster = to_lower(TString(cluster));
  2740. bool noPrefix = (lowerCluster == "pg_catalog" || lowerCluster == "information_schema");
  2741. TString tableName = noPrefix ? to_lower(TString(relname)) : TablePathPrefix + relname;
  2742. return L(A("Key"), QL(QA(isScheme ? "tablescheme" : "table"),
  2743. L(A("String"), QAX(std::move(tableName)))));
  2744. }
  2745. TReadWriteKeyExprs ParseQualifiedRelationName(const TStringBuf catalogname,
  2746. const TStringBuf schemaname,
  2747. const TStringBuf relname,
  2748. bool isSink, bool isScheme) {
  2749. if (!catalogname.empty()) {
  2750. AddError("catalogname is not supported");
  2751. return {};
  2752. }
  2753. if (relname.empty()) {
  2754. AddError("relname should be specified");
  2755. return {};
  2756. }
  2757. const auto cluster = ResolveCluster(schemaname, TString(relname));
  2758. const auto sinkOrSource = BuildClusterSinkOrSourceExpression(isSink, cluster);
  2759. const auto key = BuildTableKeyExpression(relname, cluster, isScheme);
  2760. return {sinkOrSource, key};
  2761. }
  2762. TAstNode* BuildPgObjectExpression(const TStringBuf objectName, const TStringBuf objectType) {
  2763. bool noPrefix = (objectType == "pgIndex");
  2764. TString name = noPrefix ? TString(objectName) : TablePathPrefix + TString(objectName);
  2765. return L(A("Key"), QL(QA("pgObject"),
  2766. L(A("String"), QAX(std::move(name))),
  2767. L(A("String"), QA(objectType))
  2768. ));
  2769. }
  2770. TReadWriteKeyExprs ParseQualifiedPgObjectName(const TStringBuf catalogname,
  2771. const TStringBuf schemaname,
  2772. const TStringBuf objectName,
  2773. const TStringBuf pgObjectType) {
  2774. if (!catalogname.empty()) {
  2775. AddError("catalogname is not supported");
  2776. return {};
  2777. }
  2778. if (objectName.empty()) {
  2779. AddError("objectName should be specified");
  2780. return {};
  2781. }
  2782. const auto cluster = ResolveCluster(schemaname, TString(objectName));
  2783. const auto sinkOrSource = BuildClusterSinkOrSourceExpression(true, cluster);
  2784. const auto key = BuildPgObjectExpression(objectName, pgObjectType);
  2785. return {sinkOrSource, key};
  2786. }
  2787. TReadWriteKeyExprs ParseWriteRangeVar(const RangeVar *value,
  2788. bool isScheme = false) {
  2789. if (value->alias) {
  2790. AddError("alias is not supported");
  2791. return {};
  2792. }
  2793. return ParseQualifiedRelationName(value->catalogname, value->schemaname,
  2794. value->relname,
  2795. /* isSink */ true, isScheme);
  2796. }
  2797. TMaybe<TFromDesc> ParseRangeVar(const RangeVar* value) {
  2798. AT_LOCATION(value);
  2799. const TView* view = nullptr;
  2800. if (StrLength(value->schemaname) == 0) {
  2801. for (auto rit = State.CTE.rbegin(); rit != State.CTE.rend(); ++rit) {
  2802. auto cteIt = rit->find(value->relname);
  2803. if (cteIt != rit->end()) {
  2804. view = &cteIt->second;
  2805. break;
  2806. }
  2807. }
  2808. if (!view && State.CurrentRecursiveView && State.CurrentRecursiveView->Name == value->relname) {
  2809. view = State.CurrentRecursiveView;
  2810. }
  2811. if (!view) {
  2812. auto viewIt = State.Views.find(value->relname);
  2813. if (viewIt != State.Views.end()) {
  2814. view = &viewIt->second;
  2815. }
  2816. }
  2817. }
  2818. TString alias;
  2819. TVector<TString> colnames;
  2820. if (value->alias) {
  2821. if (!ParseAlias(value->alias, alias, colnames)) {
  2822. return {};
  2823. }
  2824. } else {
  2825. alias = value->relname;
  2826. }
  2827. if (view) {
  2828. return TFromDesc{view->Source, alias, colnames.empty() ? view->ColNames : colnames, false };
  2829. }
  2830. TString schemaname = value->schemaname;
  2831. if (!StrCompare(value->schemaname, "bindings")) {
  2832. bool isBinding = false;
  2833. switch (Settings.BindingsMode) {
  2834. case NSQLTranslation::EBindingsMode::DISABLED:
  2835. AddError("Please remove 'bindings.' from your query, the support for this syntax has ended");
  2836. return {};
  2837. case NSQLTranslation::EBindingsMode::ENABLED:
  2838. isBinding = true;
  2839. break;
  2840. case NSQLTranslation::EBindingsMode::DROP_WITH_WARNING:
  2841. AddWarning(TIssuesIds::YQL_DEPRECATED_BINDINGS, "Please remove 'bindings.' from your query, the support for this syntax will be dropped soon");
  2842. [[fallthrough]];
  2843. case NSQLTranslation::EBindingsMode::DROP:
  2844. schemaname = Settings.DefaultCluster;
  2845. break;
  2846. }
  2847. if (isBinding) {
  2848. auto s = BuildBindingSource(value);
  2849. if (!s) {
  2850. return {};
  2851. }
  2852. return TFromDesc{ s, alias, colnames, true };
  2853. }
  2854. }
  2855. const auto [source, key] = ParseQualifiedRelationName(
  2856. value->catalogname, schemaname, value->relname,
  2857. /* isSink */ false,
  2858. /* isScheme */ false);
  2859. if (source == nullptr || key == nullptr) {
  2860. return {};
  2861. }
  2862. const auto readExpr = this->SqlProcArgsCount ?
  2863. L(A("Cons!"),
  2864. A("world"),
  2865. L(
  2866. A("PgTableContent"),
  2867. QA("pg_catalog"),
  2868. QAX(value->relname),
  2869. L(A("Void")),
  2870. QL()
  2871. )
  2872. ) :
  2873. L(
  2874. A("Read!"),
  2875. A("world"),
  2876. source,
  2877. key,
  2878. L(A("Void")),
  2879. QL()
  2880. );
  2881. return TFromDesc {
  2882. readExpr,
  2883. alias,
  2884. colnames,
  2885. /* injectRead */ true,
  2886. };
  2887. }
  2888. TAstNode* BuildBindingSource(const RangeVar* value) {
  2889. if (StrLength(value->relname) == 0) {
  2890. AddError("relname should be specified");
  2891. }
  2892. const TString binding = value->relname;
  2893. NSQLTranslation::TBindingInfo bindingInfo;
  2894. if (const auto& error = ExtractBindingInfo(Settings, binding, bindingInfo)) {
  2895. AddError(error);
  2896. return nullptr;
  2897. }
  2898. TVector<TAstNode*> hints;
  2899. if (bindingInfo.Schema) {
  2900. auto schema = QA(bindingInfo.Schema);
  2901. auto type = L(A("SqlTypeFromYson"), schema);
  2902. auto columns = L(A("SqlColumnOrderFromYson"), schema);
  2903. hints.emplace_back(QL(QA("userschema"), type, columns));
  2904. }
  2905. for (auto& [key, value] : bindingInfo.Attributes) {
  2906. TVector<TAstNode*> hintValues;
  2907. hintValues.push_back(QA(NormalizeName(key)));
  2908. for (auto& v : value) {
  2909. hintValues.push_back(QA(v));
  2910. }
  2911. hints.emplace_back(QVL(hintValues.data(), hintValues.size()));
  2912. }
  2913. auto source = L(A("DataSource"), QAX(bindingInfo.ClusterType), QAX(bindingInfo.Cluster));
  2914. return L(
  2915. A("Read!"),
  2916. A("world"),
  2917. source,
  2918. L(
  2919. A("MrTableConcat"),
  2920. L(
  2921. A("Key"),
  2922. QL(
  2923. QA("table"),
  2924. L(
  2925. A("String"),
  2926. QAX(bindingInfo.Path)
  2927. )
  2928. )
  2929. )
  2930. ),
  2931. L(A("Void")),
  2932. QVL(hints.data(), hints.size())
  2933. );
  2934. }
  2935. TMaybe<TFromDesc> ParseRangeFunction(const RangeFunction* value) {
  2936. if (value->lateral) {
  2937. AddError("RangeFunction: unsupported lateral");
  2938. return {};
  2939. }
  2940. if (value->ordinality) {
  2941. AddError("RangeFunction: unsupported ordinality");
  2942. return {};
  2943. }
  2944. if (value->is_rowsfrom) {
  2945. AddError("RangeFunction: unsupported is_rowsfrom");
  2946. return {};
  2947. }
  2948. if (ListLength(value->coldeflist) > 0) {
  2949. AddError("RangeFunction: unsupported coldeflist");
  2950. return {};
  2951. }
  2952. if (ListLength(value->functions) != 1) {
  2953. AddError("RangeFunction: only one function is supported");
  2954. return {};
  2955. }
  2956. TString alias;
  2957. TVector<TString> colnames;
  2958. if (value->alias) {
  2959. if (!ParseAlias(value->alias, alias, colnames)) {
  2960. return {};
  2961. }
  2962. }
  2963. auto funcNode = ListNodeNth(value->functions, 0);
  2964. if (NodeTag(funcNode) != T_List) {
  2965. AddError("RangeFunction: expected pair");
  2966. return {};
  2967. }
  2968. auto lst = CAST_NODE(List, funcNode);
  2969. if (ListLength(lst) != 2) {
  2970. AddError("RangeFunction: expected pair");
  2971. return {};
  2972. }
  2973. TExprSettings settings;
  2974. settings.AllowColumns = false;
  2975. settings.AllowReturnSet = true;
  2976. settings.Scope = "RANGE FUNCTION";
  2977. auto node = ListNodeNth(lst, 0);
  2978. if (NodeTag(node) != T_FuncCall) {
  2979. AddError("RangeFunction: extected FuncCall");
  2980. return {};
  2981. }
  2982. bool injectRead = false;
  2983. auto func = ParseFuncCall(CAST_NODE(FuncCall, node), settings, true, injectRead);
  2984. if (!func) {
  2985. return {};
  2986. }
  2987. return TFromDesc{ func, alias, colnames, injectRead };
  2988. }
  2989. TMaybe<TFromDesc> ParseRangeSubselect(const RangeSubselect* value) {
  2990. if (value->lateral) {
  2991. AddError("RangeSubselect: unsupported lateral");
  2992. return {};
  2993. }
  2994. if (!value->alias) {
  2995. AddError("RangeSubselect: expected alias");
  2996. return {};
  2997. }
  2998. TString alias;
  2999. TVector<TString> colnames;
  3000. if (!ParseAlias(value->alias, alias, colnames)) {
  3001. return {};
  3002. }
  3003. if (!value->subquery) {
  3004. AddError("RangeSubselect: expected subquery");
  3005. return {};
  3006. }
  3007. if (NodeTag(value->subquery) != T_SelectStmt) {
  3008. NodeNotImplemented(value, value->subquery);
  3009. return {};
  3010. }
  3011. return TFromDesc{ ParseSelectStmt(CAST_NODE(SelectStmt, value->subquery), { .Inner = true }), alias, colnames, false };
  3012. }
  3013. TAstNode* ParseNullTestExpr(const NullTest* value, const TExprSettings& settings) {
  3014. AT_LOCATION(value);
  3015. if (value->argisrow) {
  3016. AddError("NullTest: unsupported argisrow");
  3017. return nullptr;
  3018. }
  3019. auto arg = ParseExpr(Expr2Node(value->arg), settings);
  3020. if (!arg) {
  3021. return nullptr;
  3022. }
  3023. auto result = L(A("Exists"), arg);
  3024. if (value->nulltesttype == IS_NULL) {
  3025. result = L(A("Not"), result);
  3026. }
  3027. return L(A("ToPg"), result);
  3028. }
  3029. struct TCaseBranch {
  3030. TAstNode* Pred;
  3031. TAstNode* Value;
  3032. };
  3033. TCaseBranch ReduceCaseBranches(std::vector<TCaseBranch>::const_iterator begin, std::vector<TCaseBranch>::const_iterator end) {
  3034. Y_ENSURE(begin < end);
  3035. const size_t branchCount = end - begin;
  3036. if (branchCount == 1) {
  3037. return *begin;
  3038. }
  3039. auto mid = begin + branchCount / 2;
  3040. auto left = ReduceCaseBranches(begin, mid);
  3041. auto right = ReduceCaseBranches(mid, end);
  3042. TVector<TAstNode*> preds;
  3043. preds.reserve(branchCount + 1);
  3044. preds.push_back(A("Or"));
  3045. for (auto it = begin; it != end; ++it) {
  3046. preds.push_back(it->Pred);
  3047. }
  3048. TCaseBranch result;
  3049. result.Pred = VL(&preds[0], preds.size());
  3050. result.Value = L(A("If"), left.Pred, left.Value, right.Value);
  3051. return result;
  3052. }
  3053. TAstNode* ParseCaseExpr(const CaseExpr* value, const TExprSettings& settings) {
  3054. AT_LOCATION(value);
  3055. TAstNode* testExpr = nullptr;
  3056. if (value->arg) {
  3057. testExpr = ParseExpr(Expr2Node(value->arg), settings);
  3058. if (!testExpr) {
  3059. return nullptr;
  3060. }
  3061. }
  3062. std::vector<TCaseBranch> branches;
  3063. for (int i = 0; i < ListLength(value->args); ++i) {
  3064. auto node = ListNodeNth(value->args, i);
  3065. auto whenNode = CAST_NODE(CaseWhen, node);
  3066. auto whenExpr = ParseExpr(Expr2Node(whenNode->expr), settings);
  3067. if (!whenExpr) {
  3068. return nullptr;
  3069. }
  3070. if (testExpr) {
  3071. whenExpr = L(A("PgOp"), QA("="), testExpr, whenExpr);
  3072. }
  3073. whenExpr = L(A("Coalesce"),
  3074. L(A("FromPg"), whenExpr),
  3075. L(A("Bool"), QA("false"))
  3076. );
  3077. auto whenResult = ParseExpr(Expr2Node(whenNode->result), settings);
  3078. if (!whenResult) {
  3079. return nullptr;
  3080. }
  3081. branches.emplace_back(TCaseBranch{ .Pred = whenExpr,.Value = whenResult });
  3082. }
  3083. TAstNode* defaultResult = nullptr;
  3084. if (value->defresult) {
  3085. defaultResult = ParseExpr(Expr2Node(value->defresult), settings);
  3086. if (!defaultResult) {
  3087. return nullptr;
  3088. }
  3089. } else {
  3090. defaultResult = L(A("Null"));
  3091. }
  3092. auto final = ReduceCaseBranches(branches.begin(), branches.end());
  3093. return L(A("If"), final.Pred, final.Value, defaultResult);
  3094. }
  3095. TAstNode* ParseParamRefExpr(const ParamRef* value) {
  3096. if (SqlProcArgsCount && (value->number < 1 || (ui32)value->number > *SqlProcArgsCount)) {
  3097. AddError(TStringBuilder() << "Unexpected parameter number: " << value->number);
  3098. return nullptr;
  3099. }
  3100. const auto varName = PREPARED_PARAM_PREFIX + ToString(value->number);
  3101. if (!State.ParamNameToPgTypeName.contains(varName)) {
  3102. State.ParamNameToPgTypeName[varName] = DEFAULT_PARAM_TYPE;
  3103. }
  3104. return A(varName);
  3105. }
  3106. TAstNode* ParseReturnStmt(const ReturnStmt* value) {
  3107. TExprSettings settings;
  3108. settings.AllowColumns = false;
  3109. settings.Scope = "RETURN";
  3110. auto expr = ParseExpr(value->returnval, settings);
  3111. if (!expr) {
  3112. return nullptr;
  3113. }
  3114. State.Statements.push_back(L(A("return"), expr));
  3115. return State.Statements.back();
  3116. }
  3117. TAstNode* ParseSQLValueFunction(const SQLValueFunction* value) {
  3118. AT_LOCATION(value);
  3119. switch (value->op) {
  3120. case SVFOP_CURRENT_DATE:
  3121. return L(A("PgCast"),
  3122. L(A("PgCall"), QA("now"), QL()),
  3123. L(A("PgType"), QA("date"))
  3124. );
  3125. case SVFOP_CURRENT_TIME:
  3126. return L(A("PgCast"),
  3127. L(A("PgCall"), QA("now"), QL()),
  3128. L(A("PgType"), QA("timetz"))
  3129. );
  3130. case SVFOP_CURRENT_TIME_N:
  3131. return L(A("PgCast"),
  3132. L(A("PgCall"), QA("now"), QL()),
  3133. L(A("PgType"), QA("timetz")),
  3134. L(A("PgConst"), QA(ToString(value->typmod)), L(A("PgType"), QA("int4")))
  3135. );
  3136. case SVFOP_CURRENT_TIMESTAMP:
  3137. return L(A("PgCall"), QA("now"), QL());
  3138. case SVFOP_CURRENT_TIMESTAMP_N:
  3139. return L(A("PgCast"),
  3140. L(A("PgCall"), QA("now"), QL()),
  3141. L(A("PgType"), QA("timestamptz")),
  3142. L(A("PgConst"), QA(ToString(value->typmod)), L(A("PgType"), QA("int4")))
  3143. );
  3144. case SVFOP_CURRENT_USER:
  3145. case SVFOP_CURRENT_ROLE:
  3146. case SVFOP_USER: {
  3147. auto user = Settings.GUCSettings->Get("ydb_user");
  3148. return L(A("PgConst"), user ? QAX(TString(*user)) : QA("postgres"), L(A("PgType"), QA("name")));
  3149. }
  3150. case SVFOP_CURRENT_CATALOG: {
  3151. std::optional<TString> database;
  3152. if (Settings.GUCSettings) {
  3153. database = Settings.GUCSettings->Get("ydb_database");
  3154. }
  3155. return L(A("PgConst"), QA(database ? *database : "postgres"), L(A("PgType"), QA("name")));
  3156. }
  3157. case SVFOP_CURRENT_SCHEMA:
  3158. return GetCurrentSchema();
  3159. default:
  3160. AddError(TStringBuilder() << "Usupported SQLValueFunction: " << (int)value->op);
  3161. return nullptr;
  3162. }
  3163. }
  3164. TAstNode* GetCurrentSchema() {
  3165. std::optional<TString> searchPath;
  3166. if (Settings.GUCSettings) {
  3167. searchPath = Settings.GUCSettings->Get("search_path");
  3168. }
  3169. return L(A("PgConst"), QA(searchPath ? *searchPath : "public"), L(A("PgType"), QA("name")));
  3170. }
  3171. TAstNode* ParseBooleanTest(const BooleanTest* value, const TExprSettings& settings) {
  3172. AT_LOCATION(value);
  3173. auto arg = ParseExpr(Expr2Node(value->arg), settings);
  3174. if (!arg) {
  3175. return nullptr;
  3176. }
  3177. TString op;
  3178. bool isNot = false;
  3179. switch (value->booltesttype) {
  3180. case IS_TRUE: {
  3181. op = "PgIsTrue";
  3182. break;
  3183. }
  3184. case IS_NOT_TRUE: {
  3185. op = "PgIsTrue";
  3186. isNot = true;
  3187. break;
  3188. }
  3189. case IS_FALSE: {
  3190. op = "PgIsFalse";
  3191. break;
  3192. }
  3193. case IS_NOT_FALSE: {
  3194. op = "PgIsFalse";
  3195. isNot = true;
  3196. break;
  3197. }
  3198. case IS_UNKNOWN: {
  3199. op = "PgIsUnknown";
  3200. break;
  3201. }
  3202. case IS_NOT_UNKNOWN: {
  3203. op = "PgIsUnknown";
  3204. isNot = true;
  3205. break;
  3206. }
  3207. default: {
  3208. TStringBuilder b;
  3209. b << "Unsupported booltesttype " << static_cast<int>(value->booltesttype);
  3210. AddError(b);
  3211. return nullptr;
  3212. }
  3213. }
  3214. auto result = L(A(op), arg);
  3215. if (isNot) {
  3216. result = L(A("PgNot"), result);
  3217. }
  3218. return result;
  3219. }
  3220. TAstNode* ParseExpr(const Node* node, const TExprSettings& settings) {
  3221. switch (NodeTag(node)) {
  3222. case T_A_Const: {
  3223. return ParseAConst(CAST_NODE(A_Const, node), settings);
  3224. }
  3225. case T_A_Expr: {
  3226. return ParseAExpr(CAST_NODE(A_Expr, node), settings);
  3227. }
  3228. case T_CaseExpr: {
  3229. return ParseCaseExpr(CAST_NODE(CaseExpr, node), settings);
  3230. }
  3231. case T_ColumnRef: {
  3232. return ParseColumnRef(CAST_NODE(ColumnRef, node), settings);
  3233. }
  3234. case T_TypeCast: {
  3235. return ParseTypeCast(CAST_NODE(TypeCast, node), settings);
  3236. }
  3237. case T_BoolExpr: {
  3238. return ParseBoolExpr(CAST_NODE(BoolExpr, node), settings);
  3239. }
  3240. case T_NullTest: {
  3241. return ParseNullTestExpr(CAST_NODE(NullTest, node), settings);
  3242. }
  3243. case T_FuncCall: {
  3244. bool injectRead;
  3245. return ParseFuncCall(CAST_NODE(FuncCall, node), settings, false, injectRead);
  3246. }
  3247. case T_A_ArrayExpr: {
  3248. return ParseAArrayExpr(CAST_NODE(A_ArrayExpr, node), settings);
  3249. }
  3250. case T_SubLink: {
  3251. return ParseSubLinkExpr(CAST_NODE(SubLink, node), settings);
  3252. }
  3253. case T_CoalesceExpr: {
  3254. return ParseCoalesceExpr(CAST_NODE(CoalesceExpr, node), settings);
  3255. }
  3256. case T_GroupingFunc: {
  3257. return ParseGroupingFunc(CAST_NODE(GroupingFunc, node));
  3258. }
  3259. case T_ParamRef: {
  3260. return ParseParamRefExpr(CAST_NODE(ParamRef, node));
  3261. }
  3262. case T_SQLValueFunction: {
  3263. return ParseSQLValueFunction(CAST_NODE(SQLValueFunction, node));
  3264. }
  3265. case T_BooleanTest: {
  3266. return ParseBooleanTest(CAST_NODE(BooleanTest, node), settings);
  3267. }
  3268. default:
  3269. NodeNotImplemented(node);
  3270. return nullptr;
  3271. }
  3272. }
  3273. TAstNode* AutoParametrizeConst(TPgConst&& valueNType, TAstNode* pgType) {
  3274. const auto& paramName = AddSimpleAutoParam(std::move(valueNType));
  3275. State.Statements.push_back(L(A("declare"), A(paramName), pgType));
  3276. YQL_CLOG(INFO, Default) << "Autoparametrized " << paramName << " at " << State.Positions.back();
  3277. return A(paramName);
  3278. }
  3279. TAstNode* ParseAConst(const A_Const* value, const TExprSettings& settings) {
  3280. AT_LOCATION(value);
  3281. const auto& val = value->val;
  3282. auto valueNType = GetValueNType(value);
  3283. if (!valueNType) {
  3284. return nullptr;
  3285. }
  3286. TAstNode* pgTypeNode = !value->isnull
  3287. ? L(A("PgType"), QA(TPgConst::ToString(valueNType->type)))
  3288. : L(A("PgType"), QA("unknown"));
  3289. if (Settings.AutoParametrizeEnabled && settings.AutoParametrizeEnabled) {
  3290. return AutoParametrizeConst(std::move(valueNType.GetRef()), pgTypeNode);
  3291. }
  3292. if (value->isnull) {
  3293. return L(A("PgCast"), L(A("Null")), pgTypeNode);
  3294. }
  3295. switch (NodeTag(val)) {
  3296. case T_Integer:
  3297. case T_Float: {
  3298. return L(A("PgConst"), QA(valueNType->value.GetRef()), pgTypeNode);
  3299. }
  3300. case T_Boolean:
  3301. case T_String:
  3302. case T_BitString: {
  3303. return L(A("PgConst"), QAX(valueNType->value.GetRef()), pgTypeNode);
  3304. }
  3305. default: {
  3306. NodeNotImplemented((const Node*)value);
  3307. return nullptr;
  3308. }
  3309. }
  3310. }
  3311. TAstNode* ParseAArrayExpr(const A_ArrayExpr* value, const TExprSettings& settings) {
  3312. AT_LOCATION(value);
  3313. TVector<TAstNode*> args;
  3314. args.push_back(A("PgArray"));
  3315. for (int i = 0; i < ListLength(value->elements); ++i) {
  3316. auto elem = ParseExpr(ListNodeNth(value->elements, i), settings);
  3317. if (!elem) {
  3318. return nullptr;
  3319. }
  3320. args.push_back(elem);
  3321. }
  3322. return VL(args.data(), args.size());
  3323. }
  3324. TAstNode* ParseCoalesceExpr(const CoalesceExpr* value, const TExprSettings& settings) {
  3325. AT_LOCATION(value);
  3326. TVector<TAstNode*> args;
  3327. args.push_back(A("Coalesce"));
  3328. for (int i = 0; i < ListLength(value->args); ++i) {
  3329. auto elem = ParseExpr(ListNodeNth(value->args, i), settings);
  3330. if (!elem) {
  3331. return nullptr;
  3332. }
  3333. args.push_back(elem);
  3334. }
  3335. return VL(args.data(), args.size());
  3336. }
  3337. TAstNode* ParseGroupingFunc(const GroupingFunc* value) {
  3338. AT_LOCATION(value);
  3339. TVector<TAstNode*> args;
  3340. args.push_back(A("PgGrouping"));
  3341. TExprSettings settings;
  3342. settings.Scope = "GROUPING";
  3343. settings.AllowColumns = true;
  3344. for (int i = 0; i < ListLength(value->args); ++i) {
  3345. auto elem = ParseExpr(ListNodeNth(value->args, i), settings);
  3346. if (!elem) {
  3347. return nullptr;
  3348. }
  3349. args.push_back(elem);
  3350. }
  3351. return VL(args.data(), args.size());
  3352. }
  3353. TAstNode* ParseGroupingSet(const GroupingSet* value, const TExprSettings& settings) {
  3354. AT_LOCATION(value);
  3355. TString mode;
  3356. switch (value->kind) {
  3357. case GROUPING_SET_ROLLUP:
  3358. mode = "rollup";
  3359. break;
  3360. case GROUPING_SET_CUBE:
  3361. mode = "cube";
  3362. break;
  3363. case GROUPING_SET_SETS:
  3364. mode = "sets";
  3365. break;
  3366. default:
  3367. AddError(TStringBuilder() << "Unexpected grouping set kind: " << (int)value->kind);
  3368. return nullptr;
  3369. }
  3370. auto innerSettings = settings;
  3371. innerSettings.Scope = to_title(mode);
  3372. TVector<TAstNode*> args;
  3373. args.push_back(A("PgGroupingSet"));
  3374. args.push_back(QA(mode));
  3375. if (value->kind == GROUPING_SET_SETS) {
  3376. // tuple for each set
  3377. for (int i = 0; i < ListLength(value->content); ++i) {
  3378. auto child = ListNodeNth(value->content, i);
  3379. if (NodeTag(child) == T_GroupingSet) {
  3380. auto kind = CAST_NODE(GroupingSet, child)->kind;
  3381. if (kind != GROUPING_SET_EMPTY) {
  3382. AddError(TStringBuilder() << "Unexpected inner grouping set kind: " << (int)kind);
  3383. return nullptr;
  3384. }
  3385. args.push_back(QL());
  3386. continue;
  3387. }
  3388. if (NodeTag(child) == T_RowExpr) {
  3389. auto row = CAST_NODE(RowExpr, child);
  3390. TVector<TAstNode*> tupleItems;
  3391. for (int j = 0; j < ListLength(row->args); ++j) {
  3392. auto elem = ParseExpr(ListNodeNth(row->args, j), innerSettings);
  3393. if (!elem) {
  3394. return nullptr;
  3395. }
  3396. tupleItems.push_back(elem);
  3397. }
  3398. args.push_back(QVL(tupleItems.data(), tupleItems.size()));
  3399. continue;
  3400. }
  3401. auto elem = ParseExpr(ListNodeNth(value->content, i), innerSettings);
  3402. if (!elem) {
  3403. return nullptr;
  3404. }
  3405. args.push_back(QL(elem));
  3406. }
  3407. } else {
  3408. // one tuple
  3409. TVector<TAstNode*> tupleItems;
  3410. for (int i = 0; i < ListLength(value->content); ++i) {
  3411. auto elem = ParseExpr(ListNodeNth(value->content, i), innerSettings);
  3412. if (!elem) {
  3413. return nullptr;
  3414. }
  3415. tupleItems.push_back(elem);
  3416. }
  3417. args.push_back(QVL(tupleItems.data(), tupleItems.size()));
  3418. }
  3419. return VL(args.data(), args.size());
  3420. }
  3421. TAstNode* ParseSubLinkExpr(const SubLink* value, const TExprSettings& settings) {
  3422. AT_LOCATION(value);
  3423. if (!settings.AllowSubLinks) {
  3424. AddError(TStringBuilder() << "SubLinks are not allowed in: " << settings.Scope);
  3425. return nullptr;
  3426. }
  3427. TString linkType;
  3428. TString operName;
  3429. switch (value->subLinkType) {
  3430. case EXISTS_SUBLINK:
  3431. linkType = "exists";
  3432. break;
  3433. case ALL_SUBLINK:
  3434. linkType = "all";
  3435. operName = "=";
  3436. break;
  3437. case ANY_SUBLINK:
  3438. linkType = "any";
  3439. operName = "=";
  3440. break;
  3441. case EXPR_SUBLINK:
  3442. linkType = "expr";
  3443. break;
  3444. case ARRAY_SUBLINK:
  3445. linkType = "array";
  3446. break;
  3447. default:
  3448. AddError(TStringBuilder() << "SublinkExpr: unsupported link type: " << (int)value->subLinkType);
  3449. return nullptr;
  3450. }
  3451. if (ListLength(value->operName) > 1) {
  3452. AddError("SubLink: unsuppoted opername");
  3453. return nullptr;
  3454. } else if (ListLength(value->operName) == 1) {
  3455. auto nameNode = ListNodeNth(value->operName, 0);
  3456. if (NodeTag(nameNode) != T_String) {
  3457. NodeNotImplemented(value, nameNode);
  3458. return nullptr;
  3459. }
  3460. operName = StrVal(nameNode);
  3461. }
  3462. TAstNode* rowTest;
  3463. if (value->testexpr) {
  3464. TExprSettings localSettings = settings;
  3465. localSettings.Scope = "SUBLINK TEST";
  3466. auto test = ParseExpr(value->testexpr, localSettings);
  3467. if (!test) {
  3468. return nullptr;
  3469. }
  3470. rowTest = L(A("lambda"), QL(A("value")), L(A("PgOp"), QAX(operName), test, A("value")));
  3471. } else {
  3472. rowTest = L(A("Void"));
  3473. }
  3474. auto select = ParseSelectStmt(CAST_NODE(SelectStmt, value->subselect), {.Inner = true});
  3475. if (!select) {
  3476. return nullptr;
  3477. }
  3478. return L(A("PgSubLink"), QA(linkType), L(A("Void")), L(A("Void")), rowTest, L(A("lambda"), QL(), select));
  3479. }
  3480. TAstNode* ParseTableRangeFunction(const TString& name, const TString& schema, List* args) {
  3481. auto source = BuildClusterSinkOrSourceExpression(false, schema);
  3482. if (!source) {
  3483. return nullptr;
  3484. }
  3485. TVector<TString> argStrs;
  3486. for (int i = 0; i < ListLength(args); ++i) {
  3487. auto arg = ListNodeNth(args, i);
  3488. if (NodeTag(arg) == T_A_Const && (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String)) {
  3489. TString rawStr = StrVal(CAST_NODE(A_Const, arg)->val);
  3490. argStrs.push_back(rawStr);
  3491. } else {
  3492. AddError("Expected String argument for table function");
  3493. return nullptr;
  3494. }
  3495. }
  3496. if (argStrs.empty()) {
  3497. AddError("Expected at least one argument for table function");
  3498. return nullptr;
  3499. }
  3500. TAstNode* key;
  3501. auto lowerName = to_lower(name);
  3502. auto options = QL();
  3503. if (lowerName == "concat") {
  3504. TVector<TAstNode*> concatArgs;
  3505. concatArgs.push_back(A("MrTableConcat"));
  3506. for (const auto& s : argStrs) {
  3507. concatArgs.push_back(L(A("Key"), QL(QA("table"),L(A("String"), QAX(s)))));
  3508. }
  3509. key = VL(concatArgs);
  3510. } else if (lowerName == "concat_view") {
  3511. if (argStrs.size() % 2 != 0) {
  3512. AddError("Expected sequence of pairs of table and view for concat_view");
  3513. return nullptr;
  3514. }
  3515. TVector<TAstNode*> concatArgs;
  3516. concatArgs.push_back(A("MrTableConcat"));
  3517. for (ui32 i = 0; i < argStrs.size(); i += 2) {
  3518. concatArgs.push_back(L(A("Key"),
  3519. QL(QA("table"),L(A("String"), QAX(argStrs[i]))),
  3520. QL(QA("view"),L(A("String"), QAX(argStrs[i + 1])))));
  3521. }
  3522. key = VL(concatArgs);
  3523. } else if (lowerName == "range") {
  3524. if (argStrs.size() > 5) {
  3525. AddError("Too many arguments");
  3526. return nullptr;
  3527. }
  3528. options = QL(QL(QA("ignorenonexisting")));
  3529. TAstNode* expr;
  3530. if (argStrs.size() == 1) {
  3531. expr = L(A("Bool"),QA("true"));
  3532. } else if (argStrs.size() == 2) {
  3533. expr = L(A(">="),A("item"),L(A("String"),QAX(argStrs[1])));
  3534. } else {
  3535. expr = L(A("And"),
  3536. L(A(">="),A("item"),L(A("String"),QAX(argStrs[1]))),
  3537. L(A("<="),A("item"),L(A("String"),QAX(argStrs[2])))
  3538. );
  3539. }
  3540. auto lambda = L(A("lambda"), QL(A("item")), expr);
  3541. auto range = L(A("MrTableRange"), QAX(argStrs[0]), lambda, QAX(argStrs.size() < 4 ? "" : argStrs[3]));
  3542. if (argStrs.size() < 5) {
  3543. key = L(A("Key"), QL(QA("table"),range));
  3544. } else {
  3545. key = L(A("Key"), QL(QA("table"),range), QL(QA("view"),L(A("String"), QAX(argStrs[4]))));
  3546. }
  3547. } else if (lowerName == "regexp" || lowerName == "like") {
  3548. if (argStrs.size() < 2 || argStrs.size() > 4) {
  3549. AddError("Expected from 2 to 4 arguments");
  3550. return nullptr;
  3551. }
  3552. options = QL(QL(QA("ignorenonexisting")));
  3553. TAstNode* expr;
  3554. if (lowerName == "regexp") {
  3555. expr = L(A("Apply"),L(A("Udf"),QA("Re2.Grep"),
  3556. QL(L(A("String"),QAX(argStrs[1])),L(A("Null")))),
  3557. A("item"));
  3558. } else {
  3559. expr = L(A("Apply"),L(A("Udf"),QA("Re2.Match"),
  3560. QL(L(A("Apply"),
  3561. L(A("Udf"), QA("Re2.PatternFromLike")),
  3562. L(A("String"),QAX(argStrs[1]))),L(A("Null")))),
  3563. A("item"));
  3564. }
  3565. auto lambda = L(A("lambda"), QL(A("item")), expr);
  3566. auto range = L(A("MrTableRange"), QAX(argStrs[0]), lambda, QAX(argStrs.size() < 3 ? "" : argStrs[2]));
  3567. if (argStrs.size() < 4) {
  3568. key = L(A("Key"), QL(QA("table"),range));
  3569. } else {
  3570. key = L(A("Key"), QL(QA("table"),range), QL(QA("view"),L(A("String"), QAX(argStrs[3]))));
  3571. }
  3572. } else {
  3573. AddError(TStringBuilder() << "Unknown table function: " << name);
  3574. return nullptr;
  3575. }
  3576. return L(
  3577. A("Read!"),
  3578. A("world"),
  3579. source,
  3580. key,
  3581. L(A("Void")),
  3582. options
  3583. );
  3584. }
  3585. TAstNode* ParseFuncCall(const FuncCall* value, const TExprSettings& settings, bool rangeFunction, bool& injectRead) {
  3586. AT_LOCATION(value);
  3587. if (ListLength(value->agg_order) > 0) {
  3588. AddError("FuncCall: unsupported agg_order");
  3589. return nullptr;
  3590. }
  3591. if (value->agg_filter) {
  3592. AddError("FuncCall: unsupported agg_filter");
  3593. return nullptr;
  3594. }
  3595. if (value->agg_within_group) {
  3596. AddError("FuncCall: unsupported agg_within_group");
  3597. return nullptr;
  3598. }
  3599. if (value->func_variadic) {
  3600. AddError("FuncCall: unsupported func_variadic");
  3601. return nullptr;
  3602. }
  3603. TAstNode* window = nullptr;
  3604. if (value->over) {
  3605. if (!settings.AllowOver) {
  3606. AddError(TStringBuilder() << "Over is not allowed in: " << settings.Scope);
  3607. return nullptr;
  3608. }
  3609. if (StrLength(value->over->name)) {
  3610. window = QAX(value->over->name);
  3611. } else {
  3612. auto index = settings.WindowItems->size();
  3613. auto def = ParseWindowDef(value->over);
  3614. if (!def) {
  3615. return nullptr;
  3616. }
  3617. window = L(A("PgAnonWindow"), QA(ToString(index)));
  3618. settings.WindowItems->push_back(def);
  3619. }
  3620. }
  3621. TString name;
  3622. TString schema;
  3623. if (!ExtractFuncName(value, name, rangeFunction ? &schema : nullptr)) {
  3624. return nullptr;
  3625. }
  3626. if (rangeFunction && !schema.empty() && schema != "pg_catalog") {
  3627. injectRead = true;
  3628. return ParseTableRangeFunction(name, schema, value->args);
  3629. }
  3630. if (name == "shobj_description" || name == "obj_description") {
  3631. AddWarning(TIssuesIds::PG_COMPAT, name + " function forced to NULL");
  3632. return L(A("Null"));
  3633. }
  3634. if (name == "current_schema") {
  3635. return GetCurrentSchema();
  3636. }
  3637. // for zabbix https://github.com/ydb-platform/ydb/issues/2904
  3638. if (name == "pg_try_advisory_lock" || name == "pg_try_advisory_lock_shared" || name == "pg_advisory_unlock" || name == "pg_try_advisory_xact_lock" || name == "pg_try_advisory_xact_lock_shared"){
  3639. AddWarning(TIssuesIds::PG_COMPAT, name + " function forced to return OK without waiting and without really lock/unlock");
  3640. return L(A("PgConst"), QA("true"), L(A("PgType"), QA("bool")));
  3641. }
  3642. if (name == "pg_advisory_lock" || name == "pg_advisory_lock_shared" || name == "pg_advisory_unlock_all" || name == "pg_advisory_xact_lock" || name == "pg_advisory_xact_lock_shared"){
  3643. AddWarning(TIssuesIds::PG_COMPAT, name + " function forced to return OK without waiting and without really lock/unlock");
  3644. return L(A("Null"));
  3645. }
  3646. const bool isAggregateFunc = NYql::NPg::HasAggregation(name, NYql::NPg::EAggKind::Normal);
  3647. const bool hasReturnSet = NYql::NPg::HasReturnSetProc(name);
  3648. if (isAggregateFunc && !settings.AllowAggregates) {
  3649. AddError(TStringBuilder() << "Aggregate functions are not allowed in: " << settings.Scope);
  3650. return nullptr;
  3651. }
  3652. if (hasReturnSet && !settings.AllowReturnSet) {
  3653. AddError(TStringBuilder() << "Generator functions are not allowed in: " << settings.Scope);
  3654. return nullptr;
  3655. }
  3656. TVector<TAstNode*> args;
  3657. TString callable;
  3658. if (window) {
  3659. if (isAggregateFunc) {
  3660. callable = "PgAggWindowCall";
  3661. } else {
  3662. callable = "PgWindowCall";
  3663. }
  3664. } else {
  3665. if (isAggregateFunc) {
  3666. callable = "PgAgg";
  3667. } else {
  3668. callable = "PgCall";
  3669. }
  3670. }
  3671. args.push_back(A(callable));
  3672. args.push_back(QAX(name));
  3673. if (window) {
  3674. args.push_back(window);
  3675. }
  3676. TVector<TAstNode*> callSettings;
  3677. if (value->agg_distinct) {
  3678. if (!isAggregateFunc) {
  3679. AddError("FuncCall: agg_distinct must be set only for aggregate functions");
  3680. return nullptr;
  3681. }
  3682. callSettings.push_back(QL(QA("distinct")));
  3683. }
  3684. if (rangeFunction) {
  3685. callSettings.push_back(QL(QA("range")));
  3686. }
  3687. args.push_back(QVL(callSettings.data(), callSettings.size()));
  3688. if (value->agg_star) {
  3689. if (name != "count") {
  3690. AddError("FuncCall: * is expected only in count function");
  3691. return nullptr;
  3692. }
  3693. } else {
  3694. if (name == "count" && ListLength(value->args) == 0) {
  3695. AddError("FuncCall: count(*) must be used to call a parameterless aggregate function");
  3696. return nullptr;
  3697. }
  3698. bool hasError = false;
  3699. for (int i = 0; i < ListLength(value->args); ++i) {
  3700. auto x = ListNodeNth(value->args, i);
  3701. auto arg = ParseExpr(x, settings);
  3702. if (!arg) {
  3703. hasError = true;
  3704. continue;
  3705. }
  3706. args.push_back(arg);
  3707. }
  3708. if (hasError) {
  3709. return nullptr;
  3710. }
  3711. }
  3712. return VL(args.data(), args.size());
  3713. }
  3714. bool ExtractFuncName(const FuncCall* value, TString& name, TString* schemaName) {
  3715. TVector<TString> names;
  3716. for (int i = 0; i < ListLength(value->funcname); ++i) {
  3717. auto x = ListNodeNth(value->funcname, i);
  3718. if (NodeTag(x) != T_String) {
  3719. NodeNotImplemented(value, x);
  3720. return false;
  3721. }
  3722. names.push_back(to_lower(TString(StrVal(x))));
  3723. }
  3724. if (names.empty()) {
  3725. AddError("FuncCall: missing function name");
  3726. return false;
  3727. }
  3728. if (names.size() > 2) {
  3729. AddError(TStringBuilder() << "FuncCall: too many name components:: " << names.size());
  3730. return false;
  3731. }
  3732. if (names.size() == 2) {
  3733. if (!schemaName && names[0] != "pg_catalog") {
  3734. AddError(TStringBuilder() << "FuncCall: expected pg_catalog, but got: " << names[0]);
  3735. return false;
  3736. }
  3737. if (schemaName) {
  3738. *schemaName = names[0];
  3739. }
  3740. }
  3741. name = names.back();
  3742. return true;
  3743. }
  3744. TAstNode* ParseTypeCast(const TypeCast* value, const TExprSettings& settings) {
  3745. AT_LOCATION(value);
  3746. if (!value->arg) {
  3747. AddError("Expected arg");
  3748. return nullptr;
  3749. }
  3750. if (!value->typeName) {
  3751. AddError("Expected type_name");
  3752. return nullptr;
  3753. }
  3754. auto arg = value->arg;
  3755. auto typeName = value->typeName;
  3756. auto supportedTypeName = typeName->typeOid == 0 &&
  3757. !typeName->setof &&
  3758. !typeName->pct_type &&
  3759. (ListLength(typeName->names) == 2 &&
  3760. NodeTag(ListNodeNth(typeName->names, 0)) == T_String &&
  3761. !StrICompare(StrVal(ListNodeNth(typeName->names, 0)), "pg_catalog") || ListLength(typeName->names) == 1) &&
  3762. NodeTag(ListNodeNth(typeName->names, ListLength(typeName->names) - 1)) == T_String;
  3763. if (NodeTag(arg) == T_A_Const &&
  3764. (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String ||
  3765. CAST_NODE(A_Const, arg)->isnull) &&
  3766. supportedTypeName &&
  3767. typeName->typemod == -1 &&
  3768. ListLength(typeName->typmods) == 0 &&
  3769. ListLength(typeName->arrayBounds) == 0) {
  3770. TStringBuf targetType = StrVal(ListNodeNth(typeName->names, ListLength(typeName->names) - 1));
  3771. if (NodeTag(CAST_NODE(A_Const, arg)->val) == T_String && targetType == "bool") {
  3772. auto str = StrVal(CAST_NODE(A_Const, arg)->val);
  3773. return L(A("PgConst"), QAX(str), L(A("PgType"), QA("bool")));
  3774. }
  3775. }
  3776. if (supportedTypeName) {
  3777. AT_LOCATION(typeName);
  3778. TStringBuf targetType = StrVal(ListNodeNth(typeName->names, ListLength(typeName->names) - 1));
  3779. auto input = ParseExpr(arg, settings);
  3780. if (!input) {
  3781. return nullptr;
  3782. }
  3783. auto finalType = TString(targetType);
  3784. if (ListLength(typeName->arrayBounds) && !finalType.StartsWith('_')) {
  3785. finalType = "_" + finalType;
  3786. }
  3787. if (!NPg::HasType(finalType)) {
  3788. AddError(TStringBuilder() << "Unknown type: " << finalType);
  3789. return nullptr;
  3790. }
  3791. if (ListLength(typeName->typmods) == 0 && typeName->typemod == -1) {
  3792. return L(A("PgCast"), input, L(A("PgType"), QAX(finalType)));
  3793. } else {
  3794. const auto& typeDesc = NPg::LookupType(finalType);
  3795. ui32 typeModInFuncId;
  3796. if (typeDesc.ArrayTypeId == typeDesc.TypeId) {
  3797. const auto& typeDescElem = NPg::LookupType(typeDesc.ElementTypeId);
  3798. typeModInFuncId = typeDescElem.TypeModInFuncId;
  3799. } else {
  3800. typeModInFuncId = typeDesc.TypeModInFuncId;
  3801. }
  3802. if (!typeModInFuncId) {
  3803. AddError(TStringBuilder() << "Type " << finalType << " doesn't support modifiers");
  3804. return nullptr;
  3805. }
  3806. const auto& procDesc = NPg::LookupProc(typeModInFuncId);
  3807. TAstNode* typeMod;
  3808. if (typeName->typemod != -1) {
  3809. typeMod = L(A("PgConst"), QA(ToString(typeName->typemod)), L(A("PgType"), QA("int4")));
  3810. } else {
  3811. TVector<TAstNode*> args;
  3812. args.push_back(A("PgArray"));
  3813. for (int i = 0; i < ListLength(typeName->typmods); ++i) {
  3814. auto typeMod = ListNodeNth(typeName->typmods, i);
  3815. if (NodeTag(typeMod) != T_A_Const) {
  3816. AddError("Expected T_A_Const as typmod");
  3817. return nullptr;
  3818. }
  3819. auto aConst = CAST_NODE(A_Const, typeMod);
  3820. TString s;
  3821. if (!ValueAsString(aConst->val, aConst->isnull, s)) {
  3822. AddError("Unsupported format of typmod");
  3823. return nullptr;
  3824. }
  3825. args.push_back(L(A("PgConst"), QAX(s), L(A("PgType"), QA("cstring"))));
  3826. }
  3827. typeMod = L(A("PgCall"), QA(procDesc.Name), QL(), VL(args.data(), args.size()));
  3828. }
  3829. return L(A("PgCast"), input, L(A("PgType"), QAX(finalType)), typeMod);
  3830. }
  3831. }
  3832. AddError("Unsupported form of type cast");
  3833. return nullptr;
  3834. }
  3835. TAstNode* ParseAndOrExpr(const BoolExpr* value, const TExprSettings& settings, const TString& pgOpName) {
  3836. auto length = ListLength(value->args);
  3837. if (length < 2) {
  3838. AddError(TStringBuilder() << "Expected >1 args for " << pgOpName << " but have " << length << " args");
  3839. return nullptr;
  3840. }
  3841. auto lhs = ParseExpr(ListNodeNth(value->args, 0), settings);
  3842. if (!lhs) {
  3843. return nullptr;
  3844. }
  3845. for (auto i = 1; i < length; ++i) {
  3846. auto rhs = ParseExpr(ListNodeNth(value->args, i), settings);
  3847. if (!rhs) {
  3848. return nullptr;
  3849. }
  3850. lhs = L(A(pgOpName), lhs, rhs);
  3851. }
  3852. return lhs;
  3853. }
  3854. TAstNode* ParseBoolExpr(const BoolExpr* value, const TExprSettings& settings) {
  3855. AT_LOCATION(value);
  3856. switch (value->boolop) {
  3857. case AND_EXPR: {
  3858. return ParseAndOrExpr(value, settings, "PgAnd");
  3859. }
  3860. case OR_EXPR: {
  3861. return ParseAndOrExpr(value, settings, "PgOr");
  3862. }
  3863. case NOT_EXPR: {
  3864. if (ListLength(value->args) != 1) {
  3865. AddError("Expected 1 arg for NOT");
  3866. return nullptr;
  3867. }
  3868. auto arg = ParseExpr(ListNodeNth(value->args, 0), settings);
  3869. if (!arg) {
  3870. return nullptr;
  3871. }
  3872. return L(A("PgNot"), arg);
  3873. }
  3874. default:
  3875. AddError(TStringBuilder() << "BoolExprType unsupported value: " << (int)value->boolop);
  3876. return nullptr;
  3877. }
  3878. }
  3879. TAstNode* ParseWindowDef(const WindowDef* value) {
  3880. AT_LOCATION(value);
  3881. auto name = QAX(value->name);
  3882. auto refName = QAX(value->refname);
  3883. TVector<TAstNode*> sortItems;
  3884. for (int i = 0; i < ListLength(value->orderClause); ++i) {
  3885. auto node = ListNodeNth(value->orderClause, i);
  3886. if (NodeTag(node) != T_SortBy) {
  3887. NodeNotImplemented(value, node);
  3888. return nullptr;
  3889. }
  3890. auto sort = ParseSortBy(CAST_NODE_EXT(PG_SortBy, T_SortBy, node), true, false);
  3891. if (!sort) {
  3892. return nullptr;
  3893. }
  3894. sortItems.push_back(sort);
  3895. }
  3896. auto sort = QVL(sortItems.data(), sortItems.size());
  3897. TVector<TAstNode*> groupByItems;
  3898. for (int i = 0; i < ListLength(value->partitionClause); ++i) {
  3899. auto node = ListNodeNth(value->partitionClause, i);
  3900. TExprSettings settings;
  3901. settings.AllowColumns = true;
  3902. settings.AllowAggregates = true;
  3903. settings.Scope = "PARTITITON BY";
  3904. auto expr = ParseExpr(node, settings);
  3905. if (!expr) {
  3906. return nullptr;
  3907. }
  3908. auto lambda = L(A("lambda"), QL(), expr);
  3909. groupByItems.push_back(L(A("PgGroup"), L(A("Void")), lambda));
  3910. }
  3911. auto group = QVL(groupByItems.data(), groupByItems.size());
  3912. TVector<TAstNode*> optionItems;
  3913. if (value->frameOptions & FRAMEOPTION_NONDEFAULT) {
  3914. TString exclude;
  3915. if (value->frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) {
  3916. if (exclude) {
  3917. AddError("Wrong frame options");
  3918. return nullptr;
  3919. }
  3920. exclude = "c";
  3921. }
  3922. if (value->frameOptions & FRAMEOPTION_EXCLUDE_GROUP) {
  3923. if (exclude) {
  3924. AddError("Wrong frame options");
  3925. return nullptr;
  3926. }
  3927. exclude = "cp";
  3928. }
  3929. if (value->frameOptions & FRAMEOPTION_EXCLUDE_TIES) {
  3930. if (exclude) {
  3931. AddError("Wrong frame options");
  3932. return nullptr;
  3933. }
  3934. exclude = "p";
  3935. }
  3936. if (exclude) {
  3937. optionItems.push_back(QL(QA("exclude"), QA(exclude)));
  3938. }
  3939. TString type;
  3940. if (value->frameOptions & FRAMEOPTION_RANGE) {
  3941. if (type) {
  3942. AddError("Wrong frame options");
  3943. return nullptr;
  3944. }
  3945. type = "range";
  3946. }
  3947. if (value->frameOptions & FRAMEOPTION_ROWS) {
  3948. if (type) {
  3949. AddError("Wrong frame options");
  3950. return nullptr;
  3951. }
  3952. type = "rows";
  3953. }
  3954. if (value->frameOptions & FRAMEOPTION_GROUPS) {
  3955. if (type) {
  3956. AddError("Wrong frame options");
  3957. return nullptr;
  3958. }
  3959. type = "groups";
  3960. }
  3961. if (!type) {
  3962. AddError("Wrong frame options");
  3963. return nullptr;
  3964. }
  3965. TString from;
  3966. if (value->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
  3967. if (from) {
  3968. AddError("Wrong frame options");
  3969. return nullptr;
  3970. }
  3971. from = "up";
  3972. }
  3973. if (value->frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING) {
  3974. if (from) {
  3975. AddError("Wrong frame options");
  3976. return nullptr;
  3977. }
  3978. from = "p";
  3979. auto offset = ConvertFrameOffset(value->startOffset);
  3980. if (!offset) {
  3981. return nullptr;
  3982. }
  3983. optionItems.push_back(QL(QA("from_value"), offset));
  3984. }
  3985. if (value->frameOptions & FRAMEOPTION_START_CURRENT_ROW) {
  3986. if (from) {
  3987. AddError("Wrong frame options");
  3988. return nullptr;
  3989. }
  3990. from = "c";
  3991. }
  3992. if (value->frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING) {
  3993. if (from) {
  3994. AddError("Wrong frame options");
  3995. return nullptr;
  3996. }
  3997. from = "f";
  3998. auto offset = ConvertFrameOffset(value->startOffset);
  3999. if (!offset) {
  4000. return nullptr;
  4001. }
  4002. optionItems.push_back(QL(QA("from_value"), offset));
  4003. }
  4004. if (value->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) {
  4005. AddError("Wrong frame options");
  4006. return nullptr;
  4007. }
  4008. if (!from) {
  4009. AddError("Wrong frame options");
  4010. return nullptr;
  4011. }
  4012. TString to;
  4013. if (value->frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) {
  4014. AddError("Wrong frame options");
  4015. return nullptr;
  4016. }
  4017. if (value->frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING) {
  4018. if (to) {
  4019. AddError("Wrong frame options");
  4020. return nullptr;
  4021. }
  4022. to = "p";
  4023. auto offset = ConvertFrameOffset(value->endOffset);
  4024. if (!offset) {
  4025. return nullptr;
  4026. }
  4027. optionItems.push_back(QL(QA("to_value"), offset));
  4028. }
  4029. if (value->frameOptions & FRAMEOPTION_END_CURRENT_ROW) {
  4030. if (to) {
  4031. AddError("Wrong frame options");
  4032. return nullptr;
  4033. }
  4034. to = "c";
  4035. }
  4036. if (value->frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING) {
  4037. if (to) {
  4038. AddError("Wrong frame options");
  4039. return nullptr;
  4040. }
  4041. to = "f";
  4042. auto offset = ConvertFrameOffset(value->endOffset);
  4043. if (!offset) {
  4044. return nullptr;
  4045. }
  4046. optionItems.push_back(QL(QA("to_value"), offset));
  4047. }
  4048. if (value->frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
  4049. if (to) {
  4050. AddError("Wrong frame options");
  4051. return nullptr;
  4052. }
  4053. to = "uf";
  4054. }
  4055. if (!to) {
  4056. AddError("Wrong frame options");
  4057. return nullptr;
  4058. }
  4059. optionItems.push_back(QL(QA("type"), QAX(type)));
  4060. optionItems.push_back(QL(QA("from"), QAX(from)));
  4061. optionItems.push_back(QL(QA("to"), QAX(to)));
  4062. }
  4063. auto options = QVL(optionItems.data(), optionItems.size());
  4064. return L(A("PgWindow"), name, refName, group, sort, options);
  4065. }
  4066. TAstNode* ConvertFrameOffset(const Node* off) {
  4067. if (NodeTag(off) == T_A_Const
  4068. && NodeTag(CAST_NODE(A_Const, off)->val) == T_Integer) {
  4069. return L(A("Int32"), QA(ToString(IntVal(CAST_NODE(A_Const, off)->val))));
  4070. } else {
  4071. TExprSettings settings;
  4072. settings.AllowColumns = false;
  4073. settings.Scope = "FRAME";
  4074. auto offset = ParseExpr(off, settings);
  4075. if (!offset) {
  4076. return nullptr;
  4077. }
  4078. return L(A("EvaluateExpr"), L(A("Unwrap"), offset, L(A("String"), QA("Frame offset must be non-null"))));
  4079. }
  4080. }
  4081. TAstNode* ParseSortBy(const PG_SortBy* value, bool allowAggregates, bool useProjectionRefs) {
  4082. AT_LOCATION(value);
  4083. bool asc = true;
  4084. bool nullsFirst = true;
  4085. switch (value->sortby_dir) {
  4086. case SORTBY_DEFAULT:
  4087. case SORTBY_ASC:
  4088. if (Settings.PgSortNulls) {
  4089. nullsFirst = false;
  4090. }
  4091. break;
  4092. case SORTBY_DESC:
  4093. asc = false;
  4094. break;
  4095. default:
  4096. AddError(TStringBuilder() << "sortby_dir unsupported value: " << (int)value->sortby_dir);
  4097. return nullptr;
  4098. }
  4099. switch (value->sortby_nulls) {
  4100. case SORTBY_NULLS_DEFAULT:
  4101. break;
  4102. case SORTBY_NULLS_FIRST:
  4103. nullsFirst = true;
  4104. break;
  4105. case SORTBY_NULLS_LAST:
  4106. nullsFirst = false;
  4107. break;
  4108. default:
  4109. AddError(TStringBuilder() << "sortby_dir unsupported value: " << (int)value->sortby_dir);
  4110. return nullptr;
  4111. }
  4112. if (ListLength(value->useOp) > 0) {
  4113. AddError("Unsupported operators in sort_by");
  4114. return nullptr;
  4115. }
  4116. TAstNode* expr;
  4117. if (useProjectionRefs && NodeTag(value->node) == T_A_Const && (NodeTag(CAST_NODE(A_Const, value->node)->val) == T_Integer)) {
  4118. expr = MakeProjectionRef("ORDER BY", CAST_NODE(A_Const, value->node));
  4119. } else {
  4120. TExprSettings settings;
  4121. settings.AllowColumns = true;
  4122. settings.AllowSubLinks = true;
  4123. settings.Scope = "ORDER BY";
  4124. settings.AllowAggregates = allowAggregates;
  4125. expr = ParseExpr(value->node, settings);
  4126. }
  4127. if (!expr) {
  4128. return nullptr;
  4129. }
  4130. auto lambda = L(A("lambda"), QL(), expr);
  4131. return L(A("PgSort"), L(A("Void")), lambda, QA(asc ? "asc" : "desc"), QA(nullsFirst ? "first" : "last"));
  4132. }
  4133. TAstNode* ParseColumnRef(const ColumnRef* value, const TExprSettings& settings) {
  4134. AT_LOCATION(value);
  4135. if (!settings.AllowColumns) {
  4136. AddError(TStringBuilder() << "Columns are not allowed in: " << settings.Scope);
  4137. return nullptr;
  4138. }
  4139. if (ListLength(value->fields) == 0) {
  4140. AddError("No fields");
  4141. return nullptr;
  4142. }
  4143. if (ListLength(value->fields) > 2) {
  4144. AddError("Too many fields");
  4145. return nullptr;
  4146. }
  4147. bool isStar = false;
  4148. TVector<TString> fields;
  4149. for (int i = 0; i < ListLength(value->fields); ++i) {
  4150. auto x = ListNodeNth(value->fields, i);
  4151. if (isStar) {
  4152. AddError("Star is already defined");
  4153. return nullptr;
  4154. }
  4155. if (NodeTag(x) == T_String) {
  4156. fields.push_back(StrVal(x));
  4157. } else if (NodeTag(x) == T_A_Star) {
  4158. isStar = true;
  4159. } else {
  4160. NodeNotImplemented(value, x);
  4161. return nullptr;
  4162. }
  4163. }
  4164. if (isStar) {
  4165. if (fields.size() == 0) {
  4166. return L(A("PgStar"));
  4167. } else {
  4168. return L(A("PgQualifiedStar"), QAX(fields[0]));
  4169. }
  4170. } else if (fields.size() == 1) {
  4171. return L(A("PgColumnRef"), QAX(fields[0]));
  4172. } else {
  4173. return L(A("PgColumnRef"), QAX(fields[0]), QAX(fields[1]));
  4174. }
  4175. }
  4176. TAstNode* ParseAExprOp(const A_Expr* value, const TExprSettings& settings) {
  4177. AT_LOCATION(value);
  4178. if (ListLength(value->name) != 1) {
  4179. AddError(TStringBuilder() << "Unsupported count of names: " << ListLength(value->name));
  4180. return nullptr;
  4181. }
  4182. auto nameNode = ListNodeNth(value->name, 0);
  4183. if (NodeTag(nameNode) != T_String) {
  4184. NodeNotImplemented(value, nameNode);
  4185. return nullptr;
  4186. }
  4187. auto op = StrVal(nameNode);
  4188. if (!value->rexpr) {
  4189. AddError("Missing operands");
  4190. return nullptr;
  4191. }
  4192. if (!value->lexpr) {
  4193. auto rhs = ParseExpr(value->rexpr, settings);
  4194. if (!rhs) {
  4195. return nullptr;
  4196. }
  4197. return L(A("PgOp"), QAX(op), rhs);
  4198. }
  4199. auto lhs = ParseExpr(value->lexpr, settings);
  4200. auto rhs = ParseExpr(value->rexpr, settings);
  4201. if (!lhs || !rhs) {
  4202. return nullptr;
  4203. }
  4204. return L(A("PgOp"), QAX(op), lhs, rhs);
  4205. }
  4206. TAstNode* ParseAExprOpAnyAll(const A_Expr* value, const TExprSettings& settings, bool all) {
  4207. if (ListLength(value->name) != 1) {
  4208. AddError(TStringBuilder() << "Unsupported count of names: " << ListLength(value->name));
  4209. return nullptr;
  4210. }
  4211. auto nameNode = ListNodeNth(value->name, 0);
  4212. if (NodeTag(nameNode) != T_String) {
  4213. NodeNotImplemented(value, nameNode);
  4214. return nullptr;
  4215. }
  4216. auto op = StrVal(nameNode);
  4217. if (!value->lexpr || !value->rexpr) {
  4218. AddError("Missing operands");
  4219. return nullptr;
  4220. }
  4221. auto lhs = ParseExpr(value->lexpr, settings);
  4222. if (NodeTag(value->rexpr) == T_SubLink) {
  4223. auto sublink = CAST_NODE(SubLink, value->rexpr);
  4224. auto subselect = CAST_NODE(SelectStmt, sublink->subselect);
  4225. if (subselect->withClause && subselect->withClause->recursive) {
  4226. if (State.ApplicationName && State.ApplicationName->StartsWith("pgAdmin")) {
  4227. AddWarning(TIssuesIds::PG_COMPAT, "AEXPR_OP_ANY forced to false");
  4228. return L(A("PgConst"), QA("false"), L(A("PgType"), QA("bool")));
  4229. }
  4230. }
  4231. }
  4232. auto rhs = ParseExpr(value->rexpr, settings);
  4233. if (!lhs || !rhs) {
  4234. return nullptr;
  4235. }
  4236. return L(A(all ? "PgAllOp" : "PgAnyOp"), QAX(op), lhs, rhs);
  4237. }
  4238. TAstNode* ParseAExprLike(const A_Expr* value, const TExprSettings& settings, bool insensitive) {
  4239. if (ListLength(value->name) != 1) {
  4240. AddError(TStringBuilder() << "Unsupported count of names: " << ListLength(value->name));
  4241. return nullptr;
  4242. }
  4243. auto nameNode = ListNodeNth(value->name, 0);
  4244. if (NodeTag(nameNode) != T_String) {
  4245. NodeNotImplemented(value, nameNode);
  4246. return nullptr;
  4247. }
  4248. auto op = TString(StrVal(nameNode));
  4249. if (insensitive) {
  4250. if (op != "~~*" && op != "!~~*") {
  4251. AddError(TStringBuilder() << "Unsupported operation: " << op);
  4252. return nullptr;
  4253. }
  4254. } else {
  4255. if (op != "~~" && op != "!~~") {
  4256. AddError(TStringBuilder() << "Unsupported operation: " << op);
  4257. return nullptr;
  4258. }
  4259. }
  4260. if (!value->lexpr || !value->rexpr) {
  4261. AddError("Missing operands");
  4262. return nullptr;
  4263. }
  4264. auto lhs = ParseExpr(value->lexpr, settings);
  4265. auto rhs = ParseExpr(value->rexpr, settings);
  4266. if (!lhs || !rhs) {
  4267. return nullptr;
  4268. }
  4269. auto ret = L(A(insensitive ? "PgILike" : "PgLike"), lhs, rhs);
  4270. if (op[0] == '!') {
  4271. ret = L(A("PgNot"), ret);
  4272. }
  4273. return ret;
  4274. }
  4275. TAstNode* ParseAExprNullIf(const A_Expr* value, const TExprSettings& settings) {
  4276. if (ListLength(value->name) != 1) {
  4277. AddError(TStringBuilder() << "Unsupported count of names: " << ListLength(value->name));
  4278. return nullptr;
  4279. }
  4280. if (!value->lexpr || !value->rexpr) {
  4281. AddError("Missing operands");
  4282. return nullptr;
  4283. }
  4284. auto lhs = ParseExpr(value->lexpr, settings);
  4285. auto rhs = ParseExpr(value->rexpr, settings);
  4286. if (!lhs || !rhs) {
  4287. return nullptr;
  4288. }
  4289. return L(A("PgNullIf"), lhs, rhs);
  4290. }
  4291. TAstNode* ParseAExprIn(const A_Expr* value, const TExprSettings& settings) {
  4292. if (ListLength(value->name) != 1) {
  4293. AddError(TStringBuilder() << "Unsupported count of names: " << ListLength(value->name));
  4294. return nullptr;
  4295. }
  4296. auto nameNode = ListNodeNth(value->name, 0);
  4297. if (NodeTag(nameNode) != T_String) {
  4298. NodeNotImplemented(value, nameNode);
  4299. return nullptr;
  4300. }
  4301. auto op = TString(StrVal(nameNode));
  4302. if (op != "=" && op != "<>") {
  4303. AddError(TStringBuilder() << "Unsupported operation: " << op);
  4304. return nullptr;
  4305. }
  4306. if (!value->lexpr || !value->rexpr) {
  4307. AddError("Missing operands");
  4308. return nullptr;
  4309. }
  4310. auto lhs = ParseExpr(value->lexpr, settings);
  4311. if (!lhs) {
  4312. return nullptr;
  4313. }
  4314. if (NodeTag(value->rexpr) != T_List) {
  4315. NodeNotImplemented(value, value->rexpr);
  4316. return nullptr;
  4317. }
  4318. auto lst = CAST_NODE(List, value->rexpr);
  4319. TVector<TAstNode*> children;
  4320. children.reserve(2 + ListLength(lst));
  4321. children.push_back(A("PgIn"));
  4322. children.push_back(lhs);
  4323. for (int item = 0; item < ListLength(lst); ++item) {
  4324. auto cell = ParseExpr(ListNodeNth(lst, item), settings);
  4325. if (!cell) {
  4326. return nullptr;
  4327. }
  4328. children.push_back(cell);
  4329. }
  4330. auto ret = VL(children.data(), children.size());
  4331. if (op[0] == '<') {
  4332. ret = L(A("PgNot"), ret);
  4333. }
  4334. return ret;
  4335. }
  4336. TAstNode* ParseAExprBetween(const A_Expr* value, const TExprSettings& settings) {
  4337. if (!value->lexpr || !value->rexpr) {
  4338. AddError("Missing operands");
  4339. return nullptr;
  4340. }
  4341. if (NodeTag(value->rexpr) != T_List) {
  4342. AddError(TStringBuilder() << "Expected T_List tag, but have " << NodeTag(value->rexpr));
  4343. return nullptr;
  4344. }
  4345. const List* rexprList = CAST_NODE(List, value->rexpr);
  4346. if (ListLength(rexprList) != 2) {
  4347. AddError(TStringBuilder() << "Expected 2 args in BETWEEN range, but have " << ListLength(rexprList));
  4348. return nullptr;
  4349. }
  4350. auto b = ListNodeNth(rexprList, 0);
  4351. auto e = ListNodeNth(rexprList, 1);
  4352. auto lhs = ParseExpr(value->lexpr, settings);
  4353. auto rbhs = ParseExpr(b, settings);
  4354. auto rehs = ParseExpr(e, settings);
  4355. if (!lhs || !rbhs || !rehs) {
  4356. return nullptr;
  4357. }
  4358. A_Expr_Kind kind = value->kind;
  4359. bool inverse = false;
  4360. if (kind == AEXPR_NOT_BETWEEN) {
  4361. inverse = true;
  4362. kind = AEXPR_BETWEEN;
  4363. } else if (kind == AEXPR_NOT_BETWEEN_SYM) {
  4364. inverse = true;
  4365. kind = AEXPR_BETWEEN_SYM;
  4366. }
  4367. TAstNode* ret;
  4368. switch (kind) {
  4369. case AEXPR_BETWEEN:
  4370. case AEXPR_BETWEEN_SYM:
  4371. ret = L(A(kind == AEXPR_BETWEEN ? "PgBetween" : "PgBetweenSym"), lhs, rbhs, rehs);
  4372. break;
  4373. default:
  4374. AddError(TStringBuilder() << "BETWEEN kind unsupported value: " << (int)value->kind);
  4375. return nullptr;
  4376. }
  4377. if (inverse) {
  4378. ret = L(A("PgNot"), ret);
  4379. }
  4380. return ret;
  4381. }
  4382. TAstNode* ParseAExpr(const A_Expr* value, const TExprSettings& settings) {
  4383. AT_LOCATION(value);
  4384. switch (value->kind) {
  4385. case AEXPR_OP:
  4386. return ParseAExprOp(value, settings);
  4387. case AEXPR_LIKE:
  4388. case AEXPR_ILIKE:
  4389. return ParseAExprLike(value, settings, value->kind == AEXPR_ILIKE);
  4390. case AEXPR_IN:
  4391. return ParseAExprIn(value, settings);
  4392. case AEXPR_BETWEEN:
  4393. case AEXPR_NOT_BETWEEN:
  4394. case AEXPR_BETWEEN_SYM:
  4395. case AEXPR_NOT_BETWEEN_SYM:
  4396. return ParseAExprBetween(value, settings);
  4397. case AEXPR_OP_ANY:
  4398. case AEXPR_OP_ALL:
  4399. return ParseAExprOpAnyAll(value, settings, value->kind == AEXPR_OP_ALL);
  4400. case AEXPR_NULLIF:
  4401. return ParseAExprNullIf(value, settings);
  4402. default:
  4403. AddError(TStringBuilder() << "A_Expr_Kind unsupported value: " << (int)value->kind);
  4404. return nullptr;
  4405. }
  4406. }
  4407. void AddVariableDeclarations() {
  4408. for (const auto& [varName, typeName] : State.ParamNameToPgTypeName) {
  4409. const auto pgType = L(A("PgType"), QA(typeName));
  4410. State.Statements.push_back(L(A("declare"), A(varName), pgType));
  4411. }
  4412. }
  4413. template <typename T>
  4414. void NodeNotImplementedImpl(const Node* nodeptr) {
  4415. TStringBuilder b;
  4416. b << TypeName<T>() << ": ";
  4417. b << "alternative is not implemented yet : " << NodeTag(nodeptr);
  4418. AddError(b);
  4419. }
  4420. template <typename T>
  4421. void NodeNotImplemented(const T* outer, const Node* nodeptr) {
  4422. Y_UNUSED(outer);
  4423. NodeNotImplementedImpl<T>(nodeptr);
  4424. }
  4425. void NodeNotImplemented(const Node* nodeptr) {
  4426. TStringBuilder b;
  4427. b << "alternative is not implemented yet : " << NodeTag(nodeptr);
  4428. AddError(b);
  4429. }
  4430. TAstNode* VL(TAstNode** nodes, ui32 size, TPosition pos = {}) {
  4431. return TAstNode::NewList(pos.Row ? pos : State.Positions.back(), nodes, size, *AstParseResults[StatementId].Pool);
  4432. }
  4433. TAstNode* VL(TArrayRef<TAstNode*> nodes, TPosition pos = {}) {
  4434. return TAstNode::NewList(pos.Row ? pos : State.Positions.back(), nodes.data(), nodes.size(), *AstParseResults[StatementId].Pool);
  4435. }
  4436. TAstNode* QVL(TAstNode** nodes, ui32 size, TPosition pos = {}) {
  4437. return Q(VL(nodes, size, pos), pos);
  4438. }
  4439. TAstNode* QVL(TAstNode* node, TPosition pos = {}) {
  4440. return QVL(&node, 1, pos);
  4441. }
  4442. TAstNode* QVL(TArrayRef<TAstNode*> nodes, TPosition pos = {}) {
  4443. return Q(VL(nodes, pos), pos);
  4444. }
  4445. TAstNode* A(const TStringBuf str, TPosition pos = {}, ui32 flags = 0) {
  4446. return TAstNode::NewAtom(pos.Row ? pos : State.Positions.back(), str, *AstParseResults[StatementId].Pool, flags);
  4447. }
  4448. TAstNode* AX(const TString& str, TPosition pos = {}) {
  4449. return A(str, pos.Row ? pos : State.Positions.back(), TNodeFlags::ArbitraryContent);
  4450. }
  4451. TAstNode* Q(TAstNode* node, TPosition pos = {}) {
  4452. return L(A("quote", pos), node, pos);
  4453. }
  4454. TAstNode* QA(const TStringBuf str, TPosition pos = {}, ui32 flags = 0) {
  4455. return Q(A(str, pos, flags), pos);
  4456. }
  4457. TAstNode* QAX(const TString& str, TPosition pos = {}) {
  4458. return QA(str, pos, TNodeFlags::ArbitraryContent);
  4459. }
  4460. template <typename... TNodes>
  4461. TAstNode* L(TNodes... nodes) {
  4462. TLState state;
  4463. LImpl(state, nodes...);
  4464. return TAstNode::NewList(state.Position.Row ? state.Position : State.Positions.back(), state.Nodes.data(), state.Nodes.size(), *AstParseResults[StatementId].Pool);
  4465. }
  4466. template <typename... TNodes>
  4467. TAstNode* QL(TNodes... nodes) {
  4468. return Q(L(nodes...));
  4469. }
  4470. template <typename... TNodes>
  4471. TAstNode* E(TAstNode* list, TNodes... nodes) {
  4472. Y_ABORT_UNLESS(list->IsList());
  4473. TVector<TAstNode*> nodes_vec;
  4474. nodes_vec.reserve(list->GetChildrenCount() + sizeof...(nodes));
  4475. auto children = list->GetChildren();
  4476. if (children) {
  4477. nodes_vec.assign(children.begin(), children.end());
  4478. }
  4479. nodes_vec.assign({nodes...});
  4480. return VL(nodes_vec.data(), nodes_vec.size());
  4481. }
  4482. private:
  4483. void AddError(const TString& value) {
  4484. AstParseResults[StatementId].Issues.AddIssue(TIssue(State.Positions.back(), value));
  4485. }
  4486. void AddWarning(int code, const TString& value) {
  4487. AstParseResults[StatementId].Issues.AddIssue(TIssue(State.Positions.back(), value).SetCode(code, ESeverity::TSeverityIds_ESeverityId_S_WARNING));
  4488. }
  4489. struct TLState {
  4490. TPosition Position;
  4491. TVector<TAstNode*> Nodes;
  4492. };
  4493. template <typename... TNodes>
  4494. void LImpl(TLState& state, TNodes... nodes);
  4495. void LImpl(TLState& state) {
  4496. Y_UNUSED(state);
  4497. }
  4498. void LImpl(TLState& state, TPosition pos) {
  4499. state.Position = pos;
  4500. }
  4501. void LImpl(TLState& state, TAstNode* node) {
  4502. state.Nodes.push_back(node);
  4503. }
  4504. template <typename T, typename... TNodes>
  4505. void LImpl(TLState& state, T node, TNodes... nodes) {
  4506. state.Nodes.push_back(node);
  4507. LImpl(state, nodes...);
  4508. }
  4509. void PushPosition(int location) {
  4510. if (location == -1) {
  4511. State.Positions.push_back(State.Positions.back());
  4512. return;
  4513. }
  4514. State.Positions.push_back(Location2Position(location));
  4515. };
  4516. void PopPosition() {
  4517. State.Positions.pop_back();
  4518. }
  4519. NYql::TPosition Location2Position(int location) const {
  4520. if (!QuerySize) {
  4521. return NYql::TPosition(0, 0);
  4522. }
  4523. if (location < 0) {
  4524. return NYql::TPosition(0, 0);
  4525. }
  4526. auto it = LowerBound(RowStarts.begin(), RowStarts.end(), Min((ui32)location, QuerySize));
  4527. Y_ENSURE(it != RowStarts.end());
  4528. if (*it == (ui32)location) {
  4529. auto row = 1 + it - RowStarts.begin();
  4530. auto column = 1;
  4531. return NYql::TPosition(column, row);
  4532. } else {
  4533. Y_ENSURE(it != RowStarts.begin());
  4534. auto row = it - RowStarts.begin();
  4535. auto column = 1 + location - *(it - 1);
  4536. return NYql::TPosition(column, row);
  4537. }
  4538. }
  4539. void ScanRows(const TString& query) {
  4540. QuerySize = query.size();
  4541. RowStarts.push_back(0);
  4542. TPosition position(0, 1);
  4543. TTextWalker walker(position, true);
  4544. auto prevRow = position.Row;
  4545. for (ui32 i = 0; i < query.size(); ++i) {
  4546. walker.Advance(query[i]);
  4547. while (position.Row != prevRow) {
  4548. RowStarts.push_back(i);
  4549. ++prevRow;
  4550. }
  4551. }
  4552. RowStarts.push_back(QuerySize);
  4553. }
  4554. TAstNode* MakeProjectionRef(const TStringBuf& scope, const A_Const* aConst) {
  4555. AT_LOCATION(aConst);
  4556. auto num = IntVal(aConst->val);
  4557. if (num <= 0) {
  4558. AddError(TStringBuilder() << scope << ": position " << num << " is not in select list");
  4559. return nullptr;
  4560. }
  4561. return L(A("PgProjectionRef"), QA(ToString(num - 1)));
  4562. }
  4563. private:
  4564. TVector<TAstParseResult>& AstParseResults;
  4565. NSQLTranslation::TTranslationSettings Settings;
  4566. bool DqEngineEnabled = false;
  4567. bool DqEngineForce = false;
  4568. bool BlockEngineEnabled = false;
  4569. bool BlockEngineForce = false;
  4570. bool UnorderedResult = false;
  4571. TString TablePathPrefix;
  4572. TVector<ui32> RowStarts;
  4573. ui32 QuerySize;
  4574. TString Provider;
  4575. static const THashMap<TStringBuf, TString> ProviderToInsertModeMap;
  4576. TState State;
  4577. ui32 StatementId = 0;
  4578. TVector<TStmtParseInfo>* StmtParseInfo;
  4579. bool PerStatementResult;
  4580. TMaybe<ui32> SqlProcArgsCount;
  4581. bool HasSelectInLimitedView = false;
  4582. };
  4583. const THashMap<TStringBuf, TString> TConverter::ProviderToInsertModeMap = {
  4584. {NYql::KikimrProviderName, "insert_abort"},
  4585. {NYql::YtProviderName, "append"}
  4586. };
  4587. NYql::TAstParseResult PGToYql(const TString& query, const NSQLTranslation::TTranslationSettings& settings, TStmtParseInfo* stmtParseInfo) {
  4588. TVector<NYql::TAstParseResult> results;
  4589. TVector<TStmtParseInfo> stmtParseInfos;
  4590. TConverter converter(results, settings, query, &stmtParseInfos, false, Nothing());
  4591. NYql::PGParse(query, converter);
  4592. if (stmtParseInfo) {
  4593. Y_ENSURE(!stmtParseInfos.empty());
  4594. *stmtParseInfo = stmtParseInfos.back();
  4595. }
  4596. Y_ENSURE(!results.empty());
  4597. results.back().ActualSyntaxType = NYql::ESyntaxType::Pg;
  4598. return std::move(results.back());
  4599. }
  4600. TVector<NYql::TAstParseResult> PGToYqlStatements(const TString& query, const NSQLTranslation::TTranslationSettings& settings, TVector<TStmtParseInfo>* stmtParseInfo) {
  4601. TVector<NYql::TAstParseResult> results;
  4602. TConverter converter(results, settings, query, stmtParseInfo, true, Nothing());
  4603. NYql::PGParse(query, converter);
  4604. for (auto& res : results) {
  4605. res.ActualSyntaxType = NYql::ESyntaxType::Pg;
  4606. }
  4607. return results;
  4608. }
  4609. bool ParseTypeName(const PG_TypeName* typeName, TString& value, bool* setOf = nullptr) {
  4610. auto len = ListLength(typeName->names);
  4611. if (len < 1 || len > 2) {
  4612. return false;
  4613. }
  4614. if (len == 2) {
  4615. auto schemaStr = to_lower(TString(StrVal(ListNodeNth(typeName->names, 0))));
  4616. if (schemaStr != "pg_catalog") {
  4617. return false;
  4618. }
  4619. }
  4620. value = to_lower(TString(StrVal(ListNodeNth(typeName->names, len - 1))));
  4621. if (ListLength(typeName->arrayBounds) && !value.StartsWith('_')) {
  4622. value = "_" + value;
  4623. }
  4624. if (!setOf && typeName->setof) {
  4625. return false;
  4626. }
  4627. if (setOf) {
  4628. *setOf = typeName->setof;
  4629. }
  4630. return true;
  4631. }
  4632. bool ParseCreateFunctionStmtImpl(const CreateFunctionStmt* value, ui32 extensionIndex,
  4633. NPg::IExtensionSqlBuilder* builder, NYql::NPg::TProcDesc& desc) {
  4634. if (ListLength(value->funcname) != 1) {
  4635. return false;
  4636. }
  4637. auto nameNode = ListNodeNth(value->funcname, 0);
  4638. auto name = to_lower(TString(StrVal(nameNode)));
  4639. desc.ExtensionIndex = extensionIndex;
  4640. desc.Name = name;
  4641. desc.IsStrict = false;
  4642. if (value->returnType) {
  4643. TString resultTypeStr;
  4644. if (!ParseTypeName(value->returnType, resultTypeStr, &desc.ReturnSet)) {
  4645. return false;
  4646. }
  4647. if (builder) {
  4648. builder->PrepareType(extensionIndex, resultTypeStr);
  4649. }
  4650. desc.ResultType = NPg::LookupType(resultTypeStr).TypeId;
  4651. } else {
  4652. desc.ResultType = NPg::LookupType("record").TypeId;
  4653. }
  4654. for (ui32 pass = 0; pass < 2; ++pass) {
  4655. for (int i = 0; i < ListLength(value->options); ++i) {
  4656. auto node = LIST_CAST_NTH(DefElem, value->options, i);
  4657. TString defnameStr(node->defname);
  4658. if (pass == 1 && defnameStr == "as") {
  4659. auto asList = CAST_NODE(List, node->arg);
  4660. auto asListLen = ListLength(asList);
  4661. if (desc.Lang == NPg::LangC) {
  4662. if (asListLen < 1 || asListLen > 2) {
  4663. return false;
  4664. }
  4665. auto extStr = TString(StrVal(ListNodeNth(asList, 0)));
  4666. auto srcStr = asListLen > 1 ?
  4667. TString(StrVal(ListNodeNth(asList, 1))) :
  4668. name;
  4669. Y_ENSURE(extensionIndex == NPg::LookupExtensionByInstallName(extStr));
  4670. desc.Src = srcStr;
  4671. } else if (desc.Lang == NPg::LangInternal || desc.Lang == NPg::LangSQL) {
  4672. if (asListLen != 1) {
  4673. return false;
  4674. }
  4675. auto srcStr = TString(StrVal(ListNodeNth(asList, 0)));
  4676. desc.Src = srcStr;
  4677. }
  4678. } else if (pass == 0 && defnameStr == "strict") {
  4679. desc.IsStrict = BoolVal(node->arg);
  4680. } else if (pass == 0 && defnameStr == "language") {
  4681. auto langStr = to_lower(TString(StrVal(node->arg)));
  4682. if (langStr == "c") {
  4683. desc.Lang = NPg::LangC;
  4684. } else if (extensionIndex == 0 && langStr == "internal") {
  4685. desc.Lang = NPg::LangInternal;
  4686. } else if (langStr == "sql") {
  4687. desc.Lang = NPg::LangSQL;
  4688. } else {
  4689. return false;
  4690. }
  4691. }
  4692. }
  4693. }
  4694. bool hasArgNames = false;
  4695. for (int i = 0; i < ListLength(value->parameters); ++i) {
  4696. auto node = LIST_CAST_NTH(FunctionParameter, value->parameters, i);
  4697. hasArgNames = hasArgNames || (node->name != nullptr);
  4698. if (node->mode == FUNC_PARAM_IN || node->mode == FUNC_PARAM_DEFAULT) {
  4699. if (node->defexpr) {
  4700. desc.DefaultArgs.emplace_back();
  4701. auto& value = desc.DefaultArgs.back();
  4702. auto expr = node->defexpr;
  4703. if (NodeTag(expr) == T_TypeCast) {
  4704. expr = CAST_NODE(TypeCast, expr)->arg;
  4705. }
  4706. if (NodeTag(expr) != T_A_Const) {
  4707. return false;
  4708. }
  4709. auto pgConst = GetValueNType(CAST_NODE(A_Const, expr));
  4710. if (!pgConst) {
  4711. return false;
  4712. }
  4713. value = pgConst->value;
  4714. } else {
  4715. Y_ENSURE(desc.DefaultArgs.empty());
  4716. }
  4717. desc.InputArgNames.push_back(node->name ? node->name : "");
  4718. } else if (node->mode == FUNC_PARAM_OUT) {
  4719. desc.OutputArgNames.push_back(node->name ? node->name : "");
  4720. } else if (node->mode == FUNC_PARAM_VARIADIC) {
  4721. desc.VariadicArgName = node->name ? node->name : "";
  4722. } else {
  4723. return false;
  4724. }
  4725. TString argTypeStr;
  4726. if (!ParseTypeName(node->argType, argTypeStr)) {
  4727. return false;
  4728. }
  4729. if (builder) {
  4730. builder->PrepareType(extensionIndex, argTypeStr);
  4731. }
  4732. const auto& argTypeDesc = NPg::LookupType(argTypeStr);
  4733. if (node->mode == FUNC_PARAM_IN || node->mode == FUNC_PARAM_DEFAULT) {
  4734. desc.ArgTypes.push_back(argTypeDesc.TypeId);
  4735. } else if (node->mode == FUNC_PARAM_VARIADIC) {
  4736. desc.VariadicType = (argTypeDesc.ArrayTypeId == argTypeDesc.TypeId) ? argTypeDesc.ElementTypeId : argTypeDesc.TypeId;
  4737. desc.VariadicArgType = argTypeDesc.TypeId;
  4738. } else if (node->mode == FUNC_PARAM_OUT) {
  4739. desc.OutputArgTypes.push_back(argTypeDesc.TypeId);
  4740. }
  4741. }
  4742. if (!hasArgNames) {
  4743. desc.InputArgNames.clear();
  4744. desc.VariadicArgName.clear();
  4745. desc.OutputArgNames.clear();
  4746. }
  4747. if (desc.Lang == NPg::LangSQL) {
  4748. auto parser = NPg::GetSqlLanguageParser();
  4749. if (!value->sql_body) {
  4750. if (parser) {
  4751. parser->Parse(desc.Src, desc);
  4752. } else {
  4753. return false;
  4754. }
  4755. } else {
  4756. if (parser) {
  4757. parser->ParseNode(value->sql_body, desc);
  4758. } else {
  4759. return false;
  4760. }
  4761. }
  4762. if (!desc.ExprNode) {
  4763. return false;
  4764. }
  4765. }
  4766. return true;
  4767. }
  4768. class TExtensionHandler : public IPGParseEvents {
  4769. public:
  4770. TExtensionHandler(ui32 extensionIndex, NYql::NPg::IExtensionSqlBuilder& builder)
  4771. : ExtensionIndex(extensionIndex)
  4772. , Builder(builder)
  4773. {}
  4774. void OnResult(const List* raw) final {
  4775. for (int i = 0; i < ListLength(raw); ++i) {
  4776. if (!ParseRawStmt(LIST_CAST_NTH(RawStmt, raw, i))) {
  4777. continue;
  4778. }
  4779. }
  4780. }
  4781. void OnError(const TIssue& issue) final {
  4782. throw yexception() << "Can't parse extension DDL: " << issue.ToString();
  4783. }
  4784. [[nodiscard]]
  4785. bool ParseRawStmt(const RawStmt* value) {
  4786. auto node = value->stmt;
  4787. switch (NodeTag(node)) {
  4788. case T_CreateFunctionStmt:
  4789. return ParseCreateFunctionStmt(CAST_NODE(CreateFunctionStmt, node));
  4790. case T_DefineStmt:
  4791. return ParseDefineStmt(CAST_NODE(DefineStmt, node));
  4792. case T_CreateStmt:
  4793. return ParseCreateStmt(CAST_NODE(CreateStmt, node));
  4794. case T_InsertStmt:
  4795. return ParseInsertStmt(CAST_NODE(InsertStmt, node));
  4796. case T_CreateCastStmt:
  4797. return ParseCreateCastStmt(CAST_NODE(CreateCastStmt, node));
  4798. case T_CreateOpClassStmt:
  4799. return ParseCreateOpClassStmt(CAST_NODE(CreateOpClassStmt, node));
  4800. default:
  4801. return false;
  4802. }
  4803. }
  4804. [[nodiscard]]
  4805. bool ParseDefineStmt(const DefineStmt* value) {
  4806. switch (value->kind) {
  4807. case OBJECT_TYPE:
  4808. return ParseDefineType(value);
  4809. case OBJECT_OPERATOR:
  4810. return ParseDefineOperator(value);
  4811. case OBJECT_AGGREGATE:
  4812. return ParseDefineAggregate(value);
  4813. default:
  4814. return false;
  4815. }
  4816. }
  4817. [[nodiscard]]
  4818. bool ParseDefineType(const DefineStmt* value) {
  4819. if (ListLength(value->defnames) != 1) {
  4820. return false;
  4821. }
  4822. auto nameNode = ListNodeNth(value->defnames, 0);
  4823. auto name = to_lower(TString(StrVal(nameNode)));
  4824. Builder.PrepareType(ExtensionIndex, name);
  4825. NPg::TTypeDesc desc = NPg::LookupType(name);
  4826. for (int i = 0; i < ListLength(value->definition); ++i) {
  4827. auto node = LIST_CAST_NTH(DefElem, value->definition, i);
  4828. auto defnameStr = to_lower(TString(node->defname));
  4829. if (defnameStr == "internallength") {
  4830. if (NodeTag(node->arg) == T_Integer) {
  4831. desc.TypeLen = IntVal(node->arg);
  4832. } else if (NodeTag(node->arg) == T_TypeName) {
  4833. TString value;
  4834. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4835. return false;
  4836. }
  4837. if (value == "variable") {
  4838. desc.TypeLen = -1;
  4839. } else {
  4840. return false;
  4841. }
  4842. } else {
  4843. return false;
  4844. }
  4845. } else if (defnameStr == "alignment") {
  4846. if (NodeTag(node->arg) != T_TypeName) {
  4847. return false;
  4848. }
  4849. TString value;
  4850. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4851. return false;
  4852. }
  4853. if (value == "double") {
  4854. desc.TypeAlign = 'd';
  4855. } else if (value == "int") {
  4856. desc.TypeAlign = 'i';
  4857. } else if (value == "short") {
  4858. desc.TypeAlign = 's';
  4859. } else if (value == "char") {
  4860. desc.TypeAlign = 'c';
  4861. } else {
  4862. throw yexception() << "Unsupported alignment: " << value;
  4863. }
  4864. } else if (defnameStr == "input") {
  4865. if (NodeTag(node->arg) != T_TypeName) {
  4866. return false;
  4867. }
  4868. TString value;
  4869. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4870. return false;
  4871. }
  4872. try {
  4873. desc.InFuncId = NPg::LookupProc(value, {NPg::LookupType("cstring").TypeId}).ProcId;
  4874. } catch (const yexception&) {
  4875. desc.InFuncId = NPg::LookupProc(value, {
  4876. NPg::LookupType("cstring").TypeId,
  4877. NPg::LookupType("oid").TypeId,
  4878. NPg::LookupType("integer").TypeId
  4879. }).ProcId;
  4880. }
  4881. } else if (defnameStr == "output") {
  4882. if (NodeTag(node->arg) != T_TypeName) {
  4883. return false;
  4884. }
  4885. TString value;
  4886. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4887. return false;
  4888. }
  4889. desc.OutFuncId = NPg::LookupProc(value, {desc.TypeId}).ProcId;
  4890. } else if (defnameStr == "send") {
  4891. if (NodeTag(node->arg) != T_TypeName) {
  4892. return false;
  4893. }
  4894. TString value;
  4895. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4896. return false;
  4897. }
  4898. desc.SendFuncId = NPg::LookupProc(value, {desc.TypeId}).ProcId;
  4899. } else if (defnameStr == "receive") {
  4900. if (NodeTag(node->arg) != T_TypeName) {
  4901. return false;
  4902. }
  4903. TString value;
  4904. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4905. return false;
  4906. }
  4907. try {
  4908. desc.ReceiveFuncId = NPg::LookupProc(value, {NPg::LookupType("internal").TypeId}).ProcId;
  4909. } catch (const yexception&) {
  4910. desc.ReceiveFuncId = NPg::LookupProc(value, {
  4911. NPg::LookupType("internal").TypeId,
  4912. NPg::LookupType("oid").TypeId,
  4913. NPg::LookupType("integer").TypeId
  4914. }).ProcId;
  4915. }
  4916. } else if (defnameStr == "delimiter") {
  4917. if (NodeTag(node->arg) != T_String) {
  4918. return false;
  4919. }
  4920. TString value(StrVal(node->arg));
  4921. Y_ENSURE(value.size() == 1);
  4922. desc.TypeDelim = value[0];
  4923. } else if (defnameStr == "typmod_in") {
  4924. if (NodeTag(node->arg) != T_TypeName) {
  4925. return false;
  4926. }
  4927. TString value;
  4928. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4929. return false;
  4930. }
  4931. desc.TypeModInFuncId = NPg::LookupProc(value, {NPg::LookupType("_cstring").TypeId}).ProcId;
  4932. } else if (defnameStr == "typmod_out") {
  4933. if (NodeTag(node->arg) != T_TypeName) {
  4934. return false;
  4935. }
  4936. TString value;
  4937. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4938. return false;
  4939. }
  4940. desc.TypeModInFuncId = NPg::LookupProc(value, {NPg::LookupType("int4").TypeId}).ProcId;
  4941. }
  4942. }
  4943. if (desc.TypeLen >= 0 && desc.TypeLen <= 8) {
  4944. desc.PassByValue = true;
  4945. }
  4946. Builder.UpdateType(desc);
  4947. return true;
  4948. }
  4949. [[nodiscard]]
  4950. bool ParseDefineOperator(const DefineStmt* value) {
  4951. if (ListLength(value->defnames) != 1) {
  4952. return false;
  4953. }
  4954. auto nameNode = ListNodeNth(value->defnames, 0);
  4955. auto name = to_lower(TString(StrVal(nameNode)));
  4956. TString procedureName;
  4957. TString commutator;
  4958. TString negator;
  4959. ui32 leftType = 0;
  4960. ui32 rightType = 0;
  4961. for (int i = 0; i < ListLength(value->definition); ++i) {
  4962. auto node = LIST_CAST_NTH(DefElem, value->definition, i);
  4963. auto defnameStr = to_lower(TString(node->defname));
  4964. if (defnameStr == "leftarg") {
  4965. if (NodeTag(node->arg) != T_TypeName) {
  4966. return false;
  4967. }
  4968. TString value;
  4969. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4970. return false;
  4971. }
  4972. leftType = NPg::LookupType(value).TypeId;
  4973. } else if (defnameStr == "rightarg") {
  4974. if (NodeTag(node->arg) != T_TypeName) {
  4975. return false;
  4976. }
  4977. TString value;
  4978. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4979. return false;
  4980. }
  4981. rightType = NPg::LookupType(value).TypeId;
  4982. } else if (defnameStr == "procedure") {
  4983. if (NodeTag(node->arg) != T_TypeName) {
  4984. return false;
  4985. }
  4986. TString value;
  4987. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  4988. return false;
  4989. }
  4990. procedureName = value;
  4991. } else if (defnameStr == "commutator") {
  4992. if (NodeTag(node->arg) != T_String) {
  4993. return false;
  4994. }
  4995. commutator = StrVal(node->arg);
  4996. } else if (defnameStr == "negator") {
  4997. if (NodeTag(node->arg) != T_String) {
  4998. return false;
  4999. }
  5000. negator = StrVal(node->arg);
  5001. }
  5002. }
  5003. if (!leftType) {
  5004. return false;
  5005. }
  5006. if (procedureName.empty()) {
  5007. return false;
  5008. }
  5009. TVector<ui32> args;
  5010. args.push_back(leftType);
  5011. if (rightType) {
  5012. args.push_back(rightType);
  5013. }
  5014. Builder.PrepareOper(ExtensionIndex, name, args);
  5015. auto desc = NPg::LookupOper(name, args);
  5016. if (!commutator.empty()) {
  5017. TVector<ui32> commArgs;
  5018. commArgs.push_back(rightType);
  5019. commArgs.push_back(leftType);
  5020. Builder.PrepareOper(ExtensionIndex, commutator, commArgs);
  5021. desc.ComId = NPg::LookupOper(commutator, commArgs).OperId;
  5022. }
  5023. if (!negator.empty()) {
  5024. Builder.PrepareOper(ExtensionIndex, negator, args);
  5025. desc.NegateId = NPg::LookupOper(negator, args).OperId;
  5026. }
  5027. const auto& procDesc = NPg::LookupProc(procedureName, args);
  5028. desc.ProcId = procDesc.ProcId;
  5029. desc.ResultType = procDesc.ResultType;
  5030. Builder.UpdateOper(desc);
  5031. return true;
  5032. }
  5033. [[nodiscard]]
  5034. bool ParseDefineAggregate(const DefineStmt* value) {
  5035. if (ListLength(value->defnames) != 1) {
  5036. return false;
  5037. }
  5038. auto nameNode = ListNodeNth(value->defnames, 0);
  5039. auto name = to_lower(TString(StrVal(nameNode)));
  5040. TString sfunc;
  5041. ui32 stype = 0;
  5042. TString combinefunc;
  5043. TString finalfunc;
  5044. TString serialfunc;
  5045. TString deserialfunc;
  5046. bool hypothetical = false;
  5047. for (int i = 0; i < ListLength(value->definition); ++i) {
  5048. auto node = LIST_CAST_NTH(DefElem, value->definition, i);
  5049. auto defnameStr = to_lower(TString(node->defname));
  5050. if (defnameStr == "sfunc") {
  5051. if (NodeTag(node->arg) != T_TypeName) {
  5052. return false;
  5053. }
  5054. TString value;
  5055. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  5056. return false;
  5057. }
  5058. sfunc = value;
  5059. } else if (defnameStr == "stype") {
  5060. if (NodeTag(node->arg) != T_TypeName) {
  5061. return false;
  5062. }
  5063. TString value;
  5064. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  5065. return false;
  5066. }
  5067. stype = NPg::LookupType(value).TypeId;
  5068. } else if (defnameStr == "combinefunc") {
  5069. if (NodeTag(node->arg) != T_TypeName) {
  5070. return false;
  5071. }
  5072. TString value;
  5073. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  5074. return false;
  5075. }
  5076. combinefunc = value;
  5077. } else if (defnameStr == "finalfunc") {
  5078. if (NodeTag(node->arg) != T_TypeName) {
  5079. return false;
  5080. }
  5081. TString value;
  5082. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  5083. return false;
  5084. }
  5085. finalfunc = value;
  5086. } else if (defnameStr == "serialfunc") {
  5087. if (NodeTag(node->arg) != T_TypeName) {
  5088. return false;
  5089. }
  5090. TString value;
  5091. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  5092. return false;
  5093. }
  5094. serialfunc = value;
  5095. } else if (defnameStr == "deserialfunc") {
  5096. if (NodeTag(node->arg) != T_TypeName) {
  5097. return false;
  5098. }
  5099. TString value;
  5100. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node->arg), value)) {
  5101. return false;
  5102. }
  5103. deserialfunc = value;
  5104. } else if (defnameStr == "hypothetical") {
  5105. if (NodeTag(node->arg) != T_Boolean) {
  5106. return false;
  5107. }
  5108. if (BoolVal(node->arg)) {
  5109. hypothetical = true;
  5110. }
  5111. }
  5112. }
  5113. if (!sfunc || !stype) {
  5114. return false;
  5115. }
  5116. NPg::TAggregateDesc desc;
  5117. desc.Name = name;
  5118. desc.ExtensionIndex = ExtensionIndex;
  5119. if (ListLength(value->args) != 2) {
  5120. return false;
  5121. }
  5122. auto numDirectArgs = intVal(lsecond(value->args));
  5123. if (numDirectArgs >= 0) {
  5124. desc.NumDirectArgs = numDirectArgs;
  5125. desc.Kind = NPg::EAggKind::OrderedSet;
  5126. Y_ENSURE(!hypothetical);
  5127. } else if (hypothetical) {
  5128. desc.Kind = NPg::EAggKind::Hypothetical;
  5129. }
  5130. auto args = linitial_node(List, value->args);
  5131. for (int i = 0; i < ListLength(args); ++i) {
  5132. auto node = LIST_CAST_NTH(FunctionParameter, args, i);
  5133. if (node->mode == FUNC_PARAM_IN || node->mode == FUNC_PARAM_DEFAULT) {
  5134. if (node->defexpr) {
  5135. return false;
  5136. }
  5137. } else {
  5138. return false;
  5139. }
  5140. TString argTypeStr;
  5141. if (!ParseTypeName(node->argType, argTypeStr)) {
  5142. return false;
  5143. }
  5144. Builder.PrepareType(ExtensionIndex, argTypeStr);
  5145. auto argTypeId = NPg::LookupType(argTypeStr).TypeId;
  5146. desc.ArgTypes.push_back(argTypeId);
  5147. }
  5148. desc.TransTypeId = stype;
  5149. TVector<ui32> stateWithArgs;
  5150. stateWithArgs.push_back(stype);
  5151. stateWithArgs.insert(stateWithArgs.end(), desc.ArgTypes.begin(), desc.ArgTypes.end());
  5152. desc.TransFuncId = NPg::LookupProc(sfunc, stateWithArgs).ProcId;
  5153. if (!finalfunc.empty()) {
  5154. desc.FinalFuncId = NPg::LookupProc(finalfunc, { stype }).ProcId;
  5155. }
  5156. if (!combinefunc.empty()) {
  5157. desc.CombineFuncId = NPg::LookupProc(combinefunc, { stype, stype }).ProcId;
  5158. }
  5159. if (!serialfunc.empty()) {
  5160. const auto& procDesc = NPg::LookupProc(serialfunc, { stype });
  5161. Y_ENSURE(procDesc.ResultType == NPg::LookupType("bytea").TypeId);
  5162. desc.SerializeFuncId = procDesc.ProcId;
  5163. }
  5164. if (!deserialfunc.empty()) {
  5165. Y_ENSURE(!serialfunc.empty());
  5166. const auto& procDesc = NPg::LookupProc(deserialfunc, { NPg::LookupType("bytea").TypeId, stype });
  5167. Y_ENSURE(procDesc.ResultType == stype);
  5168. desc.DeserializeFuncId = procDesc.ProcId;
  5169. }
  5170. Builder.CreateAggregate(desc);
  5171. return true;
  5172. }
  5173. [[nodiscard]]
  5174. bool ParseCreateFunctionStmt(const CreateFunctionStmt* value) {
  5175. NYql::NPg::TProcDesc desc;
  5176. if (!ParseCreateFunctionStmtImpl(value, ExtensionIndex, &Builder, desc)) {
  5177. return false;
  5178. }
  5179. Builder.CreateProc(desc);
  5180. return true;
  5181. }
  5182. [[nodiscard]]
  5183. bool ParseCreateStmt(const CreateStmt* value) {
  5184. NPg::TTableInfo table;
  5185. table.Schema = "pg_catalog";
  5186. table.Name = value->relation->relname;
  5187. table.Kind = NPg::ERelKind::Relation;
  5188. table.ExtensionIndex = ExtensionIndex;
  5189. TVector<NPg::TColumnInfo> columns;
  5190. for (int i = 0; i < ListLength(value->tableElts); ++i) {
  5191. auto node = ListNodeNth(value->tableElts, i);
  5192. if (NodeTag(node) != T_ColumnDef) {
  5193. continue;
  5194. }
  5195. auto columnDef = CAST_NODE(ColumnDef, node);
  5196. NPg::TColumnInfo column;
  5197. column.Schema = table.Schema;
  5198. column.TableName = table.Name;
  5199. column.Name = columnDef->colname;
  5200. column.ExtensionIndex = ExtensionIndex;
  5201. Y_ENSURE(ParseTypeName(columnDef->typeName, column.UdtType));
  5202. columns.push_back(column);
  5203. }
  5204. Builder.CreateTable(table, columns);
  5205. return true;
  5206. }
  5207. [[nodiscard]]
  5208. bool ParseInsertStmt(const InsertStmt* value) {
  5209. TString tableName = value->relation->relname;
  5210. TVector<TString> colNames;
  5211. for (int i = 0; i < ListLength(value->cols); ++i) {
  5212. auto node = LIST_CAST_NTH(ResTarget, value->cols, i);
  5213. colNames.push_back(node->name);
  5214. }
  5215. auto select = CAST_NODE(SelectStmt, value->selectStmt);
  5216. int rows = ListLength(select->valuesLists);
  5217. if (!rows) {
  5218. return false;
  5219. }
  5220. int cols = ListLength(CAST_NODE(List, ListNodeNth(select->valuesLists, 0)));
  5221. TVector<TMaybe<TString>> data;
  5222. data.reserve(rows * cols);
  5223. for (int rowIdx = 0; rowIdx < rows; ++rowIdx) {
  5224. const auto rawRow = CAST_NODE(List, ListNodeNth(select->valuesLists, rowIdx));
  5225. for (int colIdx = 0; colIdx < ListLength(rawRow); ++colIdx) {
  5226. const auto rawCell = ListNodeNth(rawRow, colIdx);
  5227. if (NodeTag(rawCell) != T_A_Const) {
  5228. return false;
  5229. }
  5230. auto pgConst = GetValueNType(CAST_NODE(A_Const, rawCell));
  5231. if (!pgConst) {
  5232. return false;
  5233. }
  5234. data.push_back(pgConst->value);
  5235. }
  5236. }
  5237. Builder.InsertValues(NPg::TTableInfoKey{"pg_catalog", tableName}, colNames, data);
  5238. return true;
  5239. }
  5240. [[nodiscard]]
  5241. bool ParseCreateCastStmt(const CreateCastStmt* value) {
  5242. TString sourceType;
  5243. if (!ParseTypeName(value->sourcetype, sourceType)) {
  5244. return false;
  5245. }
  5246. TString targetType;
  5247. if (!ParseTypeName(value->targettype, targetType)) {
  5248. return false;
  5249. }
  5250. NPg::TCastDesc desc;
  5251. desc.ExtensionIndex = ExtensionIndex;
  5252. desc.SourceId = NPg::LookupType(sourceType).TypeId;
  5253. desc.TargetId = NPg::LookupType(targetType).TypeId;
  5254. if (value->func) {
  5255. if (ListLength(value->func->objname) != 1) {
  5256. return false;
  5257. }
  5258. TString funcName = StrVal(ListNodeNth(value->func->objname, 0));
  5259. TVector<ui32> argTypes;
  5260. for (int i = 0; i < ListLength(value->func->objargs); ++i) {
  5261. auto node = ListNodeNth(value->func->objargs, i);
  5262. if (NodeTag(node) != T_TypeName) {
  5263. return false;
  5264. }
  5265. TString value;
  5266. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, node), value)) {
  5267. return false;
  5268. }
  5269. argTypes.push_back(NPg::LookupType(value).TypeId);
  5270. }
  5271. desc.FunctionId = NPg::LookupProc(funcName, argTypes).ProcId;
  5272. } else if (value->inout) {
  5273. desc.Method = NPg::ECastMethod::InOut;
  5274. } else {
  5275. desc.Method = NPg::ECastMethod::Binary;
  5276. }
  5277. switch (value->context) {
  5278. case COERCION_IMPLICIT:
  5279. desc.CoercionCode = NPg::ECoercionCode::Implicit;
  5280. break;
  5281. case COERCION_ASSIGNMENT:
  5282. desc.CoercionCode = NPg::ECoercionCode::Assignment;
  5283. break;
  5284. case COERCION_EXPLICIT:
  5285. desc.CoercionCode = NPg::ECoercionCode::Explicit;
  5286. break;
  5287. default:
  5288. return false;
  5289. }
  5290. Builder.CreateCast(desc);
  5291. return true;
  5292. }
  5293. [[nodiscard]]
  5294. bool ParseCreateOpClassStmt(const CreateOpClassStmt* value) {
  5295. if (!value->isDefault) {
  5296. return false;
  5297. }
  5298. if (ListLength(value->opclassname) != 1) {
  5299. return false;
  5300. }
  5301. auto opClassName = to_lower(TString(StrVal(ListNodeNth(value->opclassname, 0))));
  5302. if (ListLength(value->opfamilyname) > 1) {
  5303. return false;
  5304. }
  5305. TString familyName;
  5306. if (ListLength(value->opfamilyname) == 1) {
  5307. familyName = to_lower(TString(StrVal(ListNodeNth(value->opfamilyname, 0))));
  5308. }
  5309. auto amName = to_lower(TString(value->amname));
  5310. NPg::EOpClassMethod method;
  5311. if (amName == "btree") {
  5312. method = NPg::EOpClassMethod::Btree;
  5313. } else if (amName == "hash") {
  5314. method = NPg::EOpClassMethod::Hash;
  5315. } else {
  5316. return false;
  5317. }
  5318. TString dataType;
  5319. if (!ParseTypeName(value->datatype, dataType)) {
  5320. return false;
  5321. }
  5322. auto typeId = NPg::LookupType(dataType).TypeId;
  5323. NPg::TOpClassDesc desc;
  5324. desc.ExtensionIndex = ExtensionIndex;
  5325. desc.Method = method;
  5326. desc.TypeId = typeId;
  5327. desc.Name = opClassName;
  5328. if (familyName.empty()) {
  5329. familyName = amName + "/" + opClassName;
  5330. }
  5331. desc.Family = familyName;
  5332. TVector<NPg::TAmOpDesc> ops;
  5333. TVector<NPg::TAmProcDesc> procs;
  5334. for (int i = 0; i < ListLength(value->items); ++i) {
  5335. auto node = LIST_CAST_NTH(CreateOpClassItem, value->items, i);
  5336. if (node->itemtype != OPCLASS_ITEM_OPERATOR && node->itemtype != OPCLASS_ITEM_FUNCTION) {
  5337. continue;
  5338. }
  5339. if (ListLength(node->name->objname) != 1) {
  5340. return false;
  5341. }
  5342. TString funcName = StrVal(ListNodeNth(node->name->objname, 0));
  5343. if (node->itemtype == OPCLASS_ITEM_OPERATOR) {
  5344. NPg::TAmOpDesc amOpDesc;
  5345. amOpDesc.ExtensionIndex = ExtensionIndex;
  5346. amOpDesc.Family = familyName;
  5347. amOpDesc.Strategy = node->number;
  5348. amOpDesc.LeftType = typeId;
  5349. amOpDesc.RightType = typeId;
  5350. amOpDesc.OperId = NPg::LookupOper(funcName, {typeId,typeId}).OperId;
  5351. ops.push_back(amOpDesc);
  5352. } else {
  5353. NPg::TAmProcDesc amProcDesc;
  5354. amProcDesc.ExtensionIndex = ExtensionIndex;
  5355. amProcDesc.Family = familyName;
  5356. amProcDesc.ProcNum = node->number;
  5357. amProcDesc.LeftType = typeId;
  5358. amProcDesc.RightType = typeId;
  5359. TVector<ui32> argTypes;
  5360. for (int i = 0; i < ListLength(node->name->objargs); ++i) {
  5361. auto typeName = ListNodeNth(node->name->objargs, i);
  5362. if (NodeTag(typeName) != T_TypeName) {
  5363. return false;
  5364. }
  5365. TString value;
  5366. if (!ParseTypeName(CAST_NODE_EXT(PG_TypeName, T_TypeName, typeName), value)) {
  5367. return false;
  5368. }
  5369. argTypes.push_back(NPg::LookupType(value).TypeId);
  5370. }
  5371. amProcDesc.ProcId = NPg::LookupProc(funcName, argTypes).ProcId;
  5372. procs.push_back(amProcDesc);
  5373. }
  5374. }
  5375. Builder.CreateOpClass(desc, ops, procs);
  5376. return true;
  5377. }
  5378. private:
  5379. const ui32 ExtensionIndex;
  5380. NYql::NPg::IExtensionSqlBuilder& Builder;
  5381. };
  5382. class TExtensionSqlParser : public NYql::NPg::IExtensionSqlParser {
  5383. public:
  5384. void Parse(ui32 extensionIndex, const TVector<TString>& sqls, NYql::NPg::IExtensionSqlBuilder& builder) final {
  5385. TExtensionHandler handler(extensionIndex, builder);
  5386. for (const auto& sql : sqls) {
  5387. NYql::PGParse(sql, handler);
  5388. }
  5389. NKikimr::NMiniKQL::RebuildTypeIndex();
  5390. }
  5391. };
  5392. class TSystemFunctionsHandler : public IPGParseEvents {
  5393. public:
  5394. TSystemFunctionsHandler(TVector<NPg::TProcDesc>& procs)
  5395. : Procs(procs)
  5396. {}
  5397. void OnResult(const List* raw) final {
  5398. for (int i = 0; i < ListLength(raw); ++i) {
  5399. if (!ParseRawStmt(LIST_CAST_NTH(RawStmt, raw, i))) {
  5400. continue;
  5401. }
  5402. }
  5403. }
  5404. void OnError(const TIssue& issue) final {
  5405. throw yexception() << "Can't parse system functions: " << issue.ToString();
  5406. }
  5407. [[nodiscard]]
  5408. bool ParseRawStmt(const RawStmt* value) {
  5409. auto node = value->stmt;
  5410. switch (NodeTag(node)) {
  5411. case T_CreateFunctionStmt:
  5412. return ParseCreateFunctionStmt(CAST_NODE(CreateFunctionStmt, node));
  5413. default:
  5414. return false;
  5415. }
  5416. }
  5417. [[nodiscard]]
  5418. bool ParseCreateFunctionStmt(const CreateFunctionStmt* value) {
  5419. NYql::NPg::TProcDesc desc;
  5420. if (!ParseCreateFunctionStmtImpl(value, 0, nullptr, desc)) {
  5421. return false;
  5422. }
  5423. Procs.push_back(desc);
  5424. return true;
  5425. }
  5426. private:
  5427. TVector<NPg::TProcDesc>& Procs;
  5428. };
  5429. class TSystemFunctionsParser : public NYql::NPg::ISystemFunctionsParser {
  5430. public:
  5431. void Parse(const TString& sql, TVector<NPg::TProcDesc>& procs) const final {
  5432. TSystemFunctionsHandler handler(procs);
  5433. NYql::PGParse(sql, handler);
  5434. }
  5435. };
  5436. class TSqlLanguageParser : public NYql::NPg::ISqlLanguageParser, public IPGParseEvents {
  5437. public:
  5438. TSqlLanguageParser() {
  5439. Settings.ClusterMapping["pg_catalog"] = TString(PgProviderName);
  5440. Settings.Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;
  5441. }
  5442. void Parse(const TString& sql, NPg::TProcDesc& proc) final {
  5443. Y_ENSURE(!FreezeGuard.Defined());
  5444. CurrentProc = &proc;
  5445. NYql::PGParse(sql, *this);
  5446. CurrentProc = nullptr;
  5447. }
  5448. void ParseNode(const Node* stmt, NPg::TProcDesc& proc) final {
  5449. Y_ENSURE(!FreezeGuard.Defined());
  5450. proc.ExprNode = nullptr;
  5451. if (proc.VariadicType) {
  5452. // Can't be expressed as usual lambda
  5453. return;
  5454. }
  5455. TVector<NYql::TAstParseResult> results(1);
  5456. results[0].Pool = std::make_unique<TMemoryPool>(4096);
  5457. TVector<TStmtParseInfo> stmtParseInfos(1);
  5458. TConverter converter(results, Settings, "", &stmtParseInfos, false, proc.ArgTypes.size());
  5459. converter.PrepareStatements();
  5460. TAstNode* root = nullptr;
  5461. switch (NodeTag(stmt)) {
  5462. case T_SelectStmt:
  5463. root = converter.ParseSelectStmt(CAST_NODE(SelectStmt, stmt), {.Inner = false});
  5464. break;
  5465. case T_ReturnStmt:
  5466. root = converter.ParseReturnStmt(CAST_NODE(ReturnStmt, stmt));
  5467. break;
  5468. default:
  5469. return;
  5470. }
  5471. if (!root) {
  5472. //Cerr << "Can't parse SQL for function: " << proc.Name << ", " << results[0].Issues.ToString();
  5473. return;
  5474. }
  5475. root = converter.L(converter.A("block"), converter.Q(converter.FinishStatements()));
  5476. if (NodeTag(stmt) == T_SelectStmt) {
  5477. root = converter.AsScalarContext(root);
  5478. }
  5479. TVector<TAstNode*> args;
  5480. for (ui32 i = 0; i < proc.ArgTypes.size(); ++i) {
  5481. args.push_back(converter.A("$p" + ToString(i + 1)));
  5482. }
  5483. root = converter.MakeLambda(args, root);
  5484. auto program = converter.L(converter.L(converter.A("return"), root));
  5485. TExprNode::TPtr graph;
  5486. Ctx.IssueManager.Reset();
  5487. if (!CompileExpr(*program, graph, Ctx, nullptr, nullptr, false, Max<ui32>(), 1)) {
  5488. Cerr << "Can't compile SQL for function: " << proc.Name << ", " << Ctx.IssueManager.GetIssues().ToString();
  5489. return;
  5490. }
  5491. SavedNodes.push_back(graph);
  5492. proc.ExprNode = graph.Get();
  5493. }
  5494. void Freeze() final {
  5495. Y_ENSURE(!FreezeGuard.Defined());
  5496. FreezeGuard.ConstructInPlace(Ctx);
  5497. }
  5498. TExprContext& GetContext() final {
  5499. Y_ENSURE(FreezeGuard.Defined());
  5500. return Ctx;
  5501. }
  5502. void OnResult(const List* raw) final {
  5503. if (ListLength(raw) == 1) {
  5504. ParseNode(LIST_CAST_NTH(RawStmt, raw, 0)->stmt, *CurrentProc);
  5505. }
  5506. }
  5507. void OnError(const TIssue& issue) final {
  5508. throw yexception() << "Can't parse SQL for function: " << CurrentProc->Name << ", " << issue.ToString();
  5509. }
  5510. private:
  5511. NSQLTranslation::TTranslationSettings Settings;
  5512. TExprContext Ctx;
  5513. TVector<TExprNode::TPtr> SavedNodes;
  5514. TMaybe<TExprContext::TFreezeGuard> FreezeGuard;
  5515. NPg::TProcDesc* CurrentProc = nullptr;
  5516. };
  5517. std::unique_ptr<NPg::IExtensionSqlParser> CreateExtensionSqlParser() {
  5518. return std::make_unique<TExtensionSqlParser>();
  5519. }
  5520. std::unique_ptr<NYql::NPg::ISystemFunctionsParser> CreateSystemFunctionsParser() {
  5521. return std::make_unique<TSystemFunctionsParser>();
  5522. }
  5523. std::unique_ptr<NYql::NPg::ISqlLanguageParser> CreateSqlLanguageParser() {
  5524. return std::make_unique<TSqlLanguageParser>();
  5525. }
  5526. class TTranslator : public NSQLTranslation::ITranslator {
  5527. public:
  5528. NSQLTranslation::ILexer::TPtr MakeLexer(const NSQLTranslation::TTranslationSettings& settings) final {
  5529. Y_UNUSED(settings);
  5530. ythrow yexception() << "Unsupported method";
  5531. }
  5532. NYql::TAstParseResult TextToAst(const TString& query, const NSQLTranslation::TTranslationSettings& settings,
  5533. NYql::TWarningRules* warningRules, NYql::TStmtParseInfo* stmtParseInfo) final {
  5534. Y_UNUSED(warningRules);
  5535. return PGToYql(query, settings, stmtParseInfo);
  5536. }
  5537. google::protobuf::Message* TextToMessage(const TString& query, const TString& queryName,
  5538. NYql::TIssues& issues, size_t maxErrors, const NSQLTranslation::TTranslationSettings& settings) final {
  5539. Y_UNUSED(query);
  5540. Y_UNUSED(queryName);
  5541. Y_UNUSED(issues);
  5542. Y_UNUSED(maxErrors);
  5543. Y_UNUSED(settings);
  5544. ythrow yexception() << "Unsupported method";
  5545. }
  5546. NYql::TAstParseResult TextAndMessageToAst(const TString& query, const google::protobuf::Message& protoAst,
  5547. const NSQLTranslation::TSQLHints& hints, const NSQLTranslation::TTranslationSettings& settings) final {
  5548. Y_UNUSED(query);
  5549. Y_UNUSED(protoAst);
  5550. Y_UNUSED(hints);
  5551. Y_UNUSED(settings);
  5552. ythrow yexception() << "Unsupported method";
  5553. }
  5554. TVector<NYql::TAstParseResult> TextToManyAst(const TString& query, const NSQLTranslation::TTranslationSettings& settings,
  5555. NYql::TWarningRules* warningRules, TVector<NYql::TStmtParseInfo>* stmtParseInfo) final {
  5556. Y_UNUSED(warningRules);
  5557. return PGToYqlStatements(query, settings, stmtParseInfo);
  5558. }
  5559. };
  5560. NSQLTranslation::TTranslatorPtr MakeTranslator() {
  5561. return MakeIntrusive<TTranslator>();
  5562. }
  5563. } // NSQLTranslationPG