sql_translation.cpp 209 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448
  1. #include "sql_translation.h"
  2. #include "sql_expression.h"
  3. #include "sql_call_expr.h"
  4. #include "sql_query.h"
  5. #include "sql_values.h"
  6. #include "sql_select.h"
  7. #include "source.h"
  8. #include <yql/essentials/parser/proto_ast/gen/v1/SQLv1Lexer.h>
  9. #include <yql/essentials/parser/proto_ast/gen/v1_antlr4/SQLv1Antlr4Lexer.h>
  10. #include <yql/essentials/sql/settings/partitioning.h>
  11. #include <yql/essentials/sql/v1/proto_parser/proto_parser.h>
  12. #include <util/generic/scope.h>
  13. #include <util/string/join.h>
  14. #include <library/cpp/protobuf/util/simple_reflection.h>
  15. namespace {
  16. using namespace NSQLTranslationV1;
  17. template <typename Callback>
  18. void VisitAllFields(const NProtoBuf::Message& msg, Callback& callback) {
  19. const auto* descr = msg.GetDescriptor();
  20. for (int i = 0; i < descr->field_count(); ++i) {
  21. const auto* fd = descr->field(i);
  22. NProtoBuf::TConstField field(msg, fd);
  23. if (field.IsMessage()) {
  24. for (size_t j = 0; j < field.Size(); ++j) {
  25. const auto& message = *field.Get<NProtoBuf::Message>(j);
  26. callback(message);
  27. VisitAllFields(message, callback);
  28. }
  29. }
  30. }
  31. }
  32. struct TTokenCollector {
  33. void operator()(const NProtoBuf::Message& message) {
  34. if (const auto* token = dynamic_cast<const NSQLv1Generated::TToken*>(&message)) {
  35. if (!Tokens.empty()) {
  36. Tokens << ' ';
  37. }
  38. Tokens << token->GetValue();
  39. }
  40. }
  41. TStringBuilder Tokens;
  42. };
  43. TString CollectTokens(const TRule_select_stmt& selectStatement) {
  44. TTokenCollector tokenCollector;
  45. VisitAllFields(selectStatement, tokenCollector);
  46. return tokenCollector.Tokens;
  47. }
  48. bool RecreateContext(
  49. TContext& ctx, const NSQLTranslation::TTranslationSettings& settings, const TString& recreationQuery
  50. ) {
  51. if (!recreationQuery) {
  52. return true;
  53. }
  54. const TString queryName = "context recreation query";
  55. const auto* ast = NSQLTranslationV1::SqlAST(
  56. ctx.Parsers,
  57. recreationQuery, queryName, ctx.Issues,
  58. settings.MaxErrors, settings.AnsiLexer, settings.Antlr4Parser, settings.Arena
  59. );
  60. if (!ast) {
  61. return false;
  62. }
  63. TSqlQuery queryTranslator(ctx, ctx.Settings.Mode, true);
  64. auto node = queryTranslator.Build(static_cast<const TSQLv1ParserAST&>(*ast));
  65. return node && node->Init(ctx, nullptr) && node->Translate(ctx);
  66. }
  67. TNodePtr BuildViewSelect(
  68. const TRule_select_stmt& selectStatement,
  69. TContext& parentContext,
  70. const TString& contextRecreationQuery
  71. ) {
  72. TIssues issues;
  73. TContext context(parentContext.Lexers, parentContext.Parsers, parentContext.Settings, {}, issues, parentContext.Query);
  74. if (!RecreateContext(context, context.Settings, contextRecreationQuery)) {
  75. parentContext.Issues.AddIssues(issues);
  76. return nullptr;
  77. }
  78. issues.Clear();
  79. // Holds (among other things) subquery references.
  80. // These references need to be passed to the parent context
  81. // to be able to compile view queries with subqueries.
  82. context.PushCurrentBlocks(&parentContext.GetCurrentBlocks());
  83. context.Settings.Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;
  84. TSqlSelect selectTranslator(context, context.Settings.Mode);
  85. TPosition pos = parentContext.Pos();
  86. auto source = selectTranslator.Build(selectStatement, pos);
  87. if (!source) {
  88. parentContext.Issues.AddIssues(issues);
  89. return nullptr;
  90. }
  91. auto node = BuildSelectResult(
  92. pos,
  93. std::move(source),
  94. false,
  95. false,
  96. context.Scoped
  97. );
  98. if (!node) {
  99. parentContext.Issues.AddIssues(issues);
  100. return nullptr;
  101. }
  102. return node;
  103. }
  104. }
  105. namespace NSQLTranslationV1 {
  106. using NALPDefault::SQLv1LexerTokens;
  107. using NALPDefaultAntlr4::SQLv1Antlr4Lexer;
  108. using namespace NSQLv1Generated;
  109. TIdentifier GetKeywordId(TTranslation& ctx, const TRule_keyword& node) {
  110. // keyword:
  111. // keyword_compat
  112. // | keyword_expr_uncompat
  113. // | keyword_table_uncompat
  114. // | keyword_select_uncompat
  115. // | keyword_alter_uncompat
  116. // | keyword_in_uncompat
  117. // | keyword_window_uncompat
  118. // | keyword_hint_uncompat
  119. //;
  120. switch (node.Alt_case()) {
  121. case TRule_keyword::kAltKeyword1:
  122. return GetIdentifier(ctx, node.GetAlt_keyword1().GetRule_keyword_compat1());
  123. case TRule_keyword::kAltKeyword2:
  124. return GetIdentifier(ctx, node.GetAlt_keyword2().GetRule_keyword_expr_uncompat1());
  125. case TRule_keyword::kAltKeyword3:
  126. return GetIdentifier(ctx, node.GetAlt_keyword3().GetRule_keyword_table_uncompat1());
  127. case TRule_keyword::kAltKeyword4:
  128. return GetIdentifier(ctx, node.GetAlt_keyword4().GetRule_keyword_select_uncompat1());
  129. case TRule_keyword::kAltKeyword5:
  130. return GetIdentifier(ctx, node.GetAlt_keyword5().GetRule_keyword_alter_uncompat1());
  131. case TRule_keyword::kAltKeyword6:
  132. return GetIdentifier(ctx, node.GetAlt_keyword6().GetRule_keyword_in_uncompat1());
  133. case TRule_keyword::kAltKeyword7:
  134. return GetIdentifier(ctx, node.GetAlt_keyword7().GetRule_keyword_window_uncompat1());
  135. case TRule_keyword::kAltKeyword8:
  136. return GetIdentifier(ctx, node.GetAlt_keyword8().GetRule_keyword_hint_uncompat1());
  137. case TRule_keyword::ALT_NOT_SET:
  138. Y_ABORT("You should change implementation according to grammar changes");
  139. }
  140. }
  141. TString Id(const TRule_id& node, TTranslation& ctx) {
  142. // id: identifier | keyword;
  143. switch (node.Alt_case()) {
  144. case TRule_id::kAltId1:
  145. return Id(node.GetAlt_id1().GetRule_identifier1(), ctx);
  146. case TRule_id::kAltId2:
  147. return GetKeyword(ctx, node.GetAlt_id2().GetRule_keyword1());
  148. case TRule_id::ALT_NOT_SET:
  149. Y_ABORT("You should change implementation according to grammar changes");
  150. }
  151. }
  152. TString Id(const TRule_id_or_type& node, TTranslation& ctx) {
  153. switch (node.Alt_case()) {
  154. case TRule_id_or_type::kAltIdOrType1:
  155. return Id(node.GetAlt_id_or_type1().GetRule_id1(), ctx);
  156. case TRule_id_or_type::kAltIdOrType2:
  157. return ctx.Identifier(node.GetAlt_id_or_type2().GetRule_type_id1().GetToken1());
  158. case TRule_id_or_type::ALT_NOT_SET:
  159. Y_ABORT("You should change implementation according to grammar changes");
  160. }
  161. }
  162. TString Id(const TRule_id_as_compat& node, TTranslation& ctx) {
  163. switch (node.Alt_case()) {
  164. case TRule_id_as_compat::kAltIdAsCompat1:
  165. return Id(node.GetAlt_id_as_compat1().GetRule_identifier1(), ctx);
  166. case TRule_id_as_compat::kAltIdAsCompat2:
  167. return ctx.Token(node.GetAlt_id_as_compat2().GetRule_keyword_as_compat1().GetToken1());
  168. case TRule_id_as_compat::ALT_NOT_SET:
  169. Y_ABORT("You should change implementation according to grammar changes");
  170. }
  171. }
  172. TString Id(const TRule_an_id_as_compat& node, TTranslation& ctx) {
  173. switch (node.Alt_case()) {
  174. case TRule_an_id_as_compat::kAltAnIdAsCompat1:
  175. return Id(node.GetAlt_an_id_as_compat1().GetRule_id_as_compat1(), ctx);
  176. case TRule_an_id_as_compat::kAltAnIdAsCompat2:
  177. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_as_compat2().GetToken1()));
  178. case TRule_an_id_as_compat::ALT_NOT_SET:
  179. Y_ABORT("You should change implementation according to grammar changes");
  180. }
  181. }
  182. TString Id(const TRule_id_schema& node, TTranslation& ctx) {
  183. //id_schema:
  184. // identifier
  185. // | keyword_compat
  186. // | keyword_expr_uncompat
  187. // // | keyword_table_uncompat
  188. // | keyword_select_uncompat
  189. // // | keyword_alter_uncompat
  190. // | keyword_in_uncompat
  191. // | keyword_window_uncompat
  192. // | keyword_hint_uncompat
  193. //;
  194. switch (node.Alt_case()) {
  195. case TRule_id_schema::kAltIdSchema1:
  196. return Id(node.GetAlt_id_schema1().GetRule_identifier1(), ctx);
  197. case TRule_id_schema::kAltIdSchema2:
  198. return GetKeyword(ctx, node.GetAlt_id_schema2().GetRule_keyword_compat1());
  199. case TRule_id_schema::kAltIdSchema3:
  200. return GetKeyword(ctx, node.GetAlt_id_schema3().GetRule_keyword_expr_uncompat1());
  201. case TRule_id_schema::kAltIdSchema4:
  202. return GetKeyword(ctx, node.GetAlt_id_schema4().GetRule_keyword_select_uncompat1());
  203. case TRule_id_schema::kAltIdSchema5:
  204. return GetKeyword(ctx, node.GetAlt_id_schema5().GetRule_keyword_in_uncompat1());
  205. case TRule_id_schema::kAltIdSchema6:
  206. return GetKeyword(ctx, node.GetAlt_id_schema6().GetRule_keyword_window_uncompat1());
  207. case TRule_id_schema::kAltIdSchema7:
  208. return GetKeyword(ctx, node.GetAlt_id_schema7().GetRule_keyword_hint_uncompat1());
  209. case TRule_id_schema::ALT_NOT_SET:
  210. Y_ABORT("You should change implementation according to grammar changes");
  211. }
  212. }
  213. TString Id(const TRule_an_id_or_type& node, TTranslation& ctx) {
  214. // an_id_or_type: id_or_type | STRING_VALUE;
  215. switch (node.Alt_case()) {
  216. case TRule_an_id_or_type::kAltAnIdOrType1:
  217. return Id(node.GetAlt_an_id_or_type1().GetRule_id_or_type1(), ctx);
  218. case TRule_an_id_or_type::kAltAnIdOrType2:
  219. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_or_type2().GetToken1()));
  220. case TRule_an_id_or_type::ALT_NOT_SET:
  221. Y_ABORT("You should change implementation according to grammar changes");
  222. }
  223. }
  224. std::pair<bool, TString> Id(const TRule_id_or_at& node, TTranslation& ctx) {
  225. bool hasAt = node.HasBlock1();
  226. return std::make_pair(hasAt, Id(node.GetRule_an_id_or_type2(), ctx) );
  227. }
  228. TString Id(const TRule_id_table& node, TTranslation& ctx) {
  229. //id_table:
  230. // identifier
  231. // | keyword_compat
  232. // | keyword_expr_uncompat
  233. // // | keyword_table_uncompat
  234. // | keyword_select_uncompat
  235. // // | keyword_alter_uncompat
  236. // | keyword_in_uncompat
  237. // | keyword_window_uncompat
  238. // | keyword_hint_uncompat
  239. //;
  240. switch (node.Alt_case()) {
  241. case TRule_id_table::kAltIdTable1:
  242. return Id(node.GetAlt_id_table1().GetRule_identifier1(), ctx);
  243. case TRule_id_table::kAltIdTable2:
  244. return GetKeyword(ctx, node.GetAlt_id_table2().GetRule_keyword_compat1());
  245. case TRule_id_table::kAltIdTable3:
  246. return GetKeyword(ctx, node.GetAlt_id_table3().GetRule_keyword_expr_uncompat1());
  247. case TRule_id_table::kAltIdTable4:
  248. return GetKeyword(ctx, node.GetAlt_id_table4().GetRule_keyword_select_uncompat1());
  249. case TRule_id_table::kAltIdTable5:
  250. return GetKeyword(ctx, node.GetAlt_id_table5().GetRule_keyword_in_uncompat1());
  251. case TRule_id_table::kAltIdTable6:
  252. return GetKeyword(ctx, node.GetAlt_id_table6().GetRule_keyword_window_uncompat1());
  253. case TRule_id_table::kAltIdTable7:
  254. return GetKeyword(ctx, node.GetAlt_id_table7().GetRule_keyword_hint_uncompat1());
  255. case TRule_id_table::ALT_NOT_SET:
  256. Y_ABORT("You should change implementation according to grammar changes");
  257. }
  258. }
  259. TString Id(const TRule_an_id_table& node, TTranslation& ctx) {
  260. // an_id_table: id_table | STRING_VALUE;
  261. switch (node.Alt_case()) {
  262. case TRule_an_id_table::kAltAnIdTable1:
  263. return Id(node.GetAlt_an_id_table1().GetRule_id_table1(), ctx);
  264. case TRule_an_id_table::kAltAnIdTable2:
  265. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_table2().GetToken1()));
  266. case TRule_an_id_table::ALT_NOT_SET:
  267. Y_ABORT("You should change implementation according to grammar changes");
  268. }
  269. }
  270. TString Id(const TRule_id_table_or_type& node, TTranslation& ctx) {
  271. switch (node.Alt_case()) {
  272. case TRule_id_table_or_type::kAltIdTableOrType1:
  273. return Id(node.GetAlt_id_table_or_type1().GetRule_an_id_table1(), ctx);
  274. case TRule_id_table_or_type::kAltIdTableOrType2:
  275. return ctx.Identifier(node.GetAlt_id_table_or_type2().GetRule_type_id1().GetToken1());
  276. case TRule_id_table_or_type::ALT_NOT_SET:
  277. Y_ABORT("You should change implementation according to grammar changes");
  278. }
  279. }
  280. TString Id(const TRule_id_expr& node, TTranslation& ctx) {
  281. //id_expr:
  282. // identifier
  283. // | keyword_compat
  284. // // | keyword_expr_uncompat
  285. // // | keyword_table_uncompat
  286. // // | keyword_select_uncompat
  287. // | keyword_alter_uncompat
  288. // | keyword_in_uncompat
  289. // | keyword_window_uncompat
  290. // | keyword_hint_uncompat
  291. //;
  292. switch (node.Alt_case()) {
  293. case TRule_id_expr::kAltIdExpr1:
  294. return Id(node.GetAlt_id_expr1().GetRule_identifier1(), ctx);
  295. case TRule_id_expr::kAltIdExpr2:
  296. return GetKeyword(ctx, node.GetAlt_id_expr2().GetRule_keyword_compat1());
  297. case TRule_id_expr::kAltIdExpr3:
  298. return GetKeyword(ctx, node.GetAlt_id_expr3().GetRule_keyword_alter_uncompat1());
  299. case TRule_id_expr::kAltIdExpr4:
  300. return GetKeyword(ctx, node.GetAlt_id_expr4().GetRule_keyword_in_uncompat1());
  301. case TRule_id_expr::kAltIdExpr5:
  302. return GetKeyword(ctx, node.GetAlt_id_expr5().GetRule_keyword_window_uncompat1());
  303. case TRule_id_expr::kAltIdExpr6:
  304. return GetKeyword(ctx, node.GetAlt_id_expr6().GetRule_keyword_hint_uncompat1());
  305. case TRule_id_expr::ALT_NOT_SET:
  306. Y_ABORT("You should change implementation according to grammar changes");
  307. }
  308. }
  309. bool IsQuotedId(const TRule_id_expr& node, TTranslation& ctx) {
  310. if (node.Alt_case() != TRule_id_expr::kAltIdExpr1) {
  311. return false;
  312. }
  313. const auto& id = ctx.Token(node.GetAlt_id_expr1().GetRule_identifier1().GetToken1());
  314. // identifier: ID_PLAIN | ID_QUOTED;
  315. return id.StartsWith('`');
  316. }
  317. TString Id(const TRule_id_expr_in& node, TTranslation& ctx) {
  318. //id_expr_in:
  319. // identifier
  320. // | keyword_compat
  321. // // | keyword_expr_uncompat
  322. // // | keyword_table_uncompat
  323. // // | keyword_select_uncompat
  324. // | keyword_alter_uncompat
  325. // // | keyword_in_uncompat
  326. // | keyword_window_uncompat
  327. // | keyword_hint_uncompat
  328. //;
  329. switch (node.Alt_case()) {
  330. case TRule_id_expr_in::kAltIdExprIn1:
  331. return Id(node.GetAlt_id_expr_in1().GetRule_identifier1(), ctx);
  332. case TRule_id_expr_in::kAltIdExprIn2:
  333. return GetKeyword(ctx, node.GetAlt_id_expr_in2().GetRule_keyword_compat1());
  334. case TRule_id_expr_in::kAltIdExprIn3:
  335. return GetKeyword(ctx, node.GetAlt_id_expr_in3().GetRule_keyword_alter_uncompat1());
  336. case TRule_id_expr_in::kAltIdExprIn4:
  337. return GetKeyword(ctx, node.GetAlt_id_expr_in4().GetRule_keyword_window_uncompat1());
  338. case TRule_id_expr_in::kAltIdExprIn5:
  339. return GetKeyword(ctx, node.GetAlt_id_expr_in5().GetRule_keyword_hint_uncompat1());
  340. case TRule_id_expr_in::ALT_NOT_SET:
  341. Y_ABORT("You should change implementation according to grammar changes");
  342. }
  343. }
  344. TString Id(const TRule_id_window& node, TTranslation& ctx) {
  345. //id_window:
  346. // identifier
  347. // | keyword_compat
  348. // | keyword_expr_uncompat
  349. // | keyword_table_uncompat
  350. // | keyword_select_uncompat
  351. // | keyword_alter_uncompat
  352. // | keyword_in_uncompat
  353. // // | keyword_window_uncompat
  354. // | keyword_hint_uncompat
  355. //;
  356. switch (node.Alt_case()) {
  357. case TRule_id_window::kAltIdWindow1:
  358. return Id(node.GetAlt_id_window1().GetRule_identifier1(), ctx);
  359. case TRule_id_window::kAltIdWindow2:
  360. return GetKeyword(ctx, node.GetAlt_id_window2().GetRule_keyword_compat1());
  361. case TRule_id_window::kAltIdWindow3:
  362. return GetKeyword(ctx, node.GetAlt_id_window3().GetRule_keyword_expr_uncompat1());
  363. case TRule_id_window::kAltIdWindow4:
  364. return GetKeyword(ctx, node.GetAlt_id_window4().GetRule_keyword_table_uncompat1());
  365. case TRule_id_window::kAltIdWindow5:
  366. return GetKeyword(ctx, node.GetAlt_id_window5().GetRule_keyword_select_uncompat1());
  367. case TRule_id_window::kAltIdWindow6:
  368. return GetKeyword(ctx, node.GetAlt_id_window6().GetRule_keyword_alter_uncompat1());
  369. case TRule_id_window::kAltIdWindow7:
  370. return GetKeyword(ctx, node.GetAlt_id_window7().GetRule_keyword_in_uncompat1());
  371. case TRule_id_window::kAltIdWindow8:
  372. return GetKeyword(ctx, node.GetAlt_id_window8().GetRule_keyword_hint_uncompat1());
  373. case TRule_id_window::ALT_NOT_SET:
  374. Y_ABORT("You should change implementation according to grammar changes");
  375. }
  376. }
  377. TString Id(const TRule_id_without& node, TTranslation& ctx) {
  378. //id_without:
  379. // identifier
  380. // | keyword_compat
  381. // // | keyword_expr_uncompat
  382. // | keyword_table_uncompat
  383. // // | keyword_select_uncompat
  384. // | keyword_alter_uncompat
  385. // | keyword_in_uncompat
  386. // | keyword_window_uncompat
  387. // | keyword_hint_uncompat
  388. //;
  389. switch (node.Alt_case()) {
  390. case TRule_id_without::kAltIdWithout1:
  391. return Id(node.GetAlt_id_without1().GetRule_identifier1(), ctx);
  392. case TRule_id_without::kAltIdWithout2:
  393. return GetKeyword(ctx, node.GetAlt_id_without2().GetRule_keyword_compat1());
  394. case TRule_id_without::kAltIdWithout3:
  395. return GetKeyword(ctx, node.GetAlt_id_without3().GetRule_keyword_table_uncompat1());
  396. case TRule_id_without::kAltIdWithout4:
  397. return GetKeyword(ctx, node.GetAlt_id_without4().GetRule_keyword_alter_uncompat1());
  398. case TRule_id_without::kAltIdWithout5:
  399. return GetKeyword(ctx, node.GetAlt_id_without5().GetRule_keyword_in_uncompat1());
  400. case TRule_id_without::kAltIdWithout6:
  401. return GetKeyword(ctx, node.GetAlt_id_without6().GetRule_keyword_window_uncompat1());
  402. case TRule_id_without::kAltIdWithout7:
  403. return GetKeyword(ctx, node.GetAlt_id_without7().GetRule_keyword_hint_uncompat1());
  404. case TRule_id_without::ALT_NOT_SET:
  405. Y_ABORT("You should change implementation according to grammar changes");
  406. }
  407. }
  408. TString Id(const TRule_id_hint& node, TTranslation& ctx) {
  409. //id_hint:
  410. // identifier
  411. // | keyword_compat
  412. // | keyword_expr_uncompat
  413. // | keyword_table_uncompat
  414. // | keyword_select_uncompat
  415. // | keyword_alter_uncompat
  416. // | keyword_in_uncompat
  417. // | keyword_window_uncompat
  418. // // | keyword_hint_uncompat
  419. //;
  420. switch (node.Alt_case()) {
  421. case TRule_id_hint::kAltIdHint1:
  422. return Id(node.GetAlt_id_hint1().GetRule_identifier1(), ctx);
  423. case TRule_id_hint::kAltIdHint2:
  424. return GetKeyword(ctx, node.GetAlt_id_hint2().GetRule_keyword_compat1());
  425. case TRule_id_hint::kAltIdHint3:
  426. return GetKeyword(ctx, node.GetAlt_id_hint3().GetRule_keyword_expr_uncompat1());
  427. case TRule_id_hint::kAltIdHint4:
  428. return GetKeyword(ctx, node.GetAlt_id_hint4().GetRule_keyword_table_uncompat1());
  429. case TRule_id_hint::kAltIdHint5:
  430. return GetKeyword(ctx, node.GetAlt_id_hint5().GetRule_keyword_select_uncompat1());
  431. case TRule_id_hint::kAltIdHint6:
  432. return GetKeyword(ctx, node.GetAlt_id_hint6().GetRule_keyword_alter_uncompat1());
  433. case TRule_id_hint::kAltIdHint7:
  434. return GetKeyword(ctx, node.GetAlt_id_hint7().GetRule_keyword_in_uncompat1());
  435. case TRule_id_hint::kAltIdHint8:
  436. return GetKeyword(ctx, node.GetAlt_id_hint8().GetRule_keyword_window_uncompat1());
  437. case TRule_id_hint::ALT_NOT_SET:
  438. Y_ABORT("You should change implementation according to grammar changes");
  439. }
  440. }
  441. TString Id(const TRule_an_id& node, TTranslation& ctx) {
  442. // an_id: id | STRING_VALUE;
  443. switch (node.Alt_case()) {
  444. case TRule_an_id::kAltAnId1:
  445. return Id(node.GetAlt_an_id1().GetRule_id1(), ctx);
  446. case TRule_an_id::kAltAnId2:
  447. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id2().GetToken1()));
  448. case TRule_an_id::ALT_NOT_SET:
  449. Y_ABORT("You should change implementation according to grammar changes");
  450. }
  451. }
  452. TString Id(const TRule_an_id_schema& node, TTranslation& ctx) {
  453. // an_id_schema: id_schema | STRING_VALUE;
  454. switch (node.Alt_case()) {
  455. case TRule_an_id_schema::kAltAnIdSchema1:
  456. return Id(node.GetAlt_an_id_schema1().GetRule_id_schema1(), ctx);
  457. case TRule_an_id_schema::kAltAnIdSchema2:
  458. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_schema2().GetToken1()));
  459. case TRule_an_id_schema::ALT_NOT_SET:
  460. Y_ABORT("You should change implementation according to grammar changes");
  461. }
  462. }
  463. TString Id(const TRule_an_id_expr& node, TTranslation& ctx) {
  464. // an_id_expr: id_expr | STRING_VALUE;
  465. switch (node.Alt_case()) {
  466. case TRule_an_id_expr::kAltAnIdExpr1:
  467. return Id(node.GetAlt_an_id_expr1().GetRule_id_expr1(), ctx);
  468. case TRule_an_id_expr::kAltAnIdExpr2:
  469. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_expr2().GetToken1()));
  470. case TRule_an_id_expr::ALT_NOT_SET:
  471. Y_ABORT("You should change implementation according to grammar changes");
  472. }
  473. }
  474. TString Id(const TRule_an_id_window& node, TTranslation& ctx) {
  475. // an_id_window: id_window | STRING_VALUE;
  476. switch (node.Alt_case()) {
  477. case TRule_an_id_window::kAltAnIdWindow1:
  478. return Id(node.GetAlt_an_id_window1().GetRule_id_window1(), ctx);
  479. case TRule_an_id_window::kAltAnIdWindow2:
  480. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_window2().GetToken1()));
  481. case TRule_an_id_window::ALT_NOT_SET:
  482. Y_ABORT("You should change implementation according to grammar changes");
  483. }
  484. }
  485. TString Id(const TRule_an_id_without& node, TTranslation& ctx) {
  486. // an_id_without: id_without | STRING_VALUE;
  487. switch (node.Alt_case()) {
  488. case TRule_an_id_without::kAltAnIdWithout1:
  489. return Id(node.GetAlt_an_id_without1().GetRule_id_without1(), ctx);
  490. case TRule_an_id_without::kAltAnIdWithout2:
  491. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_without2().GetToken1()));
  492. case TRule_an_id_without::ALT_NOT_SET:
  493. Y_ABORT("You should change implementation according to grammar changes");
  494. }
  495. }
  496. TString Id(const TRule_an_id_hint& node, TTranslation& ctx) {
  497. // an_id_hint: id_hint | STRING_VALUE;
  498. switch (node.Alt_case()) {
  499. case TRule_an_id_hint::kAltAnIdHint1:
  500. return Id(node.GetAlt_an_id_hint1().GetRule_id_hint1(), ctx);
  501. case TRule_an_id_hint::kAltAnIdHint2:
  502. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_hint2().GetToken1()));
  503. case TRule_an_id_hint::ALT_NOT_SET:
  504. Y_ABORT("You should change implementation according to grammar changes");
  505. }
  506. }
  507. TString Id(const TRule_an_id_pure& node, TTranslation& ctx) {
  508. // an_id_pure: identifier | STRING_VALUE;
  509. switch (node.Alt_case()) {
  510. case TRule_an_id_pure::kAltAnIdPure1:
  511. return Id(node.GetAlt_an_id_pure1().GetRule_identifier1(), ctx);
  512. case TRule_an_id_pure::kAltAnIdPure2:
  513. return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_pure2().GetToken1()));
  514. case TRule_an_id_pure::ALT_NOT_SET:
  515. Y_ABORT("You should change implementation according to grammar changes");
  516. }
  517. }
  518. TViewDescription Id(const TRule_view_name& node, TTranslation& ctx) {
  519. switch (node.Alt_case()) {
  520. case TRule_view_name::kAltViewName1:
  521. return {Id(node.GetAlt_view_name1().GetRule_an_id1(), ctx)};
  522. case TRule_view_name::kAltViewName2:
  523. return {"", true};
  524. case TRule_view_name::ALT_NOT_SET:
  525. Y_ABORT("You should change implementation according to grammar changes");
  526. }
  527. }
  528. bool NamedNodeImpl(const TRule_bind_parameter& node, TString& name, TTranslation& ctx) {
  529. // bind_parameter: DOLLAR (an_id_or_type | TRUE | FALSE);
  530. TString id;
  531. switch (node.GetBlock2().Alt_case()) {
  532. case TRule_bind_parameter::TBlock2::kAlt1:
  533. id = Id(node.GetBlock2().GetAlt1().GetRule_an_id_or_type1(), ctx);
  534. break;
  535. case TRule_bind_parameter::TBlock2::kAlt2:
  536. id = ctx.Token(node.GetBlock2().GetAlt2().GetToken1());
  537. break;
  538. case TRule_bind_parameter::TBlock2::kAlt3:
  539. id = ctx.Token(node.GetBlock2().GetAlt3().GetToken1());
  540. break;
  541. case TRule_bind_parameter::TBlock2::ALT_NOT_SET:
  542. Y_ABORT("You should change implementation according to grammar changes");
  543. }
  544. auto dollar = ctx.Token(node.GetToken1());
  545. if (id.empty()) {
  546. ctx.Error() << "Empty symbol name is not allowed";
  547. return false;
  548. }
  549. name = dollar + id;
  550. return true;
  551. }
  552. TString OptIdPrefixAsStr(const TRule_opt_id_prefix& node, TTranslation& ctx, const TString& defaultStr) {
  553. if (!node.HasBlock1()) {
  554. return defaultStr;
  555. }
  556. return Id(node.GetBlock1().GetRule_an_id1(), ctx);
  557. }
  558. TString OptIdPrefixAsStr(const TRule_opt_id_prefix_or_type& node, TTranslation& ctx, const TString& defaultStr) {
  559. if (!node.HasBlock1()) {
  560. return defaultStr;
  561. }
  562. return Id(node.GetBlock1().GetRule_an_id_or_type1(), ctx);
  563. }
  564. void PureColumnListStr(const TRule_pure_column_list& node, TTranslation& ctx, TVector<TString>& outList) {
  565. outList.push_back(Id(node.GetRule_an_id2(), ctx));
  566. for (auto& block: node.GetBlock3()) {
  567. outList.push_back(Id(block.GetRule_an_id2(), ctx));
  568. }
  569. }
  570. bool NamedNodeImpl(const TRule_opt_bind_parameter& node, TString& name, bool& isOptional, TTranslation& ctx) {
  571. // opt_bind_parameter: bind_parameter QUESTION?;
  572. isOptional = false;
  573. if (!NamedNodeImpl(node.GetRule_bind_parameter1(), name, ctx)) {
  574. return false;
  575. }
  576. isOptional = node.HasBlock2();
  577. return true;
  578. }
  579. TDeferredAtom PureColumnOrNamed(const TRule_pure_column_or_named& node, TTranslation& ctx) {
  580. switch (node.Alt_case()) {
  581. case TRule_pure_column_or_named::kAltPureColumnOrNamed1: {
  582. TString named;
  583. if (!NamedNodeImpl(node.GetAlt_pure_column_or_named1().GetRule_bind_parameter1(), named, ctx)) {
  584. return {};
  585. }
  586. auto namedNode = ctx.GetNamedNode(named);
  587. if (!namedNode) {
  588. return {};
  589. }
  590. return TDeferredAtom(namedNode, ctx.Context());
  591. }
  592. case TRule_pure_column_or_named::kAltPureColumnOrNamed2:
  593. return TDeferredAtom(ctx.Context().Pos(), Id(node.GetAlt_pure_column_or_named2().GetRule_an_id1(), ctx));
  594. case TRule_pure_column_or_named::ALT_NOT_SET:
  595. Y_ABORT("You should change implementation according to grammar changes");
  596. }
  597. }
  598. bool PureColumnOrNamedListStr(const TRule_pure_column_or_named_list& node, TTranslation& ctx, TVector<TDeferredAtom>& outList) {
  599. outList.push_back(PureColumnOrNamed(node.GetRule_pure_column_or_named2(), ctx));
  600. if (outList.back().Empty()) {
  601. return false;
  602. }
  603. for (auto& block : node.GetBlock3()) {
  604. outList.push_back(PureColumnOrNamed(block.GetRule_pure_column_or_named2(), ctx));
  605. if (outList.back().Empty()) {
  606. return false;
  607. }
  608. }
  609. return true;
  610. }
  611. bool TSqlTranslation::CreateTableIndex(const TRule_table_index& node, TVector<TIndexDescription>& indexes) {
  612. indexes.emplace_back(IdEx(node.GetRule_an_id2(), *this));
  613. const auto& indexType = node.GetRule_table_index_type3().GetBlock1();
  614. switch (indexType.Alt_case()) {
  615. // "GLOBAL"
  616. case TRule_table_index_type_TBlock1::kAlt1: {
  617. auto globalIndex = indexType.GetAlt1().GetRule_global_index1();
  618. bool uniqIndex = false;
  619. if (globalIndex.HasBlock2()) {
  620. uniqIndex = true;
  621. }
  622. if (globalIndex.HasBlock3()) {
  623. const TString token = to_lower(Ctx.Token(globalIndex.GetBlock3().GetToken1()));
  624. if (token == "sync") {
  625. if (uniqIndex) {
  626. indexes.back().Type = TIndexDescription::EType::GlobalSyncUnique;
  627. } else {
  628. indexes.back().Type = TIndexDescription::EType::GlobalSync;
  629. }
  630. } else if (token == "async") {
  631. if (uniqIndex) {
  632. AltNotImplemented("unique", indexType);
  633. return false;
  634. }
  635. indexes.back().Type = TIndexDescription::EType::GlobalAsync;
  636. } else {
  637. Y_ABORT("You should change implementation according to grammar changes");
  638. }
  639. }
  640. }
  641. break;
  642. // "LOCAL"
  643. case TRule_table_index_type_TBlock1::kAlt2:
  644. AltNotImplemented("local", indexType);
  645. return false;
  646. case TRule_table_index_type_TBlock1::ALT_NOT_SET:
  647. Y_ABORT("You should change implementation according to grammar changes");
  648. }
  649. if (node.GetRule_table_index_type3().HasBlock2()) {
  650. const TString subType = to_upper(IdEx(node.GetRule_table_index_type3().GetBlock2().GetRule_index_subtype2().GetRule_an_id1(), *this).Name) ;
  651. if (subType == "VECTOR_KMEANS_TREE") {
  652. if (indexes.back().Type != TIndexDescription::EType::GlobalSync) {
  653. Ctx.Error() << subType << " index can only be GLOBAL [SYNC]";
  654. return false;
  655. }
  656. indexes.back().Type = TIndexDescription::EType::GlobalVectorKmeansTree;
  657. } else {
  658. Ctx.Error() << subType << " index subtype is not supported";
  659. return false;
  660. }
  661. }
  662. // WITH
  663. if (node.HasBlock10()) {
  664. //const auto& with = node.GetBlock4();
  665. auto& index = indexes.back();
  666. if (index.Type == TIndexDescription::EType::GlobalVectorKmeansTree) {
  667. auto& vectorSettings = index.IndexSettings.emplace<TVectorIndexSettings>();
  668. if (!CreateIndexSettings(node.GetBlock10().GetRule_with_index_settings1(), index.Type, index.IndexSettings)) {
  669. return false;
  670. }
  671. if (!vectorSettings.Validate(Ctx)) {
  672. return false;
  673. }
  674. } else {
  675. AltNotImplemented("with", indexType);
  676. return false;
  677. }
  678. }
  679. indexes.back().IndexColumns.emplace_back(IdEx(node.GetRule_an_id_schema6(), *this));
  680. for (const auto& block : node.GetBlock7()) {
  681. indexes.back().IndexColumns.emplace_back(IdEx(block.GetRule_an_id_schema2(), *this));
  682. }
  683. if (node.HasBlock9()) {
  684. const auto& block = node.GetBlock9();
  685. indexes.back().DataColumns.emplace_back(IdEx(block.GetRule_an_id_schema3(), *this));
  686. for (const auto& inner : block.GetBlock4()) {
  687. indexes.back().DataColumns.emplace_back(IdEx(inner.GetRule_an_id_schema2(), *this));
  688. }
  689. }
  690. return true;
  691. }
  692. bool TSqlTranslation::CreateIndexSettings(const TRule_with_index_settings& settingsNode,
  693. TIndexDescription::EType indexType,
  694. TIndexDescription::TIndexSettings& indexSettings) {
  695. const auto& firstEntry = settingsNode.GetRule_index_setting_entry3();
  696. if (!CreateIndexSettingEntry(IdEx(firstEntry.GetRule_an_id1(), *this), firstEntry.GetRule_index_setting_value3(), indexType, indexSettings)) {
  697. return false;
  698. }
  699. for (auto& block : settingsNode.GetBlock4()) {
  700. const auto& entry = block.GetRule_index_setting_entry2();
  701. if (!CreateIndexSettingEntry(IdEx(entry.GetRule_an_id1(), *this), entry.GetRule_index_setting_value3(), indexType, indexSettings)) {
  702. return false;
  703. }
  704. }
  705. return true;
  706. }
  707. template<typename T>
  708. std::tuple<bool, T, TString> TSqlTranslation::GetIndexSettingValue(const TRule_index_setting_value& node) {
  709. T value{};
  710. // id_or_type
  711. if (node.HasAlt_index_setting_value1()) {
  712. const TString stringValue = to_lower(IdEx(node.GetAlt_index_setting_value1().GetRule_id_or_type1(), *this).Name);
  713. if (!TryFromString<T>(stringValue, value)) {
  714. return {false, value, stringValue};
  715. }
  716. return {true, value, stringValue};
  717. }
  718. // STRING_VALUE
  719. else if (node.HasAlt_index_setting_value2()) {
  720. const TString stringValue = to_lower(Token(node.GetAlt_index_setting_value2().GetToken1()));
  721. const auto unescaped = StringContent(Ctx, Ctx.Pos(), stringValue);
  722. if (!unescaped) {
  723. return {false, value, stringValue};
  724. }
  725. if (!TryFromString<T>(unescaped->Content, value)) {
  726. return {false, value, stringValue};
  727. }
  728. return {true, value, unescaped->Content};
  729. } else {
  730. Y_ABORT("You should change implementation according to grammar changes");
  731. }
  732. }
  733. template<>
  734. std::tuple<bool, ui64, TString> TSqlTranslation::GetIndexSettingValue(const TRule_index_setting_value& node) {
  735. const auto& intNode = node.GetAlt_index_setting_value3().GetRule_integer1();
  736. const TString stringValue = Token(intNode.GetToken1());
  737. ui64 value = 0;
  738. TString suffix;
  739. if (!ParseNumbers(Ctx, stringValue, value, suffix)) {
  740. return {false, value, stringValue};
  741. }
  742. return {true, value, stringValue};
  743. }
  744. template<>
  745. std::tuple<bool, bool, TString> TSqlTranslation::GetIndexSettingValue(const TRule_index_setting_value& node) {
  746. bool value = false;
  747. const TString stringValue = to_lower(Token(node.GetAlt_index_setting_value4().GetRule_bool_value1().GetToken1()));;
  748. if (!TryFromString<bool>(stringValue, value)) {
  749. return {false, value, stringValue};
  750. }
  751. return {true, value, stringValue};
  752. }
  753. bool TSqlTranslation::CreateIndexSettingEntry(const TIdentifier &id,
  754. const TRule_index_setting_value& node,
  755. TIndexDescription::EType indexType,
  756. TIndexDescription::TIndexSettings& indexSettings) {
  757. if (indexType == TIndexDescription::EType::GlobalVectorKmeansTree) {
  758. TVectorIndexSettings &vectorIndexSettings = std::get<TVectorIndexSettings>(indexSettings);
  759. if (to_lower(id.Name) == "distance") {
  760. const auto [success, value, stringValue] = GetIndexSettingValue<TVectorIndexSettings::EDistance>(node);
  761. if (!success) {
  762. Ctx.Error() << "Invalid distance: " << stringValue;
  763. return false;
  764. }
  765. vectorIndexSettings.Distance = value;
  766. } else if (to_lower(id.Name) == "similarity") {
  767. const auto [success, value, stringValue] = GetIndexSettingValue<TVectorIndexSettings::ESimilarity>(node);
  768. if (!success) {
  769. Ctx.Error() << "Invalid similarity: " << stringValue;
  770. return false;
  771. }
  772. vectorIndexSettings.Similarity = value;
  773. } else if (to_lower(id.Name) == "vector_type") {
  774. const auto [success, value, stringValue] = GetIndexSettingValue<TVectorIndexSettings::EVectorType>(node);
  775. if (!success) {
  776. Ctx.Error() << "Invalid vector_type: " << stringValue;
  777. return false;
  778. }
  779. vectorIndexSettings.VectorType = value;
  780. } else if (to_lower(id.Name) == "vector_dimension") {
  781. const auto [success, value, stringValue] = GetIndexSettingValue<ui64>(node);
  782. if (!success || value > Max<ui32>()) {
  783. Ctx.Error() << "Invalid vector_dimension: " << stringValue;
  784. return false;
  785. }
  786. vectorIndexSettings.VectorDimension = value;
  787. } else if (to_lower(id.Name) == "clusters") {
  788. const auto [success, value, stringValue] = GetIndexSettingValue<ui64>(node);
  789. if (!success || value > Max<ui32>()) {
  790. Ctx.Error() << "Invalid clusters: " << stringValue;
  791. return false;
  792. }
  793. vectorIndexSettings.Clusters = value;
  794. } else if (to_lower(id.Name) == "levels") {
  795. const auto [success, value, stringValue] = GetIndexSettingValue<ui64>(node);
  796. if (!success || value > Max<ui32>()) {
  797. Ctx.Error() << "Invalid levels: " << stringValue;
  798. return false;
  799. }
  800. vectorIndexSettings.Levels = value;
  801. } else {
  802. Ctx.Error() << "Unknown index setting: " << id.Name;
  803. return false;
  804. }
  805. } else {
  806. Ctx.Error() << "Unknown index setting: " << id.Name;
  807. return false;
  808. }
  809. return true;
  810. }
  811. std::pair<TString, TViewDescription> TableKeyImpl(const std::pair<bool, TString>& nameWithAt, TViewDescription view, TTranslation& ctx) {
  812. if (nameWithAt.first) {
  813. view = {"@"};
  814. ctx.Context().IncrementMonCounter("sql_features", "AnonymousTable");
  815. }
  816. return std::make_pair(nameWithAt.second, view);
  817. }
  818. std::pair<TString, TViewDescription> TableKeyImpl(const TRule_table_key& node, TTranslation& ctx, bool hasAt) {
  819. auto name(Id(node.GetRule_id_table_or_type1(), ctx));
  820. TViewDescription view;
  821. if (node.HasBlock2()) {
  822. view = Id(node.GetBlock2().GetRule_view_name2(), ctx);
  823. ctx.Context().IncrementMonCounter("sql_features", "View");
  824. }
  825. return TableKeyImpl(std::make_pair(hasAt, name), view, ctx);
  826. }
  827. /// \return optional prefix
  828. TString ColumnNameAsStr(TTranslation& ctx, const TRule_column_name& node, TString& id) {
  829. id = Id(node.GetRule_an_id2(), ctx);
  830. return OptIdPrefixAsStr(node.GetRule_opt_id_prefix1(), ctx);
  831. }
  832. TString ColumnNameAsSingleStr(TTranslation& ctx, const TRule_column_name& node) {
  833. TString body;
  834. const TString prefix = ColumnNameAsStr(ctx, node, body);
  835. return prefix ? prefix + '.' + body : body;
  836. }
  837. TTableHints GetContextHints(TContext& ctx) {
  838. TTableHints hints;
  839. if (ctx.PragmaInferSchema) {
  840. hints["infer_schema"] = {};
  841. }
  842. if (ctx.PragmaDirectRead) {
  843. hints["direct_read"] = {};
  844. }
  845. return hints;
  846. }
  847. TTableHints GetTableFuncHints(TStringBuf funcName) {
  848. TCiString func(funcName);
  849. TTableHints res;
  850. if (func.StartsWith("range") || func.StartsWith("like") || func.StartsWith("regexp") || func.StartsWith("filter")) {
  851. res.emplace("ignore_non_existing", TVector<TNodePtr>{});
  852. } else if (func.StartsWith("each")) {
  853. res.emplace("ignore_non_existing", TVector<TNodePtr>{});
  854. res.emplace("warn_non_existing", TVector<TNodePtr>{});
  855. }
  856. return res;
  857. }
  858. TNodePtr TSqlTranslation::NamedExpr(const TRule_named_expr& node, EExpr exprMode) {
  859. TSqlExpression expr(Ctx, Mode);
  860. if (exprMode == EExpr::GroupBy) {
  861. expr.SetSmartParenthesisMode(TSqlExpression::ESmartParenthesis::GroupBy);
  862. } else if (exprMode == EExpr::SqlLambdaParams) {
  863. expr.SetSmartParenthesisMode(TSqlExpression::ESmartParenthesis::SqlLambdaParams);
  864. }
  865. if (node.HasBlock2()) {
  866. expr.MarkAsNamed();
  867. }
  868. TNodePtr exprNode(expr.Build(node.GetRule_expr1()));
  869. if (!exprNode) {
  870. Ctx.IncrementMonCounter("sql_errors", "NamedExprInvalid");
  871. return nullptr;
  872. }
  873. if (node.HasBlock2()) {
  874. exprNode = SafeClone(exprNode);
  875. exprNode->SetLabel(Id(node.GetBlock2().GetRule_an_id_or_type2(), *this));
  876. }
  877. return exprNode;
  878. }
  879. bool TSqlTranslation::NamedExprList(const TRule_named_expr_list& node, TVector<TNodePtr>& exprs, EExpr exprMode) {
  880. exprs.emplace_back(NamedExpr(node.GetRule_named_expr1(), exprMode));
  881. if (!exprs.back()) {
  882. return false;
  883. }
  884. for (auto& b: node.GetBlock2()) {
  885. exprs.emplace_back(NamedExpr(b.GetRule_named_expr2(), exprMode));
  886. if (!exprs.back()) {
  887. return false;
  888. }
  889. }
  890. return true;
  891. }
  892. bool TSqlTranslation::BindList(const TRule_bind_parameter_list& node, TVector<TSymbolNameWithPos>& bindNames) {
  893. bindNames.clear();
  894. TString name;
  895. if (!NamedNodeImpl(node.GetRule_bind_parameter1(), name, *this)) {
  896. return false;
  897. }
  898. bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
  899. for (auto& b: node.GetBlock2()) {
  900. if (!NamedNodeImpl(b.GetRule_bind_parameter2(), name, *this)) {
  901. return false;
  902. }
  903. bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
  904. }
  905. return true;
  906. }
  907. bool TSqlTranslation::ActionOrSubqueryArgs(const TRule_action_or_subquery_args& node, TVector<TSymbolNameWithPos>& bindNames, ui32& optionalArgsCount) {
  908. bindNames.clear();
  909. optionalArgsCount = 0;
  910. TString name;
  911. bool isOptional = false;
  912. if (!NamedNodeImpl(node.GetRule_opt_bind_parameter1(), name, isOptional, *this)) {
  913. return false;
  914. }
  915. if (isOptional) {
  916. optionalArgsCount++;
  917. }
  918. bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
  919. for (auto& b: node.GetBlock2()) {
  920. if (!NamedNodeImpl(b.GetRule_opt_bind_parameter2(), name, isOptional, *this)) {
  921. return false;
  922. }
  923. if (isOptional) {
  924. optionalArgsCount++;
  925. } else if (optionalArgsCount > 0) {
  926. Context().Error() << "Non-optional argument can not follow optional one";
  927. return false;
  928. }
  929. bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
  930. }
  931. return true;
  932. }
  933. bool TSqlTranslation::ModulePath(const TRule_module_path& node, TVector<TString>& path) {
  934. if (node.HasBlock1()) {
  935. path.emplace_back(TString());
  936. }
  937. path.emplace_back(Id(node.GetRule_an_id2(), *this));
  938. for (auto& b: node.GetBlock3()) {
  939. path.emplace_back(Id(b.GetRule_an_id2(), *this));
  940. }
  941. return true;
  942. }
  943. bool TSqlTranslation::NamedBindList(const TRule_named_bind_parameter_list& node, TVector<TSymbolNameWithPos>& names,
  944. TVector<TSymbolNameWithPos>& aliases)
  945. {
  946. names.clear();
  947. aliases.clear();
  948. TSymbolNameWithPos name;
  949. TSymbolNameWithPos alias;
  950. if (!NamedBindParam(node.GetRule_named_bind_parameter1(), name, alias)) {
  951. return false;
  952. }
  953. names.push_back(name);
  954. aliases.push_back(alias);
  955. for (auto& b: node.GetBlock2()) {
  956. if (!NamedBindParam(b.GetRule_named_bind_parameter2(), name, alias)) {
  957. return false;
  958. }
  959. names.push_back(name);
  960. aliases.push_back(alias);
  961. }
  962. return true;
  963. }
  964. bool TSqlTranslation::NamedBindParam(const TRule_named_bind_parameter& node, TSymbolNameWithPos& name, TSymbolNameWithPos& alias) {
  965. name = alias = {};
  966. if (!NamedNodeImpl(node.GetRule_bind_parameter1(), name.Name, *this)) {
  967. return false;
  968. }
  969. name.Pos = Ctx.Pos();
  970. if (node.HasBlock2()) {
  971. if (!NamedNodeImpl(node.GetBlock2().GetRule_bind_parameter2(), alias.Name, *this)) {
  972. return false;
  973. }
  974. alias.Pos = Ctx.Pos();
  975. }
  976. return true;
  977. }
  978. TMaybe<TTableArg> TSqlTranslation::TableArgImpl(const TRule_table_arg& node) {
  979. TTableArg ret;
  980. ret.HasAt = node.HasBlock1();
  981. TColumnRefScope scope(Ctx, EColumnRefState::AsStringLiteral);
  982. ret.Expr = NamedExpr(node.GetRule_named_expr2());
  983. if (!ret.Expr) {
  984. return Nothing();
  985. }
  986. if (node.HasBlock3()) {
  987. ret.View = Id(node.GetBlock3().GetRule_view_name2(), *this);
  988. Context().IncrementMonCounter("sql_features", "View");
  989. }
  990. return ret;
  991. }
  992. bool TSqlTranslation::ClusterExpr(const TRule_cluster_expr& node, bool allowWildcard, TString& service, TDeferredAtom& cluster) {
  993. bool allowBinding = false;
  994. bool isBinding;
  995. return ClusterExpr(node, allowWildcard, allowBinding, service, cluster, isBinding);
  996. }
  997. bool TSqlTranslation::ClusterExprOrBinding(const TRule_cluster_expr& node, TString& service, TDeferredAtom& cluster, bool& isBinding) {
  998. bool allowWildcard = false;
  999. bool allowBinding = true;
  1000. return ClusterExpr(node, allowWildcard, allowBinding, service, cluster, isBinding);
  1001. }
  1002. bool TSqlTranslation::ClusterExpr(const TRule_cluster_expr& node, bool allowWildcard, bool allowBinding, TString& service,
  1003. TDeferredAtom& cluster, bool& isBinding)
  1004. {
  1005. service = "";
  1006. cluster = TDeferredAtom();
  1007. isBinding = false;
  1008. if (node.HasBlock1()) {
  1009. service = to_lower(Id(node.GetBlock1().GetRule_an_id1(), *this));
  1010. allowBinding = false;
  1011. if (service != YtProviderName &&
  1012. service != KikimrProviderName &&
  1013. service != RtmrProviderName && service != StatProviderName) {
  1014. Ctx.Error() << "Unknown service: " << service;
  1015. return false;
  1016. }
  1017. }
  1018. switch (node.GetBlock2().Alt_case()) {
  1019. case TRule_cluster_expr::TBlock2::kAlt1: {
  1020. auto value = PureColumnOrNamed(node.GetBlock2().GetAlt1().GetRule_pure_column_or_named1(), *this);
  1021. if (value.Empty()) {
  1022. return false;
  1023. }
  1024. if (value.GetLiteral()) {
  1025. TString clusterName = *value.GetLiteral();
  1026. if (allowBinding && to_lower(clusterName) == "bindings") {
  1027. switch (Ctx.Settings.BindingsMode) {
  1028. case NSQLTranslation::EBindingsMode::DISABLED:
  1029. Ctx.Error(Ctx.Pos(), TIssuesIds::YQL_DISABLED_BINDINGS) << "Please remove 'bindings.' from your query, the support for this syntax has ended";
  1030. Ctx.IncrementMonCounter("sql_errors", "DisabledBinding");
  1031. return false;
  1032. case NSQLTranslation::EBindingsMode::ENABLED:
  1033. isBinding = true;
  1034. break;
  1035. case NSQLTranslation::EBindingsMode::DROP_WITH_WARNING:
  1036. Ctx.Warning(Ctx.Pos(), TIssuesIds::YQL_DEPRECATED_BINDINGS) << "Please remove 'bindings.' from your query, the support for this syntax will be dropped soon";
  1037. Ctx.IncrementMonCounter("sql_errors", "DeprecatedBinding");
  1038. [[fallthrough]];
  1039. case NSQLTranslation::EBindingsMode::DROP:
  1040. service = Context().Scoped->CurrService;
  1041. cluster = Context().Scoped->CurrCluster;
  1042. break;
  1043. }
  1044. return true;
  1045. }
  1046. TString normalizedClusterName;
  1047. auto foundProvider = Ctx.GetClusterProvider(clusterName, normalizedClusterName);
  1048. if (!foundProvider) {
  1049. Ctx.Error() << "Unknown cluster: " << clusterName;
  1050. return false;
  1051. }
  1052. if (service && *foundProvider != service) {
  1053. Ctx.Error() << "Mismatch of cluster " << clusterName << " service, expected: "
  1054. << *foundProvider << ", got: " << service;
  1055. return false;
  1056. }
  1057. if (!service) {
  1058. service = *foundProvider;
  1059. }
  1060. value = TDeferredAtom(Ctx.Pos(), normalizedClusterName);
  1061. } else {
  1062. if (!service) {
  1063. Ctx.Error() << "Cluster service is not set";
  1064. return false;
  1065. }
  1066. }
  1067. cluster = value;
  1068. return true;
  1069. }
  1070. case TRule_cluster_expr::TBlock2::kAlt2: {
  1071. if (!allowWildcard) {
  1072. Ctx.Error() << "Cluster wildcards allowed only in USE statement";
  1073. return false;
  1074. }
  1075. return true;
  1076. }
  1077. case TRule_cluster_expr::TBlock2::ALT_NOT_SET:
  1078. Y_ABORT("You should change implementation according to grammar changes");
  1079. }
  1080. }
  1081. bool TSqlTranslation::ApplyTableBinding(const TString& binding, TTableRef& tr, TTableHints& hints) {
  1082. NSQLTranslation::TBindingInfo bindingInfo;
  1083. if (const auto& error = ExtractBindingInfo(Context().Settings, binding, bindingInfo)) {
  1084. Ctx.Error() << error;
  1085. return false;
  1086. }
  1087. if (bindingInfo.Schema) {
  1088. TNodePtr schema = BuildQuotedAtom(Ctx.Pos(), bindingInfo.Schema);
  1089. TNodePtr type = new TCallNodeImpl(Ctx.Pos(), "SqlTypeFromYson", { schema });
  1090. TNodePtr columns = new TCallNodeImpl(Ctx.Pos(), "SqlColumnOrderFromYson", { schema });
  1091. hints["user_schema"] = { type, columns };
  1092. }
  1093. for (auto& [key, values] : bindingInfo.Attributes) {
  1094. TVector<TNodePtr> hintValue;
  1095. for (auto& column : values) {
  1096. hintValue.push_back(BuildQuotedAtom(Ctx.Pos(), column));
  1097. }
  1098. hints[key] = std::move(hintValue);
  1099. }
  1100. tr.Service = bindingInfo.ClusterType;
  1101. tr.Cluster = TDeferredAtom(Ctx.Pos(), bindingInfo.Cluster);
  1102. const TString view = "";
  1103. tr.Keys = BuildTableKey(Ctx.Pos(), tr.Service, tr.Cluster, TDeferredAtom(Ctx.Pos(), bindingInfo.Path), {view});
  1104. return true;
  1105. }
  1106. bool TSqlTranslation::TableRefImpl(const TRule_table_ref& node, TTableRef& result, bool unorderedSubquery) {
  1107. // table_ref:
  1108. // (cluster_expr DOT)? AT?
  1109. // (table_key | an_id_expr LPAREN (table_arg (COMMA table_arg)*)? RPAREN |
  1110. // bind_parameter (LPAREN expr_list? RPAREN)? (VIEW an_id)?)
  1111. // table_hints?;
  1112. if (Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW && node.HasBlock1()) {
  1113. Ctx.Error() << "Cluster should not be used in limited view";
  1114. return false;
  1115. }
  1116. auto service = Context().Scoped->CurrService;
  1117. auto cluster = Context().Scoped->CurrCluster;
  1118. const bool hasAt = node.HasBlock2();
  1119. bool isBinding = false;
  1120. if (node.HasBlock1()) {
  1121. const auto& clusterExpr = node.GetBlock1().GetRule_cluster_expr1();
  1122. bool result = !hasAt ?
  1123. ClusterExprOrBinding(clusterExpr, service, cluster, isBinding) : ClusterExpr(clusterExpr, false, service, cluster);
  1124. if (!result) {
  1125. return false;
  1126. }
  1127. }
  1128. TTableRef tr(Context().MakeName("table"), service, cluster, nullptr);
  1129. TPosition pos(Context().Pos());
  1130. TTableHints hints = GetContextHints(Ctx);
  1131. TTableHints tableHints;
  1132. TMaybe<TString> keyFunc;
  1133. auto& block = node.GetBlock3();
  1134. switch (block.Alt_case()) {
  1135. case TRule_table_ref::TBlock3::kAlt1: {
  1136. if (!isBinding && cluster.Empty()) {
  1137. Ctx.Error() << "No cluster name given and no default cluster is selected";
  1138. return false;
  1139. }
  1140. auto pair = TableKeyImpl(block.GetAlt1().GetRule_table_key1(), *this, hasAt);
  1141. if (isBinding) {
  1142. TString binding = pair.first;
  1143. auto view = pair.second;
  1144. if (!view.ViewName.empty()) {
  1145. YQL_ENSURE(view != TViewDescription{"@"});
  1146. Ctx.Error() << "VIEW is not supported for table bindings";
  1147. return false;
  1148. }
  1149. if (!ApplyTableBinding(binding, tr, tableHints)) {
  1150. return false;
  1151. }
  1152. } else {
  1153. tr.Keys = BuildTableKey(pos, service, cluster, TDeferredAtom(pos, pair.first), pair.second);
  1154. }
  1155. break;
  1156. }
  1157. case TRule_table_ref::TBlock3::kAlt2: {
  1158. if (cluster.Empty()) {
  1159. Ctx.Error() << "No cluster name given and no default cluster is selected";
  1160. return false;
  1161. }
  1162. auto& alt = block.GetAlt2();
  1163. keyFunc = Id(alt.GetRule_an_id_expr1(), *this);
  1164. TVector<TTableArg> args;
  1165. if (alt.HasBlock3()) {
  1166. auto& argsBlock = alt.GetBlock3();
  1167. auto arg = TableArgImpl(argsBlock.GetRule_table_arg1());
  1168. if (!arg) {
  1169. return false;
  1170. }
  1171. args.push_back(std::move(*arg));
  1172. for (auto& b : argsBlock.GetBlock2()) {
  1173. arg = TableArgImpl(b.GetRule_table_arg2());
  1174. if (!arg) {
  1175. return false;
  1176. }
  1177. args.push_back(std::move(*arg));
  1178. }
  1179. }
  1180. tableHints = GetTableFuncHints(*keyFunc);
  1181. tr.Keys = BuildTableKeys(pos, service, cluster, *keyFunc, args);
  1182. break;
  1183. }
  1184. case TRule_table_ref::TBlock3::kAlt3: {
  1185. auto& alt = block.GetAlt3();
  1186. Ctx.IncrementMonCounter("sql_features", "NamedNodeUseSource");
  1187. TString named;
  1188. if (!NamedNodeImpl(alt.GetRule_bind_parameter1(), named, *this)) {
  1189. return false;
  1190. }
  1191. if (hasAt) {
  1192. if (alt.HasBlock2()) {
  1193. Ctx.Error() << "Subquery must not be used as anonymous table name";
  1194. return false;
  1195. }
  1196. if (alt.HasBlock3()) {
  1197. Ctx.Error() << "View is not supported for anonymous tables";
  1198. return false;
  1199. }
  1200. if (node.HasBlock4()) {
  1201. Ctx.Error() << "Hints are not supported for anonymous tables";
  1202. return false;
  1203. }
  1204. auto namedNode = GetNamedNode(named);
  1205. if (!namedNode) {
  1206. return false;
  1207. }
  1208. auto source = TryMakeSourceFromExpression(Ctx.Pos(), Ctx, service, cluster, namedNode, "@");
  1209. if (!source) {
  1210. Ctx.Error() << "Cannot infer cluster and table name";
  1211. return false;
  1212. }
  1213. result.Source = source;
  1214. return true;
  1215. }
  1216. auto nodePtr = GetNamedNode(named);
  1217. if (!nodePtr) {
  1218. Ctx.IncrementMonCounter("sql_errors", "NamedNodeSourceError");
  1219. return false;
  1220. }
  1221. if (alt.HasBlock2()) {
  1222. if (alt.HasBlock3()) {
  1223. Ctx.Error() << "View is not supported for subqueries";
  1224. return false;
  1225. }
  1226. if (node.HasBlock4()) {
  1227. Ctx.Error() << "Hints are not supported for subqueries";
  1228. return false;
  1229. }
  1230. TVector<TNodePtr> values;
  1231. values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "Apply", TNodeFlags::Default));
  1232. values.push_back(nodePtr);
  1233. values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "world", TNodeFlags::Default));
  1234. TSqlExpression sqlExpr(Ctx, Mode);
  1235. if (alt.GetBlock2().HasBlock2() && !ExprList(sqlExpr, values, alt.GetBlock2().GetBlock2().GetRule_expr_list1())) {
  1236. return false;
  1237. }
  1238. TNodePtr apply = new TAstListNodeImpl(Ctx.Pos(), std::move(values));
  1239. if (unorderedSubquery && Ctx.UnorderedSubqueries) {
  1240. apply = new TCallNodeImpl(Ctx.Pos(), "UnorderedSubquery", { apply });
  1241. }
  1242. result.Source = BuildNodeSource(Ctx.Pos(), apply);
  1243. return true;
  1244. }
  1245. TTableHints hints;
  1246. TTableHints contextHints = GetContextHints(Ctx);
  1247. auto ret = BuildInnerSource(Ctx.Pos(), nodePtr, service, cluster);
  1248. if (alt.HasBlock3()) {
  1249. auto view = Id(alt.GetBlock3().GetRule_view_name2(), *this);
  1250. Ctx.IncrementMonCounter("sql_features", "View");
  1251. bool result = view.PrimaryFlag
  1252. ? ret->SetPrimaryView(Ctx, Ctx.Pos())
  1253. : ret->SetViewName(Ctx, Ctx.Pos(), view.ViewName);
  1254. if (!result) {
  1255. return false;
  1256. }
  1257. }
  1258. if (node.HasBlock4()) {
  1259. auto tmp = TableHintsImpl(node.GetBlock4().GetRule_table_hints1(), service, keyFunc.GetOrElse(""));
  1260. if (!tmp) {
  1261. return false;
  1262. }
  1263. hints = *tmp;
  1264. }
  1265. if (hints || contextHints) {
  1266. if (!ret->SetTableHints(Ctx, Ctx.Pos(), hints, contextHints)) {
  1267. return false;
  1268. }
  1269. }
  1270. result.Source = ret;
  1271. return true;
  1272. }
  1273. case TRule_table_ref::TBlock3::ALT_NOT_SET:
  1274. Y_ABORT("You should change implementation according to grammar changes");
  1275. }
  1276. MergeHints(hints, tableHints);
  1277. if (node.HasBlock4()) {
  1278. auto tmp = TableHintsImpl(node.GetBlock4().GetRule_table_hints1(), service, keyFunc.GetOrElse(""));
  1279. if (!tmp) {
  1280. Ctx.Error() << "Failed to parse table hints";
  1281. return false;
  1282. }
  1283. MergeHints(hints, *tmp);
  1284. }
  1285. if (!hints.empty()) {
  1286. tr.Options = BuildInputOptions(pos, hints);
  1287. }
  1288. if (!tr.Keys) {
  1289. return false;
  1290. }
  1291. result = tr;
  1292. return true;
  1293. }
  1294. TMaybe<TSourcePtr> TSqlTranslation::AsTableImpl(const TRule_table_ref& node) {
  1295. const auto& block = node.GetBlock3();
  1296. if (block.Alt_case() == TRule_table_ref::TBlock3::kAlt2) {
  1297. auto& alt = block.GetAlt2();
  1298. TCiString func(Id(alt.GetRule_an_id_expr1(), *this));
  1299. if (func == "as_table") {
  1300. if (node.HasBlock1()) {
  1301. Ctx.Error() << "Cluster shouldn't be specified for AS_TABLE source";
  1302. return TMaybe<TSourcePtr>(nullptr);
  1303. }
  1304. if (!alt.HasBlock3() || !alt.GetBlock3().GetBlock2().empty()) {
  1305. Ctx.Error() << "Expected single argument for AS_TABLE source";
  1306. return TMaybe<TSourcePtr>(nullptr);
  1307. }
  1308. if (node.HasBlock4()) {
  1309. Ctx.Error() << "No hints expected for AS_TABLE source";
  1310. return TMaybe<TSourcePtr>(nullptr);
  1311. }
  1312. auto arg = TableArgImpl(alt.GetBlock3().GetRule_table_arg1());
  1313. if (!arg) {
  1314. return TMaybe<TSourcePtr>(nullptr);
  1315. }
  1316. if (arg->Expr->GetSource()) {
  1317. Ctx.Error() << "AS_TABLE shouldn't be used for table sources";
  1318. return TMaybe<TSourcePtr>(nullptr);
  1319. }
  1320. return BuildNodeSource(Ctx.Pos(), arg->Expr, true, Ctx.EmitTableSource);
  1321. }
  1322. }
  1323. return Nothing();
  1324. }
  1325. TMaybe<TColumnConstraints> ColumnConstraints(const TRule_column_schema& node, TTranslation& ctx) {
  1326. TNodePtr defaultExpr = nullptr;
  1327. bool nullable = true;
  1328. auto constraintsNode = node.GetRule_opt_column_constraints4();
  1329. if (constraintsNode.HasBlock1()) {
  1330. nullable = !constraintsNode.GetBlock1().HasBlock1();
  1331. }
  1332. if (constraintsNode.HasBlock2()) {
  1333. TSqlExpression expr(ctx.Context(), ctx.Context().Settings.Mode);
  1334. defaultExpr = expr.Build(constraintsNode.GetBlock2().GetRule_expr2());
  1335. if (!defaultExpr) {
  1336. return {};
  1337. }
  1338. }
  1339. return TColumnConstraints(defaultExpr, nullable);
  1340. }
  1341. TMaybe<TColumnSchema> TSqlTranslation::ColumnSchemaImpl(const TRule_column_schema& node) {
  1342. const TString name(Id(node.GetRule_an_id_schema1(), *this));
  1343. const TPosition pos(Context().Pos());
  1344. TNodePtr type = SerialTypeNode(node.GetRule_type_name_or_bind2());
  1345. const bool serial = (type != nullptr);
  1346. const auto constraints = ColumnConstraints(node, *this);
  1347. if (!constraints){
  1348. return {};
  1349. }
  1350. if (!type) {
  1351. type = TypeNodeOrBind(node.GetRule_type_name_or_bind2());
  1352. }
  1353. if (!type) {
  1354. return {};
  1355. }
  1356. TVector<TIdentifier> families;
  1357. if (node.HasBlock3()) {
  1358. const auto& familyRelation = node.GetBlock3().GetRule_family_relation1();
  1359. families.push_back(IdEx(familyRelation.GetRule_an_id2(), *this));
  1360. }
  1361. return TColumnSchema(pos, name, type, constraints->Nullable, families, serial, constraints->DefaultExpr);
  1362. }
  1363. TNodePtr TSqlTranslation::SerialTypeNode(const TRule_type_name_or_bind& node) {
  1364. if (node.Alt_case() != TRule_type_name_or_bind::kAltTypeNameOrBind1) {
  1365. return nullptr;
  1366. }
  1367. TPosition pos = Ctx.Pos();
  1368. auto typeNameNode = node.GetAlt_type_name_or_bind1().GetRule_type_name1();
  1369. if (typeNameNode.Alt_case() != TRule_type_name::kAltTypeName2) {
  1370. return nullptr;
  1371. }
  1372. auto alt = typeNameNode.GetAlt_type_name2();
  1373. auto& block = alt.GetBlock1();
  1374. if (block.Alt_case() != TRule_type_name::TAlt2::TBlock1::kAlt2) {
  1375. return nullptr;
  1376. }
  1377. auto alt2 = block.GetAlt2().GetRule_type_name_simple1();
  1378. const TString name = Id(alt2.GetRule_an_id_pure1(), *this);
  1379. if (name.empty()) {
  1380. return nullptr;
  1381. }
  1382. const auto res = to_lower(name);
  1383. if (res == "bigserial" || res == "serial8") {
  1384. return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Int64", TNodeFlags::Default) });
  1385. } else if (res == "serial" || res == "serial4") {
  1386. return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Int32", TNodeFlags::Default) });
  1387. } else if (res == "smallserial" || res == "serial2") {
  1388. return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Int16", TNodeFlags::Default) });
  1389. }
  1390. return nullptr;
  1391. }
  1392. bool StoreString(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx) {
  1393. switch (from.Alt_case()) {
  1394. case TRule_family_setting_value::kAltFamilySettingValue1: {
  1395. // STRING_VALUE
  1396. const TString stringValue(ctx.Token(from.GetAlt_family_setting_value1().GetToken1()));
  1397. TNodePtr literal = BuildLiteralSmartString(ctx, stringValue);
  1398. if (!literal) {
  1399. return false;
  1400. }
  1401. to = literal;
  1402. break;
  1403. }
  1404. default:
  1405. return false;
  1406. }
  1407. return true;
  1408. }
  1409. bool StoreInt(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx) {
  1410. switch (from.Alt_case()) {
  1411. case TRule_family_setting_value::kAltFamilySettingValue2: {
  1412. // integer
  1413. TNodePtr literal = LiteralNumber(ctx, from.GetAlt_family_setting_value2().GetRule_integer1());
  1414. if (!literal) {
  1415. return false;
  1416. }
  1417. to = literal;
  1418. break;
  1419. }
  1420. default:
  1421. return false;
  1422. }
  1423. return true;
  1424. }
  1425. bool TSqlTranslation::FillFamilySettingsEntry(const TRule_family_settings_entry& settingNode, TFamilyEntry& family) {
  1426. TIdentifier id = IdEx(settingNode.GetRule_an_id1(), *this);
  1427. const TRule_family_setting_value& value = settingNode.GetRule_family_setting_value3();
  1428. if (to_lower(id.Name) == "data") {
  1429. if (!StoreString(value, family.Data, Ctx)) {
  1430. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  1431. return false;
  1432. }
  1433. } else if (to_lower(id.Name) == "compression") {
  1434. if (!StoreString(value, family.Compression, Ctx)) {
  1435. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  1436. return false;
  1437. }
  1438. } else if (to_lower(id.Name) == "compression_level") {
  1439. if (!StoreInt(value, family.CompressionLevel, Ctx)) {
  1440. Ctx.Error() << to_upper(id.Name) << " value should be an integer";
  1441. return false;
  1442. }
  1443. } else {
  1444. Ctx.Error() << "Unknown table setting: " << id.Name;
  1445. return false;
  1446. }
  1447. return true;
  1448. }
  1449. bool TSqlTranslation::FillFamilySettings(const TRule_family_settings& settingsNode, TFamilyEntry& family) {
  1450. // family_settings: LPAREN (family_settings_entry (COMMA family_settings_entry)*)? RPAREN;
  1451. if (settingsNode.HasBlock2()) {
  1452. auto& settings = settingsNode.GetBlock2();
  1453. if (!FillFamilySettingsEntry(settings.GetRule_family_settings_entry1(), family)) {
  1454. return false;
  1455. }
  1456. for (auto& block : settings.GetBlock2()) {
  1457. if (!FillFamilySettingsEntry(block.GetRule_family_settings_entry2(), family)) {
  1458. return false;
  1459. }
  1460. }
  1461. }
  1462. return true;
  1463. }
  1464. bool TSqlTranslation::CreateTableEntry(const TRule_create_table_entry& node, TCreateTableParameters& params, const bool isCreateTableAs)
  1465. {
  1466. switch (node.Alt_case()) {
  1467. case TRule_create_table_entry::kAltCreateTableEntry1:
  1468. {
  1469. if (isCreateTableAs) {
  1470. Ctx.Error() << "Column types are not supported for CREATE TABLE AS";
  1471. return false;
  1472. }
  1473. // column_schema
  1474. auto columnSchema = ColumnSchemaImpl(node.GetAlt_create_table_entry1().GetRule_column_schema1());
  1475. if (!columnSchema) {
  1476. return false;
  1477. }
  1478. if (columnSchema->Families.size() > 1) {
  1479. Ctx.Error() << "Several column families for a single column are not yet supported";
  1480. return false;
  1481. }
  1482. params.Columns.push_back(*columnSchema);
  1483. break;
  1484. }
  1485. case TRule_create_table_entry::kAltCreateTableEntry2:
  1486. {
  1487. // table_constraint
  1488. auto& constraint = node.GetAlt_create_table_entry2().GetRule_table_constraint1();
  1489. switch (constraint.Alt_case()) {
  1490. case TRule_table_constraint::kAltTableConstraint1: {
  1491. if (!params.PkColumns.empty()) {
  1492. Ctx.Error() << "PRIMARY KEY statement must be specified only once";
  1493. return false;
  1494. }
  1495. auto& pkConstraint = constraint.GetAlt_table_constraint1();
  1496. params.PkColumns.push_back(IdEx(pkConstraint.GetRule_an_id4(), *this));
  1497. for (auto& block : pkConstraint.GetBlock5()) {
  1498. params.PkColumns.push_back(IdEx(block.GetRule_an_id2(), *this));
  1499. }
  1500. break;
  1501. }
  1502. case TRule_table_constraint::kAltTableConstraint2: {
  1503. if (!params.PartitionByColumns.empty()) {
  1504. Ctx.Error() << "PARTITION BY statement must be specified only once";
  1505. return false;
  1506. }
  1507. auto& pbConstraint = constraint.GetAlt_table_constraint2();
  1508. params.PartitionByColumns.push_back(IdEx(pbConstraint.GetRule_an_id4(), *this));
  1509. for (auto& block : pbConstraint.GetBlock5()) {
  1510. params.PartitionByColumns.push_back(IdEx(block.GetRule_an_id2(), *this));
  1511. }
  1512. break;
  1513. }
  1514. case TRule_table_constraint::kAltTableConstraint3: {
  1515. if (!params.OrderByColumns.empty()) {
  1516. Ctx.Error() << "ORDER BY statement must be specified only once";
  1517. return false;
  1518. }
  1519. auto& obConstraint = constraint.GetAlt_table_constraint3();
  1520. auto extractDirection = [this] (const TRule_column_order_by_specification& spec, bool& desc) {
  1521. desc = false;
  1522. if (!spec.HasBlock2()) {
  1523. return true;
  1524. }
  1525. auto& token = spec.GetBlock2().GetToken1();
  1526. auto tokenId = token.GetId();
  1527. if (IS_TOKEN(tokenId, ASC)) {
  1528. return true;
  1529. } else if (IS_TOKEN(tokenId, DESC)) {
  1530. desc = true;
  1531. return true;
  1532. } else {
  1533. Ctx.Error() << "Unsupported direction token: " << token.GetId();
  1534. return false;
  1535. }
  1536. };
  1537. bool desc = false;
  1538. auto& obSpec = obConstraint.GetRule_column_order_by_specification4();
  1539. if (!extractDirection(obSpec, desc)) {
  1540. return false;
  1541. }
  1542. params.OrderByColumns.push_back(std::make_pair(IdEx(obSpec.GetRule_an_id1(), *this), desc));
  1543. for (auto& block : obConstraint.GetBlock5()) {
  1544. auto& obSpec = block.GetRule_column_order_by_specification2();
  1545. if (!extractDirection(obSpec, desc)) {
  1546. return false;
  1547. }
  1548. params.OrderByColumns.push_back(std::make_pair(IdEx(obSpec.GetRule_an_id1(), *this), desc));
  1549. }
  1550. break;
  1551. }
  1552. default:
  1553. AltNotImplemented("table_constraint", constraint);
  1554. return false;
  1555. }
  1556. break;
  1557. }
  1558. case TRule_create_table_entry::kAltCreateTableEntry3:
  1559. {
  1560. // table_index
  1561. auto& table_index = node.GetAlt_create_table_entry3().GetRule_table_index1();
  1562. if (!CreateTableIndex(table_index, params.Indexes)) {
  1563. return false;
  1564. }
  1565. break;
  1566. }
  1567. case TRule_create_table_entry::kAltCreateTableEntry4:
  1568. {
  1569. if (isCreateTableAs) {
  1570. Ctx.Error() << "Column families are not supported for CREATE TABLE AS";
  1571. return false;
  1572. }
  1573. // family_entry
  1574. auto& family_entry = node.GetAlt_create_table_entry4().GetRule_family_entry1();
  1575. TFamilyEntry family(IdEx(family_entry.GetRule_an_id2(), *this));
  1576. if (!FillFamilySettings(family_entry.GetRule_family_settings3(), family)) {
  1577. return false;
  1578. }
  1579. params.ColumnFamilies.push_back(family);
  1580. break;
  1581. }
  1582. case TRule_create_table_entry::kAltCreateTableEntry5:
  1583. {
  1584. // changefeed
  1585. auto& changefeed = node.GetAlt_create_table_entry5().GetRule_changefeed1();
  1586. TSqlExpression expr(Ctx, Mode);
  1587. if (!CreateChangefeed(changefeed, expr, params.Changefeeds)) {
  1588. return false;
  1589. }
  1590. break;
  1591. }
  1592. case TRule_create_table_entry::kAltCreateTableEntry6:
  1593. {
  1594. if (!isCreateTableAs) {
  1595. Ctx.Error() << "Column requires a type";
  1596. return false;
  1597. }
  1598. // an_id_schema
  1599. const TString name(Id(node.GetAlt_create_table_entry6().GetRule_an_id_schema1(), *this));
  1600. const TPosition pos(Context().Pos());
  1601. params.Columns.push_back(TColumnSchema(pos, name, nullptr, true, {}, false, nullptr));
  1602. break;
  1603. }
  1604. default:
  1605. AltNotImplemented("create_table_entry", node);
  1606. return false;
  1607. }
  1608. return true;
  1609. }
  1610. namespace {
  1611. bool StoreId(const TRule_table_setting_value& from, TMaybe<TIdentifier>& to, TTranslation& ctx) {
  1612. switch (from.Alt_case()) {
  1613. case TRule_table_setting_value::kAltTableSettingValue1: {
  1614. // id
  1615. to = IdEx(from.GetAlt_table_setting_value1().GetRule_id1(), ctx);
  1616. break;
  1617. }
  1618. default:
  1619. return false;
  1620. }
  1621. return true;
  1622. }
  1623. bool StoreString(const TRule_table_setting_value& from, TNodePtr& to, TContext& ctx) {
  1624. switch (from.Alt_case()) {
  1625. case TRule_table_setting_value::kAltTableSettingValue2: {
  1626. // STRING_VALUE
  1627. const TString stringValue(ctx.Token(from.GetAlt_table_setting_value2().GetToken1()));
  1628. to = BuildLiteralSmartString(ctx, stringValue);
  1629. break;
  1630. }
  1631. default:
  1632. return false;
  1633. }
  1634. return true;
  1635. }
  1636. bool StoreString(const TRule_table_setting_value& from, TDeferredAtom& to, TContext& ctx, const TString& errorPrefix = {}) {
  1637. switch (from.Alt_case()) {
  1638. case TRule_table_setting_value::kAltTableSettingValue2: {
  1639. // STRING_VALUE
  1640. const TString stringValue(ctx.Token(from.GetAlt_table_setting_value2().GetToken1()));
  1641. auto unescaped = StringContent(ctx, ctx.Pos(), stringValue);
  1642. if (!unescaped) {
  1643. ctx.Error() << errorPrefix << " value cannot be unescaped";
  1644. return false;
  1645. }
  1646. to = TDeferredAtom(ctx.Pos(), unescaped->Content);
  1647. break;
  1648. }
  1649. default:
  1650. ctx.Error() << errorPrefix << " value should be a string literal";
  1651. return false;
  1652. }
  1653. return true;
  1654. }
  1655. bool StoreInt(const TRule_table_setting_value& from, TNodePtr& to, TContext& ctx) {
  1656. switch (from.Alt_case()) {
  1657. case TRule_table_setting_value::kAltTableSettingValue3: {
  1658. // integer
  1659. to = LiteralNumber(ctx, from.GetAlt_table_setting_value3().GetRule_integer1());
  1660. break;
  1661. }
  1662. default:
  1663. return false;
  1664. }
  1665. return true;
  1666. }
  1667. bool StoreInt(const TRule_table_setting_value& from, TDeferredAtom& to, TContext& ctx, const TString& errorPrefix = {}) {
  1668. switch (from.Alt_case()) {
  1669. case TRule_table_setting_value::kAltTableSettingValue3: {
  1670. // integer
  1671. to = TDeferredAtom(LiteralNumber(ctx, from.GetAlt_table_setting_value3().GetRule_integer1()), ctx);
  1672. break;
  1673. }
  1674. default:
  1675. ctx.Error() << errorPrefix << " value should be an integer";
  1676. return false;
  1677. }
  1678. return true;
  1679. }
  1680. bool StoreSplitBoundary(const TRule_literal_value_list& boundary, TVector<TVector<TNodePtr>>& to,
  1681. TSqlExpression& expr, TContext& ctx) {
  1682. TVector<TNodePtr> boundaryKeys;
  1683. auto first_key = expr.LiteralExpr(boundary.GetRule_literal_value2());
  1684. if (!first_key) {
  1685. ctx.Error() << "Empty key in partition at keys";
  1686. return false;
  1687. }
  1688. if (!first_key->Expr) {
  1689. ctx.Error() << "Identifier is not expected in partition at keys";
  1690. return false;
  1691. }
  1692. boundaryKeys.emplace_back(first_key->Expr);
  1693. for (auto& key : boundary.GetBlock3()) {
  1694. auto keyExprOrIdent = expr.LiteralExpr(key.GetRule_literal_value2());
  1695. if (!keyExprOrIdent) {
  1696. ctx.Error() << "Empty key in partition at keys";
  1697. return false;
  1698. }
  1699. if (!keyExprOrIdent->Expr) {
  1700. ctx.Error() << "Identifier is not expected in partition at keys";
  1701. return false;
  1702. }
  1703. boundaryKeys.emplace_back(keyExprOrIdent->Expr);
  1704. }
  1705. to.push_back(boundaryKeys);
  1706. return true;
  1707. }
  1708. bool StoreSplitBoundaries(const TRule_table_setting_value& from, TVector<TVector<TNodePtr>>& to,
  1709. TSqlExpression& expr, TContext& ctx) {
  1710. switch (from.Alt_case()) {
  1711. case TRule_table_setting_value::kAltTableSettingValue4: {
  1712. // split_boundaries
  1713. const auto& boundariesNode = from.GetAlt_table_setting_value4().GetRule_split_boundaries1();
  1714. switch (boundariesNode.Alt_case()) {
  1715. case TRule_split_boundaries::kAltSplitBoundaries1: {
  1716. // literal_value_list (COMMA literal_value_list)*
  1717. auto& complexBoundaries = boundariesNode.GetAlt_split_boundaries1();
  1718. auto& first_boundary = complexBoundaries.GetRule_literal_value_list2();
  1719. if (!StoreSplitBoundary(first_boundary, to, expr, ctx)) {
  1720. return false;
  1721. }
  1722. for (auto& boundary : complexBoundaries.GetBlock3()) {
  1723. if (!StoreSplitBoundary(boundary.GetRule_literal_value_list2(), to, expr, ctx)) {
  1724. return false;
  1725. }
  1726. }
  1727. break;
  1728. }
  1729. case TRule_split_boundaries::kAltSplitBoundaries2: {
  1730. // literal_value_list
  1731. auto& simpleBoundaries = boundariesNode.GetAlt_split_boundaries2().GetRule_literal_value_list1();
  1732. auto first_key = expr.LiteralExpr(simpleBoundaries.GetRule_literal_value2());
  1733. if (!first_key) {
  1734. ctx.Error() << "Empty key in partition at keys";
  1735. return false;
  1736. }
  1737. if (!first_key->Expr) {
  1738. ctx.Error() << "Identifier is not expected in partition at keys";
  1739. return false;
  1740. }
  1741. to.push_back(TVector<TNodePtr>(1, first_key->Expr));
  1742. for (auto& key : simpleBoundaries.GetBlock3()) {
  1743. auto keyExprOrIdent = expr.LiteralExpr(key.GetRule_literal_value2());
  1744. if (!keyExprOrIdent) {
  1745. ctx.Error() << "Empty key in partition at keys";
  1746. return false;
  1747. }
  1748. if (!first_key->Expr) {
  1749. ctx.Error() << "Identifier is not expected in partition at keys";
  1750. return false;
  1751. }
  1752. to.push_back(
  1753. TVector<TNodePtr>(1, keyExprOrIdent->Expr)
  1754. );
  1755. }
  1756. break;
  1757. }
  1758. default:
  1759. return false;
  1760. }
  1761. break;
  1762. }
  1763. default:
  1764. return false;
  1765. }
  1766. return true;
  1767. }
  1768. bool FillTieringInterval(const TRule_expr& from, TNodePtr& tieringInterval, TSqlExpression& expr, TContext& ctx) {
  1769. auto exprNode = expr.Build(from);
  1770. if (!exprNode) {
  1771. return false;
  1772. }
  1773. if (exprNode->GetOpName() != "Interval") {
  1774. ctx.Error() << "Literal of Interval type is expected for TTL";
  1775. return false;
  1776. }
  1777. tieringInterval = exprNode;
  1778. return true;
  1779. }
  1780. bool FillTierAction(const TRule_ttl_tier_action& from, std::optional<TIdentifier>& storageName, TTranslation& txc) {
  1781. switch (from.GetAltCase()) {
  1782. case TRule_ttl_tier_action::kAltTtlTierAction1:
  1783. storageName = IdEx(from.GetAlt_ttl_tier_action1().GetRule_an_id5(), txc);
  1784. break;
  1785. case TRule_ttl_tier_action::kAltTtlTierAction2:
  1786. storageName.reset();
  1787. break;
  1788. case TRule_ttl_tier_action::ALT_NOT_SET:
  1789. Y_ABORT("You should change implementation according to grammar changes");
  1790. }
  1791. return true;
  1792. }
  1793. bool StoreTtlSettings(const TRule_table_setting_value& from, TResetableSetting<TTtlSettings, void>& to, TSqlExpression& expr, TContext& ctx,
  1794. TTranslation& txc) {
  1795. switch (from.Alt_case()) {
  1796. case TRule_table_setting_value::kAltTableSettingValue5: {
  1797. auto columnName = IdEx(from.GetAlt_table_setting_value5().GetRule_an_id3(), txc);
  1798. auto tiersLiteral = from.GetAlt_table_setting_value5().GetRule_ttl_tier_list1();
  1799. TNodePtr firstInterval;
  1800. if (!FillTieringInterval(tiersLiteral.GetRule_expr1(), firstInterval, expr, ctx)) {
  1801. return false;
  1802. }
  1803. std::vector<TTtlSettings::TTierSettings> tiers;
  1804. if (!tiersLiteral.HasBlock2()) {
  1805. tiers.emplace_back(firstInterval);
  1806. } else {
  1807. std::optional<TIdentifier> firstStorageName;
  1808. if (!FillTierAction(tiersLiteral.GetBlock2().GetRule_ttl_tier_action1(), firstStorageName, txc)) {
  1809. return false;
  1810. }
  1811. tiers.emplace_back(firstInterval, firstStorageName);
  1812. for (const auto& tierLiteral : tiersLiteral.GetBlock2().GetBlock2()) {
  1813. TNodePtr intervalExpr;
  1814. if (!FillTieringInterval(tierLiteral.GetRule_expr2(), intervalExpr, expr, ctx)) {
  1815. return false;
  1816. }
  1817. std::optional<TIdentifier> storageName;
  1818. if (!FillTierAction(tierLiteral.GetRule_ttl_tier_action3(), storageName, txc)) {
  1819. return false;
  1820. }
  1821. tiers.emplace_back(intervalExpr, storageName);
  1822. }
  1823. }
  1824. TMaybe<TTtlSettings::EUnit> columnUnit;
  1825. if (from.GetAlt_table_setting_value5().HasBlock4()) {
  1826. const TString unit = to_lower(ctx.Token(from.GetAlt_table_setting_value5().GetBlock4().GetToken2()));
  1827. columnUnit.ConstructInPlace();
  1828. if (!TryFromString<TTtlSettings::EUnit>(unit, *columnUnit)) {
  1829. ctx.Error() << "Invalid unit: " << unit;
  1830. return false;
  1831. }
  1832. }
  1833. to.Set(TTtlSettings(columnName, tiers, columnUnit));
  1834. break;
  1835. }
  1836. default:
  1837. return false;
  1838. }
  1839. return true;
  1840. }
  1841. template<typename TChar>
  1842. struct TPatternComponent {
  1843. TBasicString<TChar> Prefix;
  1844. TBasicString<TChar> Suffix;
  1845. bool IsSimple = true;
  1846. void AppendPlain(TChar c) {
  1847. if (IsSimple) {
  1848. Prefix.push_back(c);
  1849. }
  1850. Suffix.push_back(c);
  1851. }
  1852. void AppendAnyChar() {
  1853. IsSimple = false;
  1854. Suffix.clear();
  1855. }
  1856. };
  1857. template<typename TChar>
  1858. TVector<TPatternComponent<TChar>> SplitPattern(const TBasicString<TChar>& pattern, TMaybe<char> escape, bool& inEscape) {
  1859. inEscape = false;
  1860. TVector<TPatternComponent<TChar>> result;
  1861. TPatternComponent<TChar> current;
  1862. bool prevIsPercentChar = false;
  1863. for (const TChar c : pattern) {
  1864. if (inEscape) {
  1865. current.AppendPlain(c);
  1866. inEscape = false;
  1867. prevIsPercentChar = false;
  1868. } else if (escape && c == static_cast<TChar>(*escape)) {
  1869. inEscape = true;
  1870. } else if (c == '%') {
  1871. if (!prevIsPercentChar) {
  1872. result.push_back(std::move(current));
  1873. }
  1874. current = {};
  1875. prevIsPercentChar = true;
  1876. } else if (c == '_') {
  1877. current.AppendAnyChar();
  1878. prevIsPercentChar = false;
  1879. } else {
  1880. current.AppendPlain(c);
  1881. prevIsPercentChar = false;
  1882. }
  1883. }
  1884. result.push_back(std::move(current));
  1885. return result;
  1886. }
  1887. }
  1888. bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value,
  1889. TTableSettings& settings, ETableType tableType, bool alter, bool reset) {
  1890. switch (tableType) {
  1891. case ETableType::ExternalTable:
  1892. return StoreExternalTableSettingsEntry(id, value, settings, alter, reset);
  1893. case ETableType::Table:
  1894. case ETableType::TableStore:
  1895. return StoreTableSettingsEntry(id, value, settings, alter, reset);
  1896. }
  1897. }
  1898. bool TSqlTranslation::StoreExternalTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value,
  1899. TTableSettings& settings, bool alter, bool reset) {
  1900. YQL_ENSURE(value || reset);
  1901. YQL_ENSURE(!reset || reset && alter);
  1902. if (to_lower(id.Name) == "data_source") {
  1903. if (reset) {
  1904. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  1905. return false;
  1906. }
  1907. TDeferredAtom dataSource;
  1908. if (!StoreString(*value, dataSource, Ctx, to_upper(id.Name))) {
  1909. return false;
  1910. }
  1911. TString service = Context().Scoped->CurrService;
  1912. TDeferredAtom cluster = Context().Scoped->CurrCluster;
  1913. TNodePtr root = new TAstListNodeImpl(Ctx.Pos());
  1914. root->Add("String", Ctx.GetPrefixedPath(service, cluster, dataSource));
  1915. settings.DataSourcePath = root;
  1916. } else if (to_lower(id.Name) == "location") {
  1917. if (reset) {
  1918. settings.Location.Reset();
  1919. } else {
  1920. TNodePtr location;
  1921. if (!StoreString(*value, location, Ctx)) {
  1922. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  1923. return false;
  1924. }
  1925. settings.Location.Set(location);
  1926. }
  1927. } else {
  1928. auto& setting = settings.ExternalSourceParameters.emplace_back();
  1929. if (reset) {
  1930. setting.Reset(id);
  1931. } else {
  1932. TNodePtr node;
  1933. if (!StoreString(*value, node, Ctx)) {
  1934. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  1935. return false;
  1936. }
  1937. setting.Set(std::pair<TIdentifier, TNodePtr>{id, std::move(node)});
  1938. }
  1939. }
  1940. return true;
  1941. }
  1942. bool TSqlTranslation::ValidateTableSettings(const TTableSettings& settings) {
  1943. if (settings.PartitionCount) {
  1944. if (!settings.StoreType || to_lower(settings.StoreType->Name) != "column") {
  1945. Ctx.Error() << " PARTITION_COUNT can be used only with STORE=COLUMN";
  1946. return false;
  1947. }
  1948. }
  1949. return true;
  1950. }
  1951. bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value,
  1952. TTableSettings& settings, bool alter, bool reset) {
  1953. YQL_ENSURE(value || reset);
  1954. YQL_ENSURE(!reset || reset && alter);
  1955. if (to_lower(id.Name) == "compaction_policy") {
  1956. if (reset) {
  1957. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  1958. return false;
  1959. }
  1960. if (!StoreString(*value, settings.CompactionPolicy, Ctx)) {
  1961. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  1962. return false;
  1963. }
  1964. } else if (to_lower(id.Name) == "auto_partitioning_by_size") {
  1965. if (reset) {
  1966. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  1967. return false;
  1968. }
  1969. if (!StoreId(*value, settings.AutoPartitioningBySize, *this)) {
  1970. Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
  1971. return false;
  1972. }
  1973. } else if (to_lower(id.Name) == "auto_partitioning_partition_size_mb") {
  1974. if (reset) {
  1975. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  1976. return false;
  1977. }
  1978. if (!StoreInt(*value, settings.PartitionSizeMb, Ctx)) {
  1979. Ctx.Error() << to_upper(id.Name) << " value should be an integer";
  1980. return false;
  1981. }
  1982. } else if (to_lower(id.Name) == "auto_partitioning_by_load") {
  1983. if (reset) {
  1984. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  1985. return false;
  1986. }
  1987. if (!StoreId(*value, settings.AutoPartitioningByLoad, *this)) {
  1988. Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
  1989. return false;
  1990. }
  1991. } else if (to_lower(id.Name) == "auto_partitioning_min_partitions_count") {
  1992. if (reset) {
  1993. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  1994. return false;
  1995. }
  1996. if (!StoreInt(*value, settings.MinPartitions, Ctx)) {
  1997. Ctx.Error() << to_upper(id.Name) << " value should be an integer";
  1998. return false;
  1999. }
  2000. } else if (to_lower(id.Name) == "auto_partitioning_max_partitions_count") {
  2001. if (reset) {
  2002. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2003. return false;
  2004. }
  2005. if (!StoreInt(*value, settings.MaxPartitions, Ctx)) {
  2006. Ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2007. return false;
  2008. }
  2009. } else if (to_lower(id.Name) == "partition_count") {
  2010. if (reset) {
  2011. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2012. return false;
  2013. }
  2014. if (!StoreInt(*value, settings.PartitionCount, Ctx)) {
  2015. Ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2016. return false;
  2017. }
  2018. } else if (to_lower(id.Name) == "uniform_partitions") {
  2019. if (alter) {
  2020. Ctx.Error() << to_upper(id.Name) << " alter is not supported";
  2021. return false;
  2022. }
  2023. if (!StoreInt(*value, settings.UniformPartitions, Ctx)) {
  2024. Ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2025. return false;
  2026. }
  2027. } else if (to_lower(id.Name) == "partition_at_keys") {
  2028. if (alter) {
  2029. Ctx.Error() << to_upper(id.Name) << " alter is not supported";
  2030. return false;
  2031. }
  2032. TSqlExpression expr(Ctx, Mode);
  2033. if (!StoreSplitBoundaries(*value, settings.PartitionAtKeys, expr, Ctx)) {
  2034. Ctx.Error() << to_upper(id.Name) << " value should be a list of keys. "
  2035. << "Example1: (10, 1000) Example2: ((10), (1000, \"abc\"))";
  2036. return false;
  2037. }
  2038. } else if (to_lower(id.Name) == "key_bloom_filter") {
  2039. if (reset) {
  2040. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2041. return false;
  2042. }
  2043. if (!StoreId(*value, settings.KeyBloomFilter, *this)) {
  2044. Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
  2045. return false;
  2046. }
  2047. } else if (to_lower(id.Name) == "read_replicas_settings") {
  2048. if (reset) {
  2049. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2050. return false;
  2051. }
  2052. if (!StoreString(*value, settings.ReadReplicasSettings, Ctx)) {
  2053. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  2054. return false;
  2055. }
  2056. } else if (to_lower(id.Name) == "ttl") {
  2057. if (!reset) {
  2058. TSqlExpression expr(Ctx, Mode);
  2059. if (!StoreTtlSettings(*value, settings.TtlSettings, expr, Ctx, *this)) {
  2060. Ctx.Error() << "Invalid TTL settings";
  2061. return false;
  2062. }
  2063. } else {
  2064. settings.TtlSettings.Reset();
  2065. }
  2066. } else if (to_lower(id.Name) == "tiering") {
  2067. if (!reset) {
  2068. TNodePtr tieringNode;
  2069. if (!StoreString(*value, tieringNode, Ctx)) {
  2070. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  2071. return false;
  2072. }
  2073. settings.Tiering.Set(tieringNode);
  2074. } else {
  2075. settings.Tiering.Reset();
  2076. }
  2077. } else if (to_lower(id.Name) == "store") {
  2078. if (reset) {
  2079. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2080. return false;
  2081. }
  2082. if (!StoreId(*value, settings.StoreType, *this)) {
  2083. Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
  2084. return false;
  2085. }
  2086. } else if (to_lower(id.Name) == "partition_by_hash_function") {
  2087. if (reset) {
  2088. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2089. return false;
  2090. }
  2091. if (!StoreString(*value, settings.PartitionByHashFunction, Ctx)) {
  2092. Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  2093. return false;
  2094. }
  2095. } else if (to_lower(id.Name) == "store_external_blobs") {
  2096. if (reset) {
  2097. Ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2098. return false;
  2099. }
  2100. if (!StoreId(*value, settings.StoreExternalBlobs, *this)) {
  2101. Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
  2102. return false;
  2103. }
  2104. } else {
  2105. Ctx.Error() << "Unknown table setting: " << id.Name;
  2106. return false;
  2107. }
  2108. return ValidateTableSettings(settings);
  2109. }
  2110. bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value& value,
  2111. TTableSettings& settings, ETableType tableType, bool alter) {
  2112. return StoreTableSettingsEntry(id, &value, settings, tableType, alter, false);
  2113. }
  2114. bool TSqlTranslation::ResetTableSettingsEntry(const TIdentifier& id, TTableSettings& settings, ETableType tableType) {
  2115. return StoreTableSettingsEntry(id, nullptr, settings, tableType, true, true);
  2116. }
  2117. bool TSqlTranslation::CreateTableSettings(const TRule_with_table_settings& settingsNode, TCreateTableParameters& params) {
  2118. const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
  2119. if (!StoreTableSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), firstEntry.GetRule_table_setting_value3(),
  2120. params.TableSettings, params.TableType)) {
  2121. return false;
  2122. }
  2123. for (auto& block : settingsNode.GetBlock4()) {
  2124. const auto& entry = block.GetRule_table_settings_entry2();
  2125. if (!StoreTableSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), entry.GetRule_table_setting_value3(), params.TableSettings, params.TableType)) {
  2126. return false;
  2127. }
  2128. }
  2129. return true;
  2130. }
  2131. bool StoreConsumerSettingsEntry(
  2132. const TIdentifier& id, const TRule_topic_consumer_setting_value* value, TSqlExpression& ctx,
  2133. TTopicConsumerSettings& settings,
  2134. bool reset
  2135. ) {
  2136. YQL_ENSURE(value || reset);
  2137. TNodePtr valueExprNode;
  2138. if (value) {
  2139. valueExprNode = ctx.Build(value->GetRule_expr1());
  2140. if (!valueExprNode) {
  2141. ctx.Error() << "invalid value for setting: " << id.Name;
  2142. return false;
  2143. }
  2144. }
  2145. if (to_lower(id.Name) == "important") {
  2146. if (settings.Important) {
  2147. ctx.Error() << to_upper(id.Name) << " specified multiple times in ALTER CONSUMER statements for single consumer";
  2148. return false;
  2149. }
  2150. if (reset) {
  2151. ctx.Error() << to_upper(id.Name) << " reset is not supported";
  2152. return false;
  2153. }
  2154. if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "Bool") {
  2155. ctx.Error() << to_upper(id.Name) << " value should be boolean";
  2156. return false;
  2157. }
  2158. settings.Important = valueExprNode;
  2159. } else if (to_lower(id.Name) == "read_from") {
  2160. if (settings.ReadFromTs) {
  2161. ctx.Error() << to_upper(id.Name) << " specified multiple times in ALTER CONSUMER statements for single consumer";
  2162. return false;
  2163. }
  2164. if (reset) {
  2165. settings.ReadFromTs.Reset();
  2166. } else {
  2167. //ToDo: !! validate
  2168. settings.ReadFromTs.Set(valueExprNode);
  2169. }
  2170. } else if (to_lower(id.Name) == "supported_codecs") {
  2171. if (settings.SupportedCodecs) {
  2172. ctx.Error() << to_upper(id.Name) << " specified multiple times in ALTER CONSUMER statements for single consumer";
  2173. return false;
  2174. }
  2175. if (reset) {
  2176. settings.SupportedCodecs.Reset();
  2177. } else {
  2178. if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
  2179. ctx.Error() << to_upper(id.Name) << " value should be a string literal";
  2180. return false;
  2181. }
  2182. settings.SupportedCodecs.Set(valueExprNode);
  2183. }
  2184. } else {
  2185. ctx.Error() << to_upper(id.Name) << ": unknown option for consumer";
  2186. return false;
  2187. }
  2188. return true;
  2189. }
  2190. TIdentifier TSqlTranslation::GetTopicConsumerId(const TRule_topic_consumer_ref& node) {
  2191. return IdEx(node.GetRule_an_id_pure1(), *this);
  2192. }
  2193. bool TSqlTranslation::CreateConsumerSettings(
  2194. const TRule_topic_consumer_settings& node, TTopicConsumerSettings& settings
  2195. ) {
  2196. const auto& firstEntry = node.GetRule_topic_consumer_settings_entry1();
  2197. TSqlExpression expr(Ctx, Mode);
  2198. if (!StoreConsumerSettingsEntry(
  2199. IdEx(firstEntry.GetRule_an_id1(), *this),
  2200. &firstEntry.GetRule_topic_consumer_setting_value3(),
  2201. expr, settings, false
  2202. )) {
  2203. return false;
  2204. }
  2205. for (auto& block : node.GetBlock2()) {
  2206. const auto& entry = block.GetRule_topic_consumer_settings_entry2();
  2207. if (!StoreConsumerSettingsEntry(
  2208. IdEx(entry.GetRule_an_id1(), *this),
  2209. &entry.GetRule_topic_consumer_setting_value3(),
  2210. expr, settings, false
  2211. )) {
  2212. return false;
  2213. }
  2214. }
  2215. return true;
  2216. }
  2217. bool TSqlTranslation::CreateTopicConsumer(
  2218. const TRule_topic_create_consumer_entry& node,
  2219. TVector<TTopicConsumerDescription>& consumers
  2220. ) {
  2221. consumers.emplace_back(IdEx(node.GetRule_an_id2(), *this));
  2222. if (node.HasBlock3()) {
  2223. auto& settings = node.GetBlock3().GetRule_topic_consumer_with_settings1().GetRule_topic_consumer_settings3();
  2224. if (!CreateConsumerSettings(settings, consumers.back().Settings)) {
  2225. return false;
  2226. }
  2227. }
  2228. return true;
  2229. }
  2230. bool TSqlTranslation::AlterTopicConsumerEntry(
  2231. const TRule_alter_topic_alter_consumer_entry& node, TTopicConsumerDescription& alterConsumer
  2232. ) {
  2233. switch (node.Alt_case()) {
  2234. case TRule_alter_topic_alter_consumer_entry::kAltAlterTopicAlterConsumerEntry1:
  2235. return CreateConsumerSettings(
  2236. node.GetAlt_alter_topic_alter_consumer_entry1().GetRule_topic_alter_consumer_set1()
  2237. .GetRule_topic_consumer_settings3(),
  2238. alterConsumer.Settings
  2239. );
  2240. //case TRule_alter_topic_alter_consumer_entry::ALT_NOT_SET:
  2241. case TRule_alter_topic_alter_consumer_entry::kAltAlterTopicAlterConsumerEntry2: {
  2242. auto& resetNode = node.GetAlt_alter_topic_alter_consumer_entry2().GetRule_topic_alter_consumer_reset1();
  2243. TSqlExpression expr(Ctx, Mode);
  2244. if (!StoreConsumerSettingsEntry(
  2245. IdEx(resetNode.GetRule_an_id3(), *this),
  2246. nullptr,
  2247. expr, alterConsumer.Settings, true
  2248. )) {
  2249. return false;
  2250. }
  2251. for (auto& resetItem: resetNode.GetBlock4()) {
  2252. if (!StoreConsumerSettingsEntry(
  2253. IdEx(resetItem.GetRule_an_id2(), *this),
  2254. nullptr,
  2255. expr, alterConsumer.Settings, true
  2256. )) {
  2257. return false;
  2258. }
  2259. }
  2260. return true;
  2261. }
  2262. default:
  2263. Ctx.Error() << "unknown alter consumer action";
  2264. return false;
  2265. }
  2266. return true;
  2267. }
  2268. bool TSqlTranslation::AlterTopicConsumer(
  2269. const TRule_alter_topic_alter_consumer& node,
  2270. THashMap<TString, TTopicConsumerDescription>& alterConsumers
  2271. ) {
  2272. auto consumerId = GetTopicConsumerId(node.GetRule_topic_consumer_ref3());
  2273. TString name = to_lower(consumerId.Name);
  2274. auto iter = alterConsumers.insert(std::make_pair(
  2275. name, TTopicConsumerDescription(std::move(consumerId))
  2276. )).first;
  2277. if (!AlterTopicConsumerEntry(node.GetRule_alter_topic_alter_consumer_entry4(), iter->second)) {
  2278. return false;
  2279. }
  2280. return true;
  2281. }
  2282. bool TSqlTranslation::CreateTopicEntry(const TRule_create_topic_entry& node, TCreateTopicParameters& params) {
  2283. // Will need a switch() here if (ever) create_topic_entry gets more than 1 type of statement
  2284. auto& consumer = node.GetRule_topic_create_consumer_entry1();
  2285. if (!CreateTopicConsumer(consumer, params.Consumers)) {
  2286. return false;
  2287. }
  2288. return true;
  2289. }
  2290. static bool StoreTopicSettingsEntry(
  2291. const TIdentifier& id, const TRule_topic_setting_value* value, TSqlExpression& ctx,
  2292. TTopicSettings& settings, bool reset
  2293. ) {
  2294. YQL_ENSURE(value || reset);
  2295. TNodePtr valueExprNode;
  2296. if (value) {
  2297. valueExprNode = ctx.Build(value->GetRule_expr1());
  2298. if (!valueExprNode) {
  2299. ctx.Error() << "invalid value for setting: " << id.Name;
  2300. return false;
  2301. }
  2302. }
  2303. if (to_lower(id.Name) == "min_active_partitions") {
  2304. if (reset) {
  2305. settings.MinPartitions.Reset();
  2306. } else {
  2307. if (!valueExprNode->IsIntegerLiteral()) {
  2308. ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2309. return false;
  2310. }
  2311. settings.MinPartitions.Set(valueExprNode);
  2312. }
  2313. } else if (to_lower(id.Name) == "partition_count_limit" || to_lower(id.Name) == "max_active_partitions") {
  2314. if (reset) {
  2315. settings.MaxPartitions.Reset();
  2316. } else {
  2317. if (!valueExprNode->IsIntegerLiteral()) {
  2318. ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2319. return false;
  2320. }
  2321. settings.MaxPartitions.Set(valueExprNode);
  2322. }
  2323. } else if (to_lower(id.Name) == "retention_period") {
  2324. if (reset) {
  2325. settings.RetentionPeriod.Reset();
  2326. } else {
  2327. if (valueExprNode->GetOpName() != "Interval") {
  2328. ctx.Error() << "Literal of Interval type is expected for retention";
  2329. return false;
  2330. }
  2331. settings.RetentionPeriod.Set(valueExprNode);
  2332. }
  2333. } else if (to_lower(id.Name) == "retention_storage_mb") {
  2334. if (reset) {
  2335. settings.RetentionStorage.Reset();
  2336. } else {
  2337. if (!valueExprNode->IsIntegerLiteral()) {
  2338. ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2339. return false;
  2340. }
  2341. settings.RetentionStorage.Set(valueExprNode);
  2342. }
  2343. } else if (to_lower(id.Name) == "partition_write_speed_bytes_per_second") {
  2344. if (reset) {
  2345. settings.PartitionWriteSpeed.Reset();
  2346. } else {
  2347. if (!valueExprNode->IsIntegerLiteral()) {
  2348. ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2349. return false;
  2350. }
  2351. settings.PartitionWriteSpeed.Set(valueExprNode);
  2352. }
  2353. } else if (to_lower(id.Name) == "partition_write_burst_bytes") {
  2354. if (reset) {
  2355. settings.PartitionWriteBurstSpeed.Reset();
  2356. } else {
  2357. if (!valueExprNode->IsIntegerLiteral()) {
  2358. ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2359. return false;
  2360. }
  2361. settings.PartitionWriteBurstSpeed.Set(valueExprNode);
  2362. }
  2363. } else if (to_lower(id.Name) == "metering_mode") {
  2364. if (reset) {
  2365. settings.MeteringMode.Reset();
  2366. } else {
  2367. if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
  2368. ctx.Error() << to_upper(id.Name) << " value should be string";
  2369. return false;
  2370. }
  2371. settings.MeteringMode.Set(valueExprNode);
  2372. }
  2373. } else if (to_lower(id.Name) == "supported_codecs") {
  2374. if (reset) {
  2375. settings.SupportedCodecs.Reset();
  2376. } else {
  2377. if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
  2378. ctx.Error() << to_upper(id.Name) << " value should be string";
  2379. return false;
  2380. }
  2381. settings.SupportedCodecs.Set(valueExprNode);
  2382. }
  2383. } else if (to_lower(id.Name) == "auto_partitioning_stabilization_window") {
  2384. if (reset) {
  2385. settings.AutoPartitioningStabilizationWindow.Reset();
  2386. } else {
  2387. if (valueExprNode->GetOpName() != "Interval") {
  2388. ctx.Error() << "Literal of Interval type is expected for retention";
  2389. return false;
  2390. }
  2391. settings.AutoPartitioningStabilizationWindow.Set(valueExprNode);
  2392. }
  2393. } else if (to_lower(id.Name) == "auto_partitioning_up_utilization_percent") {
  2394. if (reset) {
  2395. settings.AutoPartitioningUpUtilizationPercent.Reset();
  2396. } else {
  2397. if (!valueExprNode->IsIntegerLiteral()) {
  2398. ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2399. return false;
  2400. }
  2401. settings.AutoPartitioningUpUtilizationPercent.Set(valueExprNode);
  2402. }
  2403. } else if (to_lower(id.Name) == "auto_partitioning_down_utilization_percent") {
  2404. if (reset) {
  2405. settings.AutoPartitioningDownUtilizationPercent.Reset();
  2406. } else {
  2407. if (!valueExprNode->IsIntegerLiteral()) {
  2408. ctx.Error() << to_upper(id.Name) << " value should be an integer";
  2409. return false;
  2410. }
  2411. settings.AutoPartitioningDownUtilizationPercent.Set(valueExprNode);
  2412. }
  2413. } else if (to_lower(id.Name) == "auto_partitioning_strategy") {
  2414. if (reset) {
  2415. settings.AutoPartitioningStrategy.Reset();
  2416. } else {
  2417. if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
  2418. ctx.Error() << to_upper(id.Name) << " value should be string";
  2419. return false;
  2420. }
  2421. settings.AutoPartitioningStrategy.Set(valueExprNode);
  2422. }
  2423. } else {
  2424. ctx.Error() << "unknown topic setting: " << id.Name;
  2425. return false;
  2426. }
  2427. return true;
  2428. }
  2429. bool TSqlTranslation::AlterTopicAction(const TRule_alter_topic_action& node, TAlterTopicParameters& params) {
  2430. // alter_topic_action:
  2431. // alter_topic_add_consumer
  2432. // | alter_topic_alter_consumer
  2433. // | alter_topic_drop_consumer
  2434. // | alter_topic_set_settings
  2435. // | alter_topic_reset_settings
  2436. switch (node.Alt_case()) {
  2437. case TRule_alter_topic_action::kAltAlterTopicAction1: // alter_topic_add_consumer
  2438. return CreateTopicConsumer(
  2439. node.GetAlt_alter_topic_action1().GetRule_alter_topic_add_consumer1()
  2440. .GetRule_topic_create_consumer_entry2(),
  2441. params.AddConsumers
  2442. );
  2443. case TRule_alter_topic_action::kAltAlterTopicAction2: // alter_topic_alter_consumer
  2444. return AlterTopicConsumer(
  2445. node.GetAlt_alter_topic_action2().GetRule_alter_topic_alter_consumer1(),
  2446. params.AlterConsumers
  2447. );
  2448. case TRule_alter_topic_action::kAltAlterTopicAction3: // drop_consumer
  2449. params.DropConsumers.emplace_back(GetTopicConsumerId(
  2450. node.GetAlt_alter_topic_action3().GetRule_alter_topic_drop_consumer1()
  2451. .GetRule_topic_consumer_ref3()
  2452. ));
  2453. return true;
  2454. case TRule_alter_topic_action::kAltAlterTopicAction4: // set_settings
  2455. return CreateTopicSettings(
  2456. node.GetAlt_alter_topic_action4().GetRule_alter_topic_set_settings1()
  2457. .GetRule_topic_settings3(),
  2458. params.TopicSettings
  2459. );
  2460. case TRule_alter_topic_action::kAltAlterTopicAction5: { // reset_settings
  2461. auto& resetNode = node.GetAlt_alter_topic_action5().GetRule_alter_topic_reset_settings1();
  2462. TSqlExpression expr(Ctx, Mode);
  2463. if (!StoreTopicSettingsEntry(
  2464. IdEx(resetNode.GetRule_an_id3(), *this),
  2465. nullptr, expr,
  2466. params.TopicSettings, true
  2467. )) {
  2468. return false;
  2469. }
  2470. for (auto& resetItem: resetNode.GetBlock4()) {
  2471. if (!StoreTopicSettingsEntry(
  2472. IdEx(resetItem.GetRule_an_id_pure2(), *this),
  2473. nullptr, expr,
  2474. params.TopicSettings, true
  2475. )) {
  2476. return false;
  2477. }
  2478. }
  2479. return true;
  2480. }
  2481. default:
  2482. Ctx.Error() << "unknown alter topic action";
  2483. return false;
  2484. }
  2485. return true;
  2486. }
  2487. bool TSqlTranslation::CreateTopicSettings(const TRule_topic_settings& node, TTopicSettings& settings) {
  2488. const auto& firstEntry = node.GetRule_topic_settings_entry1();
  2489. TSqlExpression expr(Ctx, Mode);
  2490. if (!StoreTopicSettingsEntry(
  2491. IdEx(firstEntry.GetRule_an_id1(), *this),
  2492. &firstEntry.GetRule_topic_setting_value3(),
  2493. expr, settings, false
  2494. )) {
  2495. return false;
  2496. }
  2497. for (auto& block : node.GetBlock2()) {
  2498. const auto& entry = block.GetRule_topic_settings_entry2();
  2499. if (!StoreTopicSettingsEntry(
  2500. IdEx(entry.GetRule_an_id1(), *this),
  2501. &entry.GetRule_topic_setting_value3(),
  2502. expr, settings, false
  2503. )) {
  2504. return false;
  2505. }
  2506. }
  2507. return true;
  2508. }
  2509. TNodePtr TSqlTranslation::IntegerOrBind(const TRule_integer_or_bind& node) {
  2510. switch (node.Alt_case()) {
  2511. case TRule_integer_or_bind::kAltIntegerOrBind1: {
  2512. const TString intString = Ctx.Token(node.GetAlt_integer_or_bind1().GetRule_integer1().GetToken1());
  2513. ui64 value;
  2514. TString suffix;
  2515. if (!ParseNumbers(Ctx, intString, value, suffix)) {
  2516. return {};
  2517. }
  2518. return BuildQuotedAtom(Ctx.Pos(), ToString(value), TNodeFlags::ArbitraryContent);
  2519. }
  2520. case TRule_integer_or_bind::kAltIntegerOrBind2: {
  2521. TString bindName;
  2522. if (!NamedNodeImpl(node.GetAlt_integer_or_bind2().GetRule_bind_parameter1(), bindName, *this)) {
  2523. return {};
  2524. }
  2525. auto namedNode = GetNamedNode(bindName);
  2526. if (!namedNode) {
  2527. return {};
  2528. }
  2529. auto atom = MakeAtomFromExpression(Ctx.Pos(), Ctx, namedNode);
  2530. return atom.Build();
  2531. }
  2532. case TRule_integer_or_bind::ALT_NOT_SET:
  2533. Y_ABORT("You should change implementation according to grammar changes");
  2534. }
  2535. }
  2536. TNodePtr TSqlTranslation::TypeNameTag(const TRule_type_name_tag& node) {
  2537. switch (node.Alt_case()) {
  2538. case TRule_type_name_tag::kAltTypeNameTag1: {
  2539. auto content = Id(node.GetAlt_type_name_tag1().GetRule_id1(), *this);
  2540. auto atom = TDeferredAtom(Ctx.Pos(), content);
  2541. return atom.Build();
  2542. }
  2543. case TRule_type_name_tag::kAltTypeNameTag2: {
  2544. auto value = Token(node.GetAlt_type_name_tag2().GetToken1());
  2545. auto parsed = StringContentOrIdContent(Ctx, Ctx.Pos(), value);
  2546. if (!parsed) {
  2547. return {};
  2548. }
  2549. auto atom = TDeferredAtom(Ctx.Pos(), parsed->Content);
  2550. return atom.Build();
  2551. }
  2552. case TRule_type_name_tag::kAltTypeNameTag3: {
  2553. TString bindName;
  2554. if (!NamedNodeImpl(node.GetAlt_type_name_tag3().GetRule_bind_parameter1(), bindName, *this)) {
  2555. return {};
  2556. }
  2557. auto namedNode = GetNamedNode(bindName);
  2558. if (!namedNode) {
  2559. return {};
  2560. }
  2561. TDeferredAtom atom;
  2562. MakeTableFromExpression(Ctx.Pos(), Ctx, namedNode, atom);
  2563. return atom.Build();
  2564. }
  2565. case TRule_type_name_tag::ALT_NOT_SET:
  2566. Y_ABORT("You should change implementation according to grammar changes");
  2567. }
  2568. }
  2569. TNodePtr TSqlTranslation::TypeSimple(const TRule_type_name_simple& node, bool onlyDataAllowed) {
  2570. const TString origName = Id(node.GetRule_an_id_pure1(), *this);
  2571. if (origName.empty()) {
  2572. return {};
  2573. }
  2574. return BuildSimpleType(Ctx, Ctx.Pos(), origName, onlyDataAllowed);
  2575. }
  2576. TNodePtr TSqlTranslation::TypeDecimal(const TRule_type_name_decimal& node) {
  2577. auto pos = Ctx.Pos();
  2578. auto flags = TNodeFlags::Default;
  2579. auto paramOne = IntegerOrBind(node.GetRule_integer_or_bind3());
  2580. if (!paramOne) {
  2581. return {};
  2582. }
  2583. auto paramTwo = IntegerOrBind(node.GetRule_integer_or_bind5());
  2584. if (!paramTwo) {
  2585. return {};
  2586. }
  2587. return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Decimal", flags), paramOne, paramTwo });
  2588. }
  2589. TNodePtr TSqlTranslation::AddOptionals(const TNodePtr& node, size_t optionalCount) {
  2590. TNodePtr result = node;
  2591. if (node) {
  2592. TPosition pos = node->GetPos();
  2593. for (size_t i = 0; i < optionalCount; ++i) {
  2594. result = new TCallNodeImpl(pos, "OptionalType", { result });
  2595. }
  2596. }
  2597. return result;
  2598. }
  2599. TMaybe<std::pair<TVector<TNodePtr>, bool>> TSqlTranslation::CallableArgList(const TRule_callable_arg_list& argList, bool namedArgsStarted) {
  2600. auto pos = Ctx.Pos();
  2601. auto flags = TNodeFlags::Default;
  2602. auto& arg1 = argList.GetRule_callable_arg1();
  2603. auto& varArg = arg1.GetRule_variant_arg1();
  2604. TVector<TNodePtr> result;
  2605. TVector<TNodePtr> items;
  2606. auto typeNode = TypeNodeOrBind(varArg.GetRule_type_name_or_bind2());
  2607. if (!typeNode) {
  2608. return {};
  2609. }
  2610. items.push_back(typeNode);
  2611. if (varArg.HasBlock1()) {
  2612. namedArgsStarted = true;
  2613. auto tag = TypeNameTag(varArg.GetBlock1().GetRule_type_name_tag1());
  2614. if (!tag) {
  2615. return {};
  2616. }
  2617. items.push_back(tag);
  2618. }
  2619. if (arg1.HasBlock2()) {
  2620. if (!varArg.HasBlock1()) {
  2621. items.push_back(BuildQuotedAtom(pos, "", flags));
  2622. }
  2623. items.push_back(BuildQuotedAtom(pos, "1", flags));
  2624. }
  2625. result.push_back(new TAstListNodeImpl(pos, items));
  2626. for (auto& arg : argList.GetBlock2()) {
  2627. auto& varArg = arg.GetRule_callable_arg2().GetRule_variant_arg1();
  2628. TVector<TNodePtr> items;
  2629. auto typeNode = TypeNodeOrBind(varArg.GetRule_type_name_or_bind2());
  2630. if (!typeNode) {
  2631. return {};
  2632. }
  2633. items.push_back(typeNode);
  2634. if (varArg.HasBlock1()) {
  2635. auto tag = TypeNameTag(varArg.GetBlock1().GetRule_type_name_tag1());
  2636. if (!tag) {
  2637. return {};
  2638. }
  2639. items.push_back(tag);
  2640. } else {
  2641. if (namedArgsStarted) {
  2642. Ctx.Error() << "Expected named argument, previous argument was named";
  2643. return {};
  2644. }
  2645. items.push_back(BuildQuotedAtom(pos, "", flags));
  2646. }
  2647. if (arg.GetRule_callable_arg2().HasBlock2()) {
  2648. if (!varArg.HasBlock1()) {
  2649. items.push_back(BuildQuotedAtom(pos, "", flags));
  2650. }
  2651. items.push_back(BuildQuotedAtom(pos, "1", flags));
  2652. }
  2653. result.push_back(new TAstListNodeImpl(pos, items));
  2654. }
  2655. return std::make_pair(result, namedArgsStarted);
  2656. }
  2657. TNodePtr TSqlTranslation::TypeNodeOrBind(const TRule_type_name_or_bind& node) {
  2658. switch (node.Alt_case()) {
  2659. case TRule_type_name_or_bind::kAltTypeNameOrBind1: {
  2660. return TypeNode(node.GetAlt_type_name_or_bind1().GetRule_type_name1());
  2661. }
  2662. case TRule_type_name_or_bind::kAltTypeNameOrBind2: {
  2663. TString bindName;
  2664. if (!NamedNodeImpl(node.GetAlt_type_name_or_bind2().GetRule_bind_parameter1(), bindName, *this)) {
  2665. return {};
  2666. }
  2667. return GetNamedNode(bindName);
  2668. }
  2669. case TRule_type_name_or_bind::ALT_NOT_SET:
  2670. Y_ABORT("You should change implementation according to grammar changes");
  2671. }
  2672. }
  2673. TNodePtr TSqlTranslation::TypeNode(const TRule_type_name& node) {
  2674. //type_name:
  2675. // type_name_composite
  2676. // | (type_name_decimal | type_name_simple) QUESTION*;
  2677. if (node.Alt_case() == TRule_type_name::kAltTypeName1) {
  2678. return TypeNode(node.GetAlt_type_name1().GetRule_type_name_composite1());
  2679. }
  2680. TNodePtr result;
  2681. TPosition pos = Ctx.Pos();
  2682. auto& alt = node.GetAlt_type_name2();
  2683. auto& block = alt.GetBlock1();
  2684. switch (block.Alt_case()) {
  2685. case TRule_type_name::TAlt2::TBlock1::kAlt1: {
  2686. auto& decimalType = block.GetAlt1().GetRule_type_name_decimal1();
  2687. result = TypeDecimal(decimalType);
  2688. break;
  2689. }
  2690. case TRule_type_name::TAlt2::TBlock1::kAlt2: {
  2691. auto& simpleType = block.GetAlt2().GetRule_type_name_simple1();
  2692. result = TypeSimple(simpleType, false);
  2693. break;
  2694. }
  2695. case TRule_type_name::TAlt2::TBlock1::ALT_NOT_SET:
  2696. Y_ABORT("You should change implementation according to grammar changes");
  2697. }
  2698. return AddOptionals(result, alt.GetBlock2().size());
  2699. }
  2700. TNodePtr TSqlTranslation::TypeNode(const TRule_type_name_composite& node) {
  2701. //type_name_composite:
  2702. // ( type_name_optional
  2703. // | type_name_tuple
  2704. // | type_name_struct
  2705. // | type_name_variant
  2706. // | type_name_list
  2707. // | type_name_stream
  2708. // | type_name_flow
  2709. // | type_name_dict
  2710. // | type_name_set
  2711. // | type_name_enum
  2712. // | type_name_resource
  2713. // | type_name_tagged
  2714. // | type_name_callable
  2715. // ) QUESTION*;
  2716. TNodePtr result;
  2717. TPosition pos = Ctx.Pos();
  2718. auto flags = TNodeFlags::Default;
  2719. auto wrapOneParamType = [&] (const TRule_type_name_or_bind& param, const char* type) -> TNodePtr {
  2720. auto node = TypeNodeOrBind(param);
  2721. return node ? new TAstListNodeImpl(pos, { BuildAtom(pos, type, flags), node }) : nullptr;
  2722. };
  2723. auto makeVoid = [&] () -> TNodePtr {
  2724. return new TAstListNodeImpl(pos, { BuildAtom(pos, "VoidType", flags) });
  2725. };
  2726. auto makeQuote = [&] (const TNodePtr& node) -> TNodePtr {
  2727. return new TAstListNodeImpl(pos, { new TAstAtomNodeImpl(pos, "quote", 0), node });
  2728. };
  2729. auto& block = node.GetBlock1();
  2730. switch (block.Alt_case()) {
  2731. case TRule_type_name_composite_TBlock1::kAlt1: {
  2732. auto& optionalType = block.GetAlt1().GetRule_type_name_optional1();
  2733. result = wrapOneParamType(optionalType.GetRule_type_name_or_bind3(), "OptionalType");
  2734. break;
  2735. }
  2736. case TRule_type_name_composite_TBlock1::kAlt2: {
  2737. auto& tupleType = block.GetAlt2().GetRule_type_name_tuple1();
  2738. TVector<TNodePtr> items;
  2739. items.push_back(BuildAtom(pos, "TupleType", flags));
  2740. switch (tupleType.GetBlock2().Alt_case()) {
  2741. case TRule_type_name_tuple::TBlock2::kAlt1: {
  2742. if (tupleType.GetBlock2().GetAlt1().HasBlock2()) {
  2743. auto typeNode = TypeNodeOrBind(tupleType.GetBlock2().GetAlt1().GetBlock2().GetRule_type_name_or_bind1());
  2744. if (!typeNode) {
  2745. return {};
  2746. }
  2747. items.push_back(typeNode);
  2748. for (auto& arg : tupleType.GetBlock2().GetAlt1().GetBlock2().GetBlock2()) {
  2749. auto typeNode = TypeNodeOrBind(arg.GetRule_type_name_or_bind2());
  2750. if (!typeNode) {
  2751. return {};
  2752. }
  2753. items.push_back(typeNode);
  2754. }
  2755. }
  2756. [[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
  2757. }
  2758. case TRule_type_name_tuple::TBlock2::kAlt2:
  2759. break;
  2760. case TRule_type_name_tuple::TBlock2::ALT_NOT_SET:
  2761. Y_ABORT("You should change implementation according to grammar changes");
  2762. }
  2763. result = new TAstListNodeImpl(pos, items);
  2764. break;
  2765. }
  2766. case TRule_type_name_composite_TBlock1::kAlt3: {
  2767. auto& structType = block.GetAlt3().GetRule_type_name_struct1();
  2768. TVector<TNodePtr> items;
  2769. items.push_back(BuildAtom(pos, "StructType", flags));
  2770. switch (structType.GetBlock2().Alt_case()) {
  2771. case TRule_type_name_struct::TBlock2::kAlt1: {
  2772. if (structType.GetBlock2().GetAlt1().HasBlock2()) {
  2773. auto& structArg = structType.GetBlock2().GetAlt1().GetBlock2().GetRule_struct_arg1();
  2774. auto typeNode = TypeNodeOrBind(structArg.GetRule_type_name_or_bind3());
  2775. if (!typeNode) {
  2776. return {};
  2777. }
  2778. auto tag = TypeNameTag(structArg.GetRule_type_name_tag1());
  2779. if (!tag) {
  2780. return {};
  2781. }
  2782. items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
  2783. for (auto& arg : structType.GetBlock2().GetAlt1().GetBlock2().GetBlock2()) {
  2784. auto typeNode = TypeNodeOrBind(arg.GetRule_struct_arg2().GetRule_type_name_or_bind3());
  2785. if (!typeNode) {
  2786. return {};
  2787. }
  2788. auto tag = TypeNameTag(arg.GetRule_struct_arg2().GetRule_type_name_tag1());
  2789. if (!tag) {
  2790. return {};
  2791. }
  2792. items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
  2793. }
  2794. }
  2795. [[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
  2796. }
  2797. case TRule_type_name_struct::TBlock2::kAlt2:
  2798. break;
  2799. case TRule_type_name_struct::TBlock2::ALT_NOT_SET:
  2800. Y_ABORT("You should change implementation according to grammar changes");
  2801. }
  2802. result = new TAstListNodeImpl(pos, items);
  2803. break;
  2804. }
  2805. case TRule_type_name_composite_TBlock1::kAlt4: {
  2806. auto& variantType = block.GetAlt4().GetRule_type_name_variant1();
  2807. TVector<TNodePtr> items;
  2808. bool overStruct = false;
  2809. auto& variantArg = variantType.GetRule_variant_arg3();
  2810. auto typeNode = TypeNodeOrBind(variantArg.GetRule_type_name_or_bind2());
  2811. if (!typeNode) {
  2812. return {};
  2813. }
  2814. if (variantArg.HasBlock1()) {
  2815. items.push_back(BuildAtom(pos, "StructType", flags));
  2816. overStruct = true;
  2817. auto tag = TypeNameTag(variantArg.GetBlock1().GetRule_type_name_tag1());
  2818. if (!tag) {
  2819. return {};
  2820. }
  2821. items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
  2822. } else {
  2823. items.push_back(BuildAtom(pos, "TupleType", flags));
  2824. items.push_back(typeNode);
  2825. }
  2826. for (auto& arg : variantType.GetBlock4()) {
  2827. auto typeNode = TypeNodeOrBind(arg.GetRule_variant_arg2().GetRule_type_name_or_bind2());
  2828. if (!typeNode) {
  2829. return {};
  2830. }
  2831. if (overStruct) {
  2832. if (!arg.GetRule_variant_arg2().HasBlock1()) {
  2833. Ctx.Error() << "Variant over struct and tuple mixture";
  2834. return {};
  2835. }
  2836. auto tag = TypeNameTag(arg.GetRule_variant_arg2().GetBlock1().GetRule_type_name_tag1());
  2837. if (!tag) {
  2838. return {};
  2839. }
  2840. items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
  2841. } else {
  2842. if (arg.GetRule_variant_arg2().HasBlock1()) {
  2843. Ctx.Error() << "Variant over struct and tuple mixture";
  2844. return {};
  2845. }
  2846. items.push_back(typeNode);
  2847. }
  2848. }
  2849. typeNode = new TAstListNodeImpl(pos, items);
  2850. result = new TAstListNodeImpl(pos, { BuildAtom(pos, "VariantType", flags), typeNode });
  2851. break;
  2852. }
  2853. case TRule_type_name_composite_TBlock1::kAlt5: {
  2854. auto& listType = block.GetAlt5().GetRule_type_name_list1();
  2855. result = wrapOneParamType(listType.GetRule_type_name_or_bind3(), "ListType");
  2856. break;
  2857. }
  2858. case TRule_type_name_composite_TBlock1::kAlt6: {
  2859. auto& streamType = block.GetAlt6().GetRule_type_name_stream1();
  2860. result = wrapOneParamType(streamType.GetRule_type_name_or_bind3(), "StreamType");
  2861. break;
  2862. }
  2863. case TRule_type_name_composite_TBlock1::kAlt7: {
  2864. auto& flowType = block.GetAlt7().GetRule_type_name_flow1();
  2865. result = wrapOneParamType(flowType.GetRule_type_name_or_bind3(), "FlowType");
  2866. break;
  2867. }
  2868. case TRule_type_name_composite_TBlock1::kAlt8: {
  2869. auto& dictType = block.GetAlt8().GetRule_type_name_dict1();
  2870. TVector<TNodePtr> items;
  2871. items.push_back(BuildAtom(pos, "DictType", flags));
  2872. auto typeNode = TypeNodeOrBind(dictType.GetRule_type_name_or_bind3());
  2873. if (!typeNode) {
  2874. return {};
  2875. }
  2876. items.push_back(typeNode);
  2877. typeNode = TypeNodeOrBind(dictType.GetRule_type_name_or_bind5());
  2878. if (!typeNode) {
  2879. return {};
  2880. }
  2881. items.push_back(typeNode);
  2882. result = new TAstListNodeImpl(pos, items);
  2883. break;
  2884. }
  2885. case TRule_type_name_composite_TBlock1::kAlt9: {
  2886. auto& setType = block.GetAlt9().GetRule_type_name_set1();
  2887. auto typeNode = TypeNodeOrBind(setType.GetRule_type_name_or_bind3());
  2888. if (!typeNode) {
  2889. return {};
  2890. }
  2891. result = new TAstListNodeImpl(pos, { BuildAtom(pos, "DictType", flags), typeNode, makeVoid() });
  2892. break;
  2893. }
  2894. case TRule_type_name_composite_TBlock1::kAlt10: {
  2895. auto& enumType = block.GetAlt10().GetRule_type_name_enum1();
  2896. TVector<TNodePtr> items;
  2897. items.push_back(BuildAtom(pos, "StructType", flags));
  2898. auto tag = TypeNameTag(enumType.GetRule_type_name_tag3());
  2899. if (!tag) {
  2900. return {};
  2901. }
  2902. items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, makeVoid() })));
  2903. for (auto& arg : enumType.GetBlock4()) {
  2904. auto tag = TypeNameTag(arg.GetRule_type_name_tag2());
  2905. if (!tag) {
  2906. return {};
  2907. }
  2908. items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, makeVoid() })));
  2909. }
  2910. auto typeNode = new TAstListNodeImpl(pos, items);
  2911. result = new TAstListNodeImpl(pos, { BuildAtom(pos, "VariantType", flags), typeNode });
  2912. break;
  2913. }
  2914. case TRule_type_name_composite_TBlock1::kAlt11: {
  2915. auto& resourceType = block.GetAlt11().GetRule_type_name_resource1();
  2916. auto tag = TypeNameTag(resourceType.GetRule_type_name_tag3());
  2917. if (!tag) {
  2918. return {};
  2919. }
  2920. result = new TAstListNodeImpl(pos, { BuildAtom(pos, "ResourceType", flags), tag });
  2921. break;
  2922. }
  2923. case TRule_type_name_composite_TBlock1::kAlt12: {
  2924. auto& taggedType = block.GetAlt12().GetRule_type_name_tagged1();
  2925. auto typeNode = TypeNodeOrBind(taggedType.GetRule_type_name_or_bind3());
  2926. if (!typeNode) {
  2927. return {};
  2928. }
  2929. auto tag = TypeNameTag(taggedType.GetRule_type_name_tag5());
  2930. if (!tag) {
  2931. return {};
  2932. }
  2933. result = new TAstListNodeImpl(pos, { BuildAtom(pos, "TaggedType", flags), typeNode, tag });
  2934. break;
  2935. }
  2936. case TRule_type_name_composite_TBlock1::kAlt13: {
  2937. auto& callableType = block.GetAlt13().GetRule_type_name_callable1();
  2938. TMaybe<std::pair<TVector<TNodePtr>, bool>> requiredArgs, optionalArgs;
  2939. bool namedArgsStarted = false;
  2940. size_t optionalArgsCount = 0;
  2941. if (callableType.HasBlock4()) {
  2942. auto& argList = callableType.GetBlock4().GetRule_callable_arg_list1();
  2943. requiredArgs = CallableArgList(argList, namedArgsStarted);
  2944. if (!requiredArgs) {
  2945. return {};
  2946. }
  2947. namedArgsStarted = requiredArgs->second;
  2948. }
  2949. if (callableType.HasBlock6()) {
  2950. auto& argList = callableType.GetBlock6().GetRule_callable_arg_list2();
  2951. optionalArgs = CallableArgList(argList, namedArgsStarted);
  2952. if (!optionalArgs) {
  2953. return {};
  2954. }
  2955. optionalArgsCount = optionalArgs->first.size();
  2956. }
  2957. auto returnType = TypeNodeOrBind(callableType.GetRule_type_name_or_bind9());
  2958. if (!returnType) {
  2959. return {};
  2960. }
  2961. TVector<TNodePtr> items;
  2962. items.push_back(BuildAtom(pos, "CallableType", flags));
  2963. if (optionalArgsCount) {
  2964. items.push_back(makeQuote(new TAstListNodeImpl(pos,
  2965. { BuildQuotedAtom(pos, ToString(optionalArgsCount), flags) })));
  2966. } else {
  2967. items.push_back(makeQuote(new TAstListNodeImpl(pos, {})));
  2968. }
  2969. items.push_back(makeQuote(new TAstListNodeImpl(pos, { returnType })));
  2970. if (requiredArgs) {
  2971. for (auto& arg: requiredArgs->first) {
  2972. items.push_back(makeQuote(arg));
  2973. }
  2974. }
  2975. if (optionalArgs) {
  2976. for (auto& arg: optionalArgs->first) {
  2977. items.push_back(makeQuote(arg));
  2978. }
  2979. }
  2980. result = new TAstListNodeImpl(pos, items);
  2981. break;
  2982. }
  2983. case TRule_type_name_composite_TBlock1::ALT_NOT_SET:
  2984. Y_ABORT("You should change implementation according to grammar changes");
  2985. }
  2986. return AddOptionals(result, node.GetBlock2().size());
  2987. }
  2988. TNodePtr TSqlTranslation::ValueConstructorLiteral(const TRule_value_constructor_literal& node) {
  2989. return BuildLiteralSmartString(Ctx, Token(node.GetToken1()));
  2990. }
  2991. TNodePtr TSqlTranslation::ValueConstructor(const TRule_value_constructor& node) {
  2992. TSqlCallExpr call(Ctx, Mode);
  2993. if (!call.Init(node)) {
  2994. return {};
  2995. }
  2996. return call.BuildCall();
  2997. }
  2998. TNodePtr TSqlTranslation::ListLiteral(const TRule_list_literal& node) {
  2999. TVector<TNodePtr> values;
  3000. values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "AsListMayWarn", TNodeFlags::Default));
  3001. TSqlExpression sqlExpr(Ctx, Mode);
  3002. if (node.HasBlock2() && !ExprList(sqlExpr, values, node.GetBlock2().GetRule_expr_list1())) {
  3003. return nullptr;
  3004. }
  3005. return new TAstListNodeImpl(Ctx.Pos(), std::move(values));
  3006. }
  3007. TNodePtr TSqlTranslation::DictLiteral(const TRule_dict_literal& node) {
  3008. TVector<TNodePtr> values;
  3009. if (node.HasBlock2()) {
  3010. const auto& list = node.GetBlock2().GetRule_expr_dict_list1();
  3011. const bool isSet = !list.HasBlock2();
  3012. values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), isSet ? "AsSet" : "AsDict", TNodeFlags::Default));
  3013. TSqlExpression sqlExpr(Ctx, Mode);
  3014. if (isSet) {
  3015. if (!Expr(sqlExpr, values, list.GetRule_expr1())) {
  3016. return nullptr;
  3017. }
  3018. } else {
  3019. TVector<TNodePtr> tupleItems;
  3020. if (!Expr(sqlExpr, tupleItems, list.GetRule_expr1())) {
  3021. return nullptr;
  3022. }
  3023. if (!Expr(sqlExpr, tupleItems, list.GetBlock2().GetRule_expr2())) {
  3024. return nullptr;
  3025. }
  3026. values.push_back(new TTupleNode(Ctx.Pos(), std::move(tupleItems)));
  3027. }
  3028. for (auto& b : list.GetBlock3()) {
  3029. sqlExpr.Token(b.GetToken1());
  3030. const bool isSetCurr = !b.HasBlock3();
  3031. if (isSetCurr != isSet) {
  3032. Error() << "Expected keys/values pair or keys, but got mix of them";
  3033. return nullptr;
  3034. }
  3035. if (isSet) {
  3036. if (!Expr(sqlExpr, values, b.GetRule_expr2())) {
  3037. return nullptr;
  3038. }
  3039. } else {
  3040. TVector<TNodePtr> tupleItems;
  3041. if (!Expr(sqlExpr, tupleItems, b.GetRule_expr2())) {
  3042. return nullptr;
  3043. }
  3044. if (!Expr(sqlExpr, tupleItems, b.GetBlock3().GetRule_expr2())) {
  3045. return nullptr;
  3046. }
  3047. values.push_back(new TTupleNode(Ctx.Pos(), std::move(tupleItems)));
  3048. }
  3049. }
  3050. } else {
  3051. values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "AsDict", TNodeFlags::Default));
  3052. }
  3053. return new TAstListNodeImpl(Ctx.Pos(), std::move(values));
  3054. }
  3055. bool TSqlTranslation::StructLiteralItem(TVector<TNodePtr>& labels, const TRule_expr& label, TVector<TNodePtr>& values, const TRule_expr& value) {
  3056. // label expr
  3057. {
  3058. TColumnRefScope scope(Ctx, EColumnRefState::AsStringLiteral, /* topLevel */ false);
  3059. TSqlExpression sqlExpr(Ctx, Mode);
  3060. if (!Expr(sqlExpr, labels, label)) {
  3061. return false;
  3062. }
  3063. TDeferredAtom atom;
  3064. MakeTableFromExpression(Ctx.Pos(), Ctx, labels.back(), atom);
  3065. labels.back() = atom.Build();
  3066. if (!labels.back()) {
  3067. return false;
  3068. }
  3069. }
  3070. // value expr
  3071. {
  3072. TSqlExpression sqlExpr(Ctx, Mode);
  3073. if (!Expr(sqlExpr, values, value)) {
  3074. return false;
  3075. }
  3076. }
  3077. return true;
  3078. }
  3079. TNodePtr TSqlTranslation::StructLiteral(const TRule_struct_literal& node) {
  3080. TVector<TNodePtr> labels;
  3081. TVector<TNodePtr> values;
  3082. TPosition pos = Ctx.TokenPosition(node.GetToken1());
  3083. if (node.HasBlock2()) {
  3084. const auto& list = node.GetBlock2().GetRule_expr_struct_list1();
  3085. if (!StructLiteralItem(labels, list.GetRule_expr1(), values, list.GetRule_expr3())) {
  3086. return {};
  3087. }
  3088. for (auto& b : list.GetBlock4()) {
  3089. if (!StructLiteralItem(labels, b.GetRule_expr2(), values, b.GetRule_expr4())) {
  3090. return {};
  3091. }
  3092. }
  3093. }
  3094. return BuildStructure(pos, values, labels);
  3095. }
  3096. bool TSqlTranslation::TableHintImpl(const TRule_table_hint& rule, TTableHints& hints, const TString& provider, const TString& keyFunc) {
  3097. // table_hint:
  3098. // an_id_hint (EQUALS (type_name_tag | LPAREN type_name_tag (COMMA type_name_tag)* COMMA? RPAREN))?
  3099. // | (SCHEMA | COLUMNS) EQUALS? type_name_or_bind
  3100. // | SCHEMA EQUALS? LPAREN (struct_arg_positional (COMMA struct_arg_positional)*)? COMMA? RPAREN
  3101. switch (rule.Alt_case()) {
  3102. case TRule_table_hint::kAltTableHint1: {
  3103. const auto& alt = rule.GetAlt_table_hint1();
  3104. const TString id = Id(alt.GetRule_an_id_hint1(), *this);
  3105. const auto idLower = to_lower(id);
  3106. if (idLower == "schema" || idLower == "columns") {
  3107. Error() << "Expected type after " << to_upper(id);
  3108. return false;
  3109. }
  3110. TVector<TNodePtr> hint_val;
  3111. if (alt.HasBlock2()) {
  3112. auto& tags = alt.GetBlock2().GetBlock2();
  3113. switch (tags.Alt_case()) {
  3114. case TRule_table_hint_TAlt1_TBlock2_TBlock2::kAlt1:
  3115. hint_val.push_back(TypeNameTag(tags.GetAlt1().GetRule_type_name_tag1()));
  3116. break;
  3117. case TRule_table_hint_TAlt1_TBlock2_TBlock2::kAlt2: {
  3118. hint_val.push_back(TypeNameTag(tags.GetAlt2().GetRule_type_name_tag2()));
  3119. for (auto& tag : tags.GetAlt2().GetBlock3()) {
  3120. hint_val.push_back(TypeNameTag(tag.GetRule_type_name_tag2()));
  3121. }
  3122. break;
  3123. }
  3124. case TRule_table_hint_TAlt1_TBlock2_TBlock2::ALT_NOT_SET:
  3125. Y_ABORT("You should change implementation according to grammar changes");
  3126. }
  3127. }
  3128. hints[id] = hint_val;
  3129. break;
  3130. }
  3131. case TRule_table_hint::kAltTableHint2: {
  3132. const auto& alt2 = rule.GetAlt_table_hint2();
  3133. auto node = TypeNodeOrBind(alt2.GetRule_type_name_or_bind3());
  3134. if (!node) {
  3135. return false;
  3136. }
  3137. hints["user_" + to_lower(alt2.GetToken1().GetValue())] = { node };
  3138. break;
  3139. }
  3140. case TRule_table_hint::kAltTableHint3: {
  3141. const auto& alt = rule.GetAlt_table_hint3();
  3142. TVector<TNodePtr> labels;
  3143. TVector<TNodePtr> structTypeItems;
  3144. if (alt.HasBlock4()) {
  3145. bool warn = false;
  3146. auto processItem = [&](const TRule_struct_arg_positional& arg) {
  3147. // struct_arg_positional:
  3148. // type_name_tag type_name_or_bind (NOT? NULL)?
  3149. // | type_name_or_bind AS type_name_tag; //deprecated
  3150. const bool altCurrent = arg.Alt_case() == TRule_struct_arg_positional::kAltStructArgPositional1;
  3151. auto& typeNameOrBind = altCurrent ?
  3152. arg.GetAlt_struct_arg_positional1().GetRule_type_name_or_bind2() :
  3153. arg.GetAlt_struct_arg_positional2().GetRule_type_name_or_bind1();
  3154. auto typeNode = TypeNodeOrBind(typeNameOrBind);
  3155. if (!typeNode) {
  3156. return false;
  3157. }
  3158. auto pos = Ctx.Pos();
  3159. if (!altCurrent && !warn) {
  3160. Ctx.Warning(pos, TIssuesIds::YQL_DEPRECATED_POSITIONAL_SCHEMA)
  3161. << "Deprecated syntax for positional schema: please use 'column type' instead of 'type AS column'";
  3162. warn = true;
  3163. }
  3164. if (altCurrent) {
  3165. bool notNull = arg.GetAlt_struct_arg_positional1().HasBlock3() && arg.GetAlt_struct_arg_positional1().GetBlock3().HasBlock1();
  3166. if (!notNull) {
  3167. typeNode = new TCallNodeImpl(pos, "AsOptionalType", { typeNode });
  3168. }
  3169. }
  3170. auto& typeNameTag = altCurrent ?
  3171. arg.GetAlt_struct_arg_positional1().GetRule_type_name_tag1() :
  3172. arg.GetAlt_struct_arg_positional2().GetRule_type_name_tag3();
  3173. auto tag = TypeNameTag(typeNameTag);
  3174. if (!tag) {
  3175. return false;
  3176. }
  3177. labels.push_back(tag);
  3178. structTypeItems.push_back(BuildTuple(pos, { tag, typeNode }));
  3179. return true;
  3180. };
  3181. if (!processItem(alt.GetBlock4().GetRule_struct_arg_positional1())) {
  3182. return false;
  3183. }
  3184. for (auto& entry : alt.GetBlock4().GetBlock2()) {
  3185. if (!processItem(entry.GetRule_struct_arg_positional2())) {
  3186. return false;
  3187. }
  3188. }
  3189. }
  3190. TPosition pos = Ctx.TokenPosition(alt.GetToken1());
  3191. TNodePtr structType = new TCallNodeImpl(pos, "StructType", structTypeItems);
  3192. bool shouldEmitLabel = provider != YtProviderName || TCiString(keyFunc) == "object";
  3193. if (shouldEmitLabel) {
  3194. auto labelsTuple = BuildTuple(pos, labels);
  3195. hints["user_" + to_lower(alt.GetToken1().GetValue())] = { structType, labelsTuple };
  3196. break;
  3197. } else {
  3198. hints["user_" + to_lower(alt.GetToken1().GetValue())] = { structType };
  3199. break;
  3200. }
  3201. }
  3202. case TRule_table_hint::ALT_NOT_SET:
  3203. Y_ABORT("You should change implementation according to grammar changes");
  3204. }
  3205. return true;
  3206. }
  3207. TMaybe<TTableHints> TSqlTranslation::TableHintsImpl(const TRule_table_hints& node, const TString& provider, const TString& keyFunc) {
  3208. TTableHints hints;
  3209. auto& block = node.GetBlock2();
  3210. bool hasErrors = false;
  3211. switch (block.Alt_case()) {
  3212. case TRule_table_hints::TBlock2::kAlt1: {
  3213. hasErrors = !TableHintImpl(block.GetAlt1().GetRule_table_hint1(), hints, provider, keyFunc);
  3214. break;
  3215. }
  3216. case TRule_table_hints::TBlock2::kAlt2: {
  3217. hasErrors = !TableHintImpl(block.GetAlt2().GetRule_table_hint2(), hints, provider, keyFunc);
  3218. for (const auto& x : block.GetAlt2().GetBlock3()) {
  3219. hasErrors = hasErrors || !TableHintImpl(x.GetRule_table_hint2(), hints, provider, keyFunc);
  3220. }
  3221. break;
  3222. }
  3223. case TRule_table_hints::TBlock2::ALT_NOT_SET:
  3224. Y_ABORT("You should change implementation according to grammar changes");
  3225. }
  3226. if (hasErrors) {
  3227. return Nothing();
  3228. }
  3229. return hints;
  3230. }
  3231. bool TSqlTranslation::SimpleTableRefImpl(const TRule_simple_table_ref& node, TTableRef& result) {
  3232. // simple_table_ref: simple_table_ref_core table_hints?;
  3233. if (!SimpleTableRefCoreImpl(node.GetRule_simple_table_ref_core1(), result)) {
  3234. return false;
  3235. }
  3236. TTableHints hints = GetContextHints(Context());
  3237. if (node.HasBlock2()) {
  3238. const TString& service = Context().Scoped->CurrService;
  3239. auto tmp = TableHintsImpl(node.GetBlock2().GetRule_table_hints1(), service);
  3240. if (!tmp) {
  3241. Error() << "Failed to parse table hints";
  3242. return false;
  3243. }
  3244. hints = *tmp;
  3245. }
  3246. if (!hints.empty()) {
  3247. result.Options = BuildInputOptions(Context().Pos(), hints);
  3248. }
  3249. return true;
  3250. }
  3251. bool TSqlTranslation::SimpleTableRefCoreImpl(const TRule_simple_table_ref_core& node, TTableRef& result) {
  3252. // simple_table_ref_core: ((cluster_expr DOT)? id_or_at) | AT? bind_parameter;
  3253. TString service = Context().Scoped->CurrService;
  3254. TDeferredAtom cluster = Context().Scoped->CurrCluster;
  3255. switch (node.Alt_case()) {
  3256. case TRule_simple_table_ref_core::AltCase::kAltSimpleTableRefCore1: {
  3257. if (node.GetAlt_simple_table_ref_core1().GetRule_object_ref1().HasBlock1()) {
  3258. if (Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
  3259. Error() << "Cluster should not be used in limited view";
  3260. return false;
  3261. }
  3262. if (!ClusterExpr(node.GetAlt_simple_table_ref_core1().GetRule_object_ref1().GetBlock1().GetRule_cluster_expr1(), false, service, cluster)) {
  3263. return false;
  3264. }
  3265. }
  3266. if (cluster.Empty()) {
  3267. Error() << "No cluster name given and no default cluster is selected";
  3268. return false;
  3269. }
  3270. result = TTableRef(Context().MakeName("table"), service, cluster, nullptr);
  3271. auto tableOrAt = Id(node.GetAlt_simple_table_ref_core1().GetRule_object_ref1().GetRule_id_or_at2(), *this);
  3272. auto tableAndView = TableKeyImpl(tableOrAt, {}, *this);
  3273. result.Keys = BuildTableKey(Context().Pos(), result.Service, result.Cluster,
  3274. TDeferredAtom(Context().Pos(), tableAndView.first), tableAndView.second);
  3275. break;
  3276. }
  3277. case TRule_simple_table_ref_core::AltCase::kAltSimpleTableRefCore2: {
  3278. if (cluster.Empty()) {
  3279. Error() << "No cluster name given and no default cluster is selected";
  3280. return false;
  3281. }
  3282. auto at = node.GetAlt_simple_table_ref_core2().HasBlock1();
  3283. TString bindName;
  3284. if (!NamedNodeImpl(node.GetAlt_simple_table_ref_core2().GetRule_bind_parameter2(), bindName, *this)) {
  3285. return false;
  3286. }
  3287. auto named = GetNamedNode(bindName);
  3288. if (!named) {
  3289. return false;
  3290. }
  3291. TDeferredAtom table;
  3292. MakeTableFromExpression(Context().Pos(), Context(), named, table);
  3293. result = TTableRef(Context().MakeName("table"), service, cluster, nullptr);
  3294. result.Keys = BuildTableKey(Context().Pos(), result.Service, result.Cluster, table, {at ? "@" : ""});
  3295. break;
  3296. }
  3297. case TRule_simple_table_ref_core::AltCase::ALT_NOT_SET:
  3298. Y_ABORT("You should change implementation according to grammar changes");
  3299. }
  3300. return result.Keys != nullptr;
  3301. }
  3302. bool TSqlTranslation::TopicRefImpl(const TRule_topic_ref& node, TTopicRef& result) {
  3303. TString service = Context().Scoped->CurrService;
  3304. TDeferredAtom cluster = Context().Scoped->CurrCluster;
  3305. if (node.HasBlock1()) {
  3306. if (Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
  3307. Error() << "Cluster should not be used in limited view";
  3308. return false;
  3309. }
  3310. if (!ClusterExpr(node.GetBlock1().GetRule_cluster_expr1(), false, service, cluster)) {
  3311. return false;
  3312. }
  3313. }
  3314. if (cluster.Empty()) {
  3315. Error() << "No cluster name given and no default cluster is selected";
  3316. return false;
  3317. }
  3318. result = TTopicRef(Context().MakeName("topic"), cluster, nullptr);
  3319. auto topic = Id(node.GetRule_an_id2(), *this);
  3320. result.Keys = BuildTopicKey(Context().Pos(), result.Cluster, TDeferredAtom(Context().Pos(), topic));
  3321. return true;
  3322. }
  3323. TNodePtr TSqlTranslation::NamedNode(const TRule_named_nodes_stmt& rule, TVector<TSymbolNameWithPos>& names) {
  3324. // named_nodes_stmt: bind_parameter_list EQUALS (expr | subselect_stmt);
  3325. // subselect_stmt: (LPAREN select_stmt RPAREN | select_unparenthesized_stmt);
  3326. if (!BindList(rule.GetRule_bind_parameter_list1(), names)) {
  3327. return {};
  3328. }
  3329. TNodePtr nodeExpr = nullptr;
  3330. switch (rule.GetBlock3().Alt_case()) {
  3331. case TRule_named_nodes_stmt::TBlock3::kAlt1: {
  3332. TSqlExpression expr(Ctx, Mode);
  3333. auto result = expr.Build(rule.GetBlock3().GetAlt1().GetRule_expr1());
  3334. return result;
  3335. }
  3336. case TRule_named_nodes_stmt::TBlock3::kAlt2:{
  3337. const auto& subselect_rule = rule.GetBlock3().GetAlt2().GetRule_subselect_stmt1();
  3338. TSqlSelect expr(Ctx, Mode);
  3339. TPosition pos;
  3340. TSourcePtr source = nullptr;
  3341. switch (subselect_rule.GetBlock1().Alt_case()) {
  3342. case TRule_subselect_stmt::TBlock1::kAlt1:
  3343. source = expr.Build(subselect_rule.GetBlock1().GetAlt1().GetRule_select_stmt2(), pos);
  3344. break;
  3345. case TRule_subselect_stmt::TBlock1::kAlt2:
  3346. source = expr.Build(subselect_rule.GetBlock1().GetAlt2().GetRule_select_unparenthesized_stmt1(), pos);
  3347. break;
  3348. case TRule_subselect_stmt::TBlock1::ALT_NOT_SET:
  3349. AltNotImplemented("subselect_stmt", subselect_rule.GetBlock1());
  3350. Ctx.IncrementMonCounter("sql_errors", "UnknownNamedNode");
  3351. return nullptr;
  3352. }
  3353. if (!source) {
  3354. return {};
  3355. }
  3356. return BuildSourceNode(pos, std::move(source));
  3357. }
  3358. case TRule_named_nodes_stmt::TBlock3::ALT_NOT_SET:
  3359. AltNotImplemented("named_node", rule.GetBlock3());
  3360. Ctx.IncrementMonCounter("sql_errors", "UnknownNamedNode");
  3361. return nullptr;
  3362. }
  3363. }
  3364. bool TSqlTranslation::ImportStatement(const TRule_import_stmt& stmt, TVector<TString>* namesPtr) {
  3365. TVector<TString> modulePath;
  3366. if (!ModulePath(stmt.GetRule_module_path2(), modulePath)) {
  3367. return false;
  3368. }
  3369. TVector<TSymbolNameWithPos> names;
  3370. TVector<TSymbolNameWithPos> aliases;
  3371. if (!NamedBindList(stmt.GetRule_named_bind_parameter_list4(), names, aliases)) {
  3372. return false;
  3373. }
  3374. YQL_ENSURE(names.size() == aliases.size());
  3375. const TString moduleAlias = Ctx.AddImport(std::move(modulePath));
  3376. if (!moduleAlias) {
  3377. return false;
  3378. }
  3379. for (size_t i = 0; i < names.size(); ++i) {
  3380. auto& name = names[i];
  3381. auto& alias = aliases[i];
  3382. auto& var = alias.Name ? alias : name;
  3383. if (IsAnonymousName(var.Name)) {
  3384. Ctx.Error(var.Pos) << "Can not import anonymous name " << var.Name;
  3385. return false;
  3386. }
  3387. auto builder = [&](const TString& realName) {
  3388. YQL_ENSURE(realName == var.Name);
  3389. auto atom = BuildQuotedAtom(name.Pos, name.Name);
  3390. return atom->Y("bind", moduleAlias, atom);
  3391. };
  3392. var.Name = PushNamedNode(var.Pos, var.Name, builder);
  3393. if (namesPtr) {
  3394. namesPtr->push_back(var.Name);
  3395. }
  3396. }
  3397. return true;
  3398. }
  3399. bool TSqlTranslation::SortSpecification(const TRule_sort_specification& node, TVector<TSortSpecificationPtr>& sortSpecs) {
  3400. bool asc = true;
  3401. TSqlExpression expr(Ctx, Mode);
  3402. TColumnRefScope scope(Ctx, EColumnRefState::Allow);
  3403. TNodePtr exprNode = expr.Build(node.GetRule_expr1());
  3404. if (!exprNode) {
  3405. return false;
  3406. }
  3407. if (node.HasBlock2()) {
  3408. const auto& token = node.GetBlock2().GetToken1();
  3409. Token(token);
  3410. auto tokenId = token.GetId();
  3411. if (IS_TOKEN(tokenId, ASC)) {
  3412. Ctx.IncrementMonCounter("sql_features", "OrderByAsc");
  3413. } else if (IS_TOKEN(tokenId, DESC)) {
  3414. asc = false;
  3415. Ctx.IncrementMonCounter("sql_features", "OrderByDesc");
  3416. } else {
  3417. Ctx.IncrementMonCounter("sql_errors", "UnknownOrderBy");
  3418. Error() << "Unsupported direction token: " << token.GetId();
  3419. return false;
  3420. }
  3421. } else {
  3422. Ctx.IncrementMonCounter("sql_features", "OrderByDefault");
  3423. }
  3424. sortSpecs.emplace_back(MakeIntrusive<TSortSpecification>(exprNode, asc));
  3425. return true;
  3426. }
  3427. bool TSqlTranslation::SortSpecificationList(const TRule_sort_specification_list& node, TVector<TSortSpecificationPtr>& sortSpecs) {
  3428. if (!SortSpecification(node.GetRule_sort_specification1(), sortSpecs)) {
  3429. return false;
  3430. }
  3431. for (auto sortSpec: node.GetBlock2()) {
  3432. Token(sortSpec.GetToken1());
  3433. if (!SortSpecification(sortSpec.GetRule_sort_specification2(), sortSpecs)) {
  3434. return false;
  3435. }
  3436. }
  3437. return true;
  3438. }
  3439. bool TSqlTranslation::IsDistinctOptSet(const TRule_opt_set_quantifier& node) const {
  3440. TPosition pos;
  3441. return node.HasBlock1() && IS_TOKEN(node.GetBlock1().GetToken1().GetId(), DISTINCT);
  3442. }
  3443. bool TSqlTranslation::IsDistinctOptSet(const TRule_opt_set_quantifier& node, TPosition& distinctPos) const {
  3444. if (node.HasBlock1() && IS_TOKEN(node.GetBlock1().GetToken1().GetId(), DISTINCT)) {
  3445. distinctPos = Ctx.TokenPosition(node.GetBlock1().GetToken1());
  3446. return true;
  3447. }
  3448. return false;
  3449. }
  3450. bool TSqlTranslation::RoleNameClause(const TRule_role_name& node, TDeferredAtom& result, bool allowSystemRoles) {
  3451. // role_name: an_id_or_type | bind_parameter;
  3452. switch (node.Alt_case()) {
  3453. case TRule_role_name::kAltRoleName1:
  3454. {
  3455. TString name = Id(node.GetAlt_role_name1().GetRule_an_id_or_type1(), *this);
  3456. result = TDeferredAtom(Ctx.Pos(), name);
  3457. break;
  3458. }
  3459. case TRule_role_name::kAltRoleName2:
  3460. {
  3461. if (!BindParameterClause(node.GetAlt_role_name2().GetRule_bind_parameter1(), result)) {
  3462. return false;
  3463. }
  3464. break;
  3465. }
  3466. case TRule_role_name::ALT_NOT_SET:
  3467. Y_ABORT("You should change implementation according to grammar changes");
  3468. }
  3469. if (auto literalName = result.GetLiteral(); literalName && !allowSystemRoles) {
  3470. static const THashSet<TStringBuf> systemRoles = { "current_role", "current_user", "session_user" };
  3471. if (systemRoles.contains(to_lower(*literalName))) {
  3472. Ctx.Error() << "System role " << to_upper(*literalName) << " can not be used here";
  3473. return false;
  3474. }
  3475. }
  3476. return true;
  3477. }
  3478. bool TSqlTranslation::PasswordParameter(const TRule_password_option& passwordOption, TUserParameters& result) {
  3479. // password_option: ENCRYPTED? PASSWORD expr;
  3480. TSqlExpression expr(Ctx, Mode);
  3481. TNodePtr password = expr.Build(passwordOption.GetRule_expr3());
  3482. if (!password) {
  3483. Error() << "Couldn't parse the password";
  3484. return false;
  3485. }
  3486. result.IsPasswordEncrypted = passwordOption.HasBlock1();
  3487. if (!password->IsNull()) {
  3488. result.Password = MakeAtomFromExpression(Ctx.Pos(), Ctx, password);
  3489. }
  3490. return true;
  3491. }
  3492. bool TSqlTranslation::HashParameter(const TRule_hash_option& hashOption, TUserParameters& result) {
  3493. // hash_option: HASH expr;
  3494. TSqlExpression expr(Ctx, Mode);
  3495. TNodePtr hash = expr.Build(hashOption.GetRule_expr2());
  3496. if (!hash) {
  3497. Error() << "Couldn't parse the hash of password";
  3498. return false;
  3499. }
  3500. if (!hash->IsNull()) {
  3501. result.Hash = MakeAtomFromExpression(Ctx.Pos(), Ctx, hash);
  3502. }
  3503. return true;
  3504. }
  3505. void TSqlTranslation::LoginParameter(const TRule_login_option& loginOption, std::optional<bool>& canLogin) {
  3506. // login_option: LOGIN | NOLOGIN;
  3507. auto token = loginOption.GetToken1().GetId();
  3508. if (IS_TOKEN(token, LOGIN)) {
  3509. canLogin = true;
  3510. } else if (IS_TOKEN(token, NOLOGIN)) {
  3511. canLogin = false;
  3512. } else {
  3513. Y_ABORT("You should change implementation according to grammar changes");
  3514. }
  3515. }
  3516. bool TSqlTranslation::UserParameters(const std::vector<TRule_user_option>& optionsList, TUserParameters& result, bool isCreateUser) {
  3517. enum class EUserOption {
  3518. Login,
  3519. Authentication
  3520. };
  3521. std::set<EUserOption> used;
  3522. auto ParseUserOption = [&used, this](const TRule_user_option& option, TUserParameters& result) -> bool {
  3523. // user_option: authentication_option | login_option;
  3524. // authentication_option: password_option | hash_option;
  3525. switch (option.Alt_case()) {
  3526. case TRule_user_option::kAltUserOption1:
  3527. {
  3528. if (used.contains(EUserOption::Authentication)) {
  3529. Error() << "Conflicting or redundant options";
  3530. return false;
  3531. }
  3532. used.insert(EUserOption::Authentication);
  3533. const auto& authenticationOption = option.GetAlt_user_option1().GetRule_authentication_option1();
  3534. switch (authenticationOption.Alt_case()) {
  3535. case TRule_authentication_option::kAltAuthenticationOption1: {
  3536. if (!PasswordParameter(authenticationOption.GetAlt_authentication_option1().GetRule_password_option1(), result)){
  3537. return false;
  3538. }
  3539. break;
  3540. }
  3541. case TRule_authentication_option::kAltAuthenticationOption2: {
  3542. if (!HashParameter(authenticationOption.GetAlt_authentication_option2().GetRule_hash_option1(), result)){
  3543. return false;
  3544. }
  3545. break;
  3546. }
  3547. case TRule_authentication_option::ALT_NOT_SET: {
  3548. Y_ABORT("You should change implementation according to grammar changes");
  3549. }
  3550. }
  3551. break;
  3552. }
  3553. case TRule_user_option::kAltUserOption2:
  3554. {
  3555. if (used.contains(EUserOption::Login)) {
  3556. Error() << "Conflicting or redundant options";
  3557. return false;
  3558. }
  3559. used.insert(EUserOption::Login);
  3560. LoginParameter(option.GetAlt_user_option2().GetRule_login_option1(), result.CanLogin);
  3561. break;
  3562. }
  3563. case TRule_user_option::ALT_NOT_SET:
  3564. {
  3565. Y_ABORT("You should change implementation according to grammar changes");
  3566. }
  3567. }
  3568. return true;
  3569. };
  3570. if (isCreateUser) {
  3571. result.CanLogin = true;
  3572. }
  3573. for (const auto& option : optionsList) {
  3574. if (!ParseUserOption(option, result)) {
  3575. return false;
  3576. }
  3577. }
  3578. return true;
  3579. }
  3580. bool TSqlTranslation::PermissionNameClause(const TRule_permission_id& node, TDeferredAtom& result) {
  3581. // permission_id:
  3582. // CONNECT
  3583. // | LIST
  3584. // | INSERT
  3585. // | MANAGE
  3586. // | DROP
  3587. // | GRANT
  3588. // | MODIFY (TABLES | ATTRIBUTES)
  3589. // | (UPDATE | ERASE) ROW
  3590. // | (REMOVE | DESCRIBE | ALTER) SCHEMA
  3591. // | SELECT (TABLES | ATTRIBUTES | ROW)?
  3592. // | (USE | FULL) LEGACY?
  3593. // | CREATE (DIRECTORY | TABLE | QUEUE)?
  3594. auto handleOneIdentifier = [&result, this] (const auto& permissionNameKeyword) {
  3595. result = TDeferredAtom(Ctx.Pos(), GetIdentifier(*this, permissionNameKeyword).Name);
  3596. };
  3597. auto handleTwoIdentifiers = [&result, this] (const auto& permissionNameKeyword) {
  3598. const auto& token1 = permissionNameKeyword.GetToken1();
  3599. const auto& token2 = permissionNameKeyword.GetToken2();
  3600. TString identifierName = TIdentifier(TPosition(token1.GetColumn(), token1.GetLine()), Identifier(token1)).Name +
  3601. "_" +
  3602. TIdentifier(TPosition(token2.GetColumn(), token2.GetLine()), Identifier(token2)).Name;
  3603. result = TDeferredAtom(Ctx.Pos(), identifierName);
  3604. };
  3605. auto handleOneOrTwoIdentifiers = [&result, this] (const auto& permissionNameKeyword) {
  3606. TString identifierName = GetIdentifier(*this, permissionNameKeyword).Name;
  3607. if (permissionNameKeyword.HasBlock2()) {
  3608. identifierName += "_" + GetIdentifier(*this, permissionNameKeyword.GetBlock2()).Name;
  3609. }
  3610. result = TDeferredAtom(Ctx.Pos(), identifierName);
  3611. };
  3612. switch (node.GetAltCase()) {
  3613. case TRule_permission_id::kAltPermissionId1:
  3614. {
  3615. // CONNECT
  3616. handleOneIdentifier(node.GetAlt_permission_id1());
  3617. break;
  3618. }
  3619. case TRule_permission_id::kAltPermissionId2:
  3620. {
  3621. // LIST
  3622. handleOneIdentifier(node.GetAlt_permission_id2());
  3623. break;
  3624. }
  3625. case TRule_permission_id::kAltPermissionId3:
  3626. {
  3627. // INSERT
  3628. handleOneIdentifier(node.GetAlt_permission_id3());
  3629. break;
  3630. }
  3631. case TRule_permission_id::kAltPermissionId4:
  3632. {
  3633. // MANAGE
  3634. handleOneIdentifier(node.GetAlt_permission_id4());
  3635. break;
  3636. }
  3637. case TRule_permission_id::kAltPermissionId5:
  3638. {
  3639. // DROP
  3640. handleOneIdentifier(node.GetAlt_permission_id5());
  3641. break;
  3642. }
  3643. case TRule_permission_id::kAltPermissionId6:
  3644. {
  3645. // GRANT
  3646. handleOneIdentifier(node.GetAlt_permission_id6());
  3647. break;
  3648. }
  3649. case TRule_permission_id::kAltPermissionId7:
  3650. {
  3651. // MODIFY (TABLES | ATTRIBUTES)
  3652. handleTwoIdentifiers(node.GetAlt_permission_id7());
  3653. break;
  3654. }
  3655. case TRule_permission_id::kAltPermissionId8:
  3656. {
  3657. // (UPDATE | ERASE) ROW
  3658. handleTwoIdentifiers(node.GetAlt_permission_id8());
  3659. break;
  3660. }
  3661. case TRule_permission_id::kAltPermissionId9:
  3662. {
  3663. // (REMOVE | DESCRIBE | ALTER) SCHEMA
  3664. handleTwoIdentifiers(node.GetAlt_permission_id9());
  3665. break;
  3666. }
  3667. case TRule_permission_id::kAltPermissionId10:
  3668. {
  3669. // SELECT (TABLES | ATTRIBUTES | ROW)?
  3670. handleOneOrTwoIdentifiers(node.GetAlt_permission_id10());
  3671. break;
  3672. }
  3673. case TRule_permission_id::kAltPermissionId11:
  3674. {
  3675. // (USE | FULL) LEGACY?
  3676. handleOneOrTwoIdentifiers(node.GetAlt_permission_id11());
  3677. break;
  3678. }
  3679. case TRule_permission_id::kAltPermissionId12:
  3680. {
  3681. // CREATE (DIRECTORY | TABLE | QUEUE)?
  3682. handleOneOrTwoIdentifiers(node.GetAlt_permission_id12());
  3683. break;
  3684. }
  3685. case TRule_permission_id::ALT_NOT_SET:
  3686. Y_ABORT("You should change implementation according to grammar changes");
  3687. }
  3688. return true;
  3689. }
  3690. bool TSqlTranslation::PermissionNameClause(const TRule_permission_name& node, TDeferredAtom& result) {
  3691. // permission_name: permission_id | STRING_VALUE;
  3692. switch (node.Alt_case()) {
  3693. case TRule_permission_name::kAltPermissionName1:
  3694. {
  3695. return PermissionNameClause(node.GetAlt_permission_name1().GetRule_permission_id1(), result);
  3696. break;
  3697. }
  3698. case TRule_permission_name::kAltPermissionName2:
  3699. {
  3700. const TString stringValue(Ctx.Token(node.GetAlt_permission_name2().GetToken1()));
  3701. auto unescaped = StringContent(Ctx, Ctx.Pos(), stringValue);
  3702. if (!unescaped) {
  3703. return false;
  3704. }
  3705. result = TDeferredAtom(Ctx.Pos(), unescaped->Content);
  3706. break;
  3707. }
  3708. case TRule_permission_name::ALT_NOT_SET:
  3709. Y_ABORT("You should change implementation according to grammar changes");
  3710. }
  3711. return true;
  3712. }
  3713. bool TSqlTranslation::PermissionNameClause(const TRule_permission_name_target& node, TVector<TDeferredAtom>& result, bool withGrantOption) {
  3714. // permission_name_target: permission_name (COMMA permission_name)* COMMA? | ALL PRIVILEGES?;
  3715. switch (node.Alt_case()) {
  3716. case TRule_permission_name_target::kAltPermissionNameTarget1:
  3717. {
  3718. const auto& permissionNameRule = node.GetAlt_permission_name_target1();
  3719. result.emplace_back();
  3720. if (!PermissionNameClause(permissionNameRule.GetRule_permission_name1(), result.back())) {
  3721. return false;
  3722. }
  3723. for (const auto& item : permissionNameRule.GetBlock2()) {
  3724. result.emplace_back();
  3725. if (!PermissionNameClause(item.GetRule_permission_name2(), result.back())) {
  3726. return false;
  3727. }
  3728. }
  3729. break;
  3730. }
  3731. case TRule_permission_name_target::kAltPermissionNameTarget2:
  3732. {
  3733. result.emplace_back(Ctx.Pos(), "all_privileges");
  3734. break;
  3735. }
  3736. case TRule_permission_name_target::ALT_NOT_SET:
  3737. Y_ABORT("You should change implementation according to grammar changes");
  3738. }
  3739. if (withGrantOption) {
  3740. result.emplace_back(Ctx.Pos(), "grant");
  3741. }
  3742. return true;
  3743. }
  3744. bool TSqlTranslation::StoreStringSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
  3745. YQL_ENSURE(value);
  3746. const TString key = to_lower(id.Name);
  3747. if (result.find(key) != result.end()) {
  3748. Ctx.Error() << to_upper(key) << " duplicate keys";
  3749. return false;
  3750. }
  3751. switch (value->Alt_case()) {
  3752. case TRule_table_setting_value::kAltTableSettingValue2:
  3753. return StoreString(*value, result[key], Ctx, to_upper(key));
  3754. default:
  3755. Ctx.Error() << to_upper(key) << " value should be a string literal";
  3756. return false;
  3757. }
  3758. return true;
  3759. }
  3760. bool TSqlTranslation::StoreStringSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
  3761. const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
  3762. return StoreStringSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
  3763. }
  3764. bool TSqlTranslation::ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, const TRule_backup_collection_settings& settings) {
  3765. const auto& firstEntry = settings.GetRule_backup_collection_settings_entry1();
  3766. if (!StoreStringSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(), result)) {
  3767. return false;
  3768. }
  3769. for (const auto& block : settings.GetBlock2()) {
  3770. const auto& entry = block.GetRule_backup_collection_settings_entry2();
  3771. if (!StoreStringSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
  3772. return false;
  3773. }
  3774. }
  3775. return true;
  3776. }
  3777. bool TSqlTranslation::ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_backup_collection_actions& actions) {
  3778. auto parseAction = [&](auto& actionVariant) {
  3779. switch (actionVariant.Alt_case()) {
  3780. case TRule_alter_backup_collection_action::kAltAlterBackupCollectionAction1: {
  3781. const auto& action = actionVariant.GetAlt_alter_backup_collection_action1().GetRule_alter_table_set_table_setting_compat1();
  3782. if (!StoreStringSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
  3783. return false;
  3784. }
  3785. for (const auto& entry : action.GetBlock4()) {
  3786. if (!StoreStringSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
  3787. return false;
  3788. }
  3789. }
  3790. return true;
  3791. }
  3792. case TRule_alter_backup_collection_action::kAltAlterBackupCollectionAction2: {
  3793. const auto& action = actionVariant.GetAlt_alter_backup_collection_action2().GetRule_alter_table_reset_table_setting1();
  3794. const TString firstKey = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
  3795. toReset.insert(firstKey);
  3796. for (const auto& key : action.GetBlock4()) {
  3797. toReset.insert(to_lower(IdEx(key.GetRule_an_id2(), *this).Name));
  3798. }
  3799. return true;
  3800. }
  3801. case TRule_alter_backup_collection_action::ALT_NOT_SET:
  3802. Y_ABORT("You should change implementation according to grammar changes");
  3803. }
  3804. };
  3805. const auto& firstAction = actions.GetRule_alter_backup_collection_action1();
  3806. if (!parseAction(firstAction)) {
  3807. return false;
  3808. }
  3809. for (const auto& action : actions.GetBlock2()) {
  3810. if (!parseAction(action.GetRule_alter_backup_collection_action2())) {
  3811. return false;
  3812. }
  3813. }
  3814. return true;
  3815. }
  3816. bool TSqlTranslation::ParseBackupCollectionTables(TVector<TDeferredAtom>& result, const TRule_table_list& tables) {
  3817. const auto& firstEntry = tables.GetRule_an_id_table2();
  3818. result.push_back(TDeferredAtom(Ctx.Pos(), Id(firstEntry, *this)));
  3819. for (const auto& block : tables.GetBlock3()) {
  3820. const auto& entry = block.GetRule_an_id_table3();
  3821. result.push_back(TDeferredAtom(Ctx.Pos(), Id(entry, *this)));
  3822. }
  3823. return true;
  3824. }
  3825. bool TSqlTranslation::ParseBackupCollectionEntry(
  3826. bool& addDatabase,
  3827. bool& removeDatabase,
  3828. TVector<TDeferredAtom>& addTables,
  3829. TVector<TDeferredAtom>& removeTables,
  3830. const TRule_alter_backup_collection_entry& entry)
  3831. {
  3832. switch (entry.Alt_case()) {
  3833. case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry1: {
  3834. addDatabase = true;
  3835. return true;
  3836. }
  3837. case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry2: {
  3838. removeDatabase = true;
  3839. return true;
  3840. }
  3841. case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry3: {
  3842. auto table = entry.GetAlt_alter_backup_collection_entry3().GetRule_an_id_table3();
  3843. addTables.push_back(TDeferredAtom(Ctx.Pos(), Id(table, *this)));
  3844. return true;
  3845. }
  3846. case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry4: {
  3847. auto table = entry.GetAlt_alter_backup_collection_entry4().GetRule_an_id_table3();
  3848. removeTables.push_back(TDeferredAtom(Ctx.Pos(), Id(table, *this)));
  3849. return true;
  3850. }
  3851. case TRule_alter_backup_collection_entry::ALT_NOT_SET:
  3852. Y_ABORT("You should change implementation according to grammar changes");
  3853. }
  3854. return true;
  3855. }
  3856. bool TSqlTranslation::ParseBackupCollectionEntries(
  3857. bool& addDatabase,
  3858. bool& removeDatabase,
  3859. TVector<TDeferredAtom>& addTables,
  3860. TVector<TDeferredAtom>& removeTables,
  3861. const TRule_alter_backup_collection_entries& entries)
  3862. {
  3863. const auto& firstEntry = entries.GetRule_alter_backup_collection_entry1();
  3864. if (!ParseBackupCollectionEntry(addDatabase, removeDatabase, addTables, removeTables, firstEntry)) {
  3865. return false;
  3866. }
  3867. for (const auto& block : entries.GetBlock2()) {
  3868. const auto& entry = block.GetRule_alter_backup_collection_entry2();
  3869. if (!ParseBackupCollectionEntry(addDatabase, removeDatabase, addTables, removeTables, entry)) {
  3870. return false;
  3871. }
  3872. }
  3873. return true;
  3874. }
  3875. TString TSqlTranslation::FrameSettingsToString(EFrameSettings settings, bool isUnbounded) {
  3876. TString result;
  3877. switch (settings) {
  3878. case FramePreceding:
  3879. result = "PRECEDING"; break;
  3880. case FrameCurrentRow:
  3881. YQL_ENSURE(!isUnbounded);
  3882. result = "CURRENT ROW"; break;
  3883. case FrameFollowing:
  3884. result = "FOLLOWING"; break;
  3885. default:
  3886. Y_ABORT("Unexpected frame settings");
  3887. }
  3888. return (isUnbounded ? "UNBOUNDED " : "") + result;
  3889. }
  3890. bool CheckFrameBoundLiteral(TContext& ctx, const TFrameBound& bound, TMaybe<i32>& boundValue) {
  3891. boundValue = {};
  3892. auto node = bound.Bound;
  3893. if (node && node->IsLiteral()) {
  3894. auto type = node->GetLiteralType();
  3895. if (type != "Int32") {
  3896. ctx.Error(node->GetPos()) << "Expecting Int32 as frame bound value, but got " << type << " literal";
  3897. return false;
  3898. }
  3899. i32 value = FromString<i32>(node->GetLiteralValue());
  3900. if (value < 0) {
  3901. ctx.Error(node->GetPos()) << "Expecting non-negative value for frame bound, but got " << value;
  3902. return false;
  3903. }
  3904. boundValue = value;
  3905. }
  3906. return true;
  3907. }
  3908. bool TSqlTranslation::IsValidFrameSettings(TContext& ctx, const TFrameSpecification& frameSpec, size_t sortSpecSize) {
  3909. const TFrameBound& begin = *frameSpec.FrameBegin;
  3910. const TFrameBound& end = *frameSpec.FrameEnd;
  3911. YQL_ENSURE(begin.Settings != FrameUndefined);
  3912. YQL_ENSURE(end.Settings != FrameUndefined);
  3913. const bool beginUnbounded = !begin.Bound && begin.Settings != FrameCurrentRow;
  3914. const bool endUnbounded = !end.Bound && end.Settings != FrameCurrentRow;
  3915. if (beginUnbounded && begin.Settings == FrameFollowing) {
  3916. ctx.Error(begin.Pos) << "Frame cannot start from " << FrameSettingsToString(begin.Settings, beginUnbounded);
  3917. return false;
  3918. }
  3919. if (endUnbounded && end.Settings == FramePreceding) {
  3920. ctx.Error(end.Pos) << "Frame cannot end with " << FrameSettingsToString(end.Settings, endUnbounded);
  3921. return false;
  3922. }
  3923. if (begin.Settings > end.Settings) {
  3924. ctx.Error(begin.Pos) << "Frame cannot start from " << FrameSettingsToString(begin.Settings, beginUnbounded)
  3925. << " and end with " << FrameSettingsToString(end.Settings, endUnbounded);
  3926. return false;
  3927. }
  3928. if (frameSpec.FrameType == FrameByRange && sortSpecSize != 1) {
  3929. TStringBuf msg = "RANGE with <offset> PRECEDING/FOLLOWING requires exactly one expression in ORDER BY partition clause";
  3930. if (begin.Bound) {
  3931. ctx.Error(begin.Bound->GetPos()) << msg;
  3932. return false;
  3933. }
  3934. if (end.Bound) {
  3935. ctx.Error(end.Bound->GetPos()) << msg;
  3936. return false;
  3937. }
  3938. }
  3939. TMaybe<i32> beginValue;
  3940. TMaybe<i32> endValue;
  3941. if (frameSpec.FrameType != EFrameType::FrameByRange) {
  3942. if (!CheckFrameBoundLiteral(ctx, begin, beginValue) || !CheckFrameBoundLiteral(ctx, end, endValue)) {
  3943. return false;
  3944. }
  3945. }
  3946. if (beginValue.Defined() && endValue.Defined()) {
  3947. if (begin.Settings == FramePreceding) {
  3948. beginValue = 0 - *beginValue;
  3949. }
  3950. if (end.Settings == FramePreceding) {
  3951. endValue = 0 - *endValue;
  3952. }
  3953. if (*beginValue > *endValue) {
  3954. YQL_ENSURE(begin.Bound);
  3955. ctx.Warning(begin.Bound->GetPos(), TIssuesIds::YQL_EMPTY_WINDOW_FRAME) << "Used frame specification implies empty window frame";
  3956. }
  3957. }
  3958. return true;
  3959. }
  3960. bool TSqlTranslation::FrameBound(const TRule_window_frame_bound& rule, TFrameBoundPtr& bound) {
  3961. // window_frame_bound:
  3962. // CURRENT ROW
  3963. // | (expr | UNBOUNDED) (PRECEDING | FOLLOWING)
  3964. // ;
  3965. bound = new TFrameBound;
  3966. switch (rule.Alt_case()) {
  3967. case TRule_window_frame_bound::kAltWindowFrameBound1:
  3968. bound->Pos = GetPos(rule.GetAlt_window_frame_bound1().GetToken1());
  3969. bound->Settings = FrameCurrentRow;
  3970. break;
  3971. case TRule_window_frame_bound::kAltWindowFrameBound2: {
  3972. auto block = rule.GetAlt_window_frame_bound2().GetBlock1();
  3973. switch (block.Alt_case()) {
  3974. case TRule_window_frame_bound_TAlt2_TBlock1::kAlt1: {
  3975. TSqlExpression boundExpr(Ctx, Mode);
  3976. bound->Bound = boundExpr.Build(block.GetAlt1().GetRule_expr1());
  3977. if (!bound->Bound) {
  3978. return false;
  3979. }
  3980. bound->Pos = bound->Bound->GetPos();
  3981. break;
  3982. }
  3983. case TRule_window_frame_bound_TAlt2_TBlock1::kAlt2:
  3984. bound->Pos = GetPos(block.GetAlt2().GetToken1());
  3985. break;
  3986. case TRule_window_frame_bound_TAlt2_TBlock1::ALT_NOT_SET:
  3987. Y_ABORT("You should change implementation according to grammar changes");
  3988. }
  3989. const TString settingToken = to_lower(Token(rule.GetAlt_window_frame_bound2().GetToken2()));
  3990. if (settingToken == "preceding") {
  3991. bound->Settings = FramePreceding;
  3992. } else if (settingToken == "following") {
  3993. bound->Settings = FrameFollowing;
  3994. } else {
  3995. Y_ABORT("You should change implementation according to grammar changes");
  3996. }
  3997. break;
  3998. }
  3999. case TRule_window_frame_bound::ALT_NOT_SET:
  4000. Y_ABORT("FrameClause: frame bound not corresond to grammar changes");
  4001. }
  4002. return true;
  4003. }
  4004. bool TSqlTranslation::FrameClause(const TRule_window_frame_clause& rule, TFrameSpecificationPtr& frameSpec, size_t sortSpecSize) {
  4005. // window_frame_clause: window_frame_units window_frame_extent window_frame_exclusion?;
  4006. frameSpec = new TFrameSpecification;
  4007. const TString frameUnitStr = to_lower(Token(rule.GetRule_window_frame_units1().GetToken1()));
  4008. if (frameUnitStr == "rows") {
  4009. frameSpec->FrameType = EFrameType::FrameByRows;
  4010. } else if (frameUnitStr == "range") {
  4011. frameSpec->FrameType = EFrameType::FrameByRange;
  4012. } else {
  4013. YQL_ENSURE(frameUnitStr == "groups");
  4014. frameSpec->FrameType = EFrameType::FrameByGroups;
  4015. }
  4016. auto frameExtent = rule.GetRule_window_frame_extent2();
  4017. // window_frame_extent: window_frame_bound | window_frame_between;
  4018. switch (frameExtent.Alt_case()) {
  4019. case TRule_window_frame_extent::kAltWindowFrameExtent1: {
  4020. auto start = frameExtent.GetAlt_window_frame_extent1().GetRule_window_frame_bound1();
  4021. if (!FrameBound(start, frameSpec->FrameBegin)) {
  4022. return false;
  4023. }
  4024. // frame end is CURRENT ROW
  4025. frameSpec->FrameEnd = new TFrameBound;
  4026. frameSpec->FrameEnd->Pos = frameSpec->FrameBegin->Pos;
  4027. frameSpec->FrameEnd->Settings = FrameCurrentRow;
  4028. break;
  4029. }
  4030. case TRule_window_frame_extent::kAltWindowFrameExtent2: {
  4031. // window_frame_between: BETWEEN window_frame_bound AND window_frame_bound;
  4032. auto between = frameExtent.GetAlt_window_frame_extent2().GetRule_window_frame_between1();
  4033. if (!FrameBound(between.GetRule_window_frame_bound2(), frameSpec->FrameBegin)) {
  4034. return false;
  4035. }
  4036. if (!FrameBound(between.GetRule_window_frame_bound4(), frameSpec->FrameEnd)) {
  4037. return false;
  4038. }
  4039. break;
  4040. }
  4041. case TRule_window_frame_extent::ALT_NOT_SET:
  4042. Y_ABORT("FrameClause: frame extent not correspond to grammar changes");
  4043. }
  4044. YQL_ENSURE(frameSpec->FrameBegin);
  4045. YQL_ENSURE(frameSpec->FrameEnd);
  4046. if (!IsValidFrameSettings(Ctx, *frameSpec, sortSpecSize)) {
  4047. return false;
  4048. }
  4049. if (rule.HasBlock3()) {
  4050. // window_frame_exclusion: EXCLUDE CURRENT ROW | EXCLUDE GROUP | EXCLUDE TIES | EXCLUDE NO OTHERS;
  4051. switch (rule.GetBlock3().GetRule_window_frame_exclusion1().Alt_case()) {
  4052. case TRule_window_frame_exclusion::kAltWindowFrameExclusion1:
  4053. frameSpec->FrameExclusion = FrameExclCurRow;
  4054. break;
  4055. case TRule_window_frame_exclusion::kAltWindowFrameExclusion2:
  4056. frameSpec->FrameExclusion = FrameExclGroup;
  4057. break;
  4058. case TRule_window_frame_exclusion::kAltWindowFrameExclusion3:
  4059. frameSpec->FrameExclusion = FrameExclTies;
  4060. break;
  4061. case TRule_window_frame_exclusion::kAltWindowFrameExclusion4:
  4062. frameSpec->FrameExclusion = FrameExclNone;
  4063. break;
  4064. case TRule_window_frame_exclusion::ALT_NOT_SET:
  4065. Y_ABORT("FrameClause: frame exclusion not correspond to grammar changes");
  4066. }
  4067. }
  4068. if (frameSpec->FrameExclusion != FrameExclNone) {
  4069. Ctx.Error() << "Frame exclusion is not supported yet";
  4070. return false;
  4071. }
  4072. return true;
  4073. }
  4074. TWindowSpecificationPtr TSqlTranslation::WindowSpecification(const TRule_window_specification_details& rule) {
  4075. /*
  4076. window_specification_details:
  4077. existing_window_name?
  4078. window_partition_clause?
  4079. window_order_clause?
  4080. window_frame_clause?
  4081. */
  4082. TWindowSpecificationPtr winSpecPtr = new TWindowSpecification;
  4083. if (rule.HasBlock1()) {
  4084. Ctx.Error() << "Existing window name is not supported in window specification yet!";
  4085. return {};
  4086. }
  4087. if (rule.HasBlock2()) {
  4088. /*
  4089. window_partition_clause: PARTITION COMPACT? BY named_expr_list;
  4090. */
  4091. auto& partitionClause = rule.GetBlock2().GetRule_window_partition_clause1();
  4092. winSpecPtr->IsCompact = partitionClause.HasBlock2();
  4093. if (!winSpecPtr->IsCompact) {
  4094. auto hints = Ctx.PullHintForToken(Ctx.TokenPosition(partitionClause.GetToken1()));
  4095. winSpecPtr->IsCompact = AnyOf(hints, [](const NSQLTranslation::TSQLHint& hint) { return to_lower(hint.Name) == "compact"; });
  4096. }
  4097. TColumnRefScope scope(Ctx, EColumnRefState::Allow);
  4098. if (!NamedExprList(partitionClause.GetRule_named_expr_list4(), winSpecPtr->Partitions)) {
  4099. return {};
  4100. }
  4101. // ignore empty unnamed tuples:
  4102. // "PARTITION BY (), foo(x) as y, (), (z)" is allowed and will work exactly the same as
  4103. // "PARTITION BY foo(x) as y, z"
  4104. auto removed = std::remove_if(winSpecPtr->Partitions.begin(), winSpecPtr->Partitions.end(),
  4105. [](const TNodePtr& partitionNode) {
  4106. return !partitionNode->GetLabel() && !partitionNode->GetColumnName() &&
  4107. partitionNode->GetTupleNode() != nullptr &&
  4108. partitionNode->GetTupleSize() == 0;
  4109. });
  4110. winSpecPtr->Partitions.erase(removed, winSpecPtr->Partitions.end());
  4111. }
  4112. if (rule.HasBlock3()) {
  4113. if (!OrderByClause(rule.GetBlock3().GetRule_window_order_clause1().GetRule_order_by_clause1(), winSpecPtr->OrderBy)) {
  4114. return {};
  4115. }
  4116. }
  4117. const bool ordered = !winSpecPtr->OrderBy.empty();
  4118. if (rule.HasBlock4()) {
  4119. if (!FrameClause(rule.GetBlock4().GetRule_window_frame_clause1(), winSpecPtr->Frame, winSpecPtr->OrderBy.size())) {
  4120. return {};
  4121. }
  4122. } else {
  4123. winSpecPtr->Frame = new TFrameSpecification;
  4124. winSpecPtr->Frame->FrameBegin = new TFrameBound;
  4125. winSpecPtr->Frame->FrameEnd = new TFrameBound;
  4126. winSpecPtr->Frame->FrameBegin->Pos = winSpecPtr->Frame->FrameEnd->Pos = Ctx.Pos();
  4127. winSpecPtr->Frame->FrameExclusion = EFrameExclusions::FrameExclNone;
  4128. winSpecPtr->Frame->FrameBegin->Settings = EFrameSettings::FramePreceding;
  4129. if (Ctx.AnsiCurrentRow) {
  4130. // RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  4131. winSpecPtr->Frame->FrameType = EFrameType::FrameByRange;
  4132. winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameCurrentRow;
  4133. } else if (ordered) {
  4134. // legacy behavior
  4135. // ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  4136. winSpecPtr->Frame->FrameType = EFrameType::FrameByRows;
  4137. winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameCurrentRow;
  4138. } else {
  4139. // ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  4140. winSpecPtr->Frame->FrameType = EFrameType::FrameByRows;
  4141. winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameFollowing;
  4142. }
  4143. }
  4144. // Normalize and simplify
  4145. auto replaceCurrentWith = [](TFrameBound& frame, bool preceding, TNodePtr value ) {
  4146. frame.Settings = preceding ? EFrameSettings::FramePreceding : EFrameSettings::FrameFollowing;
  4147. frame.Bound = value;
  4148. };
  4149. const auto frameSpec = winSpecPtr->Frame;
  4150. if (!ordered && frameSpec->FrameType != EFrameType::FrameByRows) {
  4151. // CURRENT ROW -> UNBOUNDED
  4152. if (frameSpec->FrameBegin->Settings == EFrameSettings::FrameCurrentRow) {
  4153. replaceCurrentWith(*frameSpec->FrameBegin, true, nullptr);
  4154. }
  4155. if (frameSpec->FrameEnd->Settings == EFrameSettings::FrameCurrentRow) {
  4156. replaceCurrentWith(*frameSpec->FrameBegin, false, nullptr);
  4157. }
  4158. }
  4159. // RANGE/GROUPS UNBOUNDED -> ROWS UNBOUNDED
  4160. if (frameSpec->FrameBegin->Settings == EFrameSettings::FramePreceding && !frameSpec->FrameBegin->Bound &&
  4161. frameSpec->FrameEnd->Settings == EFrameSettings::FrameFollowing && !frameSpec->FrameEnd->Bound)
  4162. {
  4163. frameSpec->FrameType = EFrameType::FrameByRows;
  4164. }
  4165. if (frameSpec->FrameType != EFrameType::FrameByRange) {
  4166. // replace FrameCurrentRow for ROWS/GROUPS with 0 preceding/following
  4167. // FrameCurrentRow has special meaning ( = first/last peer row)
  4168. if (frameSpec->FrameBegin->Settings == EFrameSettings::FrameCurrentRow) {
  4169. TNodePtr zero = new TLiteralNumberNode<i32>(winSpecPtr->Frame->FrameBegin->Pos, "Int32", "0");
  4170. replaceCurrentWith(*frameSpec->FrameBegin, true, zero);
  4171. }
  4172. if (frameSpec->FrameEnd->Settings == EFrameSettings::FrameCurrentRow) {
  4173. TNodePtr zero = new TLiteralNumberNode<i32>(winSpecPtr->Frame->FrameEnd->Pos, "Int32", "0");
  4174. replaceCurrentWith(*frameSpec->FrameEnd, false, zero);
  4175. }
  4176. }
  4177. return winSpecPtr;
  4178. }
  4179. TNodePtr TSqlTranslation::DoStatement(const TRule_do_stmt& stmt, bool makeLambda, const TVector<TString>& args) {
  4180. switch (stmt.GetBlock2().Alt_case()) {
  4181. case TRule_do_stmt_TBlock2::kAlt1: {
  4182. const auto& callAction = stmt.GetBlock2().GetAlt1().GetRule_call_action1();
  4183. TNodePtr action;
  4184. switch (callAction.GetBlock1().GetAltCase()) {
  4185. case TRule_call_action_TBlock1::kAlt1: {
  4186. TString bindName;
  4187. if (!NamedNodeImpl(callAction.GetBlock1().GetAlt1().GetRule_bind_parameter1(), bindName, *this)) {
  4188. return nullptr;
  4189. }
  4190. action = GetNamedNode(bindName);
  4191. if (!action) {
  4192. return nullptr;
  4193. }
  4194. break;
  4195. }
  4196. case TRule_call_action_TBlock1::kAlt2:
  4197. action = BuildEmptyAction(Ctx.Pos());
  4198. break;
  4199. case TRule_call_action_TBlock1::ALT_NOT_SET:
  4200. Ctx.IncrementMonCounter("sql_errors", "UnknownDoStmt");
  4201. AltNotImplemented("do_stmt", callAction.GetBlock1());
  4202. return nullptr;
  4203. }
  4204. TVector<TNodePtr> values;
  4205. values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "Apply", TNodeFlags::Default));
  4206. values.push_back(action);
  4207. values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "world", TNodeFlags::Default));
  4208. TSqlExpression sqlExpr(Ctx, Mode);
  4209. if (callAction.HasBlock3() && !ExprList(sqlExpr, values, callAction.GetBlock3().GetRule_expr_list1())) {
  4210. return nullptr;
  4211. }
  4212. TNodePtr apply = new TAstListNodeImpl(Ctx.Pos(), std::move(values));
  4213. if (!makeLambda) {
  4214. return BuildDoCall(Ctx.Pos(), apply);
  4215. }
  4216. TNodePtr params = new TAstListNodeImpl(Ctx.Pos());
  4217. params->Add("world");
  4218. for (const auto& arg : args) {
  4219. params->Add(new TAstAtomNodeImpl(Ctx.Pos(), arg, TNodeFlags::ArbitraryContent));
  4220. }
  4221. return BuildDoCall(Ctx.Pos(), BuildLambda(Ctx.Pos(), params, apply));
  4222. }
  4223. case TRule_do_stmt_TBlock2::kAlt2: {
  4224. const auto& inlineAction = stmt.GetBlock2().GetAlt2().GetRule_inline_action1();
  4225. const auto& body = inlineAction.GetRule_define_action_or_subquery_body2();
  4226. auto saveScoped = Ctx.Scoped;
  4227. Ctx.Scoped = MakeIntrusive<TScopedState>();
  4228. Ctx.AllScopes.push_back(Ctx.Scoped);
  4229. *Ctx.Scoped = *saveScoped;
  4230. Ctx.Scoped->Local = TScopedState::TLocal{};
  4231. Ctx.ScopeLevel++;
  4232. TSqlQuery query(Ctx, Ctx.Settings.Mode, false);
  4233. TBlocks innerBlocks;
  4234. const bool hasValidBody = DefineActionOrSubqueryBody(query, innerBlocks, body);
  4235. auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped, Ctx.SeqMode) : nullptr;
  4236. WarnUnusedNodes();
  4237. Ctx.ScopeLevel--;
  4238. Ctx.Scoped = saveScoped;
  4239. if (!ret) {
  4240. return {};
  4241. }
  4242. TNodePtr blockNode = new TAstListNodeImpl(Ctx.Pos());
  4243. blockNode->Add("block");
  4244. blockNode->Add(blockNode->Q(ret));
  4245. if (!makeLambda) {
  4246. return blockNode;
  4247. }
  4248. TNodePtr params = new TAstListNodeImpl(Ctx.Pos());
  4249. params->Add("world");
  4250. for (const auto& arg : args) {
  4251. params->Add(new TAstAtomNodeImpl(Ctx.Pos(), arg, TNodeFlags::ArbitraryContent));
  4252. }
  4253. return BuildLambda(Ctx.Pos(), params, blockNode);
  4254. }
  4255. case TRule_do_stmt_TBlock2::ALT_NOT_SET:
  4256. Y_ABORT("You should change implementation according to grammar changes");
  4257. }
  4258. }
  4259. bool TSqlTranslation::DefineActionOrSubqueryBody(TSqlQuery& query, TBlocks& blocks, const TRule_define_action_or_subquery_body& body) {
  4260. if (body.HasBlock2()) {
  4261. Ctx.PushCurrentBlocks(&blocks);
  4262. Y_DEFER {
  4263. Ctx.PopCurrentBlocks();
  4264. };
  4265. size_t statementNumber = 0;
  4266. if (!query.Statement(blocks, body.GetBlock2().GetRule_sql_stmt_core1(), statementNumber++)) {
  4267. return false;
  4268. }
  4269. for (const auto& nestedStmtItem : body.GetBlock2().GetBlock2()) {
  4270. const auto& nestedStmt = nestedStmtItem.GetRule_sql_stmt_core2();
  4271. if (!query.Statement(blocks, nestedStmt, statementNumber++)) {
  4272. return false;
  4273. }
  4274. }
  4275. }
  4276. return true;
  4277. }
  4278. bool TSqlTranslation::DefineActionOrSubqueryStatement(const TRule_define_action_or_subquery_stmt& stmt, TSymbolNameWithPos& nameAndPos, TNodePtr& lambda) {
  4279. auto kind = Ctx.Token(stmt.GetToken2());
  4280. const bool isSubquery = to_lower(kind) == "subquery";
  4281. if (!isSubquery && Mode == NSQLTranslation::ESqlMode::SUBQUERY) {
  4282. Error() << "Definition of actions is not allowed in the subquery";
  4283. return false;
  4284. }
  4285. TString actionName;
  4286. if (!NamedNodeImpl(stmt.GetRule_bind_parameter3(), actionName, *this)) {
  4287. return false;
  4288. }
  4289. if (IsAnonymousName(actionName)) {
  4290. Error() << "Can not use anonymous name '" << actionName << "' as " << to_upper(kind) << " name";
  4291. return false;
  4292. }
  4293. TPosition actionNamePos = Ctx.Pos();
  4294. TVector<TSymbolNameWithPos> argNames;
  4295. ui32 optionalArgumentsCount = 0;
  4296. if (stmt.HasBlock5() && !ActionOrSubqueryArgs(stmt.GetBlock5().GetRule_action_or_subquery_args1(), argNames, optionalArgumentsCount)) {
  4297. return false;
  4298. }
  4299. auto saveScoped = Ctx.Scoped;
  4300. Ctx.Scoped = MakeIntrusive<TScopedState>();
  4301. Ctx.AllScopes.push_back(Ctx.Scoped);
  4302. *Ctx.Scoped = *saveScoped;
  4303. Ctx.Scoped->Local = TScopedState::TLocal{};
  4304. Ctx.ScopeLevel++;
  4305. for (auto& arg : argNames) {
  4306. arg.Name = PushNamedAtom(arg.Pos, arg.Name);
  4307. }
  4308. auto saveMode = Ctx.Settings.Mode;
  4309. if (isSubquery) {
  4310. Ctx.Settings.Mode = NSQLTranslation::ESqlMode::SUBQUERY;
  4311. }
  4312. TSqlQuery query(Ctx, Ctx.Settings.Mode, false);
  4313. TBlocks innerBlocks;
  4314. const bool hasValidBody = DefineActionOrSubqueryBody(query, innerBlocks, stmt.GetRule_define_action_or_subquery_body8());
  4315. ui32 topLevelSelects = 0;
  4316. bool hasTailOps = false;
  4317. for (auto& block : innerBlocks) {
  4318. if (block->SubqueryAlias()) {
  4319. continue;
  4320. }
  4321. if (block->HasSelectResult()) {
  4322. ++topLevelSelects;
  4323. } else if (topLevelSelects) {
  4324. hasTailOps = true;
  4325. }
  4326. }
  4327. if (isSubquery && (topLevelSelects != 1 || hasTailOps)) {
  4328. Error() << "Strictly one select/process/reduce statement is expected at the end of subquery";
  4329. return false;
  4330. }
  4331. auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped, Ctx.SeqMode) : nullptr;
  4332. WarnUnusedNodes();
  4333. Ctx.Scoped = saveScoped;
  4334. Ctx.ScopeLevel--;
  4335. Ctx.Settings.Mode = saveMode;
  4336. if (!ret) {
  4337. return false;
  4338. }
  4339. TNodePtr blockNode = new TAstListNodeImpl(Ctx.Pos());
  4340. blockNode->Add("block");
  4341. blockNode->Add(blockNode->Q(ret));
  4342. TNodePtr params = new TAstListNodeImpl(Ctx.Pos());
  4343. params->Add("world");
  4344. for (const auto& arg : argNames) {
  4345. params->Add(BuildAtom(arg.Pos, arg.Name));
  4346. }
  4347. lambda = BuildLambda(Ctx.Pos(), params, blockNode);
  4348. if (optionalArgumentsCount > 0) {
  4349. lambda = new TCallNodeImpl(Ctx.Pos(), "WithOptionalArgs", {
  4350. lambda,
  4351. BuildQuotedAtom(Ctx.Pos(), ToString(optionalArgumentsCount), TNodeFlags::Default)
  4352. });
  4353. }
  4354. nameAndPos.Name = actionName;
  4355. nameAndPos.Pos = actionNamePos;
  4356. return true;
  4357. }
  4358. TNodePtr TSqlTranslation::IfStatement(const TRule_if_stmt& stmt) {
  4359. bool isEvaluate = stmt.HasBlock1();
  4360. TSqlExpression expr(Ctx, Mode);
  4361. auto exprNode = expr.Build(stmt.GetRule_expr3());
  4362. if (!exprNode) {
  4363. return {};
  4364. }
  4365. auto thenNode = DoStatement(stmt.GetRule_do_stmt4(), isEvaluate);
  4366. if (!thenNode) {
  4367. return {};
  4368. }
  4369. TNodePtr elseNode;
  4370. if (stmt.HasBlock5()) {
  4371. elseNode = DoStatement(stmt.GetBlock5().GetRule_do_stmt2(), isEvaluate);
  4372. if (!elseNode) {
  4373. return {};
  4374. }
  4375. }
  4376. return BuildWorldIfNode(Ctx.Pos(), exprNode, thenNode, elseNode, isEvaluate);
  4377. }
  4378. TNodePtr TSqlTranslation::ForStatement(const TRule_for_stmt& stmt) {
  4379. bool isEvaluate = stmt.HasBlock1();
  4380. bool isParallel = stmt.HasBlock2();
  4381. TSqlExpression expr(Ctx, Mode);
  4382. TString itemArgName;
  4383. if (!NamedNodeImpl(stmt.GetRule_bind_parameter4(), itemArgName, *this)) {
  4384. return {};
  4385. }
  4386. TPosition itemArgNamePos = Ctx.Pos();
  4387. auto exprNode = expr.Build(stmt.GetRule_expr6());
  4388. if (!exprNode) {
  4389. return{};
  4390. }
  4391. itemArgName = PushNamedAtom(itemArgNamePos, itemArgName);
  4392. if (isParallel) {
  4393. ++Ctx.ParallelModeCount;
  4394. }
  4395. auto bodyNode = DoStatement(stmt.GetRule_do_stmt7(), true, { itemArgName });
  4396. if (isParallel) {
  4397. --Ctx.ParallelModeCount;
  4398. }
  4399. PopNamedNode(itemArgName);
  4400. if (!bodyNode) {
  4401. return{};
  4402. }
  4403. TNodePtr elseNode;
  4404. if (stmt.HasBlock8()) {
  4405. elseNode = DoStatement(stmt.GetBlock8().GetRule_do_stmt2(), true);
  4406. if (!elseNode) {
  4407. return{};
  4408. }
  4409. }
  4410. return BuildWorldForNode(Ctx.Pos(), exprNode, bodyNode, elseNode, isEvaluate, isParallel);
  4411. }
  4412. bool TSqlTranslation::BindParameterClause(const TRule_bind_parameter& node, TDeferredAtom& result) {
  4413. TString paramName;
  4414. if (!NamedNodeImpl(node, paramName, *this)) {
  4415. return false;
  4416. }
  4417. auto named = GetNamedNode(paramName);
  4418. if (!named) {
  4419. return false;
  4420. }
  4421. result = MakeAtomFromExpression(Ctx.Pos(), Ctx, named);
  4422. return true;
  4423. }
  4424. bool TSqlTranslation::ObjectFeatureValueClause(const TRule_object_feature_value& node, TDeferredAtom& result) {
  4425. // object_feature_value: id_or_type | bind_parameter | STRING_VALUE | bool_value;
  4426. switch (node.Alt_case()) {
  4427. case TRule_object_feature_value::kAltObjectFeatureValue1:
  4428. {
  4429. TString name = Id(node.GetAlt_object_feature_value1().GetRule_id_or_type1(), *this);
  4430. result = TDeferredAtom(Ctx.Pos(), name);
  4431. break;
  4432. }
  4433. case TRule_object_feature_value::kAltObjectFeatureValue2:
  4434. {
  4435. if (!BindParameterClause(node.GetAlt_object_feature_value2().GetRule_bind_parameter1(), result)) {
  4436. return false;
  4437. }
  4438. break;
  4439. }
  4440. case TRule_object_feature_value::kAltObjectFeatureValue3:
  4441. {
  4442. auto strValue = StringContent(Ctx, Ctx.Pos(), Ctx.Token(node.GetAlt_object_feature_value3().GetToken1()));
  4443. if (!strValue) {
  4444. Error() << "Cannot parse string correctly: " << Ctx.Token(node.GetAlt_object_feature_value3().GetToken1());
  4445. return false;
  4446. }
  4447. result = TDeferredAtom(Ctx.Pos(), strValue->Content);
  4448. break;
  4449. }
  4450. case TRule_object_feature_value::kAltObjectFeatureValue4:
  4451. {
  4452. TString value = Ctx.Token(node.GetAlt_object_feature_value4().GetRule_bool_value1().GetToken1());
  4453. result = TDeferredAtom(BuildLiteralBool(Ctx.Pos(), FromString<bool>(value)), Ctx);
  4454. break;
  4455. }
  4456. case TRule_object_feature_value::ALT_NOT_SET:
  4457. Y_ABORT("You should change implementation according to grammar changes");
  4458. }
  4459. return true;
  4460. }
  4461. bool TSqlTranslation::AddObjectFeature(std::map<TString, TDeferredAtom>& result, const TRule_object_feature& feature) {
  4462. if (feature.has_alt_object_feature1()) {
  4463. auto& kv = feature.GetAlt_object_feature1().GetRule_object_feature_kv1();
  4464. const TString& key = Id(kv.GetRule_an_id_or_type1(), *this);
  4465. auto& ruleValue = kv.GetRule_object_feature_value3();
  4466. TDeferredAtom value;
  4467. if (!ObjectFeatureValueClause(ruleValue, value)) {
  4468. return false;
  4469. }
  4470. result[key] = value;
  4471. } else if (feature.has_alt_object_feature2()) {
  4472. result[Id(feature.GetAlt_object_feature2().GetRule_object_feature_flag1().GetRule_an_id_or_type1(), *this)] = TDeferredAtom();
  4473. }
  4474. return true;
  4475. }
  4476. bool TSqlTranslation::ParseObjectFeatures(std::map<TString, TDeferredAtom>& result, const TRule_object_features& features) {
  4477. if (features.has_alt_object_features1()) {
  4478. if (!AddObjectFeature(result, features.alt_object_features1().GetRule_object_feature1())) {
  4479. return false;
  4480. }
  4481. } else if (features.has_alt_object_features2()) {
  4482. if (!AddObjectFeature(result, features.alt_object_features2().GetRule_object_feature2())) {
  4483. return false;
  4484. }
  4485. for (auto&& i : features.alt_object_features2().GetBlock3()) {
  4486. if (!AddObjectFeature(result, i.GetRule_object_feature2())) {
  4487. return false;
  4488. }
  4489. }
  4490. } else {
  4491. return false;
  4492. }
  4493. return true;
  4494. }
  4495. bool TSqlTranslation::StoreDataSourceSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
  4496. YQL_ENSURE(value);
  4497. const TString key = to_lower(id.Name);
  4498. if (result.find(key) != result.end()) {
  4499. Ctx.Error() << to_upper(key) << " duplicate keys";
  4500. return false;
  4501. }
  4502. if (!StoreString(*value, result[key], Ctx, to_upper(key))) {
  4503. return false;
  4504. }
  4505. return true;
  4506. }
  4507. bool TSqlTranslation::StoreDataSourceSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
  4508. const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
  4509. return StoreDataSourceSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
  4510. }
  4511. bool TSqlTranslation::ParseExternalDataSourceSettings(std::map<TString, TDeferredAtom>& result, const TRule_with_table_settings& settingsNode) {
  4512. const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
  4513. if (!StoreDataSourceSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(),
  4514. result)) {
  4515. return false;
  4516. }
  4517. for (auto& block : settingsNode.GetBlock4()) {
  4518. const auto& entry = block.GetRule_table_settings_entry2();
  4519. if (!StoreDataSourceSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
  4520. return false;
  4521. }
  4522. }
  4523. if (result.find("source_type") == result.end()) {
  4524. Ctx.Error() << "SOURCE_TYPE requires key";
  4525. return false;
  4526. }
  4527. if (!ValidateAuthMethod(result)) {
  4528. return false;
  4529. }
  4530. return true;
  4531. }
  4532. bool TSqlTranslation::ParseExternalDataSourceSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_external_data_source_action& alterAction) {
  4533. switch (alterAction.Alt_case()) {
  4534. case TRule_alter_external_data_source_action::kAltAlterExternalDataSourceAction1: {
  4535. const auto& action = alterAction.GetAlt_alter_external_data_source_action1().GetRule_alter_table_set_table_setting_uncompat1();
  4536. if (!StoreDataSourceSettingsEntry(IdEx(action.GetRule_an_id2(), *this), &action.GetRule_table_setting_value3(), result)) {
  4537. return false;
  4538. }
  4539. return true;
  4540. }
  4541. case TRule_alter_external_data_source_action::kAltAlterExternalDataSourceAction2: {
  4542. const auto& action = alterAction.GetAlt_alter_external_data_source_action2().GetRule_alter_table_set_table_setting_compat1();
  4543. if (!StoreDataSourceSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
  4544. return false;
  4545. }
  4546. for (const auto& entry : action.GetBlock4()) {
  4547. if (!StoreDataSourceSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
  4548. return false;
  4549. }
  4550. }
  4551. return true;
  4552. }
  4553. case TRule_alter_external_data_source_action::kAltAlterExternalDataSourceAction3: {
  4554. const auto& action = alterAction.GetAlt_alter_external_data_source_action3().GetRule_alter_table_reset_table_setting1();
  4555. const TString key = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
  4556. toReset.insert(key);
  4557. for (const auto& keys : action.GetBlock4()) {
  4558. const TString key = to_lower(IdEx(keys.GetRule_an_id2(), *this).Name);
  4559. toReset.insert(key);
  4560. }
  4561. return true;
  4562. }
  4563. case TRule_alter_external_data_source_action::ALT_NOT_SET:
  4564. Y_ABORT("You should change implementation according to grammar changes");
  4565. }
  4566. }
  4567. bool TSqlTranslation::ValidateAuthMethod(const std::map<TString, TDeferredAtom>& result) {
  4568. const static TSet<TStringBuf> allAuthFields{
  4569. "service_account_id",
  4570. "service_account_secret_name",
  4571. "login",
  4572. "password_secret_name",
  4573. "aws_access_key_id_secret_name",
  4574. "aws_secret_access_key_secret_name",
  4575. "aws_region",
  4576. "token_secret_name"
  4577. };
  4578. const static TMap<TStringBuf, TSet<TStringBuf>> authMethodFields{
  4579. {"NONE", {}},
  4580. {"SERVICE_ACCOUNT", {"service_account_id", "service_account_secret_name"}},
  4581. {"BASIC", {"login", "password_secret_name"}},
  4582. {"AWS", {"aws_access_key_id_secret_name", "aws_secret_access_key_secret_name", "aws_region"}},
  4583. {"MDB_BASIC", {"service_account_id", "service_account_secret_name", "login", "password_secret_name"}},
  4584. {"TOKEN", {"token_secret_name"}}
  4585. };
  4586. auto authMethodIt = result.find("auth_method");
  4587. if (authMethodIt == result.end() || authMethodIt->second.GetLiteral() == nullptr) {
  4588. Ctx.Error() << "AUTH_METHOD requires key";
  4589. return false;
  4590. }
  4591. const auto& authMethod = *authMethodIt->second.GetLiteral();
  4592. auto it = authMethodFields.find(authMethod);
  4593. if (it == authMethodFields.end()) {
  4594. Ctx.Error() << "Unknown AUTH_METHOD = " << authMethod;
  4595. return false;
  4596. }
  4597. const auto& currentAuthFields = it->second;
  4598. for (const auto& authField: allAuthFields) {
  4599. if (currentAuthFields.contains(authField) && !result.contains(TString{authField})) {
  4600. Ctx.Error() << to_upper(TString{authField}) << " requires key";
  4601. return false;
  4602. }
  4603. if (!currentAuthFields.contains(authField) && result.contains(TString{authField})) {
  4604. Ctx.Error() << to_upper(TString{authField}) << " key is not supported for AUTH_METHOD = " << authMethod;
  4605. return false;
  4606. }
  4607. }
  4608. return true;
  4609. }
  4610. bool TSqlTranslation::ValidateExternalTable(const TCreateTableParameters& params) {
  4611. if (params.TableType != ETableType::ExternalTable) {
  4612. return true;
  4613. }
  4614. if (!params.TableSettings.DataSourcePath) {
  4615. Ctx.Error() << "DATA_SOURCE requires key";
  4616. return false;
  4617. }
  4618. if (!params.TableSettings.Location) {
  4619. Ctx.Error() << "LOCATION requires key";
  4620. return false;
  4621. }
  4622. if (params.PkColumns) {
  4623. Ctx.Error() << "PRIMARY KEY is not supported for external table";
  4624. return false;
  4625. }
  4626. return true;
  4627. }
  4628. bool TSqlTranslation::ParseViewQuery(
  4629. std::map<TString, TDeferredAtom>& features,
  4630. const TRule_select_stmt& query
  4631. ) {
  4632. TString queryText = CollectTokens(query);
  4633. TString contextRecreationQuery;
  4634. {
  4635. const auto& service = Ctx.Scoped->CurrService;
  4636. const auto& cluster = Ctx.Scoped->CurrCluster;
  4637. const auto effectivePathPrefix = Ctx.GetPrefixPath(service, cluster);
  4638. // TO DO: capture all runtime pragmas in a similar fashion.
  4639. if (effectivePathPrefix != Ctx.Settings.PathPrefix) {
  4640. contextRecreationQuery = TStringBuilder() << "PRAGMA TablePathPrefix = \"" << effectivePathPrefix << "\";\n";
  4641. }
  4642. // TO DO: capture other compilation-affecting statements except USE.
  4643. if (cluster.GetLiteral() && *cluster.GetLiteral() != Ctx.Settings.DefaultCluster) {
  4644. contextRecreationQuery = TStringBuilder() << "USE " << *cluster.GetLiteral() << ";\n";
  4645. }
  4646. }
  4647. features["query_text"] = { Ctx.Pos(), contextRecreationQuery + queryText };
  4648. // AST is needed for ready-made validation of CREATE VIEW statement.
  4649. // Query is stored as plain text, not AST.
  4650. const auto viewSelect = BuildViewSelect(query, Ctx, contextRecreationQuery);
  4651. if (!viewSelect) {
  4652. return false;
  4653. }
  4654. features["query_ast"] = {viewSelect, Ctx};
  4655. return true;
  4656. }
  4657. namespace {
  4658. static std::string::size_type GetQueryPosition(const TString& query, const NSQLv1Generated::TToken& token, bool antlr4) {
  4659. if (1 == token.GetLine() && 0 == token.GetColumn()) {
  4660. return 0;
  4661. }
  4662. TPosition pos = {0, 1};
  4663. TTextWalker walker(pos, antlr4);
  4664. std::string::size_type position = 0;
  4665. for (char c : query) {
  4666. walker.Advance(c);
  4667. ++position;
  4668. if (pos.Row == token.GetLine() && pos.Column == token.GetColumn()) {
  4669. return position;
  4670. }
  4671. }
  4672. return std::string::npos;
  4673. }
  4674. static TString GetLambdaText(TTranslation& ctx, TContext& Ctx, const TRule_lambda_or_parameter& lambdaOrParameter) {
  4675. static const TString statementSeparator = ";\n";
  4676. TVector<TString> statements;
  4677. NYql::TIssues issues;
  4678. if (!SplitQueryToStatements(Ctx.Lexers, Ctx.Parsers, Ctx.Query, statements, issues, Ctx.Settings)) {
  4679. return {};
  4680. }
  4681. TStringBuilder result;
  4682. for (const auto id : Ctx.ForAllStatementsParts) {
  4683. result << statements[id] << "\n";
  4684. }
  4685. switch (lambdaOrParameter.Alt_case()) {
  4686. case NSQLv1Generated::TRule_lambda_or_parameter::kAltLambdaOrParameter1: {
  4687. const auto& lambda = lambdaOrParameter.GetAlt_lambda_or_parameter1().GetRule_lambda1();
  4688. auto& beginToken = lambda.GetRule_smart_parenthesis1().GetToken1();
  4689. const NSQLv1Generated::TToken* endToken = nullptr;
  4690. switch (lambda.GetBlock2().GetBlock2().GetAltCase()) {
  4691. case TRule_lambda_TBlock2_TBlock2::AltCase::kAlt1:
  4692. endToken = &lambda.GetBlock2().GetBlock2().GetAlt1().GetToken3();
  4693. break;
  4694. case TRule_lambda_TBlock2_TBlock2::AltCase::kAlt2:
  4695. endToken = &lambda.GetBlock2().GetBlock2().GetAlt2().GetToken3();
  4696. break;
  4697. case TRule_lambda_TBlock2_TBlock2::AltCase::ALT_NOT_SET:
  4698. Y_ABORT("You should change implementation according to grammar changes");
  4699. }
  4700. auto begin = GetQueryPosition(Ctx.Query, beginToken, Ctx.Settings.Antlr4Parser);
  4701. auto end = GetQueryPosition(Ctx.Query, *endToken, Ctx.Settings.Antlr4Parser);
  4702. if (begin == std::string::npos || end == std::string::npos) {
  4703. return {};
  4704. }
  4705. result << "$__ydb_transfer_lambda = " << Ctx.Query.substr(begin, end - begin + endToken->value().size()) << statementSeparator;
  4706. return result;
  4707. }
  4708. case NSQLv1Generated::TRule_lambda_or_parameter::kAltLambdaOrParameter2: {
  4709. const auto& valueBlock = lambdaOrParameter.GetAlt_lambda_or_parameter2().GetRule_bind_parameter1().GetBlock2();
  4710. const auto id = Id(valueBlock.GetAlt1().GetRule_an_id_or_type1(), ctx);
  4711. result << "$__ydb_transfer_lambda = $" << id << statementSeparator;
  4712. return result;
  4713. }
  4714. case NSQLv1Generated::TRule_lambda_or_parameter::ALT_NOT_SET:
  4715. Y_ABORT("You should change implementation according to grammar changes");
  4716. }
  4717. }
  4718. }
  4719. bool TSqlTranslation::ParseTransferLambda(
  4720. TString& lambdaText,
  4721. const TRule_lambda_or_parameter& lambdaOrParameter) {
  4722. TSqlExpression expr(Ctx, Ctx.Settings.Mode);
  4723. auto result = expr.Build(lambdaOrParameter);
  4724. if (!result) {
  4725. return false;
  4726. }
  4727. lambdaText = GetLambdaText(*this, Ctx, lambdaOrParameter);
  4728. if (lambdaText.empty()) {
  4729. Ctx.Error() << "Cannot parse lambda correctly";
  4730. }
  4731. return !lambdaText.empty();
  4732. }
  4733. class TReturningListColumns : public INode {
  4734. public:
  4735. TReturningListColumns(TPosition pos)
  4736. : INode(pos)
  4737. {
  4738. }
  4739. void SetStar() {
  4740. ColumnNames.clear();
  4741. Star = true;
  4742. }
  4743. void AddColumn(const NSQLv1Generated::TRule_an_id & rule, TTranslation& ctx) {
  4744. ColumnNames.push_back(NSQLTranslationV1::Id(rule, ctx));
  4745. }
  4746. bool DoInit(TContext& ctx, ISource* source) override {
  4747. Node = Y();
  4748. if (Star) {
  4749. Node->Add(Y("ReturningStar"));
  4750. } else {
  4751. for (auto&& column : ColumnNames) {
  4752. Node->Add(Y("ReturningListItem", Q(column)));
  4753. }
  4754. }
  4755. Node = Q(Y(Q("returning"), Q(Node)));
  4756. return Node->Init(ctx, source);
  4757. }
  4758. TNodePtr DoClone() const override {
  4759. return new TReturningListColumns(GetPos());
  4760. }
  4761. TAstNode* Translate(TContext& ctx) const override {
  4762. return Node->Translate(ctx);
  4763. }
  4764. private:
  4765. TNodePtr Node;
  4766. TVector<TString> ColumnNames;
  4767. bool Star = false;
  4768. };
  4769. TNodePtr TSqlTranslation::ReturningList(const ::NSQLv1Generated::TRule_returning_columns_list& columns) {
  4770. auto result = MakeHolder<TReturningListColumns>(Ctx.Pos());
  4771. if (columns.GetBlock2().Alt_case() == TRule_returning_columns_list_TBlock2::AltCase::kAlt1) {
  4772. result->SetStar();
  4773. } else if (columns.GetBlock2().Alt_case() == TRule_returning_columns_list_TBlock2::AltCase::kAlt2) {
  4774. result->AddColumn(columns.GetBlock2().alt2().GetRule_an_id1(), *this);
  4775. for (auto& block : columns.GetBlock2().alt2().GetBlock2()) {
  4776. result->AddColumn(block.GetRule_an_id2(), *this);
  4777. }
  4778. }
  4779. return result.Release();
  4780. }
  4781. bool TSqlTranslation::StoreResourcePoolSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
  4782. YQL_ENSURE(value);
  4783. const TString key = to_lower(id.Name);
  4784. if (result.find(key) != result.end()) {
  4785. Ctx.Error() << to_upper(key) << " duplicate keys";
  4786. return false;
  4787. }
  4788. switch (value->Alt_case()) {
  4789. case TRule_table_setting_value::kAltTableSettingValue2:
  4790. return StoreString(*value, result[key], Ctx, to_upper(key));
  4791. case TRule_table_setting_value::kAltTableSettingValue3:
  4792. return StoreInt(*value, result[key], Ctx, to_upper(key));
  4793. default:
  4794. Ctx.Error() << to_upper(key) << " value should be a string literal or integer";
  4795. return false;
  4796. }
  4797. return true;
  4798. }
  4799. bool TSqlTranslation::StoreResourcePoolSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
  4800. const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
  4801. return StoreResourcePoolSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
  4802. }
  4803. bool TSqlTranslation::ParseResourcePoolSettings(std::map<TString, TDeferredAtom>& result, const TRule_with_table_settings& settingsNode) {
  4804. const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
  4805. if (!StoreResourcePoolSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(), result)) {
  4806. return false;
  4807. }
  4808. for (const auto& block : settingsNode.GetBlock4()) {
  4809. const auto& entry = block.GetRule_table_settings_entry2();
  4810. if (!StoreResourcePoolSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
  4811. return false;
  4812. }
  4813. }
  4814. return true;
  4815. }
  4816. bool TSqlTranslation::ParseResourcePoolSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_resource_pool_action& alterAction) {
  4817. switch (alterAction.Alt_case()) {
  4818. case TRule_alter_resource_pool_action::kAltAlterResourcePoolAction1: {
  4819. const auto& action = alterAction.GetAlt_alter_resource_pool_action1().GetRule_alter_table_set_table_setting_compat1();
  4820. if (!StoreResourcePoolSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
  4821. return false;
  4822. }
  4823. for (const auto& entry : action.GetBlock4()) {
  4824. if (!StoreResourcePoolSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
  4825. return false;
  4826. }
  4827. }
  4828. return true;
  4829. }
  4830. case TRule_alter_resource_pool_action::kAltAlterResourcePoolAction2: {
  4831. const auto& action = alterAction.GetAlt_alter_resource_pool_action2().GetRule_alter_table_reset_table_setting1();
  4832. const TString firstKey = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
  4833. toReset.insert(firstKey);
  4834. for (const auto& key : action.GetBlock4()) {
  4835. toReset.insert(to_lower(IdEx(key.GetRule_an_id2(), *this).Name));
  4836. }
  4837. return true;
  4838. }
  4839. case TRule_alter_resource_pool_action::ALT_NOT_SET:
  4840. Y_ABORT("You should change implementation according to grammar changes");
  4841. }
  4842. }
  4843. bool TSqlTranslation::StoreResourcePoolClassifierSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
  4844. YQL_ENSURE(value);
  4845. const TString key = to_lower(id.Name);
  4846. if (result.find(key) != result.end()) {
  4847. Ctx.Error() << to_upper(key) << " duplicate keys";
  4848. return false;
  4849. }
  4850. switch (value->Alt_case()) {
  4851. case TRule_table_setting_value::kAltTableSettingValue2:
  4852. return StoreString(*value, result[key], Ctx, to_upper(key));
  4853. case TRule_table_setting_value::kAltTableSettingValue3:
  4854. return StoreInt(*value, result[key], Ctx, to_upper(key));
  4855. default:
  4856. Ctx.Error() << to_upper(key) << " value should be a string literal or integer";
  4857. return false;
  4858. }
  4859. return true;
  4860. }
  4861. bool TSqlTranslation::StoreResourcePoolClassifierSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
  4862. const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
  4863. return StoreResourcePoolClassifierSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
  4864. }
  4865. bool TSqlTranslation::ParseResourcePoolClassifierSettings(std::map<TString, TDeferredAtom>& result, const TRule_with_table_settings& settingsNode) {
  4866. const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
  4867. if (!StoreResourcePoolClassifierSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(), result)) {
  4868. return false;
  4869. }
  4870. for (const auto& block : settingsNode.GetBlock4()) {
  4871. const auto& entry = block.GetRule_table_settings_entry2();
  4872. if (!StoreResourcePoolClassifierSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
  4873. return false;
  4874. }
  4875. }
  4876. return true;
  4877. }
  4878. bool TSqlTranslation::ParseResourcePoolClassifierSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_resource_pool_classifier_action& alterAction) {
  4879. switch (alterAction.Alt_case()) {
  4880. case TRule_alter_resource_pool_classifier_action::kAltAlterResourcePoolClassifierAction1: {
  4881. const auto& action = alterAction.GetAlt_alter_resource_pool_classifier_action1().GetRule_alter_table_set_table_setting_compat1();
  4882. if (!StoreResourcePoolClassifierSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
  4883. return false;
  4884. }
  4885. for (const auto& entry : action.GetBlock4()) {
  4886. if (!StoreResourcePoolClassifierSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
  4887. return false;
  4888. }
  4889. }
  4890. return true;
  4891. }
  4892. case TRule_alter_resource_pool_classifier_action::kAltAlterResourcePoolClassifierAction2: {
  4893. const auto& action = alterAction.GetAlt_alter_resource_pool_classifier_action2().GetRule_alter_table_reset_table_setting1();
  4894. const TString firstKey = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
  4895. toReset.insert(firstKey);
  4896. for (const auto& key : action.GetBlock4()) {
  4897. toReset.insert(to_lower(IdEx(key.GetRule_an_id2(), *this).Name));
  4898. }
  4899. return true;
  4900. }
  4901. case TRule_alter_resource_pool_classifier_action::ALT_NOT_SET:
  4902. Y_ABORT("You should change implementation according to grammar changes");
  4903. }
  4904. }
  4905. } // namespace NSQLTranslationV1