123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448 |
- #include "sql_translation.h"
- #include "sql_expression.h"
- #include "sql_call_expr.h"
- #include "sql_query.h"
- #include "sql_values.h"
- #include "sql_select.h"
- #include "source.h"
- #include <yql/essentials/parser/proto_ast/gen/v1/SQLv1Lexer.h>
- #include <yql/essentials/parser/proto_ast/gen/v1_antlr4/SQLv1Antlr4Lexer.h>
- #include <yql/essentials/sql/settings/partitioning.h>
- #include <yql/essentials/sql/v1/proto_parser/proto_parser.h>
- #include <util/generic/scope.h>
- #include <util/string/join.h>
- #include <library/cpp/protobuf/util/simple_reflection.h>
- namespace {
- using namespace NSQLTranslationV1;
- template <typename Callback>
- void VisitAllFields(const NProtoBuf::Message& msg, Callback& callback) {
- const auto* descr = msg.GetDescriptor();
- for (int i = 0; i < descr->field_count(); ++i) {
- const auto* fd = descr->field(i);
- NProtoBuf::TConstField field(msg, fd);
- if (field.IsMessage()) {
- for (size_t j = 0; j < field.Size(); ++j) {
- const auto& message = *field.Get<NProtoBuf::Message>(j);
- callback(message);
- VisitAllFields(message, callback);
- }
- }
- }
- }
- struct TTokenCollector {
- void operator()(const NProtoBuf::Message& message) {
- if (const auto* token = dynamic_cast<const NSQLv1Generated::TToken*>(&message)) {
- if (!Tokens.empty()) {
- Tokens << ' ';
- }
- Tokens << token->GetValue();
- }
- }
- TStringBuilder Tokens;
- };
- TString CollectTokens(const TRule_select_stmt& selectStatement) {
- TTokenCollector tokenCollector;
- VisitAllFields(selectStatement, tokenCollector);
- return tokenCollector.Tokens;
- }
- bool RecreateContext(
- TContext& ctx, const NSQLTranslation::TTranslationSettings& settings, const TString& recreationQuery
- ) {
- if (!recreationQuery) {
- return true;
- }
- const TString queryName = "context recreation query";
- const auto* ast = NSQLTranslationV1::SqlAST(
- ctx.Parsers,
- recreationQuery, queryName, ctx.Issues,
- settings.MaxErrors, settings.AnsiLexer, settings.Antlr4Parser, settings.Arena
- );
- if (!ast) {
- return false;
- }
- TSqlQuery queryTranslator(ctx, ctx.Settings.Mode, true);
- auto node = queryTranslator.Build(static_cast<const TSQLv1ParserAST&>(*ast));
- return node && node->Init(ctx, nullptr) && node->Translate(ctx);
- }
- TNodePtr BuildViewSelect(
- const TRule_select_stmt& selectStatement,
- TContext& parentContext,
- const TString& contextRecreationQuery
- ) {
- TIssues issues;
- TContext context(parentContext.Lexers, parentContext.Parsers, parentContext.Settings, {}, issues, parentContext.Query);
- if (!RecreateContext(context, context.Settings, contextRecreationQuery)) {
- parentContext.Issues.AddIssues(issues);
- return nullptr;
- }
- issues.Clear();
- // Holds (among other things) subquery references.
- // These references need to be passed to the parent context
- // to be able to compile view queries with subqueries.
- context.PushCurrentBlocks(&parentContext.GetCurrentBlocks());
- context.Settings.Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;
- TSqlSelect selectTranslator(context, context.Settings.Mode);
- TPosition pos = parentContext.Pos();
- auto source = selectTranslator.Build(selectStatement, pos);
- if (!source) {
- parentContext.Issues.AddIssues(issues);
- return nullptr;
- }
- auto node = BuildSelectResult(
- pos,
- std::move(source),
- false,
- false,
- context.Scoped
- );
- if (!node) {
- parentContext.Issues.AddIssues(issues);
- return nullptr;
- }
- return node;
- }
- }
- namespace NSQLTranslationV1 {
- using NALPDefault::SQLv1LexerTokens;
- using NALPDefaultAntlr4::SQLv1Antlr4Lexer;
- using namespace NSQLv1Generated;
- TIdentifier GetKeywordId(TTranslation& ctx, const TRule_keyword& node) {
- // keyword:
- // keyword_compat
- // | keyword_expr_uncompat
- // | keyword_table_uncompat
- // | keyword_select_uncompat
- // | keyword_alter_uncompat
- // | keyword_in_uncompat
- // | keyword_window_uncompat
- // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_keyword::kAltKeyword1:
- return GetIdentifier(ctx, node.GetAlt_keyword1().GetRule_keyword_compat1());
- case TRule_keyword::kAltKeyword2:
- return GetIdentifier(ctx, node.GetAlt_keyword2().GetRule_keyword_expr_uncompat1());
- case TRule_keyword::kAltKeyword3:
- return GetIdentifier(ctx, node.GetAlt_keyword3().GetRule_keyword_table_uncompat1());
- case TRule_keyword::kAltKeyword4:
- return GetIdentifier(ctx, node.GetAlt_keyword4().GetRule_keyword_select_uncompat1());
- case TRule_keyword::kAltKeyword5:
- return GetIdentifier(ctx, node.GetAlt_keyword5().GetRule_keyword_alter_uncompat1());
- case TRule_keyword::kAltKeyword6:
- return GetIdentifier(ctx, node.GetAlt_keyword6().GetRule_keyword_in_uncompat1());
- case TRule_keyword::kAltKeyword7:
- return GetIdentifier(ctx, node.GetAlt_keyword7().GetRule_keyword_window_uncompat1());
- case TRule_keyword::kAltKeyword8:
- return GetIdentifier(ctx, node.GetAlt_keyword8().GetRule_keyword_hint_uncompat1());
- case TRule_keyword::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id& node, TTranslation& ctx) {
- // id: identifier | keyword;
- switch (node.Alt_case()) {
- case TRule_id::kAltId1:
- return Id(node.GetAlt_id1().GetRule_identifier1(), ctx);
- case TRule_id::kAltId2:
- return GetKeyword(ctx, node.GetAlt_id2().GetRule_keyword1());
- case TRule_id::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_or_type& node, TTranslation& ctx) {
- switch (node.Alt_case()) {
- case TRule_id_or_type::kAltIdOrType1:
- return Id(node.GetAlt_id_or_type1().GetRule_id1(), ctx);
- case TRule_id_or_type::kAltIdOrType2:
- return ctx.Identifier(node.GetAlt_id_or_type2().GetRule_type_id1().GetToken1());
- case TRule_id_or_type::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_as_compat& node, TTranslation& ctx) {
- switch (node.Alt_case()) {
- case TRule_id_as_compat::kAltIdAsCompat1:
- return Id(node.GetAlt_id_as_compat1().GetRule_identifier1(), ctx);
- case TRule_id_as_compat::kAltIdAsCompat2:
- return ctx.Token(node.GetAlt_id_as_compat2().GetRule_keyword_as_compat1().GetToken1());
- case TRule_id_as_compat::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_as_compat& node, TTranslation& ctx) {
- switch (node.Alt_case()) {
- case TRule_an_id_as_compat::kAltAnIdAsCompat1:
- return Id(node.GetAlt_an_id_as_compat1().GetRule_id_as_compat1(), ctx);
- case TRule_an_id_as_compat::kAltAnIdAsCompat2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_as_compat2().GetToken1()));
- case TRule_an_id_as_compat::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_schema& node, TTranslation& ctx) {
- //id_schema:
- // identifier
- // | keyword_compat
- // | keyword_expr_uncompat
- // // | keyword_table_uncompat
- // | keyword_select_uncompat
- // // | keyword_alter_uncompat
- // | keyword_in_uncompat
- // | keyword_window_uncompat
- // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_id_schema::kAltIdSchema1:
- return Id(node.GetAlt_id_schema1().GetRule_identifier1(), ctx);
- case TRule_id_schema::kAltIdSchema2:
- return GetKeyword(ctx, node.GetAlt_id_schema2().GetRule_keyword_compat1());
- case TRule_id_schema::kAltIdSchema3:
- return GetKeyword(ctx, node.GetAlt_id_schema3().GetRule_keyword_expr_uncompat1());
- case TRule_id_schema::kAltIdSchema4:
- return GetKeyword(ctx, node.GetAlt_id_schema4().GetRule_keyword_select_uncompat1());
- case TRule_id_schema::kAltIdSchema5:
- return GetKeyword(ctx, node.GetAlt_id_schema5().GetRule_keyword_in_uncompat1());
- case TRule_id_schema::kAltIdSchema6:
- return GetKeyword(ctx, node.GetAlt_id_schema6().GetRule_keyword_window_uncompat1());
- case TRule_id_schema::kAltIdSchema7:
- return GetKeyword(ctx, node.GetAlt_id_schema7().GetRule_keyword_hint_uncompat1());
- case TRule_id_schema::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_or_type& node, TTranslation& ctx) {
- // an_id_or_type: id_or_type | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_or_type::kAltAnIdOrType1:
- return Id(node.GetAlt_an_id_or_type1().GetRule_id_or_type1(), ctx);
- case TRule_an_id_or_type::kAltAnIdOrType2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_or_type2().GetToken1()));
- case TRule_an_id_or_type::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- std::pair<bool, TString> Id(const TRule_id_or_at& node, TTranslation& ctx) {
- bool hasAt = node.HasBlock1();
- return std::make_pair(hasAt, Id(node.GetRule_an_id_or_type2(), ctx) );
- }
- TString Id(const TRule_id_table& node, TTranslation& ctx) {
- //id_table:
- // identifier
- // | keyword_compat
- // | keyword_expr_uncompat
- // // | keyword_table_uncompat
- // | keyword_select_uncompat
- // // | keyword_alter_uncompat
- // | keyword_in_uncompat
- // | keyword_window_uncompat
- // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_id_table::kAltIdTable1:
- return Id(node.GetAlt_id_table1().GetRule_identifier1(), ctx);
- case TRule_id_table::kAltIdTable2:
- return GetKeyword(ctx, node.GetAlt_id_table2().GetRule_keyword_compat1());
- case TRule_id_table::kAltIdTable3:
- return GetKeyword(ctx, node.GetAlt_id_table3().GetRule_keyword_expr_uncompat1());
- case TRule_id_table::kAltIdTable4:
- return GetKeyword(ctx, node.GetAlt_id_table4().GetRule_keyword_select_uncompat1());
- case TRule_id_table::kAltIdTable5:
- return GetKeyword(ctx, node.GetAlt_id_table5().GetRule_keyword_in_uncompat1());
- case TRule_id_table::kAltIdTable6:
- return GetKeyword(ctx, node.GetAlt_id_table6().GetRule_keyword_window_uncompat1());
- case TRule_id_table::kAltIdTable7:
- return GetKeyword(ctx, node.GetAlt_id_table7().GetRule_keyword_hint_uncompat1());
- case TRule_id_table::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_table& node, TTranslation& ctx) {
- // an_id_table: id_table | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_table::kAltAnIdTable1:
- return Id(node.GetAlt_an_id_table1().GetRule_id_table1(), ctx);
- case TRule_an_id_table::kAltAnIdTable2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_table2().GetToken1()));
- case TRule_an_id_table::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_table_or_type& node, TTranslation& ctx) {
- switch (node.Alt_case()) {
- case TRule_id_table_or_type::kAltIdTableOrType1:
- return Id(node.GetAlt_id_table_or_type1().GetRule_an_id_table1(), ctx);
- case TRule_id_table_or_type::kAltIdTableOrType2:
- return ctx.Identifier(node.GetAlt_id_table_or_type2().GetRule_type_id1().GetToken1());
- case TRule_id_table_or_type::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_expr& node, TTranslation& ctx) {
- //id_expr:
- // identifier
- // | keyword_compat
- // // | keyword_expr_uncompat
- // // | keyword_table_uncompat
- // // | keyword_select_uncompat
- // | keyword_alter_uncompat
- // | keyword_in_uncompat
- // | keyword_window_uncompat
- // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_id_expr::kAltIdExpr1:
- return Id(node.GetAlt_id_expr1().GetRule_identifier1(), ctx);
- case TRule_id_expr::kAltIdExpr2:
- return GetKeyword(ctx, node.GetAlt_id_expr2().GetRule_keyword_compat1());
- case TRule_id_expr::kAltIdExpr3:
- return GetKeyword(ctx, node.GetAlt_id_expr3().GetRule_keyword_alter_uncompat1());
- case TRule_id_expr::kAltIdExpr4:
- return GetKeyword(ctx, node.GetAlt_id_expr4().GetRule_keyword_in_uncompat1());
- case TRule_id_expr::kAltIdExpr5:
- return GetKeyword(ctx, node.GetAlt_id_expr5().GetRule_keyword_window_uncompat1());
- case TRule_id_expr::kAltIdExpr6:
- return GetKeyword(ctx, node.GetAlt_id_expr6().GetRule_keyword_hint_uncompat1());
- case TRule_id_expr::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool IsQuotedId(const TRule_id_expr& node, TTranslation& ctx) {
- if (node.Alt_case() != TRule_id_expr::kAltIdExpr1) {
- return false;
- }
- const auto& id = ctx.Token(node.GetAlt_id_expr1().GetRule_identifier1().GetToken1());
- // identifier: ID_PLAIN | ID_QUOTED;
- return id.StartsWith('`');
- }
- TString Id(const TRule_id_expr_in& node, TTranslation& ctx) {
- //id_expr_in:
- // identifier
- // | keyword_compat
- // // | keyword_expr_uncompat
- // // | keyword_table_uncompat
- // // | keyword_select_uncompat
- // | keyword_alter_uncompat
- // // | keyword_in_uncompat
- // | keyword_window_uncompat
- // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_id_expr_in::kAltIdExprIn1:
- return Id(node.GetAlt_id_expr_in1().GetRule_identifier1(), ctx);
- case TRule_id_expr_in::kAltIdExprIn2:
- return GetKeyword(ctx, node.GetAlt_id_expr_in2().GetRule_keyword_compat1());
- case TRule_id_expr_in::kAltIdExprIn3:
- return GetKeyword(ctx, node.GetAlt_id_expr_in3().GetRule_keyword_alter_uncompat1());
- case TRule_id_expr_in::kAltIdExprIn4:
- return GetKeyword(ctx, node.GetAlt_id_expr_in4().GetRule_keyword_window_uncompat1());
- case TRule_id_expr_in::kAltIdExprIn5:
- return GetKeyword(ctx, node.GetAlt_id_expr_in5().GetRule_keyword_hint_uncompat1());
- case TRule_id_expr_in::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_window& node, TTranslation& ctx) {
- //id_window:
- // identifier
- // | keyword_compat
- // | keyword_expr_uncompat
- // | keyword_table_uncompat
- // | keyword_select_uncompat
- // | keyword_alter_uncompat
- // | keyword_in_uncompat
- // // | keyword_window_uncompat
- // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_id_window::kAltIdWindow1:
- return Id(node.GetAlt_id_window1().GetRule_identifier1(), ctx);
- case TRule_id_window::kAltIdWindow2:
- return GetKeyword(ctx, node.GetAlt_id_window2().GetRule_keyword_compat1());
- case TRule_id_window::kAltIdWindow3:
- return GetKeyword(ctx, node.GetAlt_id_window3().GetRule_keyword_expr_uncompat1());
- case TRule_id_window::kAltIdWindow4:
- return GetKeyword(ctx, node.GetAlt_id_window4().GetRule_keyword_table_uncompat1());
- case TRule_id_window::kAltIdWindow5:
- return GetKeyword(ctx, node.GetAlt_id_window5().GetRule_keyword_select_uncompat1());
- case TRule_id_window::kAltIdWindow6:
- return GetKeyword(ctx, node.GetAlt_id_window6().GetRule_keyword_alter_uncompat1());
- case TRule_id_window::kAltIdWindow7:
- return GetKeyword(ctx, node.GetAlt_id_window7().GetRule_keyword_in_uncompat1());
- case TRule_id_window::kAltIdWindow8:
- return GetKeyword(ctx, node.GetAlt_id_window8().GetRule_keyword_hint_uncompat1());
- case TRule_id_window::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_without& node, TTranslation& ctx) {
- //id_without:
- // identifier
- // | keyword_compat
- // // | keyword_expr_uncompat
- // | keyword_table_uncompat
- // // | keyword_select_uncompat
- // | keyword_alter_uncompat
- // | keyword_in_uncompat
- // | keyword_window_uncompat
- // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_id_without::kAltIdWithout1:
- return Id(node.GetAlt_id_without1().GetRule_identifier1(), ctx);
- case TRule_id_without::kAltIdWithout2:
- return GetKeyword(ctx, node.GetAlt_id_without2().GetRule_keyword_compat1());
- case TRule_id_without::kAltIdWithout3:
- return GetKeyword(ctx, node.GetAlt_id_without3().GetRule_keyword_table_uncompat1());
- case TRule_id_without::kAltIdWithout4:
- return GetKeyword(ctx, node.GetAlt_id_without4().GetRule_keyword_alter_uncompat1());
- case TRule_id_without::kAltIdWithout5:
- return GetKeyword(ctx, node.GetAlt_id_without5().GetRule_keyword_in_uncompat1());
- case TRule_id_without::kAltIdWithout6:
- return GetKeyword(ctx, node.GetAlt_id_without6().GetRule_keyword_window_uncompat1());
- case TRule_id_without::kAltIdWithout7:
- return GetKeyword(ctx, node.GetAlt_id_without7().GetRule_keyword_hint_uncompat1());
- case TRule_id_without::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_id_hint& node, TTranslation& ctx) {
- //id_hint:
- // identifier
- // | keyword_compat
- // | keyword_expr_uncompat
- // | keyword_table_uncompat
- // | keyword_select_uncompat
- // | keyword_alter_uncompat
- // | keyword_in_uncompat
- // | keyword_window_uncompat
- // // | keyword_hint_uncompat
- //;
- switch (node.Alt_case()) {
- case TRule_id_hint::kAltIdHint1:
- return Id(node.GetAlt_id_hint1().GetRule_identifier1(), ctx);
- case TRule_id_hint::kAltIdHint2:
- return GetKeyword(ctx, node.GetAlt_id_hint2().GetRule_keyword_compat1());
- case TRule_id_hint::kAltIdHint3:
- return GetKeyword(ctx, node.GetAlt_id_hint3().GetRule_keyword_expr_uncompat1());
- case TRule_id_hint::kAltIdHint4:
- return GetKeyword(ctx, node.GetAlt_id_hint4().GetRule_keyword_table_uncompat1());
- case TRule_id_hint::kAltIdHint5:
- return GetKeyword(ctx, node.GetAlt_id_hint5().GetRule_keyword_select_uncompat1());
- case TRule_id_hint::kAltIdHint6:
- return GetKeyword(ctx, node.GetAlt_id_hint6().GetRule_keyword_alter_uncompat1());
- case TRule_id_hint::kAltIdHint7:
- return GetKeyword(ctx, node.GetAlt_id_hint7().GetRule_keyword_in_uncompat1());
- case TRule_id_hint::kAltIdHint8:
- return GetKeyword(ctx, node.GetAlt_id_hint8().GetRule_keyword_window_uncompat1());
- case TRule_id_hint::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id& node, TTranslation& ctx) {
- // an_id: id | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id::kAltAnId1:
- return Id(node.GetAlt_an_id1().GetRule_id1(), ctx);
- case TRule_an_id::kAltAnId2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id2().GetToken1()));
- case TRule_an_id::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_schema& node, TTranslation& ctx) {
- // an_id_schema: id_schema | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_schema::kAltAnIdSchema1:
- return Id(node.GetAlt_an_id_schema1().GetRule_id_schema1(), ctx);
- case TRule_an_id_schema::kAltAnIdSchema2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_schema2().GetToken1()));
- case TRule_an_id_schema::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_expr& node, TTranslation& ctx) {
- // an_id_expr: id_expr | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_expr::kAltAnIdExpr1:
- return Id(node.GetAlt_an_id_expr1().GetRule_id_expr1(), ctx);
- case TRule_an_id_expr::kAltAnIdExpr2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_expr2().GetToken1()));
- case TRule_an_id_expr::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_window& node, TTranslation& ctx) {
- // an_id_window: id_window | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_window::kAltAnIdWindow1:
- return Id(node.GetAlt_an_id_window1().GetRule_id_window1(), ctx);
- case TRule_an_id_window::kAltAnIdWindow2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_window2().GetToken1()));
- case TRule_an_id_window::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_without& node, TTranslation& ctx) {
- // an_id_without: id_without | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_without::kAltAnIdWithout1:
- return Id(node.GetAlt_an_id_without1().GetRule_id_without1(), ctx);
- case TRule_an_id_without::kAltAnIdWithout2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_without2().GetToken1()));
- case TRule_an_id_without::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_hint& node, TTranslation& ctx) {
- // an_id_hint: id_hint | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_hint::kAltAnIdHint1:
- return Id(node.GetAlt_an_id_hint1().GetRule_id_hint1(), ctx);
- case TRule_an_id_hint::kAltAnIdHint2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_hint2().GetToken1()));
- case TRule_an_id_hint::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TString Id(const TRule_an_id_pure& node, TTranslation& ctx) {
- // an_id_pure: identifier | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_an_id_pure::kAltAnIdPure1:
- return Id(node.GetAlt_an_id_pure1().GetRule_identifier1(), ctx);
- case TRule_an_id_pure::kAltAnIdPure2:
- return IdContentFromString(ctx.Context(), ctx.Token(node.GetAlt_an_id_pure2().GetToken1()));
- case TRule_an_id_pure::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TViewDescription Id(const TRule_view_name& node, TTranslation& ctx) {
- switch (node.Alt_case()) {
- case TRule_view_name::kAltViewName1:
- return {Id(node.GetAlt_view_name1().GetRule_an_id1(), ctx)};
- case TRule_view_name::kAltViewName2:
- return {"", true};
- case TRule_view_name::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool NamedNodeImpl(const TRule_bind_parameter& node, TString& name, TTranslation& ctx) {
- // bind_parameter: DOLLAR (an_id_or_type | TRUE | FALSE);
- TString id;
- switch (node.GetBlock2().Alt_case()) {
- case TRule_bind_parameter::TBlock2::kAlt1:
- id = Id(node.GetBlock2().GetAlt1().GetRule_an_id_or_type1(), ctx);
- break;
- case TRule_bind_parameter::TBlock2::kAlt2:
- id = ctx.Token(node.GetBlock2().GetAlt2().GetToken1());
- break;
- case TRule_bind_parameter::TBlock2::kAlt3:
- id = ctx.Token(node.GetBlock2().GetAlt3().GetToken1());
- break;
- case TRule_bind_parameter::TBlock2::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- auto dollar = ctx.Token(node.GetToken1());
- if (id.empty()) {
- ctx.Error() << "Empty symbol name is not allowed";
- return false;
- }
- name = dollar + id;
- return true;
- }
- TString OptIdPrefixAsStr(const TRule_opt_id_prefix& node, TTranslation& ctx, const TString& defaultStr) {
- if (!node.HasBlock1()) {
- return defaultStr;
- }
- return Id(node.GetBlock1().GetRule_an_id1(), ctx);
- }
- TString OptIdPrefixAsStr(const TRule_opt_id_prefix_or_type& node, TTranslation& ctx, const TString& defaultStr) {
- if (!node.HasBlock1()) {
- return defaultStr;
- }
- return Id(node.GetBlock1().GetRule_an_id_or_type1(), ctx);
- }
- void PureColumnListStr(const TRule_pure_column_list& node, TTranslation& ctx, TVector<TString>& outList) {
- outList.push_back(Id(node.GetRule_an_id2(), ctx));
- for (auto& block: node.GetBlock3()) {
- outList.push_back(Id(block.GetRule_an_id2(), ctx));
- }
- }
- bool NamedNodeImpl(const TRule_opt_bind_parameter& node, TString& name, bool& isOptional, TTranslation& ctx) {
- // opt_bind_parameter: bind_parameter QUESTION?;
- isOptional = false;
- if (!NamedNodeImpl(node.GetRule_bind_parameter1(), name, ctx)) {
- return false;
- }
- isOptional = node.HasBlock2();
- return true;
- }
- TDeferredAtom PureColumnOrNamed(const TRule_pure_column_or_named& node, TTranslation& ctx) {
- switch (node.Alt_case()) {
- case TRule_pure_column_or_named::kAltPureColumnOrNamed1: {
- TString named;
- if (!NamedNodeImpl(node.GetAlt_pure_column_or_named1().GetRule_bind_parameter1(), named, ctx)) {
- return {};
- }
- auto namedNode = ctx.GetNamedNode(named);
- if (!namedNode) {
- return {};
- }
- return TDeferredAtom(namedNode, ctx.Context());
- }
- case TRule_pure_column_or_named::kAltPureColumnOrNamed2:
- return TDeferredAtom(ctx.Context().Pos(), Id(node.GetAlt_pure_column_or_named2().GetRule_an_id1(), ctx));
- case TRule_pure_column_or_named::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool PureColumnOrNamedListStr(const TRule_pure_column_or_named_list& node, TTranslation& ctx, TVector<TDeferredAtom>& outList) {
- outList.push_back(PureColumnOrNamed(node.GetRule_pure_column_or_named2(), ctx));
- if (outList.back().Empty()) {
- return false;
- }
- for (auto& block : node.GetBlock3()) {
- outList.push_back(PureColumnOrNamed(block.GetRule_pure_column_or_named2(), ctx));
- if (outList.back().Empty()) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::CreateTableIndex(const TRule_table_index& node, TVector<TIndexDescription>& indexes) {
- indexes.emplace_back(IdEx(node.GetRule_an_id2(), *this));
- const auto& indexType = node.GetRule_table_index_type3().GetBlock1();
- switch (indexType.Alt_case()) {
- // "GLOBAL"
- case TRule_table_index_type_TBlock1::kAlt1: {
- auto globalIndex = indexType.GetAlt1().GetRule_global_index1();
- bool uniqIndex = false;
- if (globalIndex.HasBlock2()) {
- uniqIndex = true;
- }
- if (globalIndex.HasBlock3()) {
- const TString token = to_lower(Ctx.Token(globalIndex.GetBlock3().GetToken1()));
- if (token == "sync") {
- if (uniqIndex) {
- indexes.back().Type = TIndexDescription::EType::GlobalSyncUnique;
- } else {
- indexes.back().Type = TIndexDescription::EType::GlobalSync;
- }
- } else if (token == "async") {
- if (uniqIndex) {
- AltNotImplemented("unique", indexType);
- return false;
- }
- indexes.back().Type = TIndexDescription::EType::GlobalAsync;
- } else {
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- }
- break;
- // "LOCAL"
- case TRule_table_index_type_TBlock1::kAlt2:
- AltNotImplemented("local", indexType);
- return false;
- case TRule_table_index_type_TBlock1::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- if (node.GetRule_table_index_type3().HasBlock2()) {
- const TString subType = to_upper(IdEx(node.GetRule_table_index_type3().GetBlock2().GetRule_index_subtype2().GetRule_an_id1(), *this).Name) ;
- if (subType == "VECTOR_KMEANS_TREE") {
- if (indexes.back().Type != TIndexDescription::EType::GlobalSync) {
- Ctx.Error() << subType << " index can only be GLOBAL [SYNC]";
- return false;
- }
- indexes.back().Type = TIndexDescription::EType::GlobalVectorKmeansTree;
- } else {
- Ctx.Error() << subType << " index subtype is not supported";
- return false;
- }
- }
- // WITH
- if (node.HasBlock10()) {
- //const auto& with = node.GetBlock4();
- auto& index = indexes.back();
- if (index.Type == TIndexDescription::EType::GlobalVectorKmeansTree) {
- auto& vectorSettings = index.IndexSettings.emplace<TVectorIndexSettings>();
- if (!CreateIndexSettings(node.GetBlock10().GetRule_with_index_settings1(), index.Type, index.IndexSettings)) {
- return false;
- }
- if (!vectorSettings.Validate(Ctx)) {
- return false;
- }
- } else {
- AltNotImplemented("with", indexType);
- return false;
- }
- }
- indexes.back().IndexColumns.emplace_back(IdEx(node.GetRule_an_id_schema6(), *this));
- for (const auto& block : node.GetBlock7()) {
- indexes.back().IndexColumns.emplace_back(IdEx(block.GetRule_an_id_schema2(), *this));
- }
- if (node.HasBlock9()) {
- const auto& block = node.GetBlock9();
- indexes.back().DataColumns.emplace_back(IdEx(block.GetRule_an_id_schema3(), *this));
- for (const auto& inner : block.GetBlock4()) {
- indexes.back().DataColumns.emplace_back(IdEx(inner.GetRule_an_id_schema2(), *this));
- }
- }
- return true;
- }
- bool TSqlTranslation::CreateIndexSettings(const TRule_with_index_settings& settingsNode,
- TIndexDescription::EType indexType,
- TIndexDescription::TIndexSettings& indexSettings) {
- const auto& firstEntry = settingsNode.GetRule_index_setting_entry3();
- if (!CreateIndexSettingEntry(IdEx(firstEntry.GetRule_an_id1(), *this), firstEntry.GetRule_index_setting_value3(), indexType, indexSettings)) {
- return false;
- }
- for (auto& block : settingsNode.GetBlock4()) {
- const auto& entry = block.GetRule_index_setting_entry2();
- if (!CreateIndexSettingEntry(IdEx(entry.GetRule_an_id1(), *this), entry.GetRule_index_setting_value3(), indexType, indexSettings)) {
- return false;
- }
- }
- return true;
- }
- template<typename T>
- std::tuple<bool, T, TString> TSqlTranslation::GetIndexSettingValue(const TRule_index_setting_value& node) {
- T value{};
- // id_or_type
- if (node.HasAlt_index_setting_value1()) {
- const TString stringValue = to_lower(IdEx(node.GetAlt_index_setting_value1().GetRule_id_or_type1(), *this).Name);
- if (!TryFromString<T>(stringValue, value)) {
- return {false, value, stringValue};
- }
- return {true, value, stringValue};
- }
- // STRING_VALUE
- else if (node.HasAlt_index_setting_value2()) {
- const TString stringValue = to_lower(Token(node.GetAlt_index_setting_value2().GetToken1()));
- const auto unescaped = StringContent(Ctx, Ctx.Pos(), stringValue);
- if (!unescaped) {
- return {false, value, stringValue};
- }
- if (!TryFromString<T>(unescaped->Content, value)) {
- return {false, value, stringValue};
- }
- return {true, value, unescaped->Content};
- } else {
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- template<>
- std::tuple<bool, ui64, TString> TSqlTranslation::GetIndexSettingValue(const TRule_index_setting_value& node) {
- const auto& intNode = node.GetAlt_index_setting_value3().GetRule_integer1();
- const TString stringValue = Token(intNode.GetToken1());
- ui64 value = 0;
- TString suffix;
- if (!ParseNumbers(Ctx, stringValue, value, suffix)) {
- return {false, value, stringValue};
- }
- return {true, value, stringValue};
- }
- template<>
- std::tuple<bool, bool, TString> TSqlTranslation::GetIndexSettingValue(const TRule_index_setting_value& node) {
- bool value = false;
- const TString stringValue = to_lower(Token(node.GetAlt_index_setting_value4().GetRule_bool_value1().GetToken1()));;
- if (!TryFromString<bool>(stringValue, value)) {
- return {false, value, stringValue};
- }
- return {true, value, stringValue};
- }
- bool TSqlTranslation::CreateIndexSettingEntry(const TIdentifier &id,
- const TRule_index_setting_value& node,
- TIndexDescription::EType indexType,
- TIndexDescription::TIndexSettings& indexSettings) {
- if (indexType == TIndexDescription::EType::GlobalVectorKmeansTree) {
- TVectorIndexSettings &vectorIndexSettings = std::get<TVectorIndexSettings>(indexSettings);
- if (to_lower(id.Name) == "distance") {
- const auto [success, value, stringValue] = GetIndexSettingValue<TVectorIndexSettings::EDistance>(node);
- if (!success) {
- Ctx.Error() << "Invalid distance: " << stringValue;
- return false;
- }
- vectorIndexSettings.Distance = value;
- } else if (to_lower(id.Name) == "similarity") {
- const auto [success, value, stringValue] = GetIndexSettingValue<TVectorIndexSettings::ESimilarity>(node);
- if (!success) {
- Ctx.Error() << "Invalid similarity: " << stringValue;
- return false;
- }
- vectorIndexSettings.Similarity = value;
- } else if (to_lower(id.Name) == "vector_type") {
- const auto [success, value, stringValue] = GetIndexSettingValue<TVectorIndexSettings::EVectorType>(node);
- if (!success) {
- Ctx.Error() << "Invalid vector_type: " << stringValue;
- return false;
- }
- vectorIndexSettings.VectorType = value;
- } else if (to_lower(id.Name) == "vector_dimension") {
- const auto [success, value, stringValue] = GetIndexSettingValue<ui64>(node);
- if (!success || value > Max<ui32>()) {
- Ctx.Error() << "Invalid vector_dimension: " << stringValue;
- return false;
- }
- vectorIndexSettings.VectorDimension = value;
- } else if (to_lower(id.Name) == "clusters") {
- const auto [success, value, stringValue] = GetIndexSettingValue<ui64>(node);
- if (!success || value > Max<ui32>()) {
- Ctx.Error() << "Invalid clusters: " << stringValue;
- return false;
- }
- vectorIndexSettings.Clusters = value;
- } else if (to_lower(id.Name) == "levels") {
- const auto [success, value, stringValue] = GetIndexSettingValue<ui64>(node);
- if (!success || value > Max<ui32>()) {
- Ctx.Error() << "Invalid levels: " << stringValue;
- return false;
- }
- vectorIndexSettings.Levels = value;
- } else {
- Ctx.Error() << "Unknown index setting: " << id.Name;
- return false;
- }
- } else {
- Ctx.Error() << "Unknown index setting: " << id.Name;
- return false;
- }
- return true;
- }
- std::pair<TString, TViewDescription> TableKeyImpl(const std::pair<bool, TString>& nameWithAt, TViewDescription view, TTranslation& ctx) {
- if (nameWithAt.first) {
- view = {"@"};
- ctx.Context().IncrementMonCounter("sql_features", "AnonymousTable");
- }
- return std::make_pair(nameWithAt.second, view);
- }
- std::pair<TString, TViewDescription> TableKeyImpl(const TRule_table_key& node, TTranslation& ctx, bool hasAt) {
- auto name(Id(node.GetRule_id_table_or_type1(), ctx));
- TViewDescription view;
- if (node.HasBlock2()) {
- view = Id(node.GetBlock2().GetRule_view_name2(), ctx);
- ctx.Context().IncrementMonCounter("sql_features", "View");
- }
- return TableKeyImpl(std::make_pair(hasAt, name), view, ctx);
- }
- /// \return optional prefix
- TString ColumnNameAsStr(TTranslation& ctx, const TRule_column_name& node, TString& id) {
- id = Id(node.GetRule_an_id2(), ctx);
- return OptIdPrefixAsStr(node.GetRule_opt_id_prefix1(), ctx);
- }
- TString ColumnNameAsSingleStr(TTranslation& ctx, const TRule_column_name& node) {
- TString body;
- const TString prefix = ColumnNameAsStr(ctx, node, body);
- return prefix ? prefix + '.' + body : body;
- }
- TTableHints GetContextHints(TContext& ctx) {
- TTableHints hints;
- if (ctx.PragmaInferSchema) {
- hints["infer_schema"] = {};
- }
- if (ctx.PragmaDirectRead) {
- hints["direct_read"] = {};
- }
- return hints;
- }
- TTableHints GetTableFuncHints(TStringBuf funcName) {
- TCiString func(funcName);
- TTableHints res;
- if (func.StartsWith("range") || func.StartsWith("like") || func.StartsWith("regexp") || func.StartsWith("filter")) {
- res.emplace("ignore_non_existing", TVector<TNodePtr>{});
- } else if (func.StartsWith("each")) {
- res.emplace("ignore_non_existing", TVector<TNodePtr>{});
- res.emplace("warn_non_existing", TVector<TNodePtr>{});
- }
- return res;
- }
- TNodePtr TSqlTranslation::NamedExpr(const TRule_named_expr& node, EExpr exprMode) {
- TSqlExpression expr(Ctx, Mode);
- if (exprMode == EExpr::GroupBy) {
- expr.SetSmartParenthesisMode(TSqlExpression::ESmartParenthesis::GroupBy);
- } else if (exprMode == EExpr::SqlLambdaParams) {
- expr.SetSmartParenthesisMode(TSqlExpression::ESmartParenthesis::SqlLambdaParams);
- }
- if (node.HasBlock2()) {
- expr.MarkAsNamed();
- }
- TNodePtr exprNode(expr.Build(node.GetRule_expr1()));
- if (!exprNode) {
- Ctx.IncrementMonCounter("sql_errors", "NamedExprInvalid");
- return nullptr;
- }
- if (node.HasBlock2()) {
- exprNode = SafeClone(exprNode);
- exprNode->SetLabel(Id(node.GetBlock2().GetRule_an_id_or_type2(), *this));
- }
- return exprNode;
- }
- bool TSqlTranslation::NamedExprList(const TRule_named_expr_list& node, TVector<TNodePtr>& exprs, EExpr exprMode) {
- exprs.emplace_back(NamedExpr(node.GetRule_named_expr1(), exprMode));
- if (!exprs.back()) {
- return false;
- }
- for (auto& b: node.GetBlock2()) {
- exprs.emplace_back(NamedExpr(b.GetRule_named_expr2(), exprMode));
- if (!exprs.back()) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::BindList(const TRule_bind_parameter_list& node, TVector<TSymbolNameWithPos>& bindNames) {
- bindNames.clear();
- TString name;
- if (!NamedNodeImpl(node.GetRule_bind_parameter1(), name, *this)) {
- return false;
- }
- bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
- for (auto& b: node.GetBlock2()) {
- if (!NamedNodeImpl(b.GetRule_bind_parameter2(), name, *this)) {
- return false;
- }
- bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
- }
- return true;
- }
- bool TSqlTranslation::ActionOrSubqueryArgs(const TRule_action_or_subquery_args& node, TVector<TSymbolNameWithPos>& bindNames, ui32& optionalArgsCount) {
- bindNames.clear();
- optionalArgsCount = 0;
- TString name;
- bool isOptional = false;
- if (!NamedNodeImpl(node.GetRule_opt_bind_parameter1(), name, isOptional, *this)) {
- return false;
- }
- if (isOptional) {
- optionalArgsCount++;
- }
- bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
- for (auto& b: node.GetBlock2()) {
- if (!NamedNodeImpl(b.GetRule_opt_bind_parameter2(), name, isOptional, *this)) {
- return false;
- }
- if (isOptional) {
- optionalArgsCount++;
- } else if (optionalArgsCount > 0) {
- Context().Error() << "Non-optional argument can not follow optional one";
- return false;
- }
- bindNames.emplace_back(TSymbolNameWithPos{name, Ctx.Pos()});
- }
- return true;
- }
- bool TSqlTranslation::ModulePath(const TRule_module_path& node, TVector<TString>& path) {
- if (node.HasBlock1()) {
- path.emplace_back(TString());
- }
- path.emplace_back(Id(node.GetRule_an_id2(), *this));
- for (auto& b: node.GetBlock3()) {
- path.emplace_back(Id(b.GetRule_an_id2(), *this));
- }
- return true;
- }
- bool TSqlTranslation::NamedBindList(const TRule_named_bind_parameter_list& node, TVector<TSymbolNameWithPos>& names,
- TVector<TSymbolNameWithPos>& aliases)
- {
- names.clear();
- aliases.clear();
- TSymbolNameWithPos name;
- TSymbolNameWithPos alias;
- if (!NamedBindParam(node.GetRule_named_bind_parameter1(), name, alias)) {
- return false;
- }
- names.push_back(name);
- aliases.push_back(alias);
- for (auto& b: node.GetBlock2()) {
- if (!NamedBindParam(b.GetRule_named_bind_parameter2(), name, alias)) {
- return false;
- }
- names.push_back(name);
- aliases.push_back(alias);
- }
- return true;
- }
- bool TSqlTranslation::NamedBindParam(const TRule_named_bind_parameter& node, TSymbolNameWithPos& name, TSymbolNameWithPos& alias) {
- name = alias = {};
- if (!NamedNodeImpl(node.GetRule_bind_parameter1(), name.Name, *this)) {
- return false;
- }
- name.Pos = Ctx.Pos();
- if (node.HasBlock2()) {
- if (!NamedNodeImpl(node.GetBlock2().GetRule_bind_parameter2(), alias.Name, *this)) {
- return false;
- }
- alias.Pos = Ctx.Pos();
- }
- return true;
- }
- TMaybe<TTableArg> TSqlTranslation::TableArgImpl(const TRule_table_arg& node) {
- TTableArg ret;
- ret.HasAt = node.HasBlock1();
- TColumnRefScope scope(Ctx, EColumnRefState::AsStringLiteral);
- ret.Expr = NamedExpr(node.GetRule_named_expr2());
- if (!ret.Expr) {
- return Nothing();
- }
- if (node.HasBlock3()) {
- ret.View = Id(node.GetBlock3().GetRule_view_name2(), *this);
- Context().IncrementMonCounter("sql_features", "View");
- }
- return ret;
- }
- bool TSqlTranslation::ClusterExpr(const TRule_cluster_expr& node, bool allowWildcard, TString& service, TDeferredAtom& cluster) {
- bool allowBinding = false;
- bool isBinding;
- return ClusterExpr(node, allowWildcard, allowBinding, service, cluster, isBinding);
- }
- bool TSqlTranslation::ClusterExprOrBinding(const TRule_cluster_expr& node, TString& service, TDeferredAtom& cluster, bool& isBinding) {
- bool allowWildcard = false;
- bool allowBinding = true;
- return ClusterExpr(node, allowWildcard, allowBinding, service, cluster, isBinding);
- }
- bool TSqlTranslation::ClusterExpr(const TRule_cluster_expr& node, bool allowWildcard, bool allowBinding, TString& service,
- TDeferredAtom& cluster, bool& isBinding)
- {
- service = "";
- cluster = TDeferredAtom();
- isBinding = false;
- if (node.HasBlock1()) {
- service = to_lower(Id(node.GetBlock1().GetRule_an_id1(), *this));
- allowBinding = false;
- if (service != YtProviderName &&
- service != KikimrProviderName &&
- service != RtmrProviderName && service != StatProviderName) {
- Ctx.Error() << "Unknown service: " << service;
- return false;
- }
- }
- switch (node.GetBlock2().Alt_case()) {
- case TRule_cluster_expr::TBlock2::kAlt1: {
- auto value = PureColumnOrNamed(node.GetBlock2().GetAlt1().GetRule_pure_column_or_named1(), *this);
- if (value.Empty()) {
- return false;
- }
- if (value.GetLiteral()) {
- TString clusterName = *value.GetLiteral();
- if (allowBinding && to_lower(clusterName) == "bindings") {
- switch (Ctx.Settings.BindingsMode) {
- case NSQLTranslation::EBindingsMode::DISABLED:
- Ctx.Error(Ctx.Pos(), TIssuesIds::YQL_DISABLED_BINDINGS) << "Please remove 'bindings.' from your query, the support for this syntax has ended";
- Ctx.IncrementMonCounter("sql_errors", "DisabledBinding");
- return false;
- case NSQLTranslation::EBindingsMode::ENABLED:
- isBinding = true;
- break;
- case NSQLTranslation::EBindingsMode::DROP_WITH_WARNING:
- Ctx.Warning(Ctx.Pos(), TIssuesIds::YQL_DEPRECATED_BINDINGS) << "Please remove 'bindings.' from your query, the support for this syntax will be dropped soon";
- Ctx.IncrementMonCounter("sql_errors", "DeprecatedBinding");
- [[fallthrough]];
- case NSQLTranslation::EBindingsMode::DROP:
- service = Context().Scoped->CurrService;
- cluster = Context().Scoped->CurrCluster;
- break;
- }
- return true;
- }
- TString normalizedClusterName;
- auto foundProvider = Ctx.GetClusterProvider(clusterName, normalizedClusterName);
- if (!foundProvider) {
- Ctx.Error() << "Unknown cluster: " << clusterName;
- return false;
- }
- if (service && *foundProvider != service) {
- Ctx.Error() << "Mismatch of cluster " << clusterName << " service, expected: "
- << *foundProvider << ", got: " << service;
- return false;
- }
- if (!service) {
- service = *foundProvider;
- }
- value = TDeferredAtom(Ctx.Pos(), normalizedClusterName);
- } else {
- if (!service) {
- Ctx.Error() << "Cluster service is not set";
- return false;
- }
- }
- cluster = value;
- return true;
- }
- case TRule_cluster_expr::TBlock2::kAlt2: {
- if (!allowWildcard) {
- Ctx.Error() << "Cluster wildcards allowed only in USE statement";
- return false;
- }
- return true;
- }
- case TRule_cluster_expr::TBlock2::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool TSqlTranslation::ApplyTableBinding(const TString& binding, TTableRef& tr, TTableHints& hints) {
- NSQLTranslation::TBindingInfo bindingInfo;
- if (const auto& error = ExtractBindingInfo(Context().Settings, binding, bindingInfo)) {
- Ctx.Error() << error;
- return false;
- }
- if (bindingInfo.Schema) {
- TNodePtr schema = BuildQuotedAtom(Ctx.Pos(), bindingInfo.Schema);
- TNodePtr type = new TCallNodeImpl(Ctx.Pos(), "SqlTypeFromYson", { schema });
- TNodePtr columns = new TCallNodeImpl(Ctx.Pos(), "SqlColumnOrderFromYson", { schema });
- hints["user_schema"] = { type, columns };
- }
- for (auto& [key, values] : bindingInfo.Attributes) {
- TVector<TNodePtr> hintValue;
- for (auto& column : values) {
- hintValue.push_back(BuildQuotedAtom(Ctx.Pos(), column));
- }
- hints[key] = std::move(hintValue);
- }
- tr.Service = bindingInfo.ClusterType;
- tr.Cluster = TDeferredAtom(Ctx.Pos(), bindingInfo.Cluster);
- const TString view = "";
- tr.Keys = BuildTableKey(Ctx.Pos(), tr.Service, tr.Cluster, TDeferredAtom(Ctx.Pos(), bindingInfo.Path), {view});
- return true;
- }
- bool TSqlTranslation::TableRefImpl(const TRule_table_ref& node, TTableRef& result, bool unorderedSubquery) {
- // table_ref:
- // (cluster_expr DOT)? AT?
- // (table_key | an_id_expr LPAREN (table_arg (COMMA table_arg)*)? RPAREN |
- // bind_parameter (LPAREN expr_list? RPAREN)? (VIEW an_id)?)
- // table_hints?;
- if (Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW && node.HasBlock1()) {
- Ctx.Error() << "Cluster should not be used in limited view";
- return false;
- }
- auto service = Context().Scoped->CurrService;
- auto cluster = Context().Scoped->CurrCluster;
- const bool hasAt = node.HasBlock2();
- bool isBinding = false;
- if (node.HasBlock1()) {
- const auto& clusterExpr = node.GetBlock1().GetRule_cluster_expr1();
- bool result = !hasAt ?
- ClusterExprOrBinding(clusterExpr, service, cluster, isBinding) : ClusterExpr(clusterExpr, false, service, cluster);
- if (!result) {
- return false;
- }
- }
- TTableRef tr(Context().MakeName("table"), service, cluster, nullptr);
- TPosition pos(Context().Pos());
- TTableHints hints = GetContextHints(Ctx);
- TTableHints tableHints;
- TMaybe<TString> keyFunc;
- auto& block = node.GetBlock3();
- switch (block.Alt_case()) {
- case TRule_table_ref::TBlock3::kAlt1: {
- if (!isBinding && cluster.Empty()) {
- Ctx.Error() << "No cluster name given and no default cluster is selected";
- return false;
- }
- auto pair = TableKeyImpl(block.GetAlt1().GetRule_table_key1(), *this, hasAt);
- if (isBinding) {
- TString binding = pair.first;
- auto view = pair.second;
- if (!view.ViewName.empty()) {
- YQL_ENSURE(view != TViewDescription{"@"});
- Ctx.Error() << "VIEW is not supported for table bindings";
- return false;
- }
- if (!ApplyTableBinding(binding, tr, tableHints)) {
- return false;
- }
- } else {
- tr.Keys = BuildTableKey(pos, service, cluster, TDeferredAtom(pos, pair.first), pair.second);
- }
- break;
- }
- case TRule_table_ref::TBlock3::kAlt2: {
- if (cluster.Empty()) {
- Ctx.Error() << "No cluster name given and no default cluster is selected";
- return false;
- }
- auto& alt = block.GetAlt2();
- keyFunc = Id(alt.GetRule_an_id_expr1(), *this);
- TVector<TTableArg> args;
- if (alt.HasBlock3()) {
- auto& argsBlock = alt.GetBlock3();
- auto arg = TableArgImpl(argsBlock.GetRule_table_arg1());
- if (!arg) {
- return false;
- }
- args.push_back(std::move(*arg));
- for (auto& b : argsBlock.GetBlock2()) {
- arg = TableArgImpl(b.GetRule_table_arg2());
- if (!arg) {
- return false;
- }
- args.push_back(std::move(*arg));
- }
- }
- tableHints = GetTableFuncHints(*keyFunc);
- tr.Keys = BuildTableKeys(pos, service, cluster, *keyFunc, args);
- break;
- }
- case TRule_table_ref::TBlock3::kAlt3: {
- auto& alt = block.GetAlt3();
- Ctx.IncrementMonCounter("sql_features", "NamedNodeUseSource");
- TString named;
- if (!NamedNodeImpl(alt.GetRule_bind_parameter1(), named, *this)) {
- return false;
- }
- if (hasAt) {
- if (alt.HasBlock2()) {
- Ctx.Error() << "Subquery must not be used as anonymous table name";
- return false;
- }
- if (alt.HasBlock3()) {
- Ctx.Error() << "View is not supported for anonymous tables";
- return false;
- }
- if (node.HasBlock4()) {
- Ctx.Error() << "Hints are not supported for anonymous tables";
- return false;
- }
- auto namedNode = GetNamedNode(named);
- if (!namedNode) {
- return false;
- }
- auto source = TryMakeSourceFromExpression(Ctx.Pos(), Ctx, service, cluster, namedNode, "@");
- if (!source) {
- Ctx.Error() << "Cannot infer cluster and table name";
- return false;
- }
- result.Source = source;
- return true;
- }
- auto nodePtr = GetNamedNode(named);
- if (!nodePtr) {
- Ctx.IncrementMonCounter("sql_errors", "NamedNodeSourceError");
- return false;
- }
- if (alt.HasBlock2()) {
- if (alt.HasBlock3()) {
- Ctx.Error() << "View is not supported for subqueries";
- return false;
- }
- if (node.HasBlock4()) {
- Ctx.Error() << "Hints are not supported for subqueries";
- return false;
- }
- TVector<TNodePtr> values;
- values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "Apply", TNodeFlags::Default));
- values.push_back(nodePtr);
- values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "world", TNodeFlags::Default));
- TSqlExpression sqlExpr(Ctx, Mode);
- if (alt.GetBlock2().HasBlock2() && !ExprList(sqlExpr, values, alt.GetBlock2().GetBlock2().GetRule_expr_list1())) {
- return false;
- }
- TNodePtr apply = new TAstListNodeImpl(Ctx.Pos(), std::move(values));
- if (unorderedSubquery && Ctx.UnorderedSubqueries) {
- apply = new TCallNodeImpl(Ctx.Pos(), "UnorderedSubquery", { apply });
- }
- result.Source = BuildNodeSource(Ctx.Pos(), apply);
- return true;
- }
- TTableHints hints;
- TTableHints contextHints = GetContextHints(Ctx);
- auto ret = BuildInnerSource(Ctx.Pos(), nodePtr, service, cluster);
- if (alt.HasBlock3()) {
- auto view = Id(alt.GetBlock3().GetRule_view_name2(), *this);
- Ctx.IncrementMonCounter("sql_features", "View");
- bool result = view.PrimaryFlag
- ? ret->SetPrimaryView(Ctx, Ctx.Pos())
- : ret->SetViewName(Ctx, Ctx.Pos(), view.ViewName);
- if (!result) {
- return false;
- }
- }
- if (node.HasBlock4()) {
- auto tmp = TableHintsImpl(node.GetBlock4().GetRule_table_hints1(), service, keyFunc.GetOrElse(""));
- if (!tmp) {
- return false;
- }
- hints = *tmp;
- }
- if (hints || contextHints) {
- if (!ret->SetTableHints(Ctx, Ctx.Pos(), hints, contextHints)) {
- return false;
- }
- }
- result.Source = ret;
- return true;
- }
- case TRule_table_ref::TBlock3::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- MergeHints(hints, tableHints);
- if (node.HasBlock4()) {
- auto tmp = TableHintsImpl(node.GetBlock4().GetRule_table_hints1(), service, keyFunc.GetOrElse(""));
- if (!tmp) {
- Ctx.Error() << "Failed to parse table hints";
- return false;
- }
- MergeHints(hints, *tmp);
- }
- if (!hints.empty()) {
- tr.Options = BuildInputOptions(pos, hints);
- }
- if (!tr.Keys) {
- return false;
- }
- result = tr;
- return true;
- }
- TMaybe<TSourcePtr> TSqlTranslation::AsTableImpl(const TRule_table_ref& node) {
- const auto& block = node.GetBlock3();
- if (block.Alt_case() == TRule_table_ref::TBlock3::kAlt2) {
- auto& alt = block.GetAlt2();
- TCiString func(Id(alt.GetRule_an_id_expr1(), *this));
- if (func == "as_table") {
- if (node.HasBlock1()) {
- Ctx.Error() << "Cluster shouldn't be specified for AS_TABLE source";
- return TMaybe<TSourcePtr>(nullptr);
- }
- if (!alt.HasBlock3() || !alt.GetBlock3().GetBlock2().empty()) {
- Ctx.Error() << "Expected single argument for AS_TABLE source";
- return TMaybe<TSourcePtr>(nullptr);
- }
- if (node.HasBlock4()) {
- Ctx.Error() << "No hints expected for AS_TABLE source";
- return TMaybe<TSourcePtr>(nullptr);
- }
- auto arg = TableArgImpl(alt.GetBlock3().GetRule_table_arg1());
- if (!arg) {
- return TMaybe<TSourcePtr>(nullptr);
- }
- if (arg->Expr->GetSource()) {
- Ctx.Error() << "AS_TABLE shouldn't be used for table sources";
- return TMaybe<TSourcePtr>(nullptr);
- }
- return BuildNodeSource(Ctx.Pos(), arg->Expr, true, Ctx.EmitTableSource);
- }
- }
- return Nothing();
- }
- TMaybe<TColumnConstraints> ColumnConstraints(const TRule_column_schema& node, TTranslation& ctx) {
- TNodePtr defaultExpr = nullptr;
- bool nullable = true;
- auto constraintsNode = node.GetRule_opt_column_constraints4();
- if (constraintsNode.HasBlock1()) {
- nullable = !constraintsNode.GetBlock1().HasBlock1();
- }
- if (constraintsNode.HasBlock2()) {
- TSqlExpression expr(ctx.Context(), ctx.Context().Settings.Mode);
- defaultExpr = expr.Build(constraintsNode.GetBlock2().GetRule_expr2());
- if (!defaultExpr) {
- return {};
- }
- }
- return TColumnConstraints(defaultExpr, nullable);
- }
- TMaybe<TColumnSchema> TSqlTranslation::ColumnSchemaImpl(const TRule_column_schema& node) {
- const TString name(Id(node.GetRule_an_id_schema1(), *this));
- const TPosition pos(Context().Pos());
- TNodePtr type = SerialTypeNode(node.GetRule_type_name_or_bind2());
- const bool serial = (type != nullptr);
- const auto constraints = ColumnConstraints(node, *this);
- if (!constraints){
- return {};
- }
- if (!type) {
- type = TypeNodeOrBind(node.GetRule_type_name_or_bind2());
- }
- if (!type) {
- return {};
- }
- TVector<TIdentifier> families;
- if (node.HasBlock3()) {
- const auto& familyRelation = node.GetBlock3().GetRule_family_relation1();
- families.push_back(IdEx(familyRelation.GetRule_an_id2(), *this));
- }
- return TColumnSchema(pos, name, type, constraints->Nullable, families, serial, constraints->DefaultExpr);
- }
- TNodePtr TSqlTranslation::SerialTypeNode(const TRule_type_name_or_bind& node) {
- if (node.Alt_case() != TRule_type_name_or_bind::kAltTypeNameOrBind1) {
- return nullptr;
- }
- TPosition pos = Ctx.Pos();
- auto typeNameNode = node.GetAlt_type_name_or_bind1().GetRule_type_name1();
- if (typeNameNode.Alt_case() != TRule_type_name::kAltTypeName2) {
- return nullptr;
- }
- auto alt = typeNameNode.GetAlt_type_name2();
- auto& block = alt.GetBlock1();
- if (block.Alt_case() != TRule_type_name::TAlt2::TBlock1::kAlt2) {
- return nullptr;
- }
- auto alt2 = block.GetAlt2().GetRule_type_name_simple1();
- const TString name = Id(alt2.GetRule_an_id_pure1(), *this);
- if (name.empty()) {
- return nullptr;
- }
- const auto res = to_lower(name);
- if (res == "bigserial" || res == "serial8") {
- return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Int64", TNodeFlags::Default) });
- } else if (res == "serial" || res == "serial4") {
- return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Int32", TNodeFlags::Default) });
- } else if (res == "smallserial" || res == "serial2") {
- return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Int16", TNodeFlags::Default) });
- }
- return nullptr;
- }
- bool StoreString(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx) {
- switch (from.Alt_case()) {
- case TRule_family_setting_value::kAltFamilySettingValue1: {
- // STRING_VALUE
- const TString stringValue(ctx.Token(from.GetAlt_family_setting_value1().GetToken1()));
- TNodePtr literal = BuildLiteralSmartString(ctx, stringValue);
- if (!literal) {
- return false;
- }
- to = literal;
- break;
- }
- default:
- return false;
- }
- return true;
- }
- bool StoreInt(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx) {
- switch (from.Alt_case()) {
- case TRule_family_setting_value::kAltFamilySettingValue2: {
- // integer
- TNodePtr literal = LiteralNumber(ctx, from.GetAlt_family_setting_value2().GetRule_integer1());
- if (!literal) {
- return false;
- }
- to = literal;
- break;
- }
- default:
- return false;
- }
- return true;
- }
- bool TSqlTranslation::FillFamilySettingsEntry(const TRule_family_settings_entry& settingNode, TFamilyEntry& family) {
- TIdentifier id = IdEx(settingNode.GetRule_an_id1(), *this);
- const TRule_family_setting_value& value = settingNode.GetRule_family_setting_value3();
- if (to_lower(id.Name) == "data") {
- if (!StoreString(value, family.Data, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- } else if (to_lower(id.Name) == "compression") {
- if (!StoreString(value, family.Compression, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- } else if (to_lower(id.Name) == "compression_level") {
- if (!StoreInt(value, family.CompressionLevel, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- } else {
- Ctx.Error() << "Unknown table setting: " << id.Name;
- return false;
- }
- return true;
- }
- bool TSqlTranslation::FillFamilySettings(const TRule_family_settings& settingsNode, TFamilyEntry& family) {
- // family_settings: LPAREN (family_settings_entry (COMMA family_settings_entry)*)? RPAREN;
- if (settingsNode.HasBlock2()) {
- auto& settings = settingsNode.GetBlock2();
- if (!FillFamilySettingsEntry(settings.GetRule_family_settings_entry1(), family)) {
- return false;
- }
- for (auto& block : settings.GetBlock2()) {
- if (!FillFamilySettingsEntry(block.GetRule_family_settings_entry2(), family)) {
- return false;
- }
- }
- }
- return true;
- }
- bool TSqlTranslation::CreateTableEntry(const TRule_create_table_entry& node, TCreateTableParameters& params, const bool isCreateTableAs)
- {
- switch (node.Alt_case()) {
- case TRule_create_table_entry::kAltCreateTableEntry1:
- {
- if (isCreateTableAs) {
- Ctx.Error() << "Column types are not supported for CREATE TABLE AS";
- return false;
- }
- // column_schema
- auto columnSchema = ColumnSchemaImpl(node.GetAlt_create_table_entry1().GetRule_column_schema1());
- if (!columnSchema) {
- return false;
- }
- if (columnSchema->Families.size() > 1) {
- Ctx.Error() << "Several column families for a single column are not yet supported";
- return false;
- }
- params.Columns.push_back(*columnSchema);
- break;
- }
- case TRule_create_table_entry::kAltCreateTableEntry2:
- {
- // table_constraint
- auto& constraint = node.GetAlt_create_table_entry2().GetRule_table_constraint1();
- switch (constraint.Alt_case()) {
- case TRule_table_constraint::kAltTableConstraint1: {
- if (!params.PkColumns.empty()) {
- Ctx.Error() << "PRIMARY KEY statement must be specified only once";
- return false;
- }
- auto& pkConstraint = constraint.GetAlt_table_constraint1();
- params.PkColumns.push_back(IdEx(pkConstraint.GetRule_an_id4(), *this));
- for (auto& block : pkConstraint.GetBlock5()) {
- params.PkColumns.push_back(IdEx(block.GetRule_an_id2(), *this));
- }
- break;
- }
- case TRule_table_constraint::kAltTableConstraint2: {
- if (!params.PartitionByColumns.empty()) {
- Ctx.Error() << "PARTITION BY statement must be specified only once";
- return false;
- }
- auto& pbConstraint = constraint.GetAlt_table_constraint2();
- params.PartitionByColumns.push_back(IdEx(pbConstraint.GetRule_an_id4(), *this));
- for (auto& block : pbConstraint.GetBlock5()) {
- params.PartitionByColumns.push_back(IdEx(block.GetRule_an_id2(), *this));
- }
- break;
- }
- case TRule_table_constraint::kAltTableConstraint3: {
- if (!params.OrderByColumns.empty()) {
- Ctx.Error() << "ORDER BY statement must be specified only once";
- return false;
- }
- auto& obConstraint = constraint.GetAlt_table_constraint3();
- auto extractDirection = [this] (const TRule_column_order_by_specification& spec, bool& desc) {
- desc = false;
- if (!spec.HasBlock2()) {
- return true;
- }
- auto& token = spec.GetBlock2().GetToken1();
- auto tokenId = token.GetId();
- if (IS_TOKEN(tokenId, ASC)) {
- return true;
- } else if (IS_TOKEN(tokenId, DESC)) {
- desc = true;
- return true;
- } else {
- Ctx.Error() << "Unsupported direction token: " << token.GetId();
- return false;
- }
- };
- bool desc = false;
- auto& obSpec = obConstraint.GetRule_column_order_by_specification4();
- if (!extractDirection(obSpec, desc)) {
- return false;
- }
- params.OrderByColumns.push_back(std::make_pair(IdEx(obSpec.GetRule_an_id1(), *this), desc));
- for (auto& block : obConstraint.GetBlock5()) {
- auto& obSpec = block.GetRule_column_order_by_specification2();
- if (!extractDirection(obSpec, desc)) {
- return false;
- }
- params.OrderByColumns.push_back(std::make_pair(IdEx(obSpec.GetRule_an_id1(), *this), desc));
- }
- break;
- }
- default:
- AltNotImplemented("table_constraint", constraint);
- return false;
- }
- break;
- }
- case TRule_create_table_entry::kAltCreateTableEntry3:
- {
- // table_index
- auto& table_index = node.GetAlt_create_table_entry3().GetRule_table_index1();
- if (!CreateTableIndex(table_index, params.Indexes)) {
- return false;
- }
- break;
- }
- case TRule_create_table_entry::kAltCreateTableEntry4:
- {
- if (isCreateTableAs) {
- Ctx.Error() << "Column families are not supported for CREATE TABLE AS";
- return false;
- }
- // family_entry
- auto& family_entry = node.GetAlt_create_table_entry4().GetRule_family_entry1();
- TFamilyEntry family(IdEx(family_entry.GetRule_an_id2(), *this));
- if (!FillFamilySettings(family_entry.GetRule_family_settings3(), family)) {
- return false;
- }
- params.ColumnFamilies.push_back(family);
- break;
- }
- case TRule_create_table_entry::kAltCreateTableEntry5:
- {
- // changefeed
- auto& changefeed = node.GetAlt_create_table_entry5().GetRule_changefeed1();
- TSqlExpression expr(Ctx, Mode);
- if (!CreateChangefeed(changefeed, expr, params.Changefeeds)) {
- return false;
- }
- break;
- }
- case TRule_create_table_entry::kAltCreateTableEntry6:
- {
- if (!isCreateTableAs) {
- Ctx.Error() << "Column requires a type";
- return false;
- }
- // an_id_schema
- const TString name(Id(node.GetAlt_create_table_entry6().GetRule_an_id_schema1(), *this));
- const TPosition pos(Context().Pos());
- params.Columns.push_back(TColumnSchema(pos, name, nullptr, true, {}, false, nullptr));
- break;
- }
- default:
- AltNotImplemented("create_table_entry", node);
- return false;
- }
- return true;
- }
- namespace {
- bool StoreId(const TRule_table_setting_value& from, TMaybe<TIdentifier>& to, TTranslation& ctx) {
- switch (from.Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue1: {
- // id
- to = IdEx(from.GetAlt_table_setting_value1().GetRule_id1(), ctx);
- break;
- }
- default:
- return false;
- }
- return true;
- }
- bool StoreString(const TRule_table_setting_value& from, TNodePtr& to, TContext& ctx) {
- switch (from.Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue2: {
- // STRING_VALUE
- const TString stringValue(ctx.Token(from.GetAlt_table_setting_value2().GetToken1()));
- to = BuildLiteralSmartString(ctx, stringValue);
- break;
- }
- default:
- return false;
- }
- return true;
- }
- bool StoreString(const TRule_table_setting_value& from, TDeferredAtom& to, TContext& ctx, const TString& errorPrefix = {}) {
- switch (from.Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue2: {
- // STRING_VALUE
- const TString stringValue(ctx.Token(from.GetAlt_table_setting_value2().GetToken1()));
- auto unescaped = StringContent(ctx, ctx.Pos(), stringValue);
- if (!unescaped) {
- ctx.Error() << errorPrefix << " value cannot be unescaped";
- return false;
- }
- to = TDeferredAtom(ctx.Pos(), unescaped->Content);
- break;
- }
- default:
- ctx.Error() << errorPrefix << " value should be a string literal";
- return false;
- }
- return true;
- }
- bool StoreInt(const TRule_table_setting_value& from, TNodePtr& to, TContext& ctx) {
- switch (from.Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue3: {
- // integer
- to = LiteralNumber(ctx, from.GetAlt_table_setting_value3().GetRule_integer1());
- break;
- }
- default:
- return false;
- }
- return true;
- }
- bool StoreInt(const TRule_table_setting_value& from, TDeferredAtom& to, TContext& ctx, const TString& errorPrefix = {}) {
- switch (from.Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue3: {
- // integer
- to = TDeferredAtom(LiteralNumber(ctx, from.GetAlt_table_setting_value3().GetRule_integer1()), ctx);
- break;
- }
- default:
- ctx.Error() << errorPrefix << " value should be an integer";
- return false;
- }
- return true;
- }
- bool StoreSplitBoundary(const TRule_literal_value_list& boundary, TVector<TVector<TNodePtr>>& to,
- TSqlExpression& expr, TContext& ctx) {
- TVector<TNodePtr> boundaryKeys;
- auto first_key = expr.LiteralExpr(boundary.GetRule_literal_value2());
- if (!first_key) {
- ctx.Error() << "Empty key in partition at keys";
- return false;
- }
- if (!first_key->Expr) {
- ctx.Error() << "Identifier is not expected in partition at keys";
- return false;
- }
- boundaryKeys.emplace_back(first_key->Expr);
- for (auto& key : boundary.GetBlock3()) {
- auto keyExprOrIdent = expr.LiteralExpr(key.GetRule_literal_value2());
- if (!keyExprOrIdent) {
- ctx.Error() << "Empty key in partition at keys";
- return false;
- }
- if (!keyExprOrIdent->Expr) {
- ctx.Error() << "Identifier is not expected in partition at keys";
- return false;
- }
- boundaryKeys.emplace_back(keyExprOrIdent->Expr);
- }
- to.push_back(boundaryKeys);
- return true;
- }
- bool StoreSplitBoundaries(const TRule_table_setting_value& from, TVector<TVector<TNodePtr>>& to,
- TSqlExpression& expr, TContext& ctx) {
- switch (from.Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue4: {
- // split_boundaries
- const auto& boundariesNode = from.GetAlt_table_setting_value4().GetRule_split_boundaries1();
- switch (boundariesNode.Alt_case()) {
- case TRule_split_boundaries::kAltSplitBoundaries1: {
- // literal_value_list (COMMA literal_value_list)*
- auto& complexBoundaries = boundariesNode.GetAlt_split_boundaries1();
- auto& first_boundary = complexBoundaries.GetRule_literal_value_list2();
- if (!StoreSplitBoundary(first_boundary, to, expr, ctx)) {
- return false;
- }
- for (auto& boundary : complexBoundaries.GetBlock3()) {
- if (!StoreSplitBoundary(boundary.GetRule_literal_value_list2(), to, expr, ctx)) {
- return false;
- }
- }
- break;
- }
- case TRule_split_boundaries::kAltSplitBoundaries2: {
- // literal_value_list
- auto& simpleBoundaries = boundariesNode.GetAlt_split_boundaries2().GetRule_literal_value_list1();
- auto first_key = expr.LiteralExpr(simpleBoundaries.GetRule_literal_value2());
- if (!first_key) {
- ctx.Error() << "Empty key in partition at keys";
- return false;
- }
- if (!first_key->Expr) {
- ctx.Error() << "Identifier is not expected in partition at keys";
- return false;
- }
- to.push_back(TVector<TNodePtr>(1, first_key->Expr));
- for (auto& key : simpleBoundaries.GetBlock3()) {
- auto keyExprOrIdent = expr.LiteralExpr(key.GetRule_literal_value2());
- if (!keyExprOrIdent) {
- ctx.Error() << "Empty key in partition at keys";
- return false;
- }
- if (!first_key->Expr) {
- ctx.Error() << "Identifier is not expected in partition at keys";
- return false;
- }
- to.push_back(
- TVector<TNodePtr>(1, keyExprOrIdent->Expr)
- );
- }
- break;
- }
- default:
- return false;
- }
- break;
- }
- default:
- return false;
- }
- return true;
- }
- bool FillTieringInterval(const TRule_expr& from, TNodePtr& tieringInterval, TSqlExpression& expr, TContext& ctx) {
- auto exprNode = expr.Build(from);
- if (!exprNode) {
- return false;
- }
- if (exprNode->GetOpName() != "Interval") {
- ctx.Error() << "Literal of Interval type is expected for TTL";
- return false;
- }
- tieringInterval = exprNode;
- return true;
- }
- bool FillTierAction(const TRule_ttl_tier_action& from, std::optional<TIdentifier>& storageName, TTranslation& txc) {
- switch (from.GetAltCase()) {
- case TRule_ttl_tier_action::kAltTtlTierAction1:
- storageName = IdEx(from.GetAlt_ttl_tier_action1().GetRule_an_id5(), txc);
- break;
- case TRule_ttl_tier_action::kAltTtlTierAction2:
- storageName.reset();
- break;
- case TRule_ttl_tier_action::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return true;
- }
- bool StoreTtlSettings(const TRule_table_setting_value& from, TResetableSetting<TTtlSettings, void>& to, TSqlExpression& expr, TContext& ctx,
- TTranslation& txc) {
- switch (from.Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue5: {
- auto columnName = IdEx(from.GetAlt_table_setting_value5().GetRule_an_id3(), txc);
- auto tiersLiteral = from.GetAlt_table_setting_value5().GetRule_ttl_tier_list1();
- TNodePtr firstInterval;
- if (!FillTieringInterval(tiersLiteral.GetRule_expr1(), firstInterval, expr, ctx)) {
- return false;
- }
- std::vector<TTtlSettings::TTierSettings> tiers;
- if (!tiersLiteral.HasBlock2()) {
- tiers.emplace_back(firstInterval);
- } else {
- std::optional<TIdentifier> firstStorageName;
- if (!FillTierAction(tiersLiteral.GetBlock2().GetRule_ttl_tier_action1(), firstStorageName, txc)) {
- return false;
- }
- tiers.emplace_back(firstInterval, firstStorageName);
- for (const auto& tierLiteral : tiersLiteral.GetBlock2().GetBlock2()) {
- TNodePtr intervalExpr;
- if (!FillTieringInterval(tierLiteral.GetRule_expr2(), intervalExpr, expr, ctx)) {
- return false;
- }
- std::optional<TIdentifier> storageName;
- if (!FillTierAction(tierLiteral.GetRule_ttl_tier_action3(), storageName, txc)) {
- return false;
- }
- tiers.emplace_back(intervalExpr, storageName);
- }
- }
- TMaybe<TTtlSettings::EUnit> columnUnit;
- if (from.GetAlt_table_setting_value5().HasBlock4()) {
- const TString unit = to_lower(ctx.Token(from.GetAlt_table_setting_value5().GetBlock4().GetToken2()));
- columnUnit.ConstructInPlace();
- if (!TryFromString<TTtlSettings::EUnit>(unit, *columnUnit)) {
- ctx.Error() << "Invalid unit: " << unit;
- return false;
- }
- }
- to.Set(TTtlSettings(columnName, tiers, columnUnit));
- break;
- }
- default:
- return false;
- }
- return true;
- }
- template<typename TChar>
- struct TPatternComponent {
- TBasicString<TChar> Prefix;
- TBasicString<TChar> Suffix;
- bool IsSimple = true;
- void AppendPlain(TChar c) {
- if (IsSimple) {
- Prefix.push_back(c);
- }
- Suffix.push_back(c);
- }
- void AppendAnyChar() {
- IsSimple = false;
- Suffix.clear();
- }
- };
- template<typename TChar>
- TVector<TPatternComponent<TChar>> SplitPattern(const TBasicString<TChar>& pattern, TMaybe<char> escape, bool& inEscape) {
- inEscape = false;
- TVector<TPatternComponent<TChar>> result;
- TPatternComponent<TChar> current;
- bool prevIsPercentChar = false;
- for (const TChar c : pattern) {
- if (inEscape) {
- current.AppendPlain(c);
- inEscape = false;
- prevIsPercentChar = false;
- } else if (escape && c == static_cast<TChar>(*escape)) {
- inEscape = true;
- } else if (c == '%') {
- if (!prevIsPercentChar) {
- result.push_back(std::move(current));
- }
- current = {};
- prevIsPercentChar = true;
- } else if (c == '_') {
- current.AppendAnyChar();
- prevIsPercentChar = false;
- } else {
- current.AppendPlain(c);
- prevIsPercentChar = false;
- }
- }
- result.push_back(std::move(current));
- return result;
- }
- }
- bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value,
- TTableSettings& settings, ETableType tableType, bool alter, bool reset) {
- switch (tableType) {
- case ETableType::ExternalTable:
- return StoreExternalTableSettingsEntry(id, value, settings, alter, reset);
- case ETableType::Table:
- case ETableType::TableStore:
- return StoreTableSettingsEntry(id, value, settings, alter, reset);
- }
- }
- bool TSqlTranslation::StoreExternalTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value,
- TTableSettings& settings, bool alter, bool reset) {
- YQL_ENSURE(value || reset);
- YQL_ENSURE(!reset || reset && alter);
- if (to_lower(id.Name) == "data_source") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- TDeferredAtom dataSource;
- if (!StoreString(*value, dataSource, Ctx, to_upper(id.Name))) {
- return false;
- }
- TString service = Context().Scoped->CurrService;
- TDeferredAtom cluster = Context().Scoped->CurrCluster;
- TNodePtr root = new TAstListNodeImpl(Ctx.Pos());
- root->Add("String", Ctx.GetPrefixedPath(service, cluster, dataSource));
- settings.DataSourcePath = root;
- } else if (to_lower(id.Name) == "location") {
- if (reset) {
- settings.Location.Reset();
- } else {
- TNodePtr location;
- if (!StoreString(*value, location, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- settings.Location.Set(location);
- }
- } else {
- auto& setting = settings.ExternalSourceParameters.emplace_back();
- if (reset) {
- setting.Reset(id);
- } else {
- TNodePtr node;
- if (!StoreString(*value, node, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- setting.Set(std::pair<TIdentifier, TNodePtr>{id, std::move(node)});
- }
- }
- return true;
- }
- bool TSqlTranslation::ValidateTableSettings(const TTableSettings& settings) {
- if (settings.PartitionCount) {
- if (!settings.StoreType || to_lower(settings.StoreType->Name) != "column") {
- Ctx.Error() << " PARTITION_COUNT can be used only with STORE=COLUMN";
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value,
- TTableSettings& settings, bool alter, bool reset) {
- YQL_ENSURE(value || reset);
- YQL_ENSURE(!reset || reset && alter);
- if (to_lower(id.Name) == "compaction_policy") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreString(*value, settings.CompactionPolicy, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- } else if (to_lower(id.Name) == "auto_partitioning_by_size") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreId(*value, settings.AutoPartitioningBySize, *this)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
- return false;
- }
- } else if (to_lower(id.Name) == "auto_partitioning_partition_size_mb") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreInt(*value, settings.PartitionSizeMb, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- } else if (to_lower(id.Name) == "auto_partitioning_by_load") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreId(*value, settings.AutoPartitioningByLoad, *this)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
- return false;
- }
- } else if (to_lower(id.Name) == "auto_partitioning_min_partitions_count") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreInt(*value, settings.MinPartitions, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- } else if (to_lower(id.Name) == "auto_partitioning_max_partitions_count") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreInt(*value, settings.MaxPartitions, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- } else if (to_lower(id.Name) == "partition_count") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreInt(*value, settings.PartitionCount, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- } else if (to_lower(id.Name) == "uniform_partitions") {
- if (alter) {
- Ctx.Error() << to_upper(id.Name) << " alter is not supported";
- return false;
- }
- if (!StoreInt(*value, settings.UniformPartitions, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- } else if (to_lower(id.Name) == "partition_at_keys") {
- if (alter) {
- Ctx.Error() << to_upper(id.Name) << " alter is not supported";
- return false;
- }
- TSqlExpression expr(Ctx, Mode);
- if (!StoreSplitBoundaries(*value, settings.PartitionAtKeys, expr, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a list of keys. "
- << "Example1: (10, 1000) Example2: ((10), (1000, \"abc\"))";
- return false;
- }
- } else if (to_lower(id.Name) == "key_bloom_filter") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreId(*value, settings.KeyBloomFilter, *this)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
- return false;
- }
- } else if (to_lower(id.Name) == "read_replicas_settings") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreString(*value, settings.ReadReplicasSettings, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- } else if (to_lower(id.Name) == "ttl") {
- if (!reset) {
- TSqlExpression expr(Ctx, Mode);
- if (!StoreTtlSettings(*value, settings.TtlSettings, expr, Ctx, *this)) {
- Ctx.Error() << "Invalid TTL settings";
- return false;
- }
- } else {
- settings.TtlSettings.Reset();
- }
- } else if (to_lower(id.Name) == "tiering") {
- if (!reset) {
- TNodePtr tieringNode;
- if (!StoreString(*value, tieringNode, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- settings.Tiering.Set(tieringNode);
- } else {
- settings.Tiering.Reset();
- }
- } else if (to_lower(id.Name) == "store") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreId(*value, settings.StoreType, *this)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
- return false;
- }
- } else if (to_lower(id.Name) == "partition_by_hash_function") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreString(*value, settings.PartitionByHashFunction, Ctx)) {
- Ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- } else if (to_lower(id.Name) == "store_external_blobs") {
- if (reset) {
- Ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!StoreId(*value, settings.StoreExternalBlobs, *this)) {
- Ctx.Error() << to_upper(id.Name) << " value should be an identifier";
- return false;
- }
- } else {
- Ctx.Error() << "Unknown table setting: " << id.Name;
- return false;
- }
- return ValidateTableSettings(settings);
- }
- bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule_table_setting_value& value,
- TTableSettings& settings, ETableType tableType, bool alter) {
- return StoreTableSettingsEntry(id, &value, settings, tableType, alter, false);
- }
- bool TSqlTranslation::ResetTableSettingsEntry(const TIdentifier& id, TTableSettings& settings, ETableType tableType) {
- return StoreTableSettingsEntry(id, nullptr, settings, tableType, true, true);
- }
- bool TSqlTranslation::CreateTableSettings(const TRule_with_table_settings& settingsNode, TCreateTableParameters& params) {
- const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
- if (!StoreTableSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), firstEntry.GetRule_table_setting_value3(),
- params.TableSettings, params.TableType)) {
- return false;
- }
- for (auto& block : settingsNode.GetBlock4()) {
- const auto& entry = block.GetRule_table_settings_entry2();
- if (!StoreTableSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), entry.GetRule_table_setting_value3(), params.TableSettings, params.TableType)) {
- return false;
- }
- }
- return true;
- }
- bool StoreConsumerSettingsEntry(
- const TIdentifier& id, const TRule_topic_consumer_setting_value* value, TSqlExpression& ctx,
- TTopicConsumerSettings& settings,
- bool reset
- ) {
- YQL_ENSURE(value || reset);
- TNodePtr valueExprNode;
- if (value) {
- valueExprNode = ctx.Build(value->GetRule_expr1());
- if (!valueExprNode) {
- ctx.Error() << "invalid value for setting: " << id.Name;
- return false;
- }
- }
- if (to_lower(id.Name) == "important") {
- if (settings.Important) {
- ctx.Error() << to_upper(id.Name) << " specified multiple times in ALTER CONSUMER statements for single consumer";
- return false;
- }
- if (reset) {
- ctx.Error() << to_upper(id.Name) << " reset is not supported";
- return false;
- }
- if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "Bool") {
- ctx.Error() << to_upper(id.Name) << " value should be boolean";
- return false;
- }
- settings.Important = valueExprNode;
- } else if (to_lower(id.Name) == "read_from") {
- if (settings.ReadFromTs) {
- ctx.Error() << to_upper(id.Name) << " specified multiple times in ALTER CONSUMER statements for single consumer";
- return false;
- }
- if (reset) {
- settings.ReadFromTs.Reset();
- } else {
- //ToDo: !! validate
- settings.ReadFromTs.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "supported_codecs") {
- if (settings.SupportedCodecs) {
- ctx.Error() << to_upper(id.Name) << " specified multiple times in ALTER CONSUMER statements for single consumer";
- return false;
- }
- if (reset) {
- settings.SupportedCodecs.Reset();
- } else {
- if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
- ctx.Error() << to_upper(id.Name) << " value should be a string literal";
- return false;
- }
- settings.SupportedCodecs.Set(valueExprNode);
- }
- } else {
- ctx.Error() << to_upper(id.Name) << ": unknown option for consumer";
- return false;
- }
- return true;
- }
- TIdentifier TSqlTranslation::GetTopicConsumerId(const TRule_topic_consumer_ref& node) {
- return IdEx(node.GetRule_an_id_pure1(), *this);
- }
- bool TSqlTranslation::CreateConsumerSettings(
- const TRule_topic_consumer_settings& node, TTopicConsumerSettings& settings
- ) {
- const auto& firstEntry = node.GetRule_topic_consumer_settings_entry1();
- TSqlExpression expr(Ctx, Mode);
- if (!StoreConsumerSettingsEntry(
- IdEx(firstEntry.GetRule_an_id1(), *this),
- &firstEntry.GetRule_topic_consumer_setting_value3(),
- expr, settings, false
- )) {
- return false;
- }
- for (auto& block : node.GetBlock2()) {
- const auto& entry = block.GetRule_topic_consumer_settings_entry2();
- if (!StoreConsumerSettingsEntry(
- IdEx(entry.GetRule_an_id1(), *this),
- &entry.GetRule_topic_consumer_setting_value3(),
- expr, settings, false
- )) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::CreateTopicConsumer(
- const TRule_topic_create_consumer_entry& node,
- TVector<TTopicConsumerDescription>& consumers
- ) {
- consumers.emplace_back(IdEx(node.GetRule_an_id2(), *this));
- if (node.HasBlock3()) {
- auto& settings = node.GetBlock3().GetRule_topic_consumer_with_settings1().GetRule_topic_consumer_settings3();
- if (!CreateConsumerSettings(settings, consumers.back().Settings)) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::AlterTopicConsumerEntry(
- const TRule_alter_topic_alter_consumer_entry& node, TTopicConsumerDescription& alterConsumer
- ) {
- switch (node.Alt_case()) {
- case TRule_alter_topic_alter_consumer_entry::kAltAlterTopicAlterConsumerEntry1:
- return CreateConsumerSettings(
- node.GetAlt_alter_topic_alter_consumer_entry1().GetRule_topic_alter_consumer_set1()
- .GetRule_topic_consumer_settings3(),
- alterConsumer.Settings
- );
- //case TRule_alter_topic_alter_consumer_entry::ALT_NOT_SET:
- case TRule_alter_topic_alter_consumer_entry::kAltAlterTopicAlterConsumerEntry2: {
- auto& resetNode = node.GetAlt_alter_topic_alter_consumer_entry2().GetRule_topic_alter_consumer_reset1();
- TSqlExpression expr(Ctx, Mode);
- if (!StoreConsumerSettingsEntry(
- IdEx(resetNode.GetRule_an_id3(), *this),
- nullptr,
- expr, alterConsumer.Settings, true
- )) {
- return false;
- }
- for (auto& resetItem: resetNode.GetBlock4()) {
- if (!StoreConsumerSettingsEntry(
- IdEx(resetItem.GetRule_an_id2(), *this),
- nullptr,
- expr, alterConsumer.Settings, true
- )) {
- return false;
- }
- }
- return true;
- }
- default:
- Ctx.Error() << "unknown alter consumer action";
- return false;
- }
- return true;
- }
- bool TSqlTranslation::AlterTopicConsumer(
- const TRule_alter_topic_alter_consumer& node,
- THashMap<TString, TTopicConsumerDescription>& alterConsumers
- ) {
- auto consumerId = GetTopicConsumerId(node.GetRule_topic_consumer_ref3());
- TString name = to_lower(consumerId.Name);
- auto iter = alterConsumers.insert(std::make_pair(
- name, TTopicConsumerDescription(std::move(consumerId))
- )).first;
- if (!AlterTopicConsumerEntry(node.GetRule_alter_topic_alter_consumer_entry4(), iter->second)) {
- return false;
- }
- return true;
- }
- bool TSqlTranslation::CreateTopicEntry(const TRule_create_topic_entry& node, TCreateTopicParameters& params) {
- // Will need a switch() here if (ever) create_topic_entry gets more than 1 type of statement
- auto& consumer = node.GetRule_topic_create_consumer_entry1();
- if (!CreateTopicConsumer(consumer, params.Consumers)) {
- return false;
- }
- return true;
- }
- static bool StoreTopicSettingsEntry(
- const TIdentifier& id, const TRule_topic_setting_value* value, TSqlExpression& ctx,
- TTopicSettings& settings, bool reset
- ) {
- YQL_ENSURE(value || reset);
- TNodePtr valueExprNode;
- if (value) {
- valueExprNode = ctx.Build(value->GetRule_expr1());
- if (!valueExprNode) {
- ctx.Error() << "invalid value for setting: " << id.Name;
- return false;
- }
- }
- if (to_lower(id.Name) == "min_active_partitions") {
- if (reset) {
- settings.MinPartitions.Reset();
- } else {
- if (!valueExprNode->IsIntegerLiteral()) {
- ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- settings.MinPartitions.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "partition_count_limit" || to_lower(id.Name) == "max_active_partitions") {
- if (reset) {
- settings.MaxPartitions.Reset();
- } else {
- if (!valueExprNode->IsIntegerLiteral()) {
- ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- settings.MaxPartitions.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "retention_period") {
- if (reset) {
- settings.RetentionPeriod.Reset();
- } else {
- if (valueExprNode->GetOpName() != "Interval") {
- ctx.Error() << "Literal of Interval type is expected for retention";
- return false;
- }
- settings.RetentionPeriod.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "retention_storage_mb") {
- if (reset) {
- settings.RetentionStorage.Reset();
- } else {
- if (!valueExprNode->IsIntegerLiteral()) {
- ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- settings.RetentionStorage.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "partition_write_speed_bytes_per_second") {
- if (reset) {
- settings.PartitionWriteSpeed.Reset();
- } else {
- if (!valueExprNode->IsIntegerLiteral()) {
- ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- settings.PartitionWriteSpeed.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "partition_write_burst_bytes") {
- if (reset) {
- settings.PartitionWriteBurstSpeed.Reset();
- } else {
- if (!valueExprNode->IsIntegerLiteral()) {
- ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- settings.PartitionWriteBurstSpeed.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "metering_mode") {
- if (reset) {
- settings.MeteringMode.Reset();
- } else {
- if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
- ctx.Error() << to_upper(id.Name) << " value should be string";
- return false;
- }
- settings.MeteringMode.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "supported_codecs") {
- if (reset) {
- settings.SupportedCodecs.Reset();
- } else {
- if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
- ctx.Error() << to_upper(id.Name) << " value should be string";
- return false;
- }
- settings.SupportedCodecs.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "auto_partitioning_stabilization_window") {
- if (reset) {
- settings.AutoPartitioningStabilizationWindow.Reset();
- } else {
- if (valueExprNode->GetOpName() != "Interval") {
- ctx.Error() << "Literal of Interval type is expected for retention";
- return false;
- }
- settings.AutoPartitioningStabilizationWindow.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "auto_partitioning_up_utilization_percent") {
- if (reset) {
- settings.AutoPartitioningUpUtilizationPercent.Reset();
- } else {
- if (!valueExprNode->IsIntegerLiteral()) {
- ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- settings.AutoPartitioningUpUtilizationPercent.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "auto_partitioning_down_utilization_percent") {
- if (reset) {
- settings.AutoPartitioningDownUtilizationPercent.Reset();
- } else {
- if (!valueExprNode->IsIntegerLiteral()) {
- ctx.Error() << to_upper(id.Name) << " value should be an integer";
- return false;
- }
- settings.AutoPartitioningDownUtilizationPercent.Set(valueExprNode);
- }
- } else if (to_lower(id.Name) == "auto_partitioning_strategy") {
- if (reset) {
- settings.AutoPartitioningStrategy.Reset();
- } else {
- if (!valueExprNode->IsLiteral() || valueExprNode->GetLiteralType() != "String") {
- ctx.Error() << to_upper(id.Name) << " value should be string";
- return false;
- }
- settings.AutoPartitioningStrategy.Set(valueExprNode);
- }
- } else {
- ctx.Error() << "unknown topic setting: " << id.Name;
- return false;
- }
- return true;
- }
- bool TSqlTranslation::AlterTopicAction(const TRule_alter_topic_action& node, TAlterTopicParameters& params) {
- // alter_topic_action:
- // alter_topic_add_consumer
- // | alter_topic_alter_consumer
- // | alter_topic_drop_consumer
- // | alter_topic_set_settings
- // | alter_topic_reset_settings
- switch (node.Alt_case()) {
- case TRule_alter_topic_action::kAltAlterTopicAction1: // alter_topic_add_consumer
- return CreateTopicConsumer(
- node.GetAlt_alter_topic_action1().GetRule_alter_topic_add_consumer1()
- .GetRule_topic_create_consumer_entry2(),
- params.AddConsumers
- );
- case TRule_alter_topic_action::kAltAlterTopicAction2: // alter_topic_alter_consumer
- return AlterTopicConsumer(
- node.GetAlt_alter_topic_action2().GetRule_alter_topic_alter_consumer1(),
- params.AlterConsumers
- );
- case TRule_alter_topic_action::kAltAlterTopicAction3: // drop_consumer
- params.DropConsumers.emplace_back(GetTopicConsumerId(
- node.GetAlt_alter_topic_action3().GetRule_alter_topic_drop_consumer1()
- .GetRule_topic_consumer_ref3()
- ));
- return true;
- case TRule_alter_topic_action::kAltAlterTopicAction4: // set_settings
- return CreateTopicSettings(
- node.GetAlt_alter_topic_action4().GetRule_alter_topic_set_settings1()
- .GetRule_topic_settings3(),
- params.TopicSettings
- );
- case TRule_alter_topic_action::kAltAlterTopicAction5: { // reset_settings
- auto& resetNode = node.GetAlt_alter_topic_action5().GetRule_alter_topic_reset_settings1();
- TSqlExpression expr(Ctx, Mode);
- if (!StoreTopicSettingsEntry(
- IdEx(resetNode.GetRule_an_id3(), *this),
- nullptr, expr,
- params.TopicSettings, true
- )) {
- return false;
- }
- for (auto& resetItem: resetNode.GetBlock4()) {
- if (!StoreTopicSettingsEntry(
- IdEx(resetItem.GetRule_an_id_pure2(), *this),
- nullptr, expr,
- params.TopicSettings, true
- )) {
- return false;
- }
- }
- return true;
- }
- default:
- Ctx.Error() << "unknown alter topic action";
- return false;
- }
- return true;
- }
- bool TSqlTranslation::CreateTopicSettings(const TRule_topic_settings& node, TTopicSettings& settings) {
- const auto& firstEntry = node.GetRule_topic_settings_entry1();
- TSqlExpression expr(Ctx, Mode);
- if (!StoreTopicSettingsEntry(
- IdEx(firstEntry.GetRule_an_id1(), *this),
- &firstEntry.GetRule_topic_setting_value3(),
- expr, settings, false
- )) {
- return false;
- }
- for (auto& block : node.GetBlock2()) {
- const auto& entry = block.GetRule_topic_settings_entry2();
- if (!StoreTopicSettingsEntry(
- IdEx(entry.GetRule_an_id1(), *this),
- &entry.GetRule_topic_setting_value3(),
- expr, settings, false
- )) {
- return false;
- }
- }
- return true;
- }
- TNodePtr TSqlTranslation::IntegerOrBind(const TRule_integer_or_bind& node) {
- switch (node.Alt_case()) {
- case TRule_integer_or_bind::kAltIntegerOrBind1: {
- const TString intString = Ctx.Token(node.GetAlt_integer_or_bind1().GetRule_integer1().GetToken1());
- ui64 value;
- TString suffix;
- if (!ParseNumbers(Ctx, intString, value, suffix)) {
- return {};
- }
- return BuildQuotedAtom(Ctx.Pos(), ToString(value), TNodeFlags::ArbitraryContent);
- }
- case TRule_integer_or_bind::kAltIntegerOrBind2: {
- TString bindName;
- if (!NamedNodeImpl(node.GetAlt_integer_or_bind2().GetRule_bind_parameter1(), bindName, *this)) {
- return {};
- }
- auto namedNode = GetNamedNode(bindName);
- if (!namedNode) {
- return {};
- }
- auto atom = MakeAtomFromExpression(Ctx.Pos(), Ctx, namedNode);
- return atom.Build();
- }
- case TRule_integer_or_bind::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TNodePtr TSqlTranslation::TypeNameTag(const TRule_type_name_tag& node) {
- switch (node.Alt_case()) {
- case TRule_type_name_tag::kAltTypeNameTag1: {
- auto content = Id(node.GetAlt_type_name_tag1().GetRule_id1(), *this);
- auto atom = TDeferredAtom(Ctx.Pos(), content);
- return atom.Build();
- }
- case TRule_type_name_tag::kAltTypeNameTag2: {
- auto value = Token(node.GetAlt_type_name_tag2().GetToken1());
- auto parsed = StringContentOrIdContent(Ctx, Ctx.Pos(), value);
- if (!parsed) {
- return {};
- }
- auto atom = TDeferredAtom(Ctx.Pos(), parsed->Content);
- return atom.Build();
- }
- case TRule_type_name_tag::kAltTypeNameTag3: {
- TString bindName;
- if (!NamedNodeImpl(node.GetAlt_type_name_tag3().GetRule_bind_parameter1(), bindName, *this)) {
- return {};
- }
- auto namedNode = GetNamedNode(bindName);
- if (!namedNode) {
- return {};
- }
- TDeferredAtom atom;
- MakeTableFromExpression(Ctx.Pos(), Ctx, namedNode, atom);
- return atom.Build();
- }
- case TRule_type_name_tag::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TNodePtr TSqlTranslation::TypeSimple(const TRule_type_name_simple& node, bool onlyDataAllowed) {
- const TString origName = Id(node.GetRule_an_id_pure1(), *this);
- if (origName.empty()) {
- return {};
- }
- return BuildSimpleType(Ctx, Ctx.Pos(), origName, onlyDataAllowed);
- }
- TNodePtr TSqlTranslation::TypeDecimal(const TRule_type_name_decimal& node) {
- auto pos = Ctx.Pos();
- auto flags = TNodeFlags::Default;
- auto paramOne = IntegerOrBind(node.GetRule_integer_or_bind3());
- if (!paramOne) {
- return {};
- }
- auto paramTwo = IntegerOrBind(node.GetRule_integer_or_bind5());
- if (!paramTwo) {
- return {};
- }
- return new TCallNodeImpl(pos, "DataType", { BuildQuotedAtom(pos, "Decimal", flags), paramOne, paramTwo });
- }
- TNodePtr TSqlTranslation::AddOptionals(const TNodePtr& node, size_t optionalCount) {
- TNodePtr result = node;
- if (node) {
- TPosition pos = node->GetPos();
- for (size_t i = 0; i < optionalCount; ++i) {
- result = new TCallNodeImpl(pos, "OptionalType", { result });
- }
- }
- return result;
- }
- TMaybe<std::pair<TVector<TNodePtr>, bool>> TSqlTranslation::CallableArgList(const TRule_callable_arg_list& argList, bool namedArgsStarted) {
- auto pos = Ctx.Pos();
- auto flags = TNodeFlags::Default;
- auto& arg1 = argList.GetRule_callable_arg1();
- auto& varArg = arg1.GetRule_variant_arg1();
- TVector<TNodePtr> result;
- TVector<TNodePtr> items;
- auto typeNode = TypeNodeOrBind(varArg.GetRule_type_name_or_bind2());
- if (!typeNode) {
- return {};
- }
- items.push_back(typeNode);
- if (varArg.HasBlock1()) {
- namedArgsStarted = true;
- auto tag = TypeNameTag(varArg.GetBlock1().GetRule_type_name_tag1());
- if (!tag) {
- return {};
- }
- items.push_back(tag);
- }
- if (arg1.HasBlock2()) {
- if (!varArg.HasBlock1()) {
- items.push_back(BuildQuotedAtom(pos, "", flags));
- }
- items.push_back(BuildQuotedAtom(pos, "1", flags));
- }
- result.push_back(new TAstListNodeImpl(pos, items));
- for (auto& arg : argList.GetBlock2()) {
- auto& varArg = arg.GetRule_callable_arg2().GetRule_variant_arg1();
- TVector<TNodePtr> items;
- auto typeNode = TypeNodeOrBind(varArg.GetRule_type_name_or_bind2());
- if (!typeNode) {
- return {};
- }
- items.push_back(typeNode);
- if (varArg.HasBlock1()) {
- auto tag = TypeNameTag(varArg.GetBlock1().GetRule_type_name_tag1());
- if (!tag) {
- return {};
- }
- items.push_back(tag);
- } else {
- if (namedArgsStarted) {
- Ctx.Error() << "Expected named argument, previous argument was named";
- return {};
- }
- items.push_back(BuildQuotedAtom(pos, "", flags));
- }
- if (arg.GetRule_callable_arg2().HasBlock2()) {
- if (!varArg.HasBlock1()) {
- items.push_back(BuildQuotedAtom(pos, "", flags));
- }
- items.push_back(BuildQuotedAtom(pos, "1", flags));
- }
- result.push_back(new TAstListNodeImpl(pos, items));
- }
- return std::make_pair(result, namedArgsStarted);
- }
- TNodePtr TSqlTranslation::TypeNodeOrBind(const TRule_type_name_or_bind& node) {
- switch (node.Alt_case()) {
- case TRule_type_name_or_bind::kAltTypeNameOrBind1: {
- return TypeNode(node.GetAlt_type_name_or_bind1().GetRule_type_name1());
- }
- case TRule_type_name_or_bind::kAltTypeNameOrBind2: {
- TString bindName;
- if (!NamedNodeImpl(node.GetAlt_type_name_or_bind2().GetRule_bind_parameter1(), bindName, *this)) {
- return {};
- }
- return GetNamedNode(bindName);
- }
- case TRule_type_name_or_bind::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- TNodePtr TSqlTranslation::TypeNode(const TRule_type_name& node) {
- //type_name:
- // type_name_composite
- // | (type_name_decimal | type_name_simple) QUESTION*;
- if (node.Alt_case() == TRule_type_name::kAltTypeName1) {
- return TypeNode(node.GetAlt_type_name1().GetRule_type_name_composite1());
- }
- TNodePtr result;
- TPosition pos = Ctx.Pos();
- auto& alt = node.GetAlt_type_name2();
- auto& block = alt.GetBlock1();
- switch (block.Alt_case()) {
- case TRule_type_name::TAlt2::TBlock1::kAlt1: {
- auto& decimalType = block.GetAlt1().GetRule_type_name_decimal1();
- result = TypeDecimal(decimalType);
- break;
- }
- case TRule_type_name::TAlt2::TBlock1::kAlt2: {
- auto& simpleType = block.GetAlt2().GetRule_type_name_simple1();
- result = TypeSimple(simpleType, false);
- break;
- }
- case TRule_type_name::TAlt2::TBlock1::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return AddOptionals(result, alt.GetBlock2().size());
- }
- TNodePtr TSqlTranslation::TypeNode(const TRule_type_name_composite& node) {
- //type_name_composite:
- // ( type_name_optional
- // | type_name_tuple
- // | type_name_struct
- // | type_name_variant
- // | type_name_list
- // | type_name_stream
- // | type_name_flow
- // | type_name_dict
- // | type_name_set
- // | type_name_enum
- // | type_name_resource
- // | type_name_tagged
- // | type_name_callable
- // ) QUESTION*;
- TNodePtr result;
- TPosition pos = Ctx.Pos();
- auto flags = TNodeFlags::Default;
- auto wrapOneParamType = [&] (const TRule_type_name_or_bind& param, const char* type) -> TNodePtr {
- auto node = TypeNodeOrBind(param);
- return node ? new TAstListNodeImpl(pos, { BuildAtom(pos, type, flags), node }) : nullptr;
- };
- auto makeVoid = [&] () -> TNodePtr {
- return new TAstListNodeImpl(pos, { BuildAtom(pos, "VoidType", flags) });
- };
- auto makeQuote = [&] (const TNodePtr& node) -> TNodePtr {
- return new TAstListNodeImpl(pos, { new TAstAtomNodeImpl(pos, "quote", 0), node });
- };
- auto& block = node.GetBlock1();
- switch (block.Alt_case()) {
- case TRule_type_name_composite_TBlock1::kAlt1: {
- auto& optionalType = block.GetAlt1().GetRule_type_name_optional1();
- result = wrapOneParamType(optionalType.GetRule_type_name_or_bind3(), "OptionalType");
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt2: {
- auto& tupleType = block.GetAlt2().GetRule_type_name_tuple1();
- TVector<TNodePtr> items;
- items.push_back(BuildAtom(pos, "TupleType", flags));
- switch (tupleType.GetBlock2().Alt_case()) {
- case TRule_type_name_tuple::TBlock2::kAlt1: {
- if (tupleType.GetBlock2().GetAlt1().HasBlock2()) {
- auto typeNode = TypeNodeOrBind(tupleType.GetBlock2().GetAlt1().GetBlock2().GetRule_type_name_or_bind1());
- if (!typeNode) {
- return {};
- }
- items.push_back(typeNode);
- for (auto& arg : tupleType.GetBlock2().GetAlt1().GetBlock2().GetBlock2()) {
- auto typeNode = TypeNodeOrBind(arg.GetRule_type_name_or_bind2());
- if (!typeNode) {
- return {};
- }
- items.push_back(typeNode);
- }
- }
- [[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- }
- case TRule_type_name_tuple::TBlock2::kAlt2:
- break;
- case TRule_type_name_tuple::TBlock2::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- result = new TAstListNodeImpl(pos, items);
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt3: {
- auto& structType = block.GetAlt3().GetRule_type_name_struct1();
- TVector<TNodePtr> items;
- items.push_back(BuildAtom(pos, "StructType", flags));
- switch (structType.GetBlock2().Alt_case()) {
- case TRule_type_name_struct::TBlock2::kAlt1: {
- if (structType.GetBlock2().GetAlt1().HasBlock2()) {
- auto& structArg = structType.GetBlock2().GetAlt1().GetBlock2().GetRule_struct_arg1();
- auto typeNode = TypeNodeOrBind(structArg.GetRule_type_name_or_bind3());
- if (!typeNode) {
- return {};
- }
- auto tag = TypeNameTag(structArg.GetRule_type_name_tag1());
- if (!tag) {
- return {};
- }
- items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
- for (auto& arg : structType.GetBlock2().GetAlt1().GetBlock2().GetBlock2()) {
- auto typeNode = TypeNodeOrBind(arg.GetRule_struct_arg2().GetRule_type_name_or_bind3());
- if (!typeNode) {
- return {};
- }
- auto tag = TypeNameTag(arg.GetRule_struct_arg2().GetRule_type_name_tag1());
- if (!tag) {
- return {};
- }
- items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
- }
- }
- [[fallthrough]]; // AUTOGENERATED_FALLTHROUGH_FIXME
- }
- case TRule_type_name_struct::TBlock2::kAlt2:
- break;
- case TRule_type_name_struct::TBlock2::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- result = new TAstListNodeImpl(pos, items);
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt4: {
- auto& variantType = block.GetAlt4().GetRule_type_name_variant1();
- TVector<TNodePtr> items;
- bool overStruct = false;
- auto& variantArg = variantType.GetRule_variant_arg3();
- auto typeNode = TypeNodeOrBind(variantArg.GetRule_type_name_or_bind2());
- if (!typeNode) {
- return {};
- }
- if (variantArg.HasBlock1()) {
- items.push_back(BuildAtom(pos, "StructType", flags));
- overStruct = true;
- auto tag = TypeNameTag(variantArg.GetBlock1().GetRule_type_name_tag1());
- if (!tag) {
- return {};
- }
- items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
- } else {
- items.push_back(BuildAtom(pos, "TupleType", flags));
- items.push_back(typeNode);
- }
- for (auto& arg : variantType.GetBlock4()) {
- auto typeNode = TypeNodeOrBind(arg.GetRule_variant_arg2().GetRule_type_name_or_bind2());
- if (!typeNode) {
- return {};
- }
- if (overStruct) {
- if (!arg.GetRule_variant_arg2().HasBlock1()) {
- Ctx.Error() << "Variant over struct and tuple mixture";
- return {};
- }
- auto tag = TypeNameTag(arg.GetRule_variant_arg2().GetBlock1().GetRule_type_name_tag1());
- if (!tag) {
- return {};
- }
- items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, typeNode })));
- } else {
- if (arg.GetRule_variant_arg2().HasBlock1()) {
- Ctx.Error() << "Variant over struct and tuple mixture";
- return {};
- }
- items.push_back(typeNode);
- }
- }
- typeNode = new TAstListNodeImpl(pos, items);
- result = new TAstListNodeImpl(pos, { BuildAtom(pos, "VariantType", flags), typeNode });
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt5: {
- auto& listType = block.GetAlt5().GetRule_type_name_list1();
- result = wrapOneParamType(listType.GetRule_type_name_or_bind3(), "ListType");
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt6: {
- auto& streamType = block.GetAlt6().GetRule_type_name_stream1();
- result = wrapOneParamType(streamType.GetRule_type_name_or_bind3(), "StreamType");
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt7: {
- auto& flowType = block.GetAlt7().GetRule_type_name_flow1();
- result = wrapOneParamType(flowType.GetRule_type_name_or_bind3(), "FlowType");
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt8: {
- auto& dictType = block.GetAlt8().GetRule_type_name_dict1();
- TVector<TNodePtr> items;
- items.push_back(BuildAtom(pos, "DictType", flags));
- auto typeNode = TypeNodeOrBind(dictType.GetRule_type_name_or_bind3());
- if (!typeNode) {
- return {};
- }
- items.push_back(typeNode);
- typeNode = TypeNodeOrBind(dictType.GetRule_type_name_or_bind5());
- if (!typeNode) {
- return {};
- }
- items.push_back(typeNode);
- result = new TAstListNodeImpl(pos, items);
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt9: {
- auto& setType = block.GetAlt9().GetRule_type_name_set1();
- auto typeNode = TypeNodeOrBind(setType.GetRule_type_name_or_bind3());
- if (!typeNode) {
- return {};
- }
- result = new TAstListNodeImpl(pos, { BuildAtom(pos, "DictType", flags), typeNode, makeVoid() });
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt10: {
- auto& enumType = block.GetAlt10().GetRule_type_name_enum1();
- TVector<TNodePtr> items;
- items.push_back(BuildAtom(pos, "StructType", flags));
- auto tag = TypeNameTag(enumType.GetRule_type_name_tag3());
- if (!tag) {
- return {};
- }
- items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, makeVoid() })));
- for (auto& arg : enumType.GetBlock4()) {
- auto tag = TypeNameTag(arg.GetRule_type_name_tag2());
- if (!tag) {
- return {};
- }
- items.push_back(makeQuote(new TAstListNodeImpl(pos, { tag, makeVoid() })));
- }
- auto typeNode = new TAstListNodeImpl(pos, items);
- result = new TAstListNodeImpl(pos, { BuildAtom(pos, "VariantType", flags), typeNode });
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt11: {
- auto& resourceType = block.GetAlt11().GetRule_type_name_resource1();
- auto tag = TypeNameTag(resourceType.GetRule_type_name_tag3());
- if (!tag) {
- return {};
- }
- result = new TAstListNodeImpl(pos, { BuildAtom(pos, "ResourceType", flags), tag });
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt12: {
- auto& taggedType = block.GetAlt12().GetRule_type_name_tagged1();
- auto typeNode = TypeNodeOrBind(taggedType.GetRule_type_name_or_bind3());
- if (!typeNode) {
- return {};
- }
- auto tag = TypeNameTag(taggedType.GetRule_type_name_tag5());
- if (!tag) {
- return {};
- }
- result = new TAstListNodeImpl(pos, { BuildAtom(pos, "TaggedType", flags), typeNode, tag });
- break;
- }
- case TRule_type_name_composite_TBlock1::kAlt13: {
- auto& callableType = block.GetAlt13().GetRule_type_name_callable1();
- TMaybe<std::pair<TVector<TNodePtr>, bool>> requiredArgs, optionalArgs;
- bool namedArgsStarted = false;
- size_t optionalArgsCount = 0;
- if (callableType.HasBlock4()) {
- auto& argList = callableType.GetBlock4().GetRule_callable_arg_list1();
- requiredArgs = CallableArgList(argList, namedArgsStarted);
- if (!requiredArgs) {
- return {};
- }
- namedArgsStarted = requiredArgs->second;
- }
- if (callableType.HasBlock6()) {
- auto& argList = callableType.GetBlock6().GetRule_callable_arg_list2();
- optionalArgs = CallableArgList(argList, namedArgsStarted);
- if (!optionalArgs) {
- return {};
- }
- optionalArgsCount = optionalArgs->first.size();
- }
- auto returnType = TypeNodeOrBind(callableType.GetRule_type_name_or_bind9());
- if (!returnType) {
- return {};
- }
- TVector<TNodePtr> items;
- items.push_back(BuildAtom(pos, "CallableType", flags));
- if (optionalArgsCount) {
- items.push_back(makeQuote(new TAstListNodeImpl(pos,
- { BuildQuotedAtom(pos, ToString(optionalArgsCount), flags) })));
- } else {
- items.push_back(makeQuote(new TAstListNodeImpl(pos, {})));
- }
- items.push_back(makeQuote(new TAstListNodeImpl(pos, { returnType })));
- if (requiredArgs) {
- for (auto& arg: requiredArgs->first) {
- items.push_back(makeQuote(arg));
- }
- }
- if (optionalArgs) {
- for (auto& arg: optionalArgs->first) {
- items.push_back(makeQuote(arg));
- }
- }
- result = new TAstListNodeImpl(pos, items);
- break;
- }
- case TRule_type_name_composite_TBlock1::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return AddOptionals(result, node.GetBlock2().size());
- }
- TNodePtr TSqlTranslation::ValueConstructorLiteral(const TRule_value_constructor_literal& node) {
- return BuildLiteralSmartString(Ctx, Token(node.GetToken1()));
- }
- TNodePtr TSqlTranslation::ValueConstructor(const TRule_value_constructor& node) {
- TSqlCallExpr call(Ctx, Mode);
- if (!call.Init(node)) {
- return {};
- }
- return call.BuildCall();
- }
- TNodePtr TSqlTranslation::ListLiteral(const TRule_list_literal& node) {
- TVector<TNodePtr> values;
- values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "AsListMayWarn", TNodeFlags::Default));
- TSqlExpression sqlExpr(Ctx, Mode);
- if (node.HasBlock2() && !ExprList(sqlExpr, values, node.GetBlock2().GetRule_expr_list1())) {
- return nullptr;
- }
- return new TAstListNodeImpl(Ctx.Pos(), std::move(values));
- }
- TNodePtr TSqlTranslation::DictLiteral(const TRule_dict_literal& node) {
- TVector<TNodePtr> values;
- if (node.HasBlock2()) {
- const auto& list = node.GetBlock2().GetRule_expr_dict_list1();
- const bool isSet = !list.HasBlock2();
- values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), isSet ? "AsSet" : "AsDict", TNodeFlags::Default));
- TSqlExpression sqlExpr(Ctx, Mode);
- if (isSet) {
- if (!Expr(sqlExpr, values, list.GetRule_expr1())) {
- return nullptr;
- }
- } else {
- TVector<TNodePtr> tupleItems;
- if (!Expr(sqlExpr, tupleItems, list.GetRule_expr1())) {
- return nullptr;
- }
- if (!Expr(sqlExpr, tupleItems, list.GetBlock2().GetRule_expr2())) {
- return nullptr;
- }
- values.push_back(new TTupleNode(Ctx.Pos(), std::move(tupleItems)));
- }
- for (auto& b : list.GetBlock3()) {
- sqlExpr.Token(b.GetToken1());
- const bool isSetCurr = !b.HasBlock3();
- if (isSetCurr != isSet) {
- Error() << "Expected keys/values pair or keys, but got mix of them";
- return nullptr;
- }
- if (isSet) {
- if (!Expr(sqlExpr, values, b.GetRule_expr2())) {
- return nullptr;
- }
- } else {
- TVector<TNodePtr> tupleItems;
- if (!Expr(sqlExpr, tupleItems, b.GetRule_expr2())) {
- return nullptr;
- }
- if (!Expr(sqlExpr, tupleItems, b.GetBlock3().GetRule_expr2())) {
- return nullptr;
- }
- values.push_back(new TTupleNode(Ctx.Pos(), std::move(tupleItems)));
- }
- }
- } else {
- values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "AsDict", TNodeFlags::Default));
- }
- return new TAstListNodeImpl(Ctx.Pos(), std::move(values));
- }
- bool TSqlTranslation::StructLiteralItem(TVector<TNodePtr>& labels, const TRule_expr& label, TVector<TNodePtr>& values, const TRule_expr& value) {
- // label expr
- {
- TColumnRefScope scope(Ctx, EColumnRefState::AsStringLiteral, /* topLevel */ false);
- TSqlExpression sqlExpr(Ctx, Mode);
- if (!Expr(sqlExpr, labels, label)) {
- return false;
- }
- TDeferredAtom atom;
- MakeTableFromExpression(Ctx.Pos(), Ctx, labels.back(), atom);
- labels.back() = atom.Build();
- if (!labels.back()) {
- return false;
- }
- }
- // value expr
- {
- TSqlExpression sqlExpr(Ctx, Mode);
- if (!Expr(sqlExpr, values, value)) {
- return false;
- }
- }
- return true;
- }
- TNodePtr TSqlTranslation::StructLiteral(const TRule_struct_literal& node) {
- TVector<TNodePtr> labels;
- TVector<TNodePtr> values;
- TPosition pos = Ctx.TokenPosition(node.GetToken1());
- if (node.HasBlock2()) {
- const auto& list = node.GetBlock2().GetRule_expr_struct_list1();
- if (!StructLiteralItem(labels, list.GetRule_expr1(), values, list.GetRule_expr3())) {
- return {};
- }
- for (auto& b : list.GetBlock4()) {
- if (!StructLiteralItem(labels, b.GetRule_expr2(), values, b.GetRule_expr4())) {
- return {};
- }
- }
- }
- return BuildStructure(pos, values, labels);
- }
- bool TSqlTranslation::TableHintImpl(const TRule_table_hint& rule, TTableHints& hints, const TString& provider, const TString& keyFunc) {
- // table_hint:
- // an_id_hint (EQUALS (type_name_tag | LPAREN type_name_tag (COMMA type_name_tag)* COMMA? RPAREN))?
- // | (SCHEMA | COLUMNS) EQUALS? type_name_or_bind
- // | SCHEMA EQUALS? LPAREN (struct_arg_positional (COMMA struct_arg_positional)*)? COMMA? RPAREN
- switch (rule.Alt_case()) {
- case TRule_table_hint::kAltTableHint1: {
- const auto& alt = rule.GetAlt_table_hint1();
- const TString id = Id(alt.GetRule_an_id_hint1(), *this);
- const auto idLower = to_lower(id);
- if (idLower == "schema" || idLower == "columns") {
- Error() << "Expected type after " << to_upper(id);
- return false;
- }
- TVector<TNodePtr> hint_val;
- if (alt.HasBlock2()) {
- auto& tags = alt.GetBlock2().GetBlock2();
- switch (tags.Alt_case()) {
- case TRule_table_hint_TAlt1_TBlock2_TBlock2::kAlt1:
- hint_val.push_back(TypeNameTag(tags.GetAlt1().GetRule_type_name_tag1()));
- break;
- case TRule_table_hint_TAlt1_TBlock2_TBlock2::kAlt2: {
- hint_val.push_back(TypeNameTag(tags.GetAlt2().GetRule_type_name_tag2()));
- for (auto& tag : tags.GetAlt2().GetBlock3()) {
- hint_val.push_back(TypeNameTag(tag.GetRule_type_name_tag2()));
- }
- break;
- }
- case TRule_table_hint_TAlt1_TBlock2_TBlock2::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- hints[id] = hint_val;
- break;
- }
- case TRule_table_hint::kAltTableHint2: {
- const auto& alt2 = rule.GetAlt_table_hint2();
- auto node = TypeNodeOrBind(alt2.GetRule_type_name_or_bind3());
- if (!node) {
- return false;
- }
- hints["user_" + to_lower(alt2.GetToken1().GetValue())] = { node };
- break;
- }
- case TRule_table_hint::kAltTableHint3: {
- const auto& alt = rule.GetAlt_table_hint3();
- TVector<TNodePtr> labels;
- TVector<TNodePtr> structTypeItems;
- if (alt.HasBlock4()) {
- bool warn = false;
- auto processItem = [&](const TRule_struct_arg_positional& arg) {
- // struct_arg_positional:
- // type_name_tag type_name_or_bind (NOT? NULL)?
- // | type_name_or_bind AS type_name_tag; //deprecated
- const bool altCurrent = arg.Alt_case() == TRule_struct_arg_positional::kAltStructArgPositional1;
- auto& typeNameOrBind = altCurrent ?
- arg.GetAlt_struct_arg_positional1().GetRule_type_name_or_bind2() :
- arg.GetAlt_struct_arg_positional2().GetRule_type_name_or_bind1();
- auto typeNode = TypeNodeOrBind(typeNameOrBind);
- if (!typeNode) {
- return false;
- }
- auto pos = Ctx.Pos();
- if (!altCurrent && !warn) {
- Ctx.Warning(pos, TIssuesIds::YQL_DEPRECATED_POSITIONAL_SCHEMA)
- << "Deprecated syntax for positional schema: please use 'column type' instead of 'type AS column'";
- warn = true;
- }
- if (altCurrent) {
- bool notNull = arg.GetAlt_struct_arg_positional1().HasBlock3() && arg.GetAlt_struct_arg_positional1().GetBlock3().HasBlock1();
- if (!notNull) {
- typeNode = new TCallNodeImpl(pos, "AsOptionalType", { typeNode });
- }
- }
- auto& typeNameTag = altCurrent ?
- arg.GetAlt_struct_arg_positional1().GetRule_type_name_tag1() :
- arg.GetAlt_struct_arg_positional2().GetRule_type_name_tag3();
- auto tag = TypeNameTag(typeNameTag);
- if (!tag) {
- return false;
- }
- labels.push_back(tag);
- structTypeItems.push_back(BuildTuple(pos, { tag, typeNode }));
- return true;
- };
- if (!processItem(alt.GetBlock4().GetRule_struct_arg_positional1())) {
- return false;
- }
- for (auto& entry : alt.GetBlock4().GetBlock2()) {
- if (!processItem(entry.GetRule_struct_arg_positional2())) {
- return false;
- }
- }
- }
- TPosition pos = Ctx.TokenPosition(alt.GetToken1());
- TNodePtr structType = new TCallNodeImpl(pos, "StructType", structTypeItems);
- bool shouldEmitLabel = provider != YtProviderName || TCiString(keyFunc) == "object";
- if (shouldEmitLabel) {
- auto labelsTuple = BuildTuple(pos, labels);
- hints["user_" + to_lower(alt.GetToken1().GetValue())] = { structType, labelsTuple };
- break;
- } else {
- hints["user_" + to_lower(alt.GetToken1().GetValue())] = { structType };
- break;
- }
- }
- case TRule_table_hint::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return true;
- }
- TMaybe<TTableHints> TSqlTranslation::TableHintsImpl(const TRule_table_hints& node, const TString& provider, const TString& keyFunc) {
- TTableHints hints;
- auto& block = node.GetBlock2();
- bool hasErrors = false;
- switch (block.Alt_case()) {
- case TRule_table_hints::TBlock2::kAlt1: {
- hasErrors = !TableHintImpl(block.GetAlt1().GetRule_table_hint1(), hints, provider, keyFunc);
- break;
- }
- case TRule_table_hints::TBlock2::kAlt2: {
- hasErrors = !TableHintImpl(block.GetAlt2().GetRule_table_hint2(), hints, provider, keyFunc);
- for (const auto& x : block.GetAlt2().GetBlock3()) {
- hasErrors = hasErrors || !TableHintImpl(x.GetRule_table_hint2(), hints, provider, keyFunc);
- }
- break;
- }
- case TRule_table_hints::TBlock2::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- if (hasErrors) {
- return Nothing();
- }
- return hints;
- }
- bool TSqlTranslation::SimpleTableRefImpl(const TRule_simple_table_ref& node, TTableRef& result) {
- // simple_table_ref: simple_table_ref_core table_hints?;
- if (!SimpleTableRefCoreImpl(node.GetRule_simple_table_ref_core1(), result)) {
- return false;
- }
- TTableHints hints = GetContextHints(Context());
- if (node.HasBlock2()) {
- const TString& service = Context().Scoped->CurrService;
- auto tmp = TableHintsImpl(node.GetBlock2().GetRule_table_hints1(), service);
- if (!tmp) {
- Error() << "Failed to parse table hints";
- return false;
- }
- hints = *tmp;
- }
- if (!hints.empty()) {
- result.Options = BuildInputOptions(Context().Pos(), hints);
- }
- return true;
- }
- bool TSqlTranslation::SimpleTableRefCoreImpl(const TRule_simple_table_ref_core& node, TTableRef& result) {
- // simple_table_ref_core: ((cluster_expr DOT)? id_or_at) | AT? bind_parameter;
- TString service = Context().Scoped->CurrService;
- TDeferredAtom cluster = Context().Scoped->CurrCluster;
- switch (node.Alt_case()) {
- case TRule_simple_table_ref_core::AltCase::kAltSimpleTableRefCore1: {
- if (node.GetAlt_simple_table_ref_core1().GetRule_object_ref1().HasBlock1()) {
- if (Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
- Error() << "Cluster should not be used in limited view";
- return false;
- }
- if (!ClusterExpr(node.GetAlt_simple_table_ref_core1().GetRule_object_ref1().GetBlock1().GetRule_cluster_expr1(), false, service, cluster)) {
- return false;
- }
- }
- if (cluster.Empty()) {
- Error() << "No cluster name given and no default cluster is selected";
- return false;
- }
- result = TTableRef(Context().MakeName("table"), service, cluster, nullptr);
- auto tableOrAt = Id(node.GetAlt_simple_table_ref_core1().GetRule_object_ref1().GetRule_id_or_at2(), *this);
- auto tableAndView = TableKeyImpl(tableOrAt, {}, *this);
- result.Keys = BuildTableKey(Context().Pos(), result.Service, result.Cluster,
- TDeferredAtom(Context().Pos(), tableAndView.first), tableAndView.second);
- break;
- }
- case TRule_simple_table_ref_core::AltCase::kAltSimpleTableRefCore2: {
- if (cluster.Empty()) {
- Error() << "No cluster name given and no default cluster is selected";
- return false;
- }
- auto at = node.GetAlt_simple_table_ref_core2().HasBlock1();
- TString bindName;
- if (!NamedNodeImpl(node.GetAlt_simple_table_ref_core2().GetRule_bind_parameter2(), bindName, *this)) {
- return false;
- }
- auto named = GetNamedNode(bindName);
- if (!named) {
- return false;
- }
- TDeferredAtom table;
- MakeTableFromExpression(Context().Pos(), Context(), named, table);
- result = TTableRef(Context().MakeName("table"), service, cluster, nullptr);
- result.Keys = BuildTableKey(Context().Pos(), result.Service, result.Cluster, table, {at ? "@" : ""});
- break;
- }
- case TRule_simple_table_ref_core::AltCase::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return result.Keys != nullptr;
- }
- bool TSqlTranslation::TopicRefImpl(const TRule_topic_ref& node, TTopicRef& result) {
- TString service = Context().Scoped->CurrService;
- TDeferredAtom cluster = Context().Scoped->CurrCluster;
- if (node.HasBlock1()) {
- if (Mode == NSQLTranslation::ESqlMode::LIMITED_VIEW) {
- Error() << "Cluster should not be used in limited view";
- return false;
- }
- if (!ClusterExpr(node.GetBlock1().GetRule_cluster_expr1(), false, service, cluster)) {
- return false;
- }
- }
- if (cluster.Empty()) {
- Error() << "No cluster name given and no default cluster is selected";
- return false;
- }
- result = TTopicRef(Context().MakeName("topic"), cluster, nullptr);
- auto topic = Id(node.GetRule_an_id2(), *this);
- result.Keys = BuildTopicKey(Context().Pos(), result.Cluster, TDeferredAtom(Context().Pos(), topic));
- return true;
- }
- TNodePtr TSqlTranslation::NamedNode(const TRule_named_nodes_stmt& rule, TVector<TSymbolNameWithPos>& names) {
- // named_nodes_stmt: bind_parameter_list EQUALS (expr | subselect_stmt);
- // subselect_stmt: (LPAREN select_stmt RPAREN | select_unparenthesized_stmt);
- if (!BindList(rule.GetRule_bind_parameter_list1(), names)) {
- return {};
- }
- TNodePtr nodeExpr = nullptr;
- switch (rule.GetBlock3().Alt_case()) {
- case TRule_named_nodes_stmt::TBlock3::kAlt1: {
- TSqlExpression expr(Ctx, Mode);
- auto result = expr.Build(rule.GetBlock3().GetAlt1().GetRule_expr1());
- return result;
- }
- case TRule_named_nodes_stmt::TBlock3::kAlt2:{
- const auto& subselect_rule = rule.GetBlock3().GetAlt2().GetRule_subselect_stmt1();
- TSqlSelect expr(Ctx, Mode);
- TPosition pos;
- TSourcePtr source = nullptr;
- switch (subselect_rule.GetBlock1().Alt_case()) {
- case TRule_subselect_stmt::TBlock1::kAlt1:
- source = expr.Build(subselect_rule.GetBlock1().GetAlt1().GetRule_select_stmt2(), pos);
- break;
- case TRule_subselect_stmt::TBlock1::kAlt2:
- source = expr.Build(subselect_rule.GetBlock1().GetAlt2().GetRule_select_unparenthesized_stmt1(), pos);
- break;
- case TRule_subselect_stmt::TBlock1::ALT_NOT_SET:
- AltNotImplemented("subselect_stmt", subselect_rule.GetBlock1());
- Ctx.IncrementMonCounter("sql_errors", "UnknownNamedNode");
- return nullptr;
- }
- if (!source) {
- return {};
- }
- return BuildSourceNode(pos, std::move(source));
- }
- case TRule_named_nodes_stmt::TBlock3::ALT_NOT_SET:
- AltNotImplemented("named_node", rule.GetBlock3());
- Ctx.IncrementMonCounter("sql_errors", "UnknownNamedNode");
- return nullptr;
- }
- }
- bool TSqlTranslation::ImportStatement(const TRule_import_stmt& stmt, TVector<TString>* namesPtr) {
- TVector<TString> modulePath;
- if (!ModulePath(stmt.GetRule_module_path2(), modulePath)) {
- return false;
- }
- TVector<TSymbolNameWithPos> names;
- TVector<TSymbolNameWithPos> aliases;
- if (!NamedBindList(stmt.GetRule_named_bind_parameter_list4(), names, aliases)) {
- return false;
- }
- YQL_ENSURE(names.size() == aliases.size());
- const TString moduleAlias = Ctx.AddImport(std::move(modulePath));
- if (!moduleAlias) {
- return false;
- }
- for (size_t i = 0; i < names.size(); ++i) {
- auto& name = names[i];
- auto& alias = aliases[i];
- auto& var = alias.Name ? alias : name;
- if (IsAnonymousName(var.Name)) {
- Ctx.Error(var.Pos) << "Can not import anonymous name " << var.Name;
- return false;
- }
- auto builder = [&](const TString& realName) {
- YQL_ENSURE(realName == var.Name);
- auto atom = BuildQuotedAtom(name.Pos, name.Name);
- return atom->Y("bind", moduleAlias, atom);
- };
- var.Name = PushNamedNode(var.Pos, var.Name, builder);
- if (namesPtr) {
- namesPtr->push_back(var.Name);
- }
- }
- return true;
- }
- bool TSqlTranslation::SortSpecification(const TRule_sort_specification& node, TVector<TSortSpecificationPtr>& sortSpecs) {
- bool asc = true;
- TSqlExpression expr(Ctx, Mode);
- TColumnRefScope scope(Ctx, EColumnRefState::Allow);
- TNodePtr exprNode = expr.Build(node.GetRule_expr1());
- if (!exprNode) {
- return false;
- }
- if (node.HasBlock2()) {
- const auto& token = node.GetBlock2().GetToken1();
- Token(token);
- auto tokenId = token.GetId();
- if (IS_TOKEN(tokenId, ASC)) {
- Ctx.IncrementMonCounter("sql_features", "OrderByAsc");
- } else if (IS_TOKEN(tokenId, DESC)) {
- asc = false;
- Ctx.IncrementMonCounter("sql_features", "OrderByDesc");
- } else {
- Ctx.IncrementMonCounter("sql_errors", "UnknownOrderBy");
- Error() << "Unsupported direction token: " << token.GetId();
- return false;
- }
- } else {
- Ctx.IncrementMonCounter("sql_features", "OrderByDefault");
- }
- sortSpecs.emplace_back(MakeIntrusive<TSortSpecification>(exprNode, asc));
- return true;
- }
- bool TSqlTranslation::SortSpecificationList(const TRule_sort_specification_list& node, TVector<TSortSpecificationPtr>& sortSpecs) {
- if (!SortSpecification(node.GetRule_sort_specification1(), sortSpecs)) {
- return false;
- }
- for (auto sortSpec: node.GetBlock2()) {
- Token(sortSpec.GetToken1());
- if (!SortSpecification(sortSpec.GetRule_sort_specification2(), sortSpecs)) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::IsDistinctOptSet(const TRule_opt_set_quantifier& node) const {
- TPosition pos;
- return node.HasBlock1() && IS_TOKEN(node.GetBlock1().GetToken1().GetId(), DISTINCT);
- }
- bool TSqlTranslation::IsDistinctOptSet(const TRule_opt_set_quantifier& node, TPosition& distinctPos) const {
- if (node.HasBlock1() && IS_TOKEN(node.GetBlock1().GetToken1().GetId(), DISTINCT)) {
- distinctPos = Ctx.TokenPosition(node.GetBlock1().GetToken1());
- return true;
- }
- return false;
- }
- bool TSqlTranslation::RoleNameClause(const TRule_role_name& node, TDeferredAtom& result, bool allowSystemRoles) {
- // role_name: an_id_or_type | bind_parameter;
- switch (node.Alt_case()) {
- case TRule_role_name::kAltRoleName1:
- {
- TString name = Id(node.GetAlt_role_name1().GetRule_an_id_or_type1(), *this);
- result = TDeferredAtom(Ctx.Pos(), name);
- break;
- }
- case TRule_role_name::kAltRoleName2:
- {
- if (!BindParameterClause(node.GetAlt_role_name2().GetRule_bind_parameter1(), result)) {
- return false;
- }
- break;
- }
- case TRule_role_name::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- if (auto literalName = result.GetLiteral(); literalName && !allowSystemRoles) {
- static const THashSet<TStringBuf> systemRoles = { "current_role", "current_user", "session_user" };
- if (systemRoles.contains(to_lower(*literalName))) {
- Ctx.Error() << "System role " << to_upper(*literalName) << " can not be used here";
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::PasswordParameter(const TRule_password_option& passwordOption, TUserParameters& result) {
- // password_option: ENCRYPTED? PASSWORD expr;
- TSqlExpression expr(Ctx, Mode);
- TNodePtr password = expr.Build(passwordOption.GetRule_expr3());
- if (!password) {
- Error() << "Couldn't parse the password";
- return false;
- }
- result.IsPasswordEncrypted = passwordOption.HasBlock1();
- if (!password->IsNull()) {
- result.Password = MakeAtomFromExpression(Ctx.Pos(), Ctx, password);
- }
- return true;
- }
- bool TSqlTranslation::HashParameter(const TRule_hash_option& hashOption, TUserParameters& result) {
- // hash_option: HASH expr;
- TSqlExpression expr(Ctx, Mode);
- TNodePtr hash = expr.Build(hashOption.GetRule_expr2());
- if (!hash) {
- Error() << "Couldn't parse the hash of password";
- return false;
- }
- if (!hash->IsNull()) {
- result.Hash = MakeAtomFromExpression(Ctx.Pos(), Ctx, hash);
- }
- return true;
- }
- void TSqlTranslation::LoginParameter(const TRule_login_option& loginOption, std::optional<bool>& canLogin) {
- // login_option: LOGIN | NOLOGIN;
- auto token = loginOption.GetToken1().GetId();
- if (IS_TOKEN(token, LOGIN)) {
- canLogin = true;
- } else if (IS_TOKEN(token, NOLOGIN)) {
- canLogin = false;
- } else {
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool TSqlTranslation::UserParameters(const std::vector<TRule_user_option>& optionsList, TUserParameters& result, bool isCreateUser) {
- enum class EUserOption {
- Login,
- Authentication
- };
- std::set<EUserOption> used;
- auto ParseUserOption = [&used, this](const TRule_user_option& option, TUserParameters& result) -> bool {
- // user_option: authentication_option | login_option;
- // authentication_option: password_option | hash_option;
- switch (option.Alt_case()) {
- case TRule_user_option::kAltUserOption1:
- {
- if (used.contains(EUserOption::Authentication)) {
- Error() << "Conflicting or redundant options";
- return false;
- }
- used.insert(EUserOption::Authentication);
- const auto& authenticationOption = option.GetAlt_user_option1().GetRule_authentication_option1();
- switch (authenticationOption.Alt_case()) {
- case TRule_authentication_option::kAltAuthenticationOption1: {
- if (!PasswordParameter(authenticationOption.GetAlt_authentication_option1().GetRule_password_option1(), result)){
- return false;
- }
- break;
- }
- case TRule_authentication_option::kAltAuthenticationOption2: {
- if (!HashParameter(authenticationOption.GetAlt_authentication_option2().GetRule_hash_option1(), result)){
- return false;
- }
- break;
- }
- case TRule_authentication_option::ALT_NOT_SET: {
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- break;
- }
- case TRule_user_option::kAltUserOption2:
- {
- if (used.contains(EUserOption::Login)) {
- Error() << "Conflicting or redundant options";
- return false;
- }
- used.insert(EUserOption::Login);
- LoginParameter(option.GetAlt_user_option2().GetRule_login_option1(), result.CanLogin);
- break;
- }
- case TRule_user_option::ALT_NOT_SET:
- {
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- return true;
- };
- if (isCreateUser) {
- result.CanLogin = true;
- }
- for (const auto& option : optionsList) {
- if (!ParseUserOption(option, result)) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::PermissionNameClause(const TRule_permission_id& node, TDeferredAtom& result) {
- // permission_id:
- // CONNECT
- // | LIST
- // | INSERT
- // | MANAGE
- // | DROP
- // | GRANT
- // | MODIFY (TABLES | ATTRIBUTES)
- // | (UPDATE | ERASE) ROW
- // | (REMOVE | DESCRIBE | ALTER) SCHEMA
- // | SELECT (TABLES | ATTRIBUTES | ROW)?
- // | (USE | FULL) LEGACY?
- // | CREATE (DIRECTORY | TABLE | QUEUE)?
- auto handleOneIdentifier = [&result, this] (const auto& permissionNameKeyword) {
- result = TDeferredAtom(Ctx.Pos(), GetIdentifier(*this, permissionNameKeyword).Name);
- };
- auto handleTwoIdentifiers = [&result, this] (const auto& permissionNameKeyword) {
- const auto& token1 = permissionNameKeyword.GetToken1();
- const auto& token2 = permissionNameKeyword.GetToken2();
- TString identifierName = TIdentifier(TPosition(token1.GetColumn(), token1.GetLine()), Identifier(token1)).Name +
- "_" +
- TIdentifier(TPosition(token2.GetColumn(), token2.GetLine()), Identifier(token2)).Name;
- result = TDeferredAtom(Ctx.Pos(), identifierName);
- };
- auto handleOneOrTwoIdentifiers = [&result, this] (const auto& permissionNameKeyword) {
- TString identifierName = GetIdentifier(*this, permissionNameKeyword).Name;
- if (permissionNameKeyword.HasBlock2()) {
- identifierName += "_" + GetIdentifier(*this, permissionNameKeyword.GetBlock2()).Name;
- }
- result = TDeferredAtom(Ctx.Pos(), identifierName);
- };
- switch (node.GetAltCase()) {
- case TRule_permission_id::kAltPermissionId1:
- {
- // CONNECT
- handleOneIdentifier(node.GetAlt_permission_id1());
- break;
- }
- case TRule_permission_id::kAltPermissionId2:
- {
- // LIST
- handleOneIdentifier(node.GetAlt_permission_id2());
- break;
- }
- case TRule_permission_id::kAltPermissionId3:
- {
- // INSERT
- handleOneIdentifier(node.GetAlt_permission_id3());
- break;
- }
- case TRule_permission_id::kAltPermissionId4:
- {
- // MANAGE
- handleOneIdentifier(node.GetAlt_permission_id4());
- break;
- }
- case TRule_permission_id::kAltPermissionId5:
- {
- // DROP
- handleOneIdentifier(node.GetAlt_permission_id5());
- break;
- }
- case TRule_permission_id::kAltPermissionId6:
- {
- // GRANT
- handleOneIdentifier(node.GetAlt_permission_id6());
- break;
- }
- case TRule_permission_id::kAltPermissionId7:
- {
- // MODIFY (TABLES | ATTRIBUTES)
- handleTwoIdentifiers(node.GetAlt_permission_id7());
- break;
- }
- case TRule_permission_id::kAltPermissionId8:
- {
- // (UPDATE | ERASE) ROW
- handleTwoIdentifiers(node.GetAlt_permission_id8());
- break;
- }
- case TRule_permission_id::kAltPermissionId9:
- {
- // (REMOVE | DESCRIBE | ALTER) SCHEMA
- handleTwoIdentifiers(node.GetAlt_permission_id9());
- break;
- }
- case TRule_permission_id::kAltPermissionId10:
- {
- // SELECT (TABLES | ATTRIBUTES | ROW)?
- handleOneOrTwoIdentifiers(node.GetAlt_permission_id10());
- break;
- }
- case TRule_permission_id::kAltPermissionId11:
- {
- // (USE | FULL) LEGACY?
- handleOneOrTwoIdentifiers(node.GetAlt_permission_id11());
- break;
- }
- case TRule_permission_id::kAltPermissionId12:
- {
- // CREATE (DIRECTORY | TABLE | QUEUE)?
- handleOneOrTwoIdentifiers(node.GetAlt_permission_id12());
- break;
- }
- case TRule_permission_id::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return true;
- }
- bool TSqlTranslation::PermissionNameClause(const TRule_permission_name& node, TDeferredAtom& result) {
- // permission_name: permission_id | STRING_VALUE;
- switch (node.Alt_case()) {
- case TRule_permission_name::kAltPermissionName1:
- {
- return PermissionNameClause(node.GetAlt_permission_name1().GetRule_permission_id1(), result);
- break;
- }
- case TRule_permission_name::kAltPermissionName2:
- {
- const TString stringValue(Ctx.Token(node.GetAlt_permission_name2().GetToken1()));
- auto unescaped = StringContent(Ctx, Ctx.Pos(), stringValue);
- if (!unescaped) {
- return false;
- }
- result = TDeferredAtom(Ctx.Pos(), unescaped->Content);
- break;
- }
- case TRule_permission_name::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return true;
- }
- bool TSqlTranslation::PermissionNameClause(const TRule_permission_name_target& node, TVector<TDeferredAtom>& result, bool withGrantOption) {
- // permission_name_target: permission_name (COMMA permission_name)* COMMA? | ALL PRIVILEGES?;
- switch (node.Alt_case()) {
- case TRule_permission_name_target::kAltPermissionNameTarget1:
- {
- const auto& permissionNameRule = node.GetAlt_permission_name_target1();
- result.emplace_back();
- if (!PermissionNameClause(permissionNameRule.GetRule_permission_name1(), result.back())) {
- return false;
- }
- for (const auto& item : permissionNameRule.GetBlock2()) {
- result.emplace_back();
- if (!PermissionNameClause(item.GetRule_permission_name2(), result.back())) {
- return false;
- }
- }
- break;
- }
- case TRule_permission_name_target::kAltPermissionNameTarget2:
- {
- result.emplace_back(Ctx.Pos(), "all_privileges");
- break;
- }
- case TRule_permission_name_target::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- if (withGrantOption) {
- result.emplace_back(Ctx.Pos(), "grant");
- }
- return true;
- }
- bool TSqlTranslation::StoreStringSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
- YQL_ENSURE(value);
- const TString key = to_lower(id.Name);
- if (result.find(key) != result.end()) {
- Ctx.Error() << to_upper(key) << " duplicate keys";
- return false;
- }
- switch (value->Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue2:
- return StoreString(*value, result[key], Ctx, to_upper(key));
- default:
- Ctx.Error() << to_upper(key) << " value should be a string literal";
- return false;
- }
- return true;
- }
- bool TSqlTranslation::StoreStringSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
- const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
- return StoreStringSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
- }
- bool TSqlTranslation::ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, const TRule_backup_collection_settings& settings) {
- const auto& firstEntry = settings.GetRule_backup_collection_settings_entry1();
- if (!StoreStringSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(), result)) {
- return false;
- }
- for (const auto& block : settings.GetBlock2()) {
- const auto& entry = block.GetRule_backup_collection_settings_entry2();
- if (!StoreStringSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_backup_collection_actions& actions) {
- auto parseAction = [&](auto& actionVariant) {
- switch (actionVariant.Alt_case()) {
- case TRule_alter_backup_collection_action::kAltAlterBackupCollectionAction1: {
- const auto& action = actionVariant.GetAlt_alter_backup_collection_action1().GetRule_alter_table_set_table_setting_compat1();
- if (!StoreStringSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
- return false;
- }
- for (const auto& entry : action.GetBlock4()) {
- if (!StoreStringSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
- return false;
- }
- }
- return true;
- }
- case TRule_alter_backup_collection_action::kAltAlterBackupCollectionAction2: {
- const auto& action = actionVariant.GetAlt_alter_backup_collection_action2().GetRule_alter_table_reset_table_setting1();
- const TString firstKey = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
- toReset.insert(firstKey);
- for (const auto& key : action.GetBlock4()) {
- toReset.insert(to_lower(IdEx(key.GetRule_an_id2(), *this).Name));
- }
- return true;
- }
- case TRule_alter_backup_collection_action::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- };
- const auto& firstAction = actions.GetRule_alter_backup_collection_action1();
- if (!parseAction(firstAction)) {
- return false;
- }
- for (const auto& action : actions.GetBlock2()) {
- if (!parseAction(action.GetRule_alter_backup_collection_action2())) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::ParseBackupCollectionTables(TVector<TDeferredAtom>& result, const TRule_table_list& tables) {
- const auto& firstEntry = tables.GetRule_an_id_table2();
- result.push_back(TDeferredAtom(Ctx.Pos(), Id(firstEntry, *this)));
- for (const auto& block : tables.GetBlock3()) {
- const auto& entry = block.GetRule_an_id_table3();
- result.push_back(TDeferredAtom(Ctx.Pos(), Id(entry, *this)));
- }
- return true;
- }
- bool TSqlTranslation::ParseBackupCollectionEntry(
- bool& addDatabase,
- bool& removeDatabase,
- TVector<TDeferredAtom>& addTables,
- TVector<TDeferredAtom>& removeTables,
- const TRule_alter_backup_collection_entry& entry)
- {
- switch (entry.Alt_case()) {
- case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry1: {
- addDatabase = true;
- return true;
- }
- case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry2: {
- removeDatabase = true;
- return true;
- }
- case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry3: {
- auto table = entry.GetAlt_alter_backup_collection_entry3().GetRule_an_id_table3();
- addTables.push_back(TDeferredAtom(Ctx.Pos(), Id(table, *this)));
- return true;
- }
- case TRule_alter_backup_collection_entry::kAltAlterBackupCollectionEntry4: {
- auto table = entry.GetAlt_alter_backup_collection_entry4().GetRule_an_id_table3();
- removeTables.push_back(TDeferredAtom(Ctx.Pos(), Id(table, *this)));
- return true;
- }
- case TRule_alter_backup_collection_entry::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return true;
- }
- bool TSqlTranslation::ParseBackupCollectionEntries(
- bool& addDatabase,
- bool& removeDatabase,
- TVector<TDeferredAtom>& addTables,
- TVector<TDeferredAtom>& removeTables,
- const TRule_alter_backup_collection_entries& entries)
- {
- const auto& firstEntry = entries.GetRule_alter_backup_collection_entry1();
- if (!ParseBackupCollectionEntry(addDatabase, removeDatabase, addTables, removeTables, firstEntry)) {
- return false;
- }
- for (const auto& block : entries.GetBlock2()) {
- const auto& entry = block.GetRule_alter_backup_collection_entry2();
- if (!ParseBackupCollectionEntry(addDatabase, removeDatabase, addTables, removeTables, entry)) {
- return false;
- }
- }
- return true;
- }
- TString TSqlTranslation::FrameSettingsToString(EFrameSettings settings, bool isUnbounded) {
- TString result;
- switch (settings) {
- case FramePreceding:
- result = "PRECEDING"; break;
- case FrameCurrentRow:
- YQL_ENSURE(!isUnbounded);
- result = "CURRENT ROW"; break;
- case FrameFollowing:
- result = "FOLLOWING"; break;
- default:
- Y_ABORT("Unexpected frame settings");
- }
- return (isUnbounded ? "UNBOUNDED " : "") + result;
- }
- bool CheckFrameBoundLiteral(TContext& ctx, const TFrameBound& bound, TMaybe<i32>& boundValue) {
- boundValue = {};
- auto node = bound.Bound;
- if (node && node->IsLiteral()) {
- auto type = node->GetLiteralType();
- if (type != "Int32") {
- ctx.Error(node->GetPos()) << "Expecting Int32 as frame bound value, but got " << type << " literal";
- return false;
- }
- i32 value = FromString<i32>(node->GetLiteralValue());
- if (value < 0) {
- ctx.Error(node->GetPos()) << "Expecting non-negative value for frame bound, but got " << value;
- return false;
- }
- boundValue = value;
- }
- return true;
- }
- bool TSqlTranslation::IsValidFrameSettings(TContext& ctx, const TFrameSpecification& frameSpec, size_t sortSpecSize) {
- const TFrameBound& begin = *frameSpec.FrameBegin;
- const TFrameBound& end = *frameSpec.FrameEnd;
- YQL_ENSURE(begin.Settings != FrameUndefined);
- YQL_ENSURE(end.Settings != FrameUndefined);
- const bool beginUnbounded = !begin.Bound && begin.Settings != FrameCurrentRow;
- const bool endUnbounded = !end.Bound && end.Settings != FrameCurrentRow;
- if (beginUnbounded && begin.Settings == FrameFollowing) {
- ctx.Error(begin.Pos) << "Frame cannot start from " << FrameSettingsToString(begin.Settings, beginUnbounded);
- return false;
- }
- if (endUnbounded && end.Settings == FramePreceding) {
- ctx.Error(end.Pos) << "Frame cannot end with " << FrameSettingsToString(end.Settings, endUnbounded);
- return false;
- }
- if (begin.Settings > end.Settings) {
- ctx.Error(begin.Pos) << "Frame cannot start from " << FrameSettingsToString(begin.Settings, beginUnbounded)
- << " and end with " << FrameSettingsToString(end.Settings, endUnbounded);
- return false;
- }
- if (frameSpec.FrameType == FrameByRange && sortSpecSize != 1) {
- TStringBuf msg = "RANGE with <offset> PRECEDING/FOLLOWING requires exactly one expression in ORDER BY partition clause";
- if (begin.Bound) {
- ctx.Error(begin.Bound->GetPos()) << msg;
- return false;
- }
- if (end.Bound) {
- ctx.Error(end.Bound->GetPos()) << msg;
- return false;
- }
- }
- TMaybe<i32> beginValue;
- TMaybe<i32> endValue;
- if (frameSpec.FrameType != EFrameType::FrameByRange) {
- if (!CheckFrameBoundLiteral(ctx, begin, beginValue) || !CheckFrameBoundLiteral(ctx, end, endValue)) {
- return false;
- }
- }
- if (beginValue.Defined() && endValue.Defined()) {
- if (begin.Settings == FramePreceding) {
- beginValue = 0 - *beginValue;
- }
- if (end.Settings == FramePreceding) {
- endValue = 0 - *endValue;
- }
- if (*beginValue > *endValue) {
- YQL_ENSURE(begin.Bound);
- ctx.Warning(begin.Bound->GetPos(), TIssuesIds::YQL_EMPTY_WINDOW_FRAME) << "Used frame specification implies empty window frame";
- }
- }
- return true;
- }
- bool TSqlTranslation::FrameBound(const TRule_window_frame_bound& rule, TFrameBoundPtr& bound) {
- // window_frame_bound:
- // CURRENT ROW
- // | (expr | UNBOUNDED) (PRECEDING | FOLLOWING)
- // ;
- bound = new TFrameBound;
- switch (rule.Alt_case()) {
- case TRule_window_frame_bound::kAltWindowFrameBound1:
- bound->Pos = GetPos(rule.GetAlt_window_frame_bound1().GetToken1());
- bound->Settings = FrameCurrentRow;
- break;
- case TRule_window_frame_bound::kAltWindowFrameBound2: {
- auto block = rule.GetAlt_window_frame_bound2().GetBlock1();
- switch (block.Alt_case()) {
- case TRule_window_frame_bound_TAlt2_TBlock1::kAlt1: {
- TSqlExpression boundExpr(Ctx, Mode);
- bound->Bound = boundExpr.Build(block.GetAlt1().GetRule_expr1());
- if (!bound->Bound) {
- return false;
- }
- bound->Pos = bound->Bound->GetPos();
- break;
- }
- case TRule_window_frame_bound_TAlt2_TBlock1::kAlt2:
- bound->Pos = GetPos(block.GetAlt2().GetToken1());
- break;
- case TRule_window_frame_bound_TAlt2_TBlock1::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- const TString settingToken = to_lower(Token(rule.GetAlt_window_frame_bound2().GetToken2()));
- if (settingToken == "preceding") {
- bound->Settings = FramePreceding;
- } else if (settingToken == "following") {
- bound->Settings = FrameFollowing;
- } else {
- Y_ABORT("You should change implementation according to grammar changes");
- }
- break;
- }
- case TRule_window_frame_bound::ALT_NOT_SET:
- Y_ABORT("FrameClause: frame bound not corresond to grammar changes");
- }
- return true;
- }
- bool TSqlTranslation::FrameClause(const TRule_window_frame_clause& rule, TFrameSpecificationPtr& frameSpec, size_t sortSpecSize) {
- // window_frame_clause: window_frame_units window_frame_extent window_frame_exclusion?;
- frameSpec = new TFrameSpecification;
- const TString frameUnitStr = to_lower(Token(rule.GetRule_window_frame_units1().GetToken1()));
- if (frameUnitStr == "rows") {
- frameSpec->FrameType = EFrameType::FrameByRows;
- } else if (frameUnitStr == "range") {
- frameSpec->FrameType = EFrameType::FrameByRange;
- } else {
- YQL_ENSURE(frameUnitStr == "groups");
- frameSpec->FrameType = EFrameType::FrameByGroups;
- }
- auto frameExtent = rule.GetRule_window_frame_extent2();
- // window_frame_extent: window_frame_bound | window_frame_between;
- switch (frameExtent.Alt_case()) {
- case TRule_window_frame_extent::kAltWindowFrameExtent1: {
- auto start = frameExtent.GetAlt_window_frame_extent1().GetRule_window_frame_bound1();
- if (!FrameBound(start, frameSpec->FrameBegin)) {
- return false;
- }
- // frame end is CURRENT ROW
- frameSpec->FrameEnd = new TFrameBound;
- frameSpec->FrameEnd->Pos = frameSpec->FrameBegin->Pos;
- frameSpec->FrameEnd->Settings = FrameCurrentRow;
- break;
- }
- case TRule_window_frame_extent::kAltWindowFrameExtent2: {
- // window_frame_between: BETWEEN window_frame_bound AND window_frame_bound;
- auto between = frameExtent.GetAlt_window_frame_extent2().GetRule_window_frame_between1();
- if (!FrameBound(between.GetRule_window_frame_bound2(), frameSpec->FrameBegin)) {
- return false;
- }
- if (!FrameBound(between.GetRule_window_frame_bound4(), frameSpec->FrameEnd)) {
- return false;
- }
- break;
- }
- case TRule_window_frame_extent::ALT_NOT_SET:
- Y_ABORT("FrameClause: frame extent not correspond to grammar changes");
- }
- YQL_ENSURE(frameSpec->FrameBegin);
- YQL_ENSURE(frameSpec->FrameEnd);
- if (!IsValidFrameSettings(Ctx, *frameSpec, sortSpecSize)) {
- return false;
- }
- if (rule.HasBlock3()) {
- // window_frame_exclusion: EXCLUDE CURRENT ROW | EXCLUDE GROUP | EXCLUDE TIES | EXCLUDE NO OTHERS;
- switch (rule.GetBlock3().GetRule_window_frame_exclusion1().Alt_case()) {
- case TRule_window_frame_exclusion::kAltWindowFrameExclusion1:
- frameSpec->FrameExclusion = FrameExclCurRow;
- break;
- case TRule_window_frame_exclusion::kAltWindowFrameExclusion2:
- frameSpec->FrameExclusion = FrameExclGroup;
- break;
- case TRule_window_frame_exclusion::kAltWindowFrameExclusion3:
- frameSpec->FrameExclusion = FrameExclTies;
- break;
- case TRule_window_frame_exclusion::kAltWindowFrameExclusion4:
- frameSpec->FrameExclusion = FrameExclNone;
- break;
- case TRule_window_frame_exclusion::ALT_NOT_SET:
- Y_ABORT("FrameClause: frame exclusion not correspond to grammar changes");
- }
- }
- if (frameSpec->FrameExclusion != FrameExclNone) {
- Ctx.Error() << "Frame exclusion is not supported yet";
- return false;
- }
- return true;
- }
- TWindowSpecificationPtr TSqlTranslation::WindowSpecification(const TRule_window_specification_details& rule) {
- /*
- window_specification_details:
- existing_window_name?
- window_partition_clause?
- window_order_clause?
- window_frame_clause?
- */
- TWindowSpecificationPtr winSpecPtr = new TWindowSpecification;
- if (rule.HasBlock1()) {
- Ctx.Error() << "Existing window name is not supported in window specification yet!";
- return {};
- }
- if (rule.HasBlock2()) {
- /*
- window_partition_clause: PARTITION COMPACT? BY named_expr_list;
- */
- auto& partitionClause = rule.GetBlock2().GetRule_window_partition_clause1();
- winSpecPtr->IsCompact = partitionClause.HasBlock2();
- if (!winSpecPtr->IsCompact) {
- auto hints = Ctx.PullHintForToken(Ctx.TokenPosition(partitionClause.GetToken1()));
- winSpecPtr->IsCompact = AnyOf(hints, [](const NSQLTranslation::TSQLHint& hint) { return to_lower(hint.Name) == "compact"; });
- }
- TColumnRefScope scope(Ctx, EColumnRefState::Allow);
- if (!NamedExprList(partitionClause.GetRule_named_expr_list4(), winSpecPtr->Partitions)) {
- return {};
- }
- // ignore empty unnamed tuples:
- // "PARTITION BY (), foo(x) as y, (), (z)" is allowed and will work exactly the same as
- // "PARTITION BY foo(x) as y, z"
- auto removed = std::remove_if(winSpecPtr->Partitions.begin(), winSpecPtr->Partitions.end(),
- [](const TNodePtr& partitionNode) {
- return !partitionNode->GetLabel() && !partitionNode->GetColumnName() &&
- partitionNode->GetTupleNode() != nullptr &&
- partitionNode->GetTupleSize() == 0;
- });
- winSpecPtr->Partitions.erase(removed, winSpecPtr->Partitions.end());
- }
- if (rule.HasBlock3()) {
- if (!OrderByClause(rule.GetBlock3().GetRule_window_order_clause1().GetRule_order_by_clause1(), winSpecPtr->OrderBy)) {
- return {};
- }
- }
- const bool ordered = !winSpecPtr->OrderBy.empty();
- if (rule.HasBlock4()) {
- if (!FrameClause(rule.GetBlock4().GetRule_window_frame_clause1(), winSpecPtr->Frame, winSpecPtr->OrderBy.size())) {
- return {};
- }
- } else {
- winSpecPtr->Frame = new TFrameSpecification;
- winSpecPtr->Frame->FrameBegin = new TFrameBound;
- winSpecPtr->Frame->FrameEnd = new TFrameBound;
- winSpecPtr->Frame->FrameBegin->Pos = winSpecPtr->Frame->FrameEnd->Pos = Ctx.Pos();
- winSpecPtr->Frame->FrameExclusion = EFrameExclusions::FrameExclNone;
- winSpecPtr->Frame->FrameBegin->Settings = EFrameSettings::FramePreceding;
- if (Ctx.AnsiCurrentRow) {
- // RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- winSpecPtr->Frame->FrameType = EFrameType::FrameByRange;
- winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameCurrentRow;
- } else if (ordered) {
- // legacy behavior
- // ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- winSpecPtr->Frame->FrameType = EFrameType::FrameByRows;
- winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameCurrentRow;
- } else {
- // ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
- winSpecPtr->Frame->FrameType = EFrameType::FrameByRows;
- winSpecPtr->Frame->FrameEnd->Settings = EFrameSettings::FrameFollowing;
- }
- }
- // Normalize and simplify
- auto replaceCurrentWith = [](TFrameBound& frame, bool preceding, TNodePtr value ) {
- frame.Settings = preceding ? EFrameSettings::FramePreceding : EFrameSettings::FrameFollowing;
- frame.Bound = value;
- };
- const auto frameSpec = winSpecPtr->Frame;
- if (!ordered && frameSpec->FrameType != EFrameType::FrameByRows) {
- // CURRENT ROW -> UNBOUNDED
- if (frameSpec->FrameBegin->Settings == EFrameSettings::FrameCurrentRow) {
- replaceCurrentWith(*frameSpec->FrameBegin, true, nullptr);
- }
- if (frameSpec->FrameEnd->Settings == EFrameSettings::FrameCurrentRow) {
- replaceCurrentWith(*frameSpec->FrameBegin, false, nullptr);
- }
- }
- // RANGE/GROUPS UNBOUNDED -> ROWS UNBOUNDED
- if (frameSpec->FrameBegin->Settings == EFrameSettings::FramePreceding && !frameSpec->FrameBegin->Bound &&
- frameSpec->FrameEnd->Settings == EFrameSettings::FrameFollowing && !frameSpec->FrameEnd->Bound)
- {
- frameSpec->FrameType = EFrameType::FrameByRows;
- }
- if (frameSpec->FrameType != EFrameType::FrameByRange) {
- // replace FrameCurrentRow for ROWS/GROUPS with 0 preceding/following
- // FrameCurrentRow has special meaning ( = first/last peer row)
- if (frameSpec->FrameBegin->Settings == EFrameSettings::FrameCurrentRow) {
- TNodePtr zero = new TLiteralNumberNode<i32>(winSpecPtr->Frame->FrameBegin->Pos, "Int32", "0");
- replaceCurrentWith(*frameSpec->FrameBegin, true, zero);
- }
- if (frameSpec->FrameEnd->Settings == EFrameSettings::FrameCurrentRow) {
- TNodePtr zero = new TLiteralNumberNode<i32>(winSpecPtr->Frame->FrameEnd->Pos, "Int32", "0");
- replaceCurrentWith(*frameSpec->FrameEnd, false, zero);
- }
- }
- return winSpecPtr;
- }
- TNodePtr TSqlTranslation::DoStatement(const TRule_do_stmt& stmt, bool makeLambda, const TVector<TString>& args) {
- switch (stmt.GetBlock2().Alt_case()) {
- case TRule_do_stmt_TBlock2::kAlt1: {
- const auto& callAction = stmt.GetBlock2().GetAlt1().GetRule_call_action1();
- TNodePtr action;
- switch (callAction.GetBlock1().GetAltCase()) {
- case TRule_call_action_TBlock1::kAlt1: {
- TString bindName;
- if (!NamedNodeImpl(callAction.GetBlock1().GetAlt1().GetRule_bind_parameter1(), bindName, *this)) {
- return nullptr;
- }
- action = GetNamedNode(bindName);
- if (!action) {
- return nullptr;
- }
- break;
- }
- case TRule_call_action_TBlock1::kAlt2:
- action = BuildEmptyAction(Ctx.Pos());
- break;
- case TRule_call_action_TBlock1::ALT_NOT_SET:
- Ctx.IncrementMonCounter("sql_errors", "UnknownDoStmt");
- AltNotImplemented("do_stmt", callAction.GetBlock1());
- return nullptr;
- }
- TVector<TNodePtr> values;
- values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "Apply", TNodeFlags::Default));
- values.push_back(action);
- values.push_back(new TAstAtomNodeImpl(Ctx.Pos(), "world", TNodeFlags::Default));
- TSqlExpression sqlExpr(Ctx, Mode);
- if (callAction.HasBlock3() && !ExprList(sqlExpr, values, callAction.GetBlock3().GetRule_expr_list1())) {
- return nullptr;
- }
- TNodePtr apply = new TAstListNodeImpl(Ctx.Pos(), std::move(values));
- if (!makeLambda) {
- return BuildDoCall(Ctx.Pos(), apply);
- }
- TNodePtr params = new TAstListNodeImpl(Ctx.Pos());
- params->Add("world");
- for (const auto& arg : args) {
- params->Add(new TAstAtomNodeImpl(Ctx.Pos(), arg, TNodeFlags::ArbitraryContent));
- }
- return BuildDoCall(Ctx.Pos(), BuildLambda(Ctx.Pos(), params, apply));
- }
- case TRule_do_stmt_TBlock2::kAlt2: {
- const auto& inlineAction = stmt.GetBlock2().GetAlt2().GetRule_inline_action1();
- const auto& body = inlineAction.GetRule_define_action_or_subquery_body2();
- auto saveScoped = Ctx.Scoped;
- Ctx.Scoped = MakeIntrusive<TScopedState>();
- Ctx.AllScopes.push_back(Ctx.Scoped);
- *Ctx.Scoped = *saveScoped;
- Ctx.Scoped->Local = TScopedState::TLocal{};
- Ctx.ScopeLevel++;
- TSqlQuery query(Ctx, Ctx.Settings.Mode, false);
- TBlocks innerBlocks;
- const bool hasValidBody = DefineActionOrSubqueryBody(query, innerBlocks, body);
- auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped, Ctx.SeqMode) : nullptr;
- WarnUnusedNodes();
- Ctx.ScopeLevel--;
- Ctx.Scoped = saveScoped;
- if (!ret) {
- return {};
- }
- TNodePtr blockNode = new TAstListNodeImpl(Ctx.Pos());
- blockNode->Add("block");
- blockNode->Add(blockNode->Q(ret));
- if (!makeLambda) {
- return blockNode;
- }
- TNodePtr params = new TAstListNodeImpl(Ctx.Pos());
- params->Add("world");
- for (const auto& arg : args) {
- params->Add(new TAstAtomNodeImpl(Ctx.Pos(), arg, TNodeFlags::ArbitraryContent));
- }
- return BuildLambda(Ctx.Pos(), params, blockNode);
- }
- case TRule_do_stmt_TBlock2::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool TSqlTranslation::DefineActionOrSubqueryBody(TSqlQuery& query, TBlocks& blocks, const TRule_define_action_or_subquery_body& body) {
- if (body.HasBlock2()) {
- Ctx.PushCurrentBlocks(&blocks);
- Y_DEFER {
- Ctx.PopCurrentBlocks();
- };
- size_t statementNumber = 0;
- if (!query.Statement(blocks, body.GetBlock2().GetRule_sql_stmt_core1(), statementNumber++)) {
- return false;
- }
- for (const auto& nestedStmtItem : body.GetBlock2().GetBlock2()) {
- const auto& nestedStmt = nestedStmtItem.GetRule_sql_stmt_core2();
- if (!query.Statement(blocks, nestedStmt, statementNumber++)) {
- return false;
- }
- }
- }
- return true;
- }
- bool TSqlTranslation::DefineActionOrSubqueryStatement(const TRule_define_action_or_subquery_stmt& stmt, TSymbolNameWithPos& nameAndPos, TNodePtr& lambda) {
- auto kind = Ctx.Token(stmt.GetToken2());
- const bool isSubquery = to_lower(kind) == "subquery";
- if (!isSubquery && Mode == NSQLTranslation::ESqlMode::SUBQUERY) {
- Error() << "Definition of actions is not allowed in the subquery";
- return false;
- }
- TString actionName;
- if (!NamedNodeImpl(stmt.GetRule_bind_parameter3(), actionName, *this)) {
- return false;
- }
- if (IsAnonymousName(actionName)) {
- Error() << "Can not use anonymous name '" << actionName << "' as " << to_upper(kind) << " name";
- return false;
- }
- TPosition actionNamePos = Ctx.Pos();
- TVector<TSymbolNameWithPos> argNames;
- ui32 optionalArgumentsCount = 0;
- if (stmt.HasBlock5() && !ActionOrSubqueryArgs(stmt.GetBlock5().GetRule_action_or_subquery_args1(), argNames, optionalArgumentsCount)) {
- return false;
- }
- auto saveScoped = Ctx.Scoped;
- Ctx.Scoped = MakeIntrusive<TScopedState>();
- Ctx.AllScopes.push_back(Ctx.Scoped);
- *Ctx.Scoped = *saveScoped;
- Ctx.Scoped->Local = TScopedState::TLocal{};
- Ctx.ScopeLevel++;
- for (auto& arg : argNames) {
- arg.Name = PushNamedAtom(arg.Pos, arg.Name);
- }
- auto saveMode = Ctx.Settings.Mode;
- if (isSubquery) {
- Ctx.Settings.Mode = NSQLTranslation::ESqlMode::SUBQUERY;
- }
- TSqlQuery query(Ctx, Ctx.Settings.Mode, false);
- TBlocks innerBlocks;
- const bool hasValidBody = DefineActionOrSubqueryBody(query, innerBlocks, stmt.GetRule_define_action_or_subquery_body8());
- ui32 topLevelSelects = 0;
- bool hasTailOps = false;
- for (auto& block : innerBlocks) {
- if (block->SubqueryAlias()) {
- continue;
- }
- if (block->HasSelectResult()) {
- ++topLevelSelects;
- } else if (topLevelSelects) {
- hasTailOps = true;
- }
- }
- if (isSubquery && (topLevelSelects != 1 || hasTailOps)) {
- Error() << "Strictly one select/process/reduce statement is expected at the end of subquery";
- return false;
- }
- auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped, Ctx.SeqMode) : nullptr;
- WarnUnusedNodes();
- Ctx.Scoped = saveScoped;
- Ctx.ScopeLevel--;
- Ctx.Settings.Mode = saveMode;
- if (!ret) {
- return false;
- }
- TNodePtr blockNode = new TAstListNodeImpl(Ctx.Pos());
- blockNode->Add("block");
- blockNode->Add(blockNode->Q(ret));
- TNodePtr params = new TAstListNodeImpl(Ctx.Pos());
- params->Add("world");
- for (const auto& arg : argNames) {
- params->Add(BuildAtom(arg.Pos, arg.Name));
- }
- lambda = BuildLambda(Ctx.Pos(), params, blockNode);
- if (optionalArgumentsCount > 0) {
- lambda = new TCallNodeImpl(Ctx.Pos(), "WithOptionalArgs", {
- lambda,
- BuildQuotedAtom(Ctx.Pos(), ToString(optionalArgumentsCount), TNodeFlags::Default)
- });
- }
- nameAndPos.Name = actionName;
- nameAndPos.Pos = actionNamePos;
- return true;
- }
- TNodePtr TSqlTranslation::IfStatement(const TRule_if_stmt& stmt) {
- bool isEvaluate = stmt.HasBlock1();
- TSqlExpression expr(Ctx, Mode);
- auto exprNode = expr.Build(stmt.GetRule_expr3());
- if (!exprNode) {
- return {};
- }
- auto thenNode = DoStatement(stmt.GetRule_do_stmt4(), isEvaluate);
- if (!thenNode) {
- return {};
- }
- TNodePtr elseNode;
- if (stmt.HasBlock5()) {
- elseNode = DoStatement(stmt.GetBlock5().GetRule_do_stmt2(), isEvaluate);
- if (!elseNode) {
- return {};
- }
- }
- return BuildWorldIfNode(Ctx.Pos(), exprNode, thenNode, elseNode, isEvaluate);
- }
- TNodePtr TSqlTranslation::ForStatement(const TRule_for_stmt& stmt) {
- bool isEvaluate = stmt.HasBlock1();
- bool isParallel = stmt.HasBlock2();
- TSqlExpression expr(Ctx, Mode);
- TString itemArgName;
- if (!NamedNodeImpl(stmt.GetRule_bind_parameter4(), itemArgName, *this)) {
- return {};
- }
- TPosition itemArgNamePos = Ctx.Pos();
- auto exprNode = expr.Build(stmt.GetRule_expr6());
- if (!exprNode) {
- return{};
- }
- itemArgName = PushNamedAtom(itemArgNamePos, itemArgName);
- if (isParallel) {
- ++Ctx.ParallelModeCount;
- }
- auto bodyNode = DoStatement(stmt.GetRule_do_stmt7(), true, { itemArgName });
- if (isParallel) {
- --Ctx.ParallelModeCount;
- }
- PopNamedNode(itemArgName);
- if (!bodyNode) {
- return{};
- }
- TNodePtr elseNode;
- if (stmt.HasBlock8()) {
- elseNode = DoStatement(stmt.GetBlock8().GetRule_do_stmt2(), true);
- if (!elseNode) {
- return{};
- }
- }
- return BuildWorldForNode(Ctx.Pos(), exprNode, bodyNode, elseNode, isEvaluate, isParallel);
- }
- bool TSqlTranslation::BindParameterClause(const TRule_bind_parameter& node, TDeferredAtom& result) {
- TString paramName;
- if (!NamedNodeImpl(node, paramName, *this)) {
- return false;
- }
- auto named = GetNamedNode(paramName);
- if (!named) {
- return false;
- }
- result = MakeAtomFromExpression(Ctx.Pos(), Ctx, named);
- return true;
- }
- bool TSqlTranslation::ObjectFeatureValueClause(const TRule_object_feature_value& node, TDeferredAtom& result) {
- // object_feature_value: id_or_type | bind_parameter | STRING_VALUE | bool_value;
- switch (node.Alt_case()) {
- case TRule_object_feature_value::kAltObjectFeatureValue1:
- {
- TString name = Id(node.GetAlt_object_feature_value1().GetRule_id_or_type1(), *this);
- result = TDeferredAtom(Ctx.Pos(), name);
- break;
- }
- case TRule_object_feature_value::kAltObjectFeatureValue2:
- {
- if (!BindParameterClause(node.GetAlt_object_feature_value2().GetRule_bind_parameter1(), result)) {
- return false;
- }
- break;
- }
- case TRule_object_feature_value::kAltObjectFeatureValue3:
- {
- auto strValue = StringContent(Ctx, Ctx.Pos(), Ctx.Token(node.GetAlt_object_feature_value3().GetToken1()));
- if (!strValue) {
- Error() << "Cannot parse string correctly: " << Ctx.Token(node.GetAlt_object_feature_value3().GetToken1());
- return false;
- }
- result = TDeferredAtom(Ctx.Pos(), strValue->Content);
- break;
- }
- case TRule_object_feature_value::kAltObjectFeatureValue4:
- {
- TString value = Ctx.Token(node.GetAlt_object_feature_value4().GetRule_bool_value1().GetToken1());
- result = TDeferredAtom(BuildLiteralBool(Ctx.Pos(), FromString<bool>(value)), Ctx);
- break;
- }
- case TRule_object_feature_value::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- return true;
- }
- bool TSqlTranslation::AddObjectFeature(std::map<TString, TDeferredAtom>& result, const TRule_object_feature& feature) {
- if (feature.has_alt_object_feature1()) {
- auto& kv = feature.GetAlt_object_feature1().GetRule_object_feature_kv1();
- const TString& key = Id(kv.GetRule_an_id_or_type1(), *this);
- auto& ruleValue = kv.GetRule_object_feature_value3();
- TDeferredAtom value;
- if (!ObjectFeatureValueClause(ruleValue, value)) {
- return false;
- }
- result[key] = value;
- } else if (feature.has_alt_object_feature2()) {
- result[Id(feature.GetAlt_object_feature2().GetRule_object_feature_flag1().GetRule_an_id_or_type1(), *this)] = TDeferredAtom();
- }
- return true;
- }
- bool TSqlTranslation::ParseObjectFeatures(std::map<TString, TDeferredAtom>& result, const TRule_object_features& features) {
- if (features.has_alt_object_features1()) {
- if (!AddObjectFeature(result, features.alt_object_features1().GetRule_object_feature1())) {
- return false;
- }
- } else if (features.has_alt_object_features2()) {
- if (!AddObjectFeature(result, features.alt_object_features2().GetRule_object_feature2())) {
- return false;
- }
- for (auto&& i : features.alt_object_features2().GetBlock3()) {
- if (!AddObjectFeature(result, i.GetRule_object_feature2())) {
- return false;
- }
- }
- } else {
- return false;
- }
- return true;
- }
- bool TSqlTranslation::StoreDataSourceSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
- YQL_ENSURE(value);
- const TString key = to_lower(id.Name);
- if (result.find(key) != result.end()) {
- Ctx.Error() << to_upper(key) << " duplicate keys";
- return false;
- }
- if (!StoreString(*value, result[key], Ctx, to_upper(key))) {
- return false;
- }
- return true;
- }
- bool TSqlTranslation::StoreDataSourceSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
- const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
- return StoreDataSourceSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
- }
- bool TSqlTranslation::ParseExternalDataSourceSettings(std::map<TString, TDeferredAtom>& result, const TRule_with_table_settings& settingsNode) {
- const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
- if (!StoreDataSourceSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(),
- result)) {
- return false;
- }
- for (auto& block : settingsNode.GetBlock4()) {
- const auto& entry = block.GetRule_table_settings_entry2();
- if (!StoreDataSourceSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
- return false;
- }
- }
- if (result.find("source_type") == result.end()) {
- Ctx.Error() << "SOURCE_TYPE requires key";
- return false;
- }
- if (!ValidateAuthMethod(result)) {
- return false;
- }
- return true;
- }
- bool TSqlTranslation::ParseExternalDataSourceSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_external_data_source_action& alterAction) {
- switch (alterAction.Alt_case()) {
- case TRule_alter_external_data_source_action::kAltAlterExternalDataSourceAction1: {
- const auto& action = alterAction.GetAlt_alter_external_data_source_action1().GetRule_alter_table_set_table_setting_uncompat1();
- if (!StoreDataSourceSettingsEntry(IdEx(action.GetRule_an_id2(), *this), &action.GetRule_table_setting_value3(), result)) {
- return false;
- }
- return true;
- }
- case TRule_alter_external_data_source_action::kAltAlterExternalDataSourceAction2: {
- const auto& action = alterAction.GetAlt_alter_external_data_source_action2().GetRule_alter_table_set_table_setting_compat1();
- if (!StoreDataSourceSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
- return false;
- }
- for (const auto& entry : action.GetBlock4()) {
- if (!StoreDataSourceSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
- return false;
- }
- }
- return true;
- }
- case TRule_alter_external_data_source_action::kAltAlterExternalDataSourceAction3: {
- const auto& action = alterAction.GetAlt_alter_external_data_source_action3().GetRule_alter_table_reset_table_setting1();
- const TString key = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
- toReset.insert(key);
- for (const auto& keys : action.GetBlock4()) {
- const TString key = to_lower(IdEx(keys.GetRule_an_id2(), *this).Name);
- toReset.insert(key);
- }
- return true;
- }
- case TRule_alter_external_data_source_action::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool TSqlTranslation::ValidateAuthMethod(const std::map<TString, TDeferredAtom>& result) {
- const static TSet<TStringBuf> allAuthFields{
- "service_account_id",
- "service_account_secret_name",
- "login",
- "password_secret_name",
- "aws_access_key_id_secret_name",
- "aws_secret_access_key_secret_name",
- "aws_region",
- "token_secret_name"
- };
- const static TMap<TStringBuf, TSet<TStringBuf>> authMethodFields{
- {"NONE", {}},
- {"SERVICE_ACCOUNT", {"service_account_id", "service_account_secret_name"}},
- {"BASIC", {"login", "password_secret_name"}},
- {"AWS", {"aws_access_key_id_secret_name", "aws_secret_access_key_secret_name", "aws_region"}},
- {"MDB_BASIC", {"service_account_id", "service_account_secret_name", "login", "password_secret_name"}},
- {"TOKEN", {"token_secret_name"}}
- };
- auto authMethodIt = result.find("auth_method");
- if (authMethodIt == result.end() || authMethodIt->second.GetLiteral() == nullptr) {
- Ctx.Error() << "AUTH_METHOD requires key";
- return false;
- }
- const auto& authMethod = *authMethodIt->second.GetLiteral();
- auto it = authMethodFields.find(authMethod);
- if (it == authMethodFields.end()) {
- Ctx.Error() << "Unknown AUTH_METHOD = " << authMethod;
- return false;
- }
- const auto& currentAuthFields = it->second;
- for (const auto& authField: allAuthFields) {
- if (currentAuthFields.contains(authField) && !result.contains(TString{authField})) {
- Ctx.Error() << to_upper(TString{authField}) << " requires key";
- return false;
- }
- if (!currentAuthFields.contains(authField) && result.contains(TString{authField})) {
- Ctx.Error() << to_upper(TString{authField}) << " key is not supported for AUTH_METHOD = " << authMethod;
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::ValidateExternalTable(const TCreateTableParameters& params) {
- if (params.TableType != ETableType::ExternalTable) {
- return true;
- }
- if (!params.TableSettings.DataSourcePath) {
- Ctx.Error() << "DATA_SOURCE requires key";
- return false;
- }
- if (!params.TableSettings.Location) {
- Ctx.Error() << "LOCATION requires key";
- return false;
- }
- if (params.PkColumns) {
- Ctx.Error() << "PRIMARY KEY is not supported for external table";
- return false;
- }
- return true;
- }
- bool TSqlTranslation::ParseViewQuery(
- std::map<TString, TDeferredAtom>& features,
- const TRule_select_stmt& query
- ) {
- TString queryText = CollectTokens(query);
- TString contextRecreationQuery;
- {
- const auto& service = Ctx.Scoped->CurrService;
- const auto& cluster = Ctx.Scoped->CurrCluster;
- const auto effectivePathPrefix = Ctx.GetPrefixPath(service, cluster);
- // TO DO: capture all runtime pragmas in a similar fashion.
- if (effectivePathPrefix != Ctx.Settings.PathPrefix) {
- contextRecreationQuery = TStringBuilder() << "PRAGMA TablePathPrefix = \"" << effectivePathPrefix << "\";\n";
- }
- // TO DO: capture other compilation-affecting statements except USE.
- if (cluster.GetLiteral() && *cluster.GetLiteral() != Ctx.Settings.DefaultCluster) {
- contextRecreationQuery = TStringBuilder() << "USE " << *cluster.GetLiteral() << ";\n";
- }
- }
- features["query_text"] = { Ctx.Pos(), contextRecreationQuery + queryText };
- // AST is needed for ready-made validation of CREATE VIEW statement.
- // Query is stored as plain text, not AST.
- const auto viewSelect = BuildViewSelect(query, Ctx, contextRecreationQuery);
- if (!viewSelect) {
- return false;
- }
- features["query_ast"] = {viewSelect, Ctx};
- return true;
- }
- namespace {
- static std::string::size_type GetQueryPosition(const TString& query, const NSQLv1Generated::TToken& token, bool antlr4) {
- if (1 == token.GetLine() && 0 == token.GetColumn()) {
- return 0;
- }
- TPosition pos = {0, 1};
- TTextWalker walker(pos, antlr4);
- std::string::size_type position = 0;
- for (char c : query) {
- walker.Advance(c);
- ++position;
- if (pos.Row == token.GetLine() && pos.Column == token.GetColumn()) {
- return position;
- }
- }
- return std::string::npos;
- }
- static TString GetLambdaText(TTranslation& ctx, TContext& Ctx, const TRule_lambda_or_parameter& lambdaOrParameter) {
- static const TString statementSeparator = ";\n";
- TVector<TString> statements;
- NYql::TIssues issues;
- if (!SplitQueryToStatements(Ctx.Lexers, Ctx.Parsers, Ctx.Query, statements, issues, Ctx.Settings)) {
- return {};
- }
- TStringBuilder result;
- for (const auto id : Ctx.ForAllStatementsParts) {
- result << statements[id] << "\n";
- }
- switch (lambdaOrParameter.Alt_case()) {
- case NSQLv1Generated::TRule_lambda_or_parameter::kAltLambdaOrParameter1: {
- const auto& lambda = lambdaOrParameter.GetAlt_lambda_or_parameter1().GetRule_lambda1();
- auto& beginToken = lambda.GetRule_smart_parenthesis1().GetToken1();
- const NSQLv1Generated::TToken* endToken = nullptr;
- switch (lambda.GetBlock2().GetBlock2().GetAltCase()) {
- case TRule_lambda_TBlock2_TBlock2::AltCase::kAlt1:
- endToken = &lambda.GetBlock2().GetBlock2().GetAlt1().GetToken3();
- break;
- case TRule_lambda_TBlock2_TBlock2::AltCase::kAlt2:
- endToken = &lambda.GetBlock2().GetBlock2().GetAlt2().GetToken3();
- break;
- case TRule_lambda_TBlock2_TBlock2::AltCase::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- auto begin = GetQueryPosition(Ctx.Query, beginToken, Ctx.Settings.Antlr4Parser);
- auto end = GetQueryPosition(Ctx.Query, *endToken, Ctx.Settings.Antlr4Parser);
- if (begin == std::string::npos || end == std::string::npos) {
- return {};
- }
- result << "$__ydb_transfer_lambda = " << Ctx.Query.substr(begin, end - begin + endToken->value().size()) << statementSeparator;
- return result;
- }
- case NSQLv1Generated::TRule_lambda_or_parameter::kAltLambdaOrParameter2: {
- const auto& valueBlock = lambdaOrParameter.GetAlt_lambda_or_parameter2().GetRule_bind_parameter1().GetBlock2();
- const auto id = Id(valueBlock.GetAlt1().GetRule_an_id_or_type1(), ctx);
- result << "$__ydb_transfer_lambda = $" << id << statementSeparator;
- return result;
- }
- case NSQLv1Generated::TRule_lambda_or_parameter::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- }
- bool TSqlTranslation::ParseTransferLambda(
- TString& lambdaText,
- const TRule_lambda_or_parameter& lambdaOrParameter) {
- TSqlExpression expr(Ctx, Ctx.Settings.Mode);
- auto result = expr.Build(lambdaOrParameter);
- if (!result) {
- return false;
- }
- lambdaText = GetLambdaText(*this, Ctx, lambdaOrParameter);
- if (lambdaText.empty()) {
- Ctx.Error() << "Cannot parse lambda correctly";
- }
- return !lambdaText.empty();
- }
- class TReturningListColumns : public INode {
- public:
- TReturningListColumns(TPosition pos)
- : INode(pos)
- {
- }
- void SetStar() {
- ColumnNames.clear();
- Star = true;
- }
- void AddColumn(const NSQLv1Generated::TRule_an_id & rule, TTranslation& ctx) {
- ColumnNames.push_back(NSQLTranslationV1::Id(rule, ctx));
- }
- bool DoInit(TContext& ctx, ISource* source) override {
- Node = Y();
- if (Star) {
- Node->Add(Y("ReturningStar"));
- } else {
- for (auto&& column : ColumnNames) {
- Node->Add(Y("ReturningListItem", Q(column)));
- }
- }
- Node = Q(Y(Q("returning"), Q(Node)));
- return Node->Init(ctx, source);
- }
- TNodePtr DoClone() const override {
- return new TReturningListColumns(GetPos());
- }
- TAstNode* Translate(TContext& ctx) const override {
- return Node->Translate(ctx);
- }
- private:
- TNodePtr Node;
- TVector<TString> ColumnNames;
- bool Star = false;
- };
- TNodePtr TSqlTranslation::ReturningList(const ::NSQLv1Generated::TRule_returning_columns_list& columns) {
- auto result = MakeHolder<TReturningListColumns>(Ctx.Pos());
- if (columns.GetBlock2().Alt_case() == TRule_returning_columns_list_TBlock2::AltCase::kAlt1) {
- result->SetStar();
- } else if (columns.GetBlock2().Alt_case() == TRule_returning_columns_list_TBlock2::AltCase::kAlt2) {
- result->AddColumn(columns.GetBlock2().alt2().GetRule_an_id1(), *this);
- for (auto& block : columns.GetBlock2().alt2().GetBlock2()) {
- result->AddColumn(block.GetRule_an_id2(), *this);
- }
- }
- return result.Release();
- }
- bool TSqlTranslation::StoreResourcePoolSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
- YQL_ENSURE(value);
- const TString key = to_lower(id.Name);
- if (result.find(key) != result.end()) {
- Ctx.Error() << to_upper(key) << " duplicate keys";
- return false;
- }
- switch (value->Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue2:
- return StoreString(*value, result[key], Ctx, to_upper(key));
- case TRule_table_setting_value::kAltTableSettingValue3:
- return StoreInt(*value, result[key], Ctx, to_upper(key));
- default:
- Ctx.Error() << to_upper(key) << " value should be a string literal or integer";
- return false;
- }
- return true;
- }
- bool TSqlTranslation::StoreResourcePoolSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
- const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
- return StoreResourcePoolSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
- }
- bool TSqlTranslation::ParseResourcePoolSettings(std::map<TString, TDeferredAtom>& result, const TRule_with_table_settings& settingsNode) {
- const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
- if (!StoreResourcePoolSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(), result)) {
- return false;
- }
- for (const auto& block : settingsNode.GetBlock4()) {
- const auto& entry = block.GetRule_table_settings_entry2();
- if (!StoreResourcePoolSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::ParseResourcePoolSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_resource_pool_action& alterAction) {
- switch (alterAction.Alt_case()) {
- case TRule_alter_resource_pool_action::kAltAlterResourcePoolAction1: {
- const auto& action = alterAction.GetAlt_alter_resource_pool_action1().GetRule_alter_table_set_table_setting_compat1();
- if (!StoreResourcePoolSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
- return false;
- }
- for (const auto& entry : action.GetBlock4()) {
- if (!StoreResourcePoolSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
- return false;
- }
- }
- return true;
- }
- case TRule_alter_resource_pool_action::kAltAlterResourcePoolAction2: {
- const auto& action = alterAction.GetAlt_alter_resource_pool_action2().GetRule_alter_table_reset_table_setting1();
- const TString firstKey = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
- toReset.insert(firstKey);
- for (const auto& key : action.GetBlock4()) {
- toReset.insert(to_lower(IdEx(key.GetRule_an_id2(), *this).Name));
- }
- return true;
- }
- case TRule_alter_resource_pool_action::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- bool TSqlTranslation::StoreResourcePoolClassifierSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
- YQL_ENSURE(value);
- const TString key = to_lower(id.Name);
- if (result.find(key) != result.end()) {
- Ctx.Error() << to_upper(key) << " duplicate keys";
- return false;
- }
- switch (value->Alt_case()) {
- case TRule_table_setting_value::kAltTableSettingValue2:
- return StoreString(*value, result[key], Ctx, to_upper(key));
- case TRule_table_setting_value::kAltTableSettingValue3:
- return StoreInt(*value, result[key], Ctx, to_upper(key));
- default:
- Ctx.Error() << to_upper(key) << " value should be a string literal or integer";
- return false;
- }
- return true;
- }
- bool TSqlTranslation::StoreResourcePoolClassifierSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
- const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
- return StoreResourcePoolClassifierSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
- }
- bool TSqlTranslation::ParseResourcePoolClassifierSettings(std::map<TString, TDeferredAtom>& result, const TRule_with_table_settings& settingsNode) {
- const auto& firstEntry = settingsNode.GetRule_table_settings_entry3();
- if (!StoreResourcePoolClassifierSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(), result)) {
- return false;
- }
- for (const auto& block : settingsNode.GetBlock4()) {
- const auto& entry = block.GetRule_table_settings_entry2();
- if (!StoreResourcePoolClassifierSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
- return false;
- }
- }
- return true;
- }
- bool TSqlTranslation::ParseResourcePoolClassifierSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_resource_pool_classifier_action& alterAction) {
- switch (alterAction.Alt_case()) {
- case TRule_alter_resource_pool_classifier_action::kAltAlterResourcePoolClassifierAction1: {
- const auto& action = alterAction.GetAlt_alter_resource_pool_classifier_action1().GetRule_alter_table_set_table_setting_compat1();
- if (!StoreResourcePoolClassifierSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
- return false;
- }
- for (const auto& entry : action.GetBlock4()) {
- if (!StoreResourcePoolClassifierSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
- return false;
- }
- }
- return true;
- }
- case TRule_alter_resource_pool_classifier_action::kAltAlterResourcePoolClassifierAction2: {
- const auto& action = alterAction.GetAlt_alter_resource_pool_classifier_action2().GetRule_alter_table_reset_table_setting1();
- const TString firstKey = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
- toReset.insert(firstKey);
- for (const auto& key : action.GetBlock4()) {
- toReset.insert(to_lower(IdEx(key.GetRule_an_id2(), *this).Name));
- }
- return true;
- }
- case TRule_alter_resource_pool_classifier_action::ALT_NOT_SET:
- Y_ABORT("You should change implementation according to grammar changes");
- }
- }
- } // namespace NSQLTranslationV1
|