sql_translation.cpp 209 KB

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