123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918 |
- #include "node.h"
- #include "context.h"
- #include "list_builtin.h"
- #include "match_recognize.h"
- #include <yql/essentials/ast/yql_type_string.h>
- #include <yql/essentials/public/udf/udf_data_type.h>
- #include <yql/essentials/core/sql_types/simple_types.h>
- #include <yql/essentials/minikql/mkql_program_builder.h>
- #include <yql/essentials/minikql/mkql_type_ops.h>
- #include <yql/essentials/public/issue/yql_issue_id.h>
- #include <yql/essentials/parser/pg_catalog/catalog.h>
- #include <library/cpp/charset/ci_string.h>
- #include <library/cpp/yson/node/node_io.h>
- #include <util/string/builder.h>
- #include <util/string/cast.h>
- #include <util/string/util.h>
- #include <util/string/join.h>
- #include <util/system/env.h>
- #include <unordered_map>
- using namespace NYql;
- namespace NSQLTranslationV1 {
- extern const char SubqueryExtendFor[] = "SubqueryExtendFor";
- extern const char SubqueryUnionAllFor[] = "SubqueryUnionAllFor";
- extern const char SubqueryMergeFor[] = "SubqueryMergeFor";
- extern const char SubqueryUnionMergeFor[] = "SubqueryUnionMergeFor";
- extern const char SubqueryOrderBy[] = "SubqueryOrderBy";
- extern const char SubqueryAssumeOrderBy[] = "SubqueryAssumeOrderBy";
- TNodePtr MakeTypeConfig(const TPosition& pos, const TString& ns, const TVector<TNodePtr>& udfArgs) {
- if (ns == "clickhouse") {
- auto settings = NYT::TNode::CreateMap();
- auto args = NYT::TNode::CreateMap();
- for (ui32 i = 0; i < udfArgs.size(); ++i) {
- if (!udfArgs[i]->IsNull() && udfArgs[i]->IsLiteral()) {
- args[ToString(i)] = NYT::TNode()
- ("type", udfArgs[i]->GetLiteralType())
- ("value", udfArgs[i]->GetLiteralValue());
- }
- }
- settings["args"] = args;
- return (TDeferredAtom(pos, NYT::NodeToYsonString(settings))).Build();
- }
- return nullptr;
- }
- void AdjustCheckedAggFuncName(TString& aggNormalizedName, TContext& ctx) {
- if (!ctx.Scoped->PragmaCheckedOps) {
- return;
- }
- if (aggNormalizedName == "sum") {
- aggNormalizedName = "checked_sum";
- } else if (aggNormalizedName == "sumif") {
- aggNormalizedName = "checked_sumif";
- }
- }
- class TGroupingNode final: public TAstListNode {
- public:
- TGroupingNode(TPosition pos, const TVector<TNodePtr>& args)
- : TAstListNode(pos)
- , Args(args)
- {}
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!src) {
- ctx.Error(Pos) << "Grouping function should have source";
- return false;
- }
- TVector<TString> columns;
- columns.reserve(Args.size());
- const bool isJoin = src->GetJoin();
- ISource* composite = src->GetCompositeSource();
- for (const auto& node: Args) {
- auto namePtr = node->GetColumnName();
- if (!namePtr || !*namePtr) {
- ctx.Error(Pos) << "GROUPING function should use columns as arguments";
- return false;
- }
- TString column = *namePtr;
- if (isJoin) {
- auto sourceNamePtr = node->GetSourceName();
- if (sourceNamePtr && !sourceNamePtr->empty()) {
- column = DotJoin(*sourceNamePtr, column);
- }
- }
- if (!src->IsGroupByColumn(column) && !src->IsAlias(EExprSeat::GroupBy, *namePtr) && (!composite || !composite->IsGroupByColumn(column))) {
- ctx.Error(node->GetPos()) << "Column '" << column << "' is not a grouping column";
- return false;
- }
- columns.emplace_back(column);
- }
- TString groupingColumn;
- if (!src->AddGrouping(ctx, columns, groupingColumn)) {
- return false;
- }
- Nodes.push_back(BuildAtom(Pos, "Member"));
- Nodes.push_back(BuildAtom(Pos, "row"));
- Nodes.push_back(BuildQuotedAtom(Pos, groupingColumn));
- return TAstListNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TGroupingNode(Pos, CloneContainer(Args));
- }
- private:
- const TVector<TNodePtr> Args;
- };
- class TBasicAggrFunc final: public TAstListNode {
- public:
- TBasicAggrFunc(TPosition pos, const TString& name, TAggregationPtr aggr, const TVector<TNodePtr>& args)
- : TAstListNode(pos)
- , Name(name)
- , Aggr(aggr)
- , Args(args)
- {}
- TCiString GetName() const {
- return Name;
- }
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!src) {
- ctx.Error(Pos) << "Unable to use aggregation function '" << Name << "' without data source";
- return false;
- }
- if (!DoInitAggregation(ctx, src)) {
- return false;
- }
- return TAstListNode::DoInit(ctx, src);
- }
- void CollectPreaggregateExprs(TContext& ctx, ISource& src, TVector<INode::TPtr>& exprs) override {
- if (Args.empty() || (Aggr->GetAggregationMode() != EAggregateMode::Distinct && Aggr->GetAggregationMode() != EAggregateMode::OverWindowDistinct)) {
- return;
- }
- auto& expr = Args.front();
- // need to initialize expr before checking whether it is a column
- auto clone = expr->Clone();
- if (!clone->Init(ctx, &src)) {
- return;
- }
- const auto column = clone->GetColumnName();
- if (column) {
- return;
- }
- auto tmpColumn = src.MakeLocalName("_yql_preagg_" + Name);
- YQL_ENSURE(!expr->GetLabel());
- expr->SetLabel(tmpColumn);
- PreaggregateExpr = expr;
- exprs.push_back(PreaggregateExpr);
- expr = BuildColumn(expr->GetPos(), tmpColumn);
- Aggr->MarkKeyColumnAsGenerated();
- }
- TNodePtr DoClone() const final {
- TAggregationPtr aggrClone = static_cast<IAggregation*>(Aggr->Clone().Release());
- return new TBasicAggrFunc(Pos, Name, aggrClone, CloneContainer(Args));
- }
- TAggregationPtr GetAggregation() const override {
- return Aggr;
- }
- private:
- bool DoInitAggregation(TContext& ctx, ISource* src) {
- if (PreaggregateExpr) {
- YQL_ENSURE(PreaggregateExpr->HasState(ENodeState::Initialized));
- if (PreaggregateExpr->IsAggregated() && !PreaggregateExpr->IsAggregationKey() && !Aggr->IsOverWindow()) {
- ctx.Error(Aggr->GetPos()) << "Aggregation of aggregated values is forbidden";
- return false;
- }
- }
- if (!Aggr->InitAggr(ctx, false, src, *this, Args)) {
- return false;
- }
- return src->AddAggregation(ctx, Aggr);
- }
- void DoUpdateState() const final {
- State.Set(ENodeState::Const, !Args.empty() && AllOf(Args, [](const auto& arg){ return arg->IsConstant(); }));
- State.Set(ENodeState::Aggregated);
- }
- TNodePtr PreaggregateExpr;
- protected:
- const TString Name;
- TAggregationPtr Aggr;
- TVector<TNodePtr> Args;
- };
- class TBasicAggrFactory final : public TAstListNode {
- public:
- TBasicAggrFactory(TPosition pos, const TString& name, TAggregationPtr aggr, const TVector<TNodePtr>& args)
- : TAstListNode(pos)
- , Name(name)
- , Aggr(aggr)
- , Args(args)
- {}
- TCiString GetName() const {
- return Name;
- }
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!DoInitAggregation(ctx)) {
- return false;
- }
- auto factory = Aggr->AggregationTraitsFactory();
- auto apply = Y("Apply", factory, Y("ListType", "type"));
- auto columnIndices = Aggr->GetFactoryColumnIndices();
- if (columnIndices.size() == 1) {
- apply = L(apply, "extractor");
- } else {
- // make several extractors from main that returns a tuple
- for (ui32 arg = 0; arg < columnIndices.size(); ++arg) {
- auto partial = BuildLambda(Pos, Y("row"), Y("Nth", Y("Apply", "extractor", "row"), Q(ToString(columnIndices[arg]))));
- apply = L(apply, partial);
- }
- }
- Aggr->AddFactoryArguments(apply);
- Lambda = BuildLambda(Pos, Y("type", "extractor"), apply);
- return TAstListNode::DoInit(ctx, src);
- }
- TAstNode* Translate(TContext& ctx) const override {
- return Lambda->Translate(ctx);
- }
- TNodePtr DoClone() const final {
- TAggregationPtr aggrClone = static_cast<IAggregation*>(Aggr->Clone().Release());
- return new TBasicAggrFactory(Pos, Name, aggrClone, CloneContainer(Args));
- }
- TAggregationPtr GetAggregation() const override {
- return Aggr;
- }
- private:
- bool DoInitAggregation(TContext& ctx) {
- return Aggr->InitAggr(ctx, true, nullptr, *this, Args);
- }
- protected:
- const TString Name;
- TAggregationPtr Aggr;
- TVector<TNodePtr> Args;
- TNodePtr Lambda;
- };
- typedef THolder<TBasicAggrFunc> TAggrFuncPtr;
- class TLiteralStringAtom: public INode {
- public:
- TLiteralStringAtom(TPosition pos, TNodePtr node, const TString& info, const TString& prefix = {})
- : INode(pos)
- , Node(node)
- , Info(info)
- , Prefix(prefix)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- Y_UNUSED(src);
- if (!Node) {
- ctx.Error(Pos) << Info;
- return false;
- }
- if (!Node->Init(ctx, src)) {
- return false;
- }
- Atom = MakeAtomFromExpression(Pos, ctx, Node, Prefix).Build();
- return true;
- }
- bool IsLiteral() const override {
- return Atom ? Atom->IsLiteral() : false;
- }
- TString GetLiteralType() const override {
- return Atom ? Atom->GetLiteralType() : "";
- }
- TString GetLiteralValue() const override {
- return Atom ? Atom->GetLiteralValue() : "";
- }
- TAstNode* Translate(TContext& ctx) const override {
- return Atom->Translate(ctx);
- }
- TPtr DoClone() const final {
- return new TLiteralStringAtom(GetPos(), SafeClone(Node), Info, Prefix);
- }
- void DoUpdateState() const override {
- YQL_ENSURE(Atom);
- State.Set(ENodeState::Const, Atom->IsConstant());
- State.Set(ENodeState::Aggregated, Atom->IsAggregated());
- State.Set(ENodeState::OverWindow, Atom->IsOverWindow());
- }
- private:
- TNodePtr Node;
- TNodePtr Atom;
- TString Info;
- TString Prefix;
- };
- class TYqlAsAtom: public TLiteralStringAtom {
- public:
- TYqlAsAtom(TPosition pos, const TVector<TNodePtr>& args)
- : TLiteralStringAtom(pos, args.size() == 1 ? args[0] : nullptr, "Literal string is required as argument")
- {
- }
- };
- class TYqlData: public TCallNode {
- public:
- TYqlData(TPosition pos, const TString& type, const TVector<TNodePtr>& args)
- : TCallNode(pos, type, 1, 1, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- auto slot = NUdf::FindDataSlot(GetOpName());
- if (!slot) {
- ctx.Error(Pos) << "Unexpected type " << GetOpName();
- return false;
- }
- if (*slot == NUdf::EDataSlot::Decimal) {
- MinArgs = MaxArgs = 3;
- }
- if (!ValidateArguments(ctx)) {
- return false;
- }
- auto stringNode = Args[0];
- auto atom = stringNode->GetLiteral("String");
- if (!atom) {
- ctx.Error(Pos) << "Expected literal string as argument in " << GetOpName() << " function";
- return false;
- }
- TString value;
- if (*slot == NUdf::EDataSlot::Decimal) {
- const auto precision = Args[1]->GetLiteral("Int32");
- const auto scale = Args[2]->GetLiteral("Int32");
- if (!NKikimr::NMiniKQL::IsValidDecimal(*atom)) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
- ui8 stub;
- if (!(precision && TryFromString<ui8>(*precision, stub))) {
- ctx.Error(Pos) << "Invalid precision " << (precision ? precision->Quote() : "") << " for type " << GetOpName();
- return false;
- }
- if (!(scale && TryFromString<ui8>(*scale, stub))) {
- ctx.Error(Pos) << "Invalid scale " << (scale ? scale->Quote() : "") << " for type " << GetOpName();
- return false;
- }
- Args[0] = BuildQuotedAtom(GetPos(), *atom);
- Args[1] = BuildQuotedAtom(GetPos(), *precision);
- Args[2] = BuildQuotedAtom(GetPos(), *scale);
- return TCallNode::DoInit(ctx, src);
- } else if (NUdf::GetDataTypeInfo(*slot).Features & (NUdf::DateType | NUdf::TzDateType | NUdf::TimeIntervalType)) {
- const auto out = NKikimr::NMiniKQL::ValueFromString(*slot, *atom);
- if (!out) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
- switch (*slot) {
- case NUdf::EDataSlot::Date:
- case NUdf::EDataSlot::TzDate:
- value = ToString(out.Get<ui16>());
- break;
- case NUdf::EDataSlot::Date32:
- case NUdf::EDataSlot::TzDate32:
- value = ToString(out.Get<i32>());
- break;
- case NUdf::EDataSlot::Datetime:
- case NUdf::EDataSlot::TzDatetime:
- value = ToString(out.Get<ui32>());
- break;
- case NUdf::EDataSlot::Timestamp:
- case NUdf::EDataSlot::TzTimestamp:
- value = ToString(out.Get<ui64>());
- break;
- case NUdf::EDataSlot::Datetime64:
- case NUdf::EDataSlot::Timestamp64:
- case NUdf::EDataSlot::TzDatetime64:
- case NUdf::EDataSlot::TzTimestamp64:
- value = ToString(out.Get<i64>());
- break;
- case NUdf::EDataSlot::Interval:
- case NUdf::EDataSlot::Interval64:
- value = ToString(out.Get<i64>());
- if ('T' == atom->back()) {
- ctx.Error(Pos) << "Time prefix 'T' at end of interval constant. The designator 'T' shall be absent if all of the time components are absent.";
- return false;
- }
- break;
- default:
- Y_ABORT("Unexpected data slot");
- }
- if (NUdf::GetDataTypeInfo(*slot).Features & NUdf::TzDateType) {
- value += ",";
- value += NKikimr::NMiniKQL::GetTimezoneIANAName(out.GetTimezoneId());
- }
- } else if (NUdf::EDataSlot::Uuid == *slot) {
- char out[0x10];
- if (!NKikimr::NMiniKQL::ParseUuid(*atom, out)) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
- value.assign(out, sizeof(out));
- } else {
- if (!NKikimr::NMiniKQL::IsValidStringValue(*slot, *atom)) {
- ctx.Error(Pos) << "Invalid value " << atom->Quote() << " for type " << GetOpName();
- return false;
- }
- value = *atom;
- }
- Args[0] = BuildQuotedAtom(GetPos(), value);
- return TCallNode::DoInit(ctx, src);
- }
- TPtr DoClone() const final {
- return new TYqlData(GetPos(), OpName, CloneContainer(Args));
- }
- };
- class TTableName : public TCallNode {
- public:
- TTableName(TPosition pos, const TVector<TNodePtr>& args, const TString& service)
- : TCallNode(pos, "TableName", 0, 2, args)
- , Service(service)
- , EmptyArgs(args.empty())
- {
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (Args.empty()) {
- if (!src) {
- ctx.Error(Pos) << "Unable to use TableName() without source";
- return false;
- }
- // TODO: TablePath() and TableRecordIndex() have more strict limitations
- if (src->GetJoin()) {
- ctx.Warning(Pos,
- TIssuesIds::YQL_EMPTY_TABLENAME_RESULT) << "TableName() may produce empty result when used in ambiguous context (with JOIN)";
- }
- if (src->HasAggregations()) {
- ctx.Warning(Pos,
- TIssuesIds::YQL_EMPTY_TABLENAME_RESULT) << "TableName() will produce empty result when used with aggregation.\n"
- "Please consult documentation for possible workaround";
- }
- Args.push_back(Y("TablePath", Y("DependsOn", "row")));
- }
- if (Args.size() == 2) {
- auto literal = Args[1]->GetLiteral("String");
- if (!literal) {
- ctx.Error(Args[1]->GetPos()) << "Expected literal string as second argument in TableName function";
- return false;
- }
- Args[1] = BuildQuotedAtom(Args[1]->GetPos(), *literal);
- } else {
- if (Service.empty()) {
- ctx.Error(GetPos()) << GetOpName() << " requires either service name as second argument or current cluster name";
- return false;
- }
- Args.push_back(BuildQuotedAtom(GetPos(), Service));
- }
- return TCallNode::DoInit(ctx, src);
- }
- TPtr DoClone() const final {
- return new TTableName(GetPos(), CloneContainer(Args), Service);
- }
- void DoUpdateState() const override {
- if (EmptyArgs) {
- State.Set(ENodeState::Const, false);
- } else {
- TCallNode::DoUpdateState();
- }
- }
- private:
- TString Service;
- const bool EmptyArgs;
- };
- class TYqlParseType final : public INode {
- public:
- TYqlParseType(TPosition pos, const TVector<TNodePtr>& args)
- : INode(pos)
- , Args(args)
- {}
- TAstNode* Translate(TContext& ctx) const override {
- if (Args.size() != 1) {
- ctx.Error(Pos) << "Expected 1 argument in ParseType function";
- return nullptr;
- }
- auto literal = Args[0]->GetLiteral("String");
- if (!literal) {
- ctx.Error(Args[0]->GetPos()) << "Expected literal string as argument in ParseType function";
- return nullptr;
- }
- auto parsed = ParseType(*literal, *ctx.Pool, ctx.Issues, Args[0]->GetPos());
- if (!parsed) {
- ctx.Error(Args[0]->GetPos()) << "Failed to parse type";
- return nullptr;
- }
- return parsed;
- }
- TNodePtr DoClone() const final {
- return new TYqlParseType(Pos, CloneContainer(Args));
- }
- void DoUpdateState() const final {
- State.Set(ENodeState::Const);
- }
- private:
- TVector<TNodePtr> Args;
- };
- class TYqlAddTimezone: public TCallNode {
- public:
- TYqlAddTimezone(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "AddTimezone", 2, 2, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- Args[1] = Y("TimezoneId", Args[1]);
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlAddTimezone(Pos, CloneContainer(Args));
- }
- };
- class TYqlPgType: public TCallNode {
- public:
- TYqlPgType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "PgType", 1, 1, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- ui32 oid;
- if (Args[0]->IsIntegerLiteral() && TryFromString<ui32>(Args[0]->GetLiteralValue(), oid)) {
- if (!NPg::HasType(oid)) {
- ctx.Error(Args[0]->GetPos()) << "Unknown pg type oid: " << oid;
- return false;
- } else {
- Args[0] = BuildQuotedAtom(Args[0]->GetPos(), NPg::LookupType(oid).Name);
- }
- } else if (Args[0]->IsLiteral() && Args[0]->GetLiteralType() == "String") {
- if (!NPg::HasType(Args[0]->GetLiteralValue())) {
- ctx.Error(Args[0]->GetPos()) << "Unknown pg type: " << Args[0]->GetLiteralValue();
- return false;
- } else {
- Args[0] = BuildQuotedAtom(Args[0]->GetPos(), Args[0]->GetLiteralValue());
- }
- } else {
- ctx.Error(Args[0]->GetPos()) << "Expecting string literal with pg type name or integer literal with pg type oid";
- return false;
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlPgType(Pos, CloneContainer(Args));
- }
- };
- class TYqlPgConst : public TCallNode {
- public:
- TYqlPgConst(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "PgConst", 2, -1, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[0]->Init(ctx, src)) {
- return false;
- }
- if (Args[0]->IsLiteral()) {
- Args[0] = BuildQuotedAtom(Args[0]->GetPos(), Args[0]->GetLiteralValue());
- } else {
- auto value = MakeAtomFromExpression(Pos, ctx, Args[0]).Build();
- Args[0] = value;
- }
- if (Args.size() > 2) {
- TVector<TNodePtr> typeModArgs;
- typeModArgs.push_back(Args[1]);
- for (ui32 i = 2; i < Args.size(); ++i) {
- if (!Args[i]->IsLiteral()) {
- ctx.Error(Args[i]->GetPos()) << "Expecting literal";
- return false;
- }
- typeModArgs.push_back(BuildQuotedAtom(Args[i]->GetPos(), Args[i]->GetLiteralValue()));
- }
- Args.erase(Args.begin() + 2, Args.end());
- Args.push_back(new TCallNodeImpl(Pos, "PgTypeMod", typeModArgs));
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlPgConst(Pos, CloneContainer(Args));
- }
- };
- class TYqlPgCast : public TCallNode {
- public:
- TYqlPgCast(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "PgCast", 2, -1, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (Args.size() > 2) {
- TVector<TNodePtr> typeModArgs;
- typeModArgs.push_back(Args[1]);
- for (ui32 i = 2; i < Args.size(); ++i) {
- if (!Args[i]->IsLiteral()) {
- ctx.Error(Args[i]->GetPos()) << "Expecting literal";
- return false;
- }
- typeModArgs.push_back(BuildQuotedAtom(Args[i]->GetPos(), Args[i]->GetLiteralValue()));
- }
- Args.erase(Args.begin() + 2, Args.end());
- Args.push_back(new TCallNodeImpl(Pos, "PgTypeMod", typeModArgs));
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlPgCast(Pos, CloneContainer(Args));
- }
- };
- class TYqlPgOp : public TCallNode {
- public:
- TYqlPgOp(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "PgOp", 2, 3, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[0]->Init(ctx, src)) {
- return false;
- }
- if (!Args[0]->IsLiteral() || Args[0]->GetLiteralType() != "String") {
- ctx.Error(Args[0]->GetPos()) << "Expecting string literal as first argument";
- return false;
- }
- Args[0] = BuildQuotedAtom(Args[0]->GetPos(), Args[0]->GetLiteralValue());
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlPgOp(Pos, CloneContainer(Args));
- }
- };
- template <bool RangeFunction>
- class TYqlPgCall : public TCallNode {
- public:
- TYqlPgCall(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "PgCall", 1, -1, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) final {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[0]->Init(ctx, src)) {
- return false;
- }
- if (!Args[0]->IsLiteral() || Args[0]->GetLiteralType() != "String") {
- ctx.Error(Args[0]->GetPos()) << "Expecting string literal as first argument";
- return false;
- }
- Args[0] = BuildQuotedAtom(Args[0]->GetPos(), Args[0]->GetLiteralValue());
- Args.insert(Args.begin() + 1, RangeFunction ? Q(Y(Q(Y(Q("range"))))) : Q(Y()));
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlPgCall<RangeFunction>(Pos, CloneContainer(Args));
- }
- };
- template <const char* Name>
- class TYqlSubqueryFor : public TCallNode {
- public:
- TYqlSubqueryFor(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, Name, 2, 2, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- Args[0] = Y("EvaluateExpr", Args[0]);
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlSubqueryFor<Name>(Pos, CloneContainer(Args));
- }
- };
- template <const char* Name>
- class TYqlSubqueryOrderBy : public TCallNode {
- public:
- TYqlSubqueryOrderBy(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, Name, 2, 2, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- Args[1] = Y("EvaluateExpr", Args[1]);
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlSubqueryOrderBy<Name>(Pos, CloneContainer(Args));
- }
- };
- template <bool Strict>
- class TYqlTypeAssert : public TCallNode {
- public:
- TYqlTypeAssert(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, Strict ? "EnsureType" : "EnsureConvertibleTo", 2, 3, args)
- {
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- if (Args.size() == 3) {
- if (!Args[2]->Init(ctx, src)) {
- return false;
- }
- auto message = MakeAtomFromExpression(Pos, ctx, Args[2]).Build();
- Args[2] = message;
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlTypeAssert<Strict>(Pos, CloneContainer(Args));
- }
- };
- class TFromBytes final : public TCallNode {
- public:
- TFromBytes(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "FromBytes", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Y("FormatType", Args[1])).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TFromBytes(Pos, CloneContainer(Args));
- }
- };
- class TYqlTaggedBase : public TCallNode {
- public:
- TYqlTaggedBase(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- };
- class TYqlAsTagged final : public TYqlTaggedBase {
- public:
- TYqlAsTagged(TPosition pos, const TVector<TNodePtr>& args)
- : TYqlTaggedBase(pos, "AsTagged", args)
- {}
- TNodePtr DoClone() const final {
- return new TYqlAsTagged(Pos, CloneContainer(Args));
- }
- };
- class TYqlUntag final : public TYqlTaggedBase {
- public:
- TYqlUntag(TPosition pos, const TVector<TNodePtr>& args)
- : TYqlTaggedBase(pos, "Untag", args)
- {}
- TNodePtr DoClone() const final {
- return new TYqlUntag(Pos, CloneContainer(Args));
- }
- };
- class TYqlVariant final : public TCallNode {
- public:
- TYqlVariant(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "Variant", 3, 3, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlVariant(Pos, CloneContainer(Args));
- }
- };
- class TYqlEnum final : public TCallNode {
- public:
- TYqlEnum(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "Enum", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[0]->Init(ctx, src)) {
- return false;
- }
- Args[0] = MakeAtomFromExpression(Pos, ctx, Args[0]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlEnum(Pos, CloneContainer(Args));
- }
- };
- class TYqlAsVariant final : public TCallNode {
- public:
- TYqlAsVariant(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "AsVariant", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlAsVariant(Pos, CloneContainer(Args));
- }
- };
- class TYqlAsEnum final : public TCallNode {
- public:
- TYqlAsEnum(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "AsEnum", 1, 1, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[0]->Init(ctx, src)) {
- return false;
- }
- Args[0] = MakeAtomFromExpression(Pos, ctx, Args[0]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlAsEnum(Pos, CloneContainer(Args));
- }
- };
- TNodePtr BuildFileNameArgument(TPosition pos, const TNodePtr& argument, const TString& prefix) {
- return new TLiteralStringAtom(pos, argument, "FilePath requires string literal as parameter", prefix);
- }
- template <typename TDerived, bool IsFile>
- class TYqlAtomBase: public TCallNode {
- public:
- TYqlAtomBase(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 1, 1, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!Args.empty()) {
- Args[0] = BuildFileNameArgument(Pos, Args[0], IsFile ? ctx.Settings.FileAliasPrefix : TString());
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TDerived(Pos, OpName, CloneContainer(Args));
- }
- bool IsLiteral() const override {
- return !Args.empty() ? Args[0]->IsLiteral() : false;
- }
- TString GetLiteralType() const override {
- return !Args.empty() ? Args[0]->GetLiteralType() : "";
- }
- TString GetLiteralValue() const override {
- return !Args.empty() ? Args[0]->GetLiteralValue() : "";
- }
- };
- class TYqlAtom final : public TYqlAtomBase<TYqlAtom, false>
- {
- using TBase = TYqlAtomBase<TYqlAtom, false>;
- using TBase::TBase;
- };
- class TFileYqlAtom final : public TYqlAtomBase<TFileYqlAtom, true>
- {
- using TBase = TYqlAtomBase<TFileYqlAtom, true>;
- using TBase::TBase;
- };
- class TTryMember final: public TCallNode {
- public:
- TTryMember(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 3, 3, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.size() != 3) {
- ctx.Error(Pos) << OpName << " requires exactly three arguments";
- return false;
- }
- for (const auto& arg : Args) {
- if (!arg->Init(ctx, src)) {
- return false;
- }
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TTryMember(Pos, OpName, CloneContainer(Args));
- }
- };
- template<bool Pretty>
- class TFormatTypeDiff final: public TCallNode {
- public:
- TFormatTypeDiff(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 3, 3, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.size() != 2) {
- ctx.Error(Pos) << OpName << " requires exactly 2 arguments";
- return false;
- }
- for (const auto& arg : Args) {
- if (!arg->Init(ctx, src)) {
- return false;
- }
- }
- Args.push_back(Q(Pretty ? "true" : "false"));
- OpName = "FormatTypeDiff";
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TFormatTypeDiff<Pretty>(GetPos(), OpName, CloneContainer(Args));
- }
- };
- class TAddMember final: public TCallNode {
- public:
- TAddMember(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 3, 3, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.size() != 3) {
- ctx.Error(Pos) << OpName << " requires exactly three arguments";
- return false;
- }
- for (const auto& arg : Args) {
- if (!arg->Init(ctx, src)) {
- return false;
- }
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TAddMember(Pos, OpName, CloneContainer(Args));
- }
- };
- class TRemoveMember final: public TCallNode {
- public:
- TRemoveMember(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.size() != 2) {
- ctx.Error(Pos) << OpName << " requires exactly two arguments";
- return false;
- }
- for (const auto& arg : Args) {
- if (!arg->Init(ctx, src)) {
- return false;
- }
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TRemoveMember(Pos, OpName, CloneContainer(Args));
- }
- };
- class TCombineMembers final: public TCallNode {
- public:
- TCombineMembers(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 1, -1, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.empty()) {
- ctx.Error(Pos) << "CombineMembers requires at least one argument";
- return false;
- }
- for (size_t i = 0; i < Args.size(); ++i) {
- Args[i] = Q(Y(Q(""), Args[i])); // flatten without prefix
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TCombineMembers(Pos, OpName, CloneContainer(Args));
- }
- };
- class TFlattenMembers final: public TCallNode {
- public:
- TFlattenMembers(TPosition pos, const TString& opName, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, 1, -1, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.empty()) {
- ctx.Error(Pos) << OpName << " requires at least one argument";
- return false;
- }
- for (size_t i = 0; i < Args.size(); ++i) {
- if (!Args[i]->Init(ctx, src)) {
- return false;
- }
- if (Args[i]->GetTupleSize() == 2) {
- // flatten with prefix
- Args[i] = Q(Y(
- MakeAtomFromExpression(Pos, ctx, Args[i]->GetTupleElement(0)).Build(),
- Args[i]->GetTupleElement(1)
- ));
- } else {
- ctx.Error(Pos) << OpName << " requires arguments to be tuples of size 2: prefix and struct";
- return false;
- }
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TFlattenMembers(Pos, OpName, CloneContainer(Args));
- }
- };
- TString NormalizeTypeString(const TString& str) {
- auto ret = to_title(str);
- if (ret.StartsWith("Tz")) {
- ret = "Tz" + to_title(ret.substr(2));
- }
- if (ret.StartsWith("Json")) {
- ret = "Json" + to_title(ret.substr(4));
- }
- if (ret.StartsWith("Dy")) {
- ret = "Dy" + to_title(ret.substr(2));
- }
- return ret;
- }
- static const TSet<TString> AvailableDataTypes = {"Bool", "String", "Uint32", "Uint64", "Int32", "Int64", "Float", "Double", "Utf8", "Yson", "Json", "JsonDocument",
- "Date", "Datetime", "Timestamp", "Interval", "Uint8", "Int8", "Uint16", "Int16", "TzDate", "TzDatetime", "TzTimestamp", "Uuid", "Decimal", "DyNumber",
- "Date32", "Datetime64", "Timestamp64", "Interval64", "TzDate32", "TzDatetime64", "TzTimestamp64"};
- TNodePtr GetDataTypeStringNode(TContext& ctx, TCallNode& node, unsigned argNum, TString* outTypeStrPtr = nullptr) {
- auto errMsgFunc = [&node, argNum]() {
- static std::array<TString, 2> numToName = {{"first", "second"}};
- TStringBuilder sb;
- sb << "At " << numToName.at(argNum) << " argument of " << node.GetOpName() << " expected type string, available one of: "
- << JoinRange(", ", AvailableDataTypes.begin(), AvailableDataTypes.end()) << ";";
- return TString(sb);
- };
- auto typeStringNode = node.GetArgs().at(argNum);
- auto typeStringPtr = typeStringNode->GetLiteral("String");
- TNodePtr dataTypeNode;
- if (typeStringPtr) {
- TString typeString = NormalizeTypeString(*typeStringPtr);
- if (!AvailableDataTypes.contains(typeString)) {
- ctx.Error(typeStringNode->GetPos()) << "Bad type string: '" << typeString << "'. " << errMsgFunc();
- return {};
- }
- if (outTypeStrPtr) {
- *outTypeStrPtr = typeString;
- }
- dataTypeNode = typeStringNode->Q(typeString);
- } else {
- ctx.Error(typeStringNode->GetPos()) << errMsgFunc();
- return {};
- }
- return dataTypeNode;
- }
- class TYqlParseFileOp final: public TCallNode {
- public:
- TYqlParseFileOp(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "ParseFile", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- auto dataTypeStringNode = GetDataTypeStringNode(ctx, *this, 0);
- if (!dataTypeStringNode) {
- return false;
- }
- auto aliasNode = BuildFileNameArgument(Args[1]->GetPos(), Args[1], ctx.Settings.FileAliasPrefix);
- OpName = "Apply";
- Args[0] = Y("Udf", Q("File.ByLines"), Y("Void"),
- Y("TupleType",
- Y("TupleType", Y("DataType", dataTypeStringNode)),
- Y("StructType"),
- Y("TupleType")));
- Args[1] = Y("FilePath", aliasNode);
- return TCallNode::DoInit(ctx, src);
- }
- TString GetOpName() const override {
- return "ParseFile";
- }
- TNodePtr DoClone() const final {
- return new TYqlParseFileOp(Pos, CloneContainer(Args));
- }
- };
- class TYqlDataType final : public TCallNode {
- public:
- TYqlDataType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "DataType", 1, 3, args)
- {
- FakeSource = BuildFakeSource(pos);
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- for (ui32 i = 0; i < Args.size(); ++i) {
- if (!Args[i]->Init(ctx, FakeSource.Get())) {
- return false;
- }
- Args[i] = MakeAtomFromExpression(Pos, ctx, Args[i]).Build();
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlDataType(Pos, CloneContainer(Args));
- }
- private:
- TSourcePtr FakeSource;
- };
- class TYqlResourceType final : public TCallNode {
- public:
- TYqlResourceType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "ResourceType", 1, 1, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[0]->Init(ctx, src)) {
- return false;
- }
- Args[0] = MakeAtomFromExpression(Pos, ctx, Args[0]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlResourceType(Pos, CloneContainer(Args));
- }
- };
- class TYqlTaggedType final : public TCallNode {
- public:
- TYqlTaggedType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "TaggedType", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlTaggedType(Pos, CloneContainer(Args));
- }
- };
- class TYqlCallableType final : public TCallNode {
- public:
- TYqlCallableType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "CallableType", 2, -1, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[0]->GetTupleNode()) {
- ui32 numOptArgs;
- if (!Parseui32(Args[0], numOptArgs)) {
- ctx.Error(Args[0]->GetPos()) << "Expected either tuple or number of optional arguments";
- return false;
- }
- Args[0] = Q(Y(BuildQuotedAtom(Args[0]->GetPos(), ToString(numOptArgs))));
- }
- if (!Args[1]->GetTupleNode()) {
- Args[1] = Q(Y(Args[1]));
- }
- for (ui32 index = 2; index < Args.size(); ++index) {
- if (!Args[index]->GetTupleNode()) {
- Args[index] = Q(Y(Args[index]));
- }
- }
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlCallableType(Pos, CloneContainer(Args));
- }
- };
- class TYqlTupleElementType final : public TCallNode {
- public:
- TYqlTupleElementType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "TupleElementType", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlTupleElementType(Pos, CloneContainer(Args));
- }
- };
- class TYqlStructMemberType final : public TCallNode {
- public:
- TYqlStructMemberType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "StructMemberType", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[1]->Init(ctx, src)) {
- return false;
- }
- Args[1] = MakeAtomFromExpression(Pos, ctx, Args[1]).Build();
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlStructMemberType(Pos, CloneContainer(Args));
- }
- };
- class TYqlCallableArgumentType final : public TCallNode {
- public:
- TYqlCallableArgumentType(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "CallableArgumentType", 2, 2, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- ui32 index;
- if (!Parseui32(Args[1], index)) {
- ctx.Error(Args[1]->GetPos()) << "Expected index of the callable argument";
- return false;
- }
- Args[1] = BuildQuotedAtom(Args[1]->GetPos(), ToString(index));
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlCallableArgumentType(Pos, CloneContainer(Args));
- }
- };
- class TStructTypeNode : public TAstListNode {
- public:
- TStructTypeNode(TPosition pos, const TVector<TNodePtr>& exprs)
- : TAstListNode(pos)
- , Exprs(exprs)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- Nodes.push_back(BuildAtom(Pos, "StructType", TNodeFlags::Default));
- for (const auto& expr : Exprs) {
- const auto& label = expr->GetLabel();
- if (!label) {
- ctx.Error(expr->GetPos()) << "Structure does not allow anonymous members";
- return false;
- }
- Nodes.push_back(Q(Y(Q(label), expr)));
- }
- return TAstListNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TStructTypeNode(Pos, CloneContainer(Exprs));
- }
- private:
- const TVector<TNodePtr> Exprs;
- };
- template <bool IsStrict>
- class TYqlIf final: public TCallNode {
- public:
- TYqlIf(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, IsStrict ? "IfStrict" : "If", 2, 3, args)
- {}
- private:
- TCallNode::TPtr DoClone() const override {
- return new TYqlIf(GetPos(), CloneContainer(Args));
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- Args[0] = Y("Coalesce", Args[0], Y("Bool", Q("false")));
- if (Args.size() == 2) {
- Args.push_back(Y("Null"));
- }
- return TCallNode::DoInit(ctx, src);
- }
- };
- class TYqlSubstring final: public TCallNode {
- public:
- TYqlSubstring(TPosition pos, const TString& name, const TVector<TNodePtr>& args)
- : TCallNode(pos, name, 2, 3, args)
- {}
- private:
- TCallNode::TPtr DoClone() const override {
- return new TYqlSubstring(GetPos(), OpName, CloneContainer(Args));
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.size() == 2) {
- Args.push_back(Y("Null"));
- }
- return TCallNode::DoInit(ctx, src);
- }
- };
- class TYqlIn final: public TCallNode {
- public:
- TYqlIn(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "IN", 3, 3, args)
- {}
- private:
- TNodePtr DoClone() const final {
- return new TYqlIn(Pos, CloneContainer(Args));
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- auto key = Args[0];
- auto inNode = Args[1];
- auto hints = Args[2];
- const auto pos = inNode->GetPos();
- if (!key->Init(ctx, src)) {
- return false;
- }
- if (!inNode->Init(ctx, inNode->GetSource() ? nullptr : src)) {
- return false;
- }
- if (inNode->GetLiteral("String")) {
- ctx.Error(pos) << "Unable to use IN predicate with string argument, it won't search substring - "
- "expecting tuple, list, dict or single column table source";
- return false;
- }
- if (inNode->GetTupleSize() == 1) {
- auto singleElement = inNode->GetTupleElement(0);
- // TODO: 'IN ((select ...))' is parsed exactly like 'IN (select ...)' instead of a single element tuple
- if (singleElement->GetSource() || singleElement->IsSelect()) {
- TStringBuf parenKind = singleElement->GetSource() ? "" : "external ";
- ctx.Warning(pos,
- TIssuesIds::YQL_CONST_SUBREQUEST_IN_LIST) << "Using subrequest in scalar context after IN, "
- << "perhaps you should remove "
- << parenKind << "parenthesis here";
- }
- }
- TVector<TNodePtr> hintElements;
- for (size_t i = 0; i < hints->GetTupleSize(); ++i) {
- hintElements.push_back(hints->GetTupleElement(i));
- }
- if (inNode->GetSource() || inNode->IsSelect()) {
- hintElements.push_back(BuildHint(pos, "tableSource"));
- }
- if (!ctx.AnsiInForEmptyOrNullableItemsCollections.Defined()) {
- hintElements.push_back(BuildHint(pos, "warnNoAnsi"));
- } else if (*ctx.AnsiInForEmptyOrNullableItemsCollections) {
- hintElements.push_back(BuildHint(pos, "ansi"));
- }
- OpName = "SqlIn";
- MinArgs = MaxArgs = 3;
- Args = {
- inNode->GetSource() ? inNode->GetSource() : inNode,
- key,
- BuildTuple(pos, hintElements)
- };
- return TCallNode::DoInit(ctx, src);
- }
- static TNodePtr BuildHint(TPosition pos, const TString& name) {
- return BuildTuple(pos, { BuildQuotedAtom(pos, name, NYql::TNodeFlags::Default) });
- }
- TString GetOpName() const override {
- return "IN predicate";
- }
- };
- class TYqlUdfBase : public TCallNode {
- public:
- TYqlUdfBase(TPosition pos, const TString& name)
- : TCallNode(pos, "Udf", 1, 1, UdfArgs(pos, name))
- {}
- TYqlUdfBase(TPosition pos, const TString& name, const TVector<TNodePtr>& args, ui32 argsCount = 2)
- : TCallNode(pos, "Udf", argsCount, argsCount, UdfArgs(pos, name, &args))
- {}
- protected:
- TYqlUdfBase(TPosition pos, const TString& opName, ui32 minArgs, ui32 maxArgs, const TVector<TNodePtr>& args)
- : TCallNode(pos, opName, minArgs, maxArgs, args)
- {}
- private:
- static TVector<TNodePtr> UdfArgs(TPosition pos, const TString& name, const TVector<TNodePtr>* args = nullptr) {
- TVector<TNodePtr> res = { BuildQuotedAtom(pos, name) };
- if (args) {
- res.insert(res.end(), args->begin(), args->end());
- }
- return res;
- }
- void DoUpdateState() const override {
- TCallNode::DoUpdateState();
- State.Set(ENodeState::Aggregated, false/*!RunConfig || RunConfig->IsAggregated()*/);
- State.Set(ENodeState::Const, true /* FIXME: To avoid CheckAggregationLevel issue for non-const TypeOf. */);
- }
- private:
- TNodePtr RunConfig;
- };
- class TYqlUdf final : public TYqlUdfBase {
- public:
- TYqlUdf(TPosition pos, const TString& name)
- : TYqlUdfBase(pos, name)
- {}
- TYqlUdf(TPosition pos, const TString& name, const TVector<TNodePtr>& args, ui32 argsCount = 2)
- : TYqlUdfBase(pos, name, args, argsCount)
- {}
- private:
- TYqlUdf(const TYqlUdf& other)
- : TYqlUdfBase(other.GetPos(), "Udf", other.MinArgs, other.MaxArgs, CloneContainer(other.Args))
- {}
- TNodePtr DoClone() const final {
- return new TYqlUdf(*this);
- }
- };
- class TYqlTypeConfigUdf final : public TYqlUdfBase {
- public:
- TYqlTypeConfigUdf(TPosition pos, const TString& name)
- : TYqlUdfBase(pos, name)
- {}
- TYqlTypeConfigUdf(TPosition pos, const TString& name, const TVector<TNodePtr>& args, ui32 argsCount = 2)
- : TYqlUdfBase(pos, name, args, argsCount)
- {}
- private:
- TYqlTypeConfigUdf(const TYqlTypeConfigUdf& other)
- : TYqlUdfBase(other.GetPos(), "Udf", other.MinArgs, other.MaxArgs, CloneContainer(other.Args))
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!ValidateArguments(ctx)) {
- return false;
- }
- if (!Args[3]->Init(ctx, src)) {
- return false;
- }
- Args[3] = MakeAtomFromExpression(Pos, ctx, Args[3]).Build();
- return TYqlUdfBase::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TYqlTypeConfigUdf(*this);
- }
- };
- class TWeakFieldOp final: public TCallNode {
- public:
- TWeakFieldOp(TPosition pos, const TVector<TNodePtr>& args)
- : TCallNode(pos, "WeakField", 2, 3, args)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!src) {
- ctx.Error(Pos) << GetCallExplain() << " unable use without source";
- return false;
- }
- src->AllColumns();
- if (!ValidateArguments(ctx)) {
- return false;
- }
- bool hasError = false;
- for (auto& arg: Args) {
- if (!arg->Init(ctx, src)) {
- hasError = true;
- continue;
- }
- }
- if (hasError) {
- return false;
- }
- PrecacheState();
- const auto memberPos = Args[0]->GetPos();
- TVector<TNodePtr> repackArgs = {BuildAtom(memberPos, "row", NYql::TNodeFlags::Default)};
- if (auto literal = Args[1]->GetLiteral("String")) {
- TString targetType;
- if (!GetDataTypeStringNode(ctx, *this, 1, &targetType)) {
- return false;
- }
- repackArgs.push_back(Args[1]->Q(targetType));
- } else {
- repackArgs.push_back(Args[1]);
- }
- TVector<TNodePtr> column;
- auto namePtr = Args[0]->GetColumnName();
- if (!namePtr || !*namePtr) {
- ctx.Error(Pos) << GetCallExplain() << " expects column name as first argument";
- return false;
- }
- auto memberName = *namePtr;
- column.push_back(Args[0]->Q(*namePtr));
- if (src->GetJoin() && !src->IsJoinKeysInitializing()) {
- const auto sourcePtr = Args[0]->GetSourceName();
- if (!sourcePtr || !*sourcePtr) {
- ctx.Error(Pos) << GetOpName() << " required to have correlation name in case of JOIN for column at first parameter";
- return false;
- }
- column.push_back(Args[0]->Q(*sourcePtr));
- memberName = DotJoin(*sourcePtr, memberName);
- }
- if (!GetLabel()) {
- SetLabel(memberName);
- }
- repackArgs.push_back(BuildTuple(memberPos, column));
- if (Args.size() == 3) {
- repackArgs.push_back(Args[2]);
- }
- ++MinArgs;
- ++MaxArgs;
- Args.swap(repackArgs);
- return TCallNode::DoInit(ctx, src);
- }
- TNodePtr DoClone() const final {
- return new TWeakFieldOp(Pos, CloneContainer(Args));
- }
- };
- template <bool Join>
- class TTableRow final : public INode {
- public:
- TTableRow(TPosition pos, const TVector<TNodePtr>& args)
- : TTableRow(pos, args.size())
- {}
- TTableRow(TPosition pos, ui32 argsCount)
- : INode(pos)
- , ArgsCount(argsCount)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!src || src->IsFake()) {
- ctx.Error(Pos) << TStringBuilder() << (Join ? "Join" : "") << "TableRow requires data source";
- return false;
- }
- if (ArgsCount > 0) {
- ctx.Error(Pos) << "TableRow requires exactly 0 arguments";
- return false;
- }
- src->AllColumns();
- const bool isJoin = src->GetJoin();
- if (!Join && ctx.SimpleColumns && isJoin) {
- TNodePtr block = Y();
- const auto& sameKeyMap = src->GetJoin()->GetSameKeysMap();
- if (sameKeyMap) {
- block = L(block, Y("let", "flatSameKeys", "row"));
- for (const auto& sameKeysPair: sameKeyMap) {
- const auto& column = sameKeysPair.first;
- auto keys = Y("Coalesce");
- auto sameSourceIter = sameKeysPair.second.begin();
- for (auto end = sameKeysPair.second.end(); sameSourceIter != end; ++sameSourceIter) {
- auto addKeyNode = Q(DotJoin(*sameSourceIter, column));
- keys = L(keys, Y("TryMember", "row", addKeyNode, Y("Null")));
- }
- block = L(block, Y("let", "flatSameKeys", Y("AddMember", "flatSameKeys", Q(column), keys)));
- sameSourceIter = sameKeysPair.second.begin();
- for (auto end = sameKeysPair.second.end(); sameSourceIter != end; ++sameSourceIter) {
- auto removeKeyNode = Q(DotJoin(*sameSourceIter, column));
- block = L(block, Y("let", "flatSameKeys", Y("ForceRemoveMember", "flatSameKeys", removeKeyNode)));
- }
- }
- block = L(block, Y("let", "row", "flatSameKeys"));
- }
- auto members = Y();
- for (auto& joinLabel: src->GetJoin()->GetJoinLabels()) {
- members = L(members, BuildQuotedAtom(Pos, joinLabel + "."));
- }
- block = L(block, Y("let", "res", Y("DivePrefixMembers", "row", Q(members))));
- for (const auto& sameKeysPair: src->GetJoin()->GetSameKeysMap()) {
- const auto& column = sameKeysPair.first;
- auto addMemberKeyNode = Y("Member", "row", Q(column));
- block = L(block, Y("let", "res", Y("AddMember", "res", Q(column), addMemberKeyNode)));
- }
- Node = Y("block", Q(L(block, Y("return", "res"))));
- } else {
- Node = ctx.EnableSystemColumns ? Y("RemoveSystemMembers", "row") : BuildAtom(Pos, "row", 0);
- }
- return true;
- }
- TAstNode* Translate(TContext& ctx) const override {
- Y_DEBUG_ABORT_UNLESS(Node);
- return Node->Translate(ctx);
- }
- void DoUpdateState() const override {
- State.Set(ENodeState::Const, false);
- }
- TNodePtr DoClone() const final {
- return new TTableRow<Join>(Pos, ArgsCount);
- }
- bool IsTableRow() const final {
- return true;
- }
- private:
- const size_t ArgsCount;
- TNodePtr Node;
- };
- TTableRows::TTableRows(TPosition pos, const TVector<TNodePtr>& args)
- : TTableRows(pos, args.size())
- {}
- TTableRows::TTableRows(TPosition pos, ui32 argsCount)
- : INode(pos)
- , ArgsCount(argsCount)
- {}
- bool TTableRows::DoInit(TContext& ctx, ISource* /*src*/) {
- if (ArgsCount > 0) {
- ctx.Error(Pos) << "TableRows requires exactly 0 arguments";
- return false;
- }
- Node = ctx.EnableSystemColumns ? Y("RemoveSystemMembers", "inputRowsList") : BuildAtom(Pos, "inputRowsList", 0);
- return true;
- }
- TAstNode* TTableRows::Translate(TContext& ctx) const {
- Y_DEBUG_ABORT_UNLESS(Node);
- return Node->Translate(ctx);
- }
- void TTableRows::DoUpdateState() const {
- State.Set(ENodeState::Const, false);
- }
- TNodePtr TTableRows::DoClone() const {
- return MakeIntrusive<TTableRows>(Pos, ArgsCount);
- }
- TSessionWindow::TSessionWindow(TPosition pos, const TVector<TNodePtr>& args)
- : INode(pos)
- , Args(args)
- , FakeSource(BuildFakeSource(pos))
- , Valid(false)
- {}
- void TSessionWindow::MarkValid() {
- YQL_ENSURE(!HasState(ENodeState::Initialized));
- Valid = true;
- }
- TNodePtr TSessionWindow::BuildTraits(const TString& label) const {
- YQL_ENSURE(HasState(ENodeState::Initialized));
- auto trueNode = Y("Bool", Q("true"));
- if (Args.size() == 2) {
- auto timeExpr = Args[0];
- auto timeoutExpr = Args[1];
- auto coalesceLess = [&](auto first, auto second) {
- // first < second ?? true
- return Y("Coalesce", Y("<", first, second), trueNode);
- };
- auto absDelta = Y("If",
- coalesceLess("prev", "curr"),
- Y("-", "curr", "prev"),
- Y("-", "prev", "curr"));
- auto newSessionPred = Y("And", Y("AggrNotEquals", "curr", "prev"), coalesceLess(timeoutExpr, absDelta));
- auto timeoutLambda = BuildLambda(timeoutExpr->GetPos(), Y("prev", "curr"), newSessionPred);
- auto sortSpec = Y("SortTraits", Y("TypeOf", label), trueNode, BuildLambda(Pos, Y("row"), Y("PersistableRepr", timeExpr)));
- return Y("SessionWindowTraits",
- Y("TypeOf", label),
- sortSpec,
- BuildLambda(Pos, Y("row"), timeExpr),
- timeoutLambda);
- }
- auto orderExpr = Args[0];
- auto initLambda = Args[1];
- auto updateLambda = Args[2];
- auto calculateLambda = Args[3];
- auto sortSpec = Y("SortTraits", Y("TypeOf", label), trueNode, BuildLambda(Pos, Y("row"), Y("PersistableRepr", orderExpr)));
- return Y("SessionWindowTraits",
- Y("TypeOf", label),
- sortSpec,
- initLambda,
- updateLambda,
- calculateLambda);
- }
- bool TSessionWindow::DoInit(TContext& ctx, ISource* src) {
- if (!src || src->IsFake()) {
- ctx.Error(Pos) << "SessionWindow requires data source";
- return false;
- }
- if (!(Args.size() == 2 || Args.size() == 4)) {
- ctx.Error(Pos) << "SessionWindow requires either two or four arguments";
- return false;
- }
- if (!Valid) {
- ctx.Error(Pos) << "SessionWindow can only be used as a top-level GROUP BY / PARTITION BY expression";
- return false;
- }
- if (Args.size() == 2) {
- auto timeExpr = Args[0];
- auto timeoutExpr = Args[1];
- return timeExpr->Init(ctx, src) && timeoutExpr->Init(ctx, FakeSource.Get());
- }
- auto orderExpr = Args[0];
- auto initLambda = Args[1];
- auto updateLambda = Args[2];
- auto calculateLambda = Args[3];
- src->AllColumns();
- return orderExpr->Init(ctx, src) && initLambda->Init(ctx, FakeSource.Get()) &&
- updateLambda->Init(ctx, FakeSource.Get()) && calculateLambda->Init(ctx, FakeSource.Get());
- }
- TAstNode* TSessionWindow::Translate(TContext&) const {
- YQL_ENSURE(false, "Translate is called for SessionWindow");
- return nullptr;
- }
- void TSessionWindow::DoUpdateState() const {
- State.Set(ENodeState::Const, false);
- }
- TNodePtr TSessionWindow::DoClone() const {
- return new TSessionWindow(Pos, CloneContainer(Args));
- }
- TString TSessionWindow::GetOpName() const {
- return "SessionWindow";
- }
- template<bool IsStart>
- class TSessionStart final : public INode {
- public:
- TSessionStart(TPosition pos, const TVector<TNodePtr>& args)
- : INode(pos)
- , ArgsCount(args.size())
- {
- }
- private:
- TSessionStart(TPosition pos, size_t argsCount)
- : INode(pos)
- , ArgsCount(argsCount)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (!src || src->IsFake()) {
- ctx.Error(Pos) << GetOpName() << " requires data source";
- return false;
- }
- if (ArgsCount > 0) {
- ctx.Error(Pos) << GetOpName() << " requires exactly 0 arguments";
- return false;
- }
- auto windowName = src->GetWindowName();
- OverWindow = windowName != nullptr;
- TNodePtr sessionWindow;
- if (windowName) {
- auto spec = src->FindWindowSpecification(ctx, *windowName);
- if (!spec) {
- return false;
- }
- sessionWindow = spec->Session;
- if (!sessionWindow) {
- ctx.Error(Pos) << GetOpName() << " can not be used with window " << *windowName << ": SessionWindow specification is missing in PARTITION BY";
- return false;
- }
- } else {
- sessionWindow = src->GetSessionWindowSpec();
- if (!sessionWindow) {
- TString extra;
- if (src->IsOverWindowSource()) {
- extra = ". Maybe you forgot to add OVER `window_name`?";
- }
- if (src->HasAggregations()) {
- ctx.Error(Pos) << GetOpName() << " can not be used here: SessionWindow specification is missing in GROUP BY" << extra;
- } else {
- ctx.Error(Pos) << GetOpName() << " can not be used without aggregation by SessionWindow" << extra;
- }
- return false;
- }
- if (!IsStart) {
- ctx.Error(Pos) << GetOpName() << " with GROUP BY is not supported yet";
- return false;
- }
- }
- if (sessionWindow->HasState(ENodeState::Failed)) {
- return false;
- }
- YQL_ENSURE(sessionWindow->HasState(ENodeState::Initialized));
- YQL_ENSURE(sessionWindow->GetLabel());
- Node = Y("Member", "row", BuildQuotedAtom(Pos, sessionWindow->GetLabel()));
- if (OverWindow) {
- Node = Y("Member", Node, BuildQuotedAtom(Pos, IsStart ? "start" : "state"));
- }
- return true;
- }
- TAstNode* Translate(TContext& ctx) const override {
- Y_DEBUG_ABORT_UNLESS(Node);
- return Node->Translate(ctx);
- }
- void DoUpdateState() const override {
- State.Set(ENodeState::Const, false);
- if (OverWindow) {
- State.Set(ENodeState::OverWindow, true);
- } else if (IsStart) {
- State.Set(ENodeState::Aggregated, true);
- }
- }
- TNodePtr DoClone() const override {
- return new TSessionStart<IsStart>(Pos, ArgsCount);
- }
- TString GetOpName() const override {
- return IsStart ? "SessionStart" : "SessionState";
- }
- const size_t ArgsCount;
- bool OverWindow = false;
- TNodePtr Node;
- };
- THoppingWindow::THoppingWindow(TPosition pos, const TVector<TNodePtr>& args)
- : INode(pos)
- , Args(args)
- , FakeSource(BuildFakeSource(pos))
- , Valid(false)
- {}
- void THoppingWindow::MarkValid() {
- YQL_ENSURE(!HasState(ENodeState::Initialized));
- Valid = true;
- }
- TNodePtr THoppingWindow::BuildTraits(const TString& label) const {
- YQL_ENSURE(HasState(ENodeState::Initialized));
- return Y(
- "HoppingTraits",
- Y("ListItemType", Y("TypeOf", label)),
- BuildLambda(Pos, Y("row"), Y("Just", Y("SystemMetadata", Y("String", Q("write_time")), Y("DependsOn", "row")))),
- Hop,
- Interval,
- Interval,
- Q("true"),
- Q("v2"));
- }
- bool THoppingWindow::DoInit(TContext& ctx, ISource* src) {
- if (!src || src->IsFake()) {
- ctx.Error(Pos) << "HoppingWindow requires data source";
- return false;
- }
- if (!(Args.size() == 2)) {
- ctx.Error(Pos) << "HoppingWindow requires two arguments";
- return false;
- }
- if (!Valid) {
- ctx.Error(Pos) << "HoppingWindow can only be used as a top-level GROUP BY expression";
- return false;
- }
- auto hopExpr = Args[0];
- auto intervalExpr = Args[1];
- if (!(hopExpr->Init(ctx, FakeSource.Get()) && intervalExpr->Init(ctx, FakeSource.Get()))) {
- return false;
- }
- Hop = ProcessIntervalParam(hopExpr);
- Interval = ProcessIntervalParam(intervalExpr);
- return true;
- }
- TAstNode* THoppingWindow::Translate(TContext&) const {
- YQL_ENSURE(false, "Translate is called for HoppingWindow");
- return nullptr;
- }
- void THoppingWindow::DoUpdateState() const {
- State.Set(ENodeState::Const, false);
- }
- TNodePtr THoppingWindow::DoClone() const {
- return new THoppingWindow(Pos, CloneContainer(Args));
- }
- TString THoppingWindow::GetOpName() const {
- return "HoppingWindow";
- }
- TNodePtr THoppingWindow::ProcessIntervalParam(const TNodePtr& node) const {
- auto literal = node->GetLiteral("String");
- if (!literal) {
- return Y("EvaluateExpr", node);
- }
- return new TYqlData(node->GetPos(), "Interval", {node});
- }
- TNodePtr BuildUdfUserTypeArg(TPosition pos, const TVector<TNodePtr>& args, TNodePtr customUserType) {
- TVector<TNodePtr> argsTypeItems;
- for (auto& arg : args) {
- argsTypeItems.push_back(new TCallNodeImpl(pos, "TypeOf", TVector<TNodePtr>(1, arg)));
- }
- TVector<TNodePtr> userTypeItems;
- userTypeItems.push_back(new TCallNodeImpl(pos, "TupleType", argsTypeItems));
- userTypeItems.push_back(new TCallNodeImpl(pos, "StructType", {}));
- if (customUserType) {
- userTypeItems.push_back(customUserType);
- } else {
- userTypeItems.push_back(new TCallNodeImpl(pos, "TupleType", {}));
- }
- return new TCallNodeImpl(pos, "TupleType", userTypeItems);
- }
- TNodePtr BuildUdfUserTypeArg(TPosition pos, TNodePtr positionalArgs, TNodePtr namedArgs, TNodePtr customUserType) {
- TVector<TNodePtr> userTypeItems;
- userTypeItems.reserve(3);
- userTypeItems.push_back(positionalArgs->Y("TypeOf", positionalArgs));
- userTypeItems.push_back(positionalArgs->Y("TypeOf", namedArgs));
- if (customUserType) {
- userTypeItems.push_back(customUserType);
- } else {
- userTypeItems.push_back(new TCallNodeImpl(pos, "TupleType", {}));
- }
- return new TCallNodeImpl(pos, "TupleType", userTypeItems);
- }
- TVector<TNodePtr> BuildUdfArgs(const TContext& ctx, TPosition pos, const TVector<TNodePtr>& args,
- TNodePtr positionalArgs, TNodePtr namedArgs, TNodePtr customUserType, TNodePtr typeConfig) {
- if (!ctx.Settings.EnableGenericUdfs) {
- return {};
- }
- TVector<TNodePtr> udfArgs;
- udfArgs.push_back(new TAstListNodeImpl(pos));
- udfArgs[0]->Add(new TAstAtomNodeImpl(pos, "Void", 0));
- if (namedArgs) {
- udfArgs.push_back(BuildUdfUserTypeArg(pos, positionalArgs, namedArgs, customUserType));
- } else {
- udfArgs.push_back(BuildUdfUserTypeArg(pos, args, customUserType));
- }
- if (typeConfig) {
- udfArgs.push_back(typeConfig);
- }
- return udfArgs;
- }
- TNodePtr BuildSqlCall(TContext& ctx, TPosition pos, const TString& module, const TString& name, const TVector<TNodePtr>& args,
- TNodePtr positionalArgs, TNodePtr namedArgs, TNodePtr customUserType, const TDeferredAtom& typeConfig, TNodePtr runConfig,
- TNodePtr options)
- {
- const TString fullName = module + "." + name;
- TNodePtr callable;
- if (to_lower(module) == "@yql") {
- callable = BuildCallable(pos, module, name, {});
- } else if (!ctx.Settings.EnableGenericUdfs) {
- auto varName = ctx.AddSimpleUdf(fullName);
- callable = new TAstAtomNodeImpl(pos, varName, TNodeFlags::ArbitraryContent);
- }
- if (callable) {
- TVector<TNodePtr> applyArgs = { callable };
- applyArgs.insert(applyArgs.end(), args.begin(), args.end());
- return new TCallNodeImpl(pos, namedArgs ? "NamedApply" : "Apply", applyArgs);
- }
- TVector<TNodePtr> sqlCallArgs;
- sqlCallArgs.push_back(BuildQuotedAtom(pos, fullName));
- if (namedArgs) {
- auto tupleNodePtr = positionalArgs->GetTupleNode();
- YQL_ENSURE(tupleNodePtr);
- TNodePtr positionalArgsNode = new TCallNodeImpl(pos, "PositionalArgs", tupleNodePtr->Elements());
- sqlCallArgs.push_back(BuildTuple(pos, { positionalArgsNode, namedArgs }));
- } else {
- TNodePtr positionalArgsNode = new TCallNodeImpl(pos, "PositionalArgs", args);
- sqlCallArgs.push_back(BuildTuple(pos, { positionalArgsNode }));
- }
- // optional arguments
- if (customUserType) {
- sqlCallArgs.push_back(customUserType);
- } else if (!typeConfig.Empty() || runConfig || options) {
- sqlCallArgs.push_back(new TCallNodeImpl(pos, "TupleType", {}));
- }
- if (!typeConfig.Empty()) {
- sqlCallArgs.push_back(typeConfig.Build());
- } else if (runConfig || options) {
- sqlCallArgs.push_back(BuildQuotedAtom(pos, ""));
- }
- if (runConfig) {
- sqlCallArgs.push_back(runConfig);
- } else if (options) {
- sqlCallArgs.push_back(new TCallNodeImpl(pos, "Void", {}));
- }
- if (options) {
- sqlCallArgs.push_back(options);
- }
- return new TCallNodeImpl(pos, "SqlCall", sqlCallArgs);
- }
- class TCallableNode final: public INode {
- public:
- TCallableNode(TPosition pos, const TString& module, const TString& name, const TVector<TNodePtr>& args, bool forReduce)
- : INode(pos)
- , Module(module)
- , Name(name)
- , Args(args)
- , ForReduce(forReduce)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Module == "yql") {
- Node = new TFuncNodeImpl(Pos, Name);
- } else if (Module == "@yql") {
- auto parsedName = StringContent(ctx, Pos, Name);
- if (!parsedName) {
- return false;
- }
- const TString yql("(" + parsedName->Content + ")");
- TAstParseResult ast = ParseAst(yql, ctx.Pool.get());
- /// TODO: do not drop warnings
- if (ast.IsOk()) {
- const auto rootCount = ast.Root->GetChildrenCount();
- if (rootCount != 1) {
- ctx.Error(Pos) << "Failed to parse YQL: expecting AST root node with single child, but got " << rootCount;
- return false;
- }
- Node = AstNode(ast.Root->GetChild(0));
- } else {
- ctx.Error(Pos) << "Failed to parse YQL: " << ast.Issues.ToString();
- return false;
- }
- if (src) {
- src->AllColumns();
- }
- } else if (ctx.Settings.ModuleMapping.contains(Module)) {
- Node = Y("bind", Module + "_module", Q(Name));
- if (src) {
- src->AllColumns();
- }
- } else {
- TNodePtr customUserType = nullptr;
- if (Module == "Tensorflow" && Name == "RunBatch") {
- if (Args.size() > 2) {
- auto passThroughAtom = Q("PassThrough");
- auto passThroughType = Y("StructMemberType", Y("ListItemType", Y("TypeOf", Args[1])), passThroughAtom);
- customUserType = Y("AddMemberType", Args[2], passThroughAtom, passThroughType);
- Args.erase(Args.begin() + 2);
- }
- }
- if ("Datetime" == Module || ("Yson" == Module && ctx.PragmaYsonFast))
- Module.append('2');
- TNodePtr typeConfig = MakeTypeConfig(Pos, to_lower(Module), Args);
- if (ForReduce) {
- TVector<TNodePtr> udfArgs;
- udfArgs.push_back(BuildQuotedAtom(Pos, TString(Module) + "." + Name));
- udfArgs.push_back(customUserType ? customUserType : new TCallNodeImpl(Pos, "TupleType", {}));
- if (typeConfig) {
- udfArgs.push_back(typeConfig);
- }
- Node = new TCallNodeImpl(Pos, "SqlReduceUdf", udfArgs);
- } else {
- auto udfArgs = BuildUdfArgs(ctx, Pos, Args, nullptr, nullptr, customUserType, typeConfig);
- Node = BuildUdf(ctx, Pos, Module, Name, udfArgs);
- }
- }
- return Node->Init(ctx, src);
- }
- TAstNode* Translate(TContext& ctx) const override {
- Y_DEBUG_ABORT_UNLESS(Node);
- return Node->Translate(ctx);
- }
- const TString* FuncName() const override {
- return &Name;
- }
- const TString* ModuleName() const override {
- return &Module;
- }
- void DoUpdateState() const override {
- State.Set(ENodeState::Const, Node->IsConstant());
- State.Set(ENodeState::Aggregated, Node->IsAggregated());
- }
- TNodePtr DoClone() const override {
- return new TCallableNode(Pos, Module, Name, CloneContainer(Args), ForReduce);
- }
- void DoVisitChildren(const TVisitFunc& func, TVisitNodeSet& visited) const final {
- Y_DEBUG_ABORT_UNLESS(Node);
- Node->VisitTree(func, visited);
- }
- private:
- TCiString Module;
- TString Name;
- TVector<TNodePtr> Args;
- TNodePtr Node;
- const bool ForReduce;
- };
- TNodePtr BuildCallable(TPosition pos, const TString& module, const TString& name, const TVector<TNodePtr>& args, bool forReduce) {
- return new TCallableNode(pos, module, name, args, forReduce);
- }
- TNodePtr BuildUdf(TContext& ctx, TPosition pos, const TString& module, const TString& name, const TVector<TNodePtr>& args) {
- if (to_lower(module) == "@yql") {
- return BuildCallable(pos, module, name, args);
- }
- auto fullName = module + "." + name;
- if (!args.empty()) {
- return new TYqlUdf(pos, fullName, args, args.size() + 1);
- } else {
- auto varName = ctx.AddSimpleUdf(fullName);
- return new TAstAtomNodeImpl(pos, varName, TNodeFlags::ArbitraryContent);
- }
- }
- class TScriptUdf final: public INode {
- public:
- TScriptUdf(TPosition pos, const TString& moduleName, const TString& funcName, const TVector<TNodePtr>& args,
- TNodePtr options)
- : INode(pos)
- , ModuleName_(moduleName)
- , FuncName_(funcName)
- , Args_(args)
- , Options_(options)
- {}
- bool DoInit(TContext& ctx, ISource* src) override {
- const bool isPython = ModuleName_.find(TStringBuf("Python")) != TString::npos;
- if (!isPython) {
- if (Args_.size() != 2) {
- ctx.Error(Pos) << ModuleName_ << " script declaration requires exactly two parameters";
- return false;
- }
- } else {
- if (Args_.size() < 1 || Args_.size() > 2) {
- ctx.Error(Pos) << ModuleName_ << " script declaration requires one or two parameters";
- return false;
- }
- }
- auto nameAtom = BuildQuotedAtom(Pos, FuncName_);
- auto scriptNode = Args_.back();
- if (!scriptNode->Init(ctx, src)) {
- return false;
- }
- auto scriptStrPtr = Args_.back()->GetLiteral("String");
- if (!ctx.CompactNamedExprs && scriptStrPtr && scriptStrPtr->size() > SQL_MAX_INLINE_SCRIPT_LEN) {
- scriptNode = ctx.UniversalAlias("scriptudf", std::move(scriptNode));
- }
- INode::TPtr type;
- if (Args_.size() == 2) {
- type = Args_[0];
- } else {
- // Python supports getting functions signatures right from docstrings
- type = Y("EvaluateType", Y("ParseTypeHandle", Y("Apply",
- Y("bind", "core_module", Q("PythonFuncSignature")),
- Q(ModuleName_),
- scriptNode,
- Y("String", nameAtom)
- )));
- }
- if (!type->Init(ctx, src)) {
- return false;
- }
- Node_ = Y("ScriptUdf", Q(ModuleName_), nameAtom, type, scriptNode);
- if (Options_) {
- Node_ = L(Node_, Options_);
- }
- return true;
- }
- TAstNode* Translate(TContext& ctx) const override {
- Y_UNUSED(ctx);
- Y_DEBUG_ABORT_UNLESS(Node_);
- return Node_->Translate(ctx);
- }
- void DoUpdateState() const override {
- State.Set(ENodeState::Const, true);
- }
- TNodePtr DoClone() const final {
- return new TScriptUdf(GetPos(), ModuleName_, FuncName_, CloneContainer(Args_), Options_);
- }
- void DoVisitChildren(const TVisitFunc& func, TVisitNodeSet& visited) const final {
- Y_DEBUG_ABORT_UNLESS(Node_);
- Node_->VisitTree(func, visited);
- }
- const TString* FuncName() const final {
- return &FuncName_;
- }
- const TString* ModuleName() const final {
- return &ModuleName_;
- }
- bool IsScript() const final {
- return true;
- }
- size_t GetTupleSize() const final {
- return Args_.size();
- }
- TPtr GetTupleElement(size_t index) const final {
- return Args_[index];
- }
- private:
- TString ModuleName_;
- TString FuncName_;
- TVector<TNodePtr> Args_;
- TNodePtr Node_;
- TNodePtr Options_;
- };
- TNodePtr BuildScriptUdf(TPosition pos, const TString& moduleName, const TString& funcName, const TVector<TNodePtr>& args,
- TNodePtr options) {
- return new TScriptUdf(pos, moduleName, funcName, args, options);
- }
- template <bool Sorted, bool Hashed>
- class TYqlToDict final: public TCallNode {
- public:
- TYqlToDict(TPosition pos, const TString& mode, const TVector<TNodePtr>& args)
- : TCallNode(pos, "ToDict", 4, 4, args)
- , Mode(mode)
- {}
- private:
- TCallNode::TPtr DoClone() const override {
- return new TYqlToDict<Sorted, Hashed>(GetPos(), Mode, CloneContainer(Args));
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- if (Args.size() != 1) {
- ctx.Error(Pos) << "ToDict required exactly one argument";
- return false;
- }
- Args.push_back(BuildLambda(Pos, Y("val"), Y("Nth", "val", Q("0"))));
- Args.push_back(BuildLambda(Pos, Y("val"), Y("Nth", "val", Q("1"))));
- Args.push_back(Q(Y(Q(Sorted ? "Sorted" : Hashed ? "Hashed" : "Auto"), Q(Mode))));
- return TCallNode::DoInit(ctx, src);
- }
- private:
- TString Mode;
- };
- template <bool IsStart>
- class THoppingTime final: public TAstListNode {
- public:
- THoppingTime(TPosition pos, const TVector<TNodePtr>& args = {})
- : TAstListNode(pos)
- {
- Y_UNUSED(args);
- }
- private:
- TNodePtr DoClone() const override {
- return new THoppingTime(GetPos());
- }
- bool DoInit(TContext& ctx, ISource* src) override {
- Y_UNUSED(ctx);
- auto legacySpec = src->GetLegacyHoppingWindowSpec();
- auto spec = src->GetHoppingWindowSpec();
- if (!legacySpec && !spec) {
- ctx.Error(Pos) << "No hopping window parameters in aggregation";
- return false;
- }
- Nodes.clear();
- const auto fieldName = legacySpec
- ? "_yql_time"
- : spec->GetLabel();
- const auto interval = legacySpec
- ? legacySpec->Interval
- : dynamic_cast<THoppingWindow*>(spec.Get())->Interval;
- if (!IsStart) {
- Add("Member", "row", Q(fieldName));
- return true;
- }
- Add("Sub",
- Y("Member", "row", Q(fieldName)),
- interval);
- return true;
- }
- void DoUpdateState() const override {
- State.Set(ENodeState::Aggregated, true);
- }
- };
- class TInvalidBuiltin final: public INode {
- public:
- TInvalidBuiltin(TPosition pos, const TString& info)
- : INode(pos)
- , Info(info)
- {
- }
- bool DoInit(TContext& ctx, ISource*) override {
- ctx.Error(Pos) << Info;
- return false;
- }
- TAstNode* Translate(TContext&) const override {
- return nullptr;
- }
- TPtr DoClone() const override {
- return new TInvalidBuiltin(GetPos(), Info);
- }
- private:
- TString Info;
- };
- enum EAggrFuncTypeCallback {
- NORMAL,
- KEY_PAYLOAD,
- PAYLOAD_PREDICATE,
- TWO_ARGS,
- COUNT,
- HISTOGRAM,
- LINEAR_HISTOGRAM,
- PERCENTILE,
- TOPFREQ,
- TOP,
- TOP_BY,
- COUNT_DISTINCT_ESTIMATE,
- LIST,
- UDAF,
- PG,
- NTH_VALUE
- };
- struct TCoreFuncInfo {
- TString Name;
- ui32 MinArgs;
- ui32 MaxArgs;
- };
- using TAggrFuncFactoryCallback = std::function<INode::TPtr(TPosition pos, const TVector<TNodePtr>& args, EAggregateMode aggMode, bool isFactory)>;
- using TAggrFuncFactoryCallbackMap = std::unordered_map<TString, TAggrFuncFactoryCallback, THash<TString>>;
- using TBuiltinFactoryCallback = std::function<TNodePtr(TPosition pos, const TVector<TNodePtr>& args)>;
- using TBuiltinFactoryCallbackMap = std::unordered_map<TString, TBuiltinFactoryCallback, THash<TString>>;
- using TCoreFuncMap = std::unordered_map<TString, TCoreFuncInfo, THash<TString>>;
- TAggrFuncFactoryCallback BuildAggrFuncFactoryCallback(
- const TString& functionName,
- const TString& factoryName,
- EAggrFuncTypeCallback type = NORMAL,
- const TString& functionNameOverride = TString(),
- const TVector<EAggregateMode>& validModes = {}) {
- const TString realFunctionName = functionNameOverride.empty() ? functionName : functionNameOverride;
- return [functionName, realFunctionName, factoryName, type, validModes] (TPosition pos, const TVector<TNodePtr>& args, EAggregateMode aggMode, bool isFactory) -> INode::TPtr {
- if (!validModes.empty()) {
- if (!IsIn(validModes, aggMode)) {
- TString errorText;
- if (TVector{EAggregateMode::OverWindow} == validModes) {
- errorText = TStringBuilder()
- << "Can't use window function " << functionName << " without window specification (OVER keyword is missing)";
- } else {
- errorText = TStringBuilder()
- << "Can't use " << functionName << " in " << ToString(aggMode) << " aggregation mode";
- }
- return INode::TPtr(new TInvalidBuiltin(pos, errorText));
- }
- }
- TAggregationPtr factory = nullptr;
- switch (type) {
- case NORMAL:
- factory = BuildFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case KEY_PAYLOAD:
- factory = BuildKeyPayloadFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case PAYLOAD_PREDICATE:
- factory = BuildPayloadPredicateFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case TWO_ARGS:
- factory = BuildTwoArgsFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case COUNT:
- factory = BuildCountAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case HISTOGRAM:
- factory = BuildHistogramFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case LINEAR_HISTOGRAM:
- factory = BuildLinearHistogramFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case PERCENTILE:
- factory = BuildPercentileFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case TOPFREQ:
- factory = BuildTopFreqFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case TOP:
- factory = BuildTopFactoryAggregation<false>(pos, realFunctionName, factoryName, aggMode);
- break;
- case TOP_BY:
- factory = BuildTopFactoryAggregation<true>(pos, realFunctionName, factoryName, aggMode);
- break;
- case COUNT_DISTINCT_ESTIMATE:
- factory = BuildCountDistinctEstimateFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case LIST:
- factory = BuildListFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case UDAF:
- factory = BuildUserDefinedFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- case PG:
- factory = BuildPGFactoryAggregation(pos, realFunctionName, aggMode);
- break;
- case NTH_VALUE:
- factory = BuildNthFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
- break;
- }
- if (isFactory) {
- auto realArgs = args;
- realArgs.erase(realArgs.begin()); // skip function name
- return new TBasicAggrFactory(pos, functionName, factory, realArgs);
- } else {
- return new TBasicAggrFunc(pos, functionName, factory, args);
- }
- };
- }
- TAggrFuncFactoryCallback BuildAggrFuncFactoryCallback(
- const TString& functionName,
- const TString& factoryName,
- const TVector<EAggregateMode>& validModes,
- EAggrFuncTypeCallback type = NORMAL,
- const TString& functionNameOverride = TString()) {
- return BuildAggrFuncFactoryCallback(functionName, factoryName, type, functionNameOverride, validModes);
- }
- template<typename TType>
- TBuiltinFactoryCallback BuildSimpleBuiltinFactoryCallback() {
- return [] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
- return new TType(pos, args);
- };
- }
- template<typename TType>
- TBuiltinFactoryCallback BuildNamedBuiltinFactoryCallback(const TString& name) {
- return [name] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
- return new TType(pos, name, args);
- };
- }
- template<typename TType>
- TBuiltinFactoryCallback BuildArgcBuiltinFactoryCallback(i32 minArgs, i32 maxArgs) {
- return [minArgs, maxArgs] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
- return new TType(pos, minArgs, maxArgs, args);
- };
- }
- template<typename TType>
- TBuiltinFactoryCallback BuildNamedArgcBuiltinFactoryCallback(const TString& name, i32 minArgs, i32 maxArgs) {
- return [name, minArgs, maxArgs] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
- return new TType(pos, name, minArgs, maxArgs, args);
- };
- }
- template<typename TType>
- TBuiltinFactoryCallback BuildNamedDepsArgcBuiltinFactoryCallback(ui32 reqArgsCount, const TString& name, i32 minArgs, i32 maxArgs) {
- return [reqArgsCount, name, minArgs, maxArgs](TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
- return new TType(reqArgsCount, pos, name, minArgs, maxArgs, args);
- };
- }
- template<typename TType>
- TBuiltinFactoryCallback BuildBoolBuiltinFactoryCallback(bool arg) {
- return [arg] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
- return new TType(pos, args, arg);
- };
- }
- template<typename TType>
- TBuiltinFactoryCallback BuildFoldBuiltinFactoryCallback(const TString& name, const TString& defaultValue) {
- return [name, defaultValue] (TPosition pos, const TVector<TNodePtr>& args) -> TNodePtr {
- return new TType(pos, name, "Bool", defaultValue, 1, args);
- };
- }
- TNodePtr MakePair(TPosition pos, const TVector<TNodePtr>& args) {
- TNodePtr list = new TAstListNodeImpl(pos, {
- args[0],
- args.size() > 1 ? args[1] : new TAstListNodeImpl(pos,{ new TAstAtomNodeImpl(pos, "Null", TNodeFlags::Default) })
- });
- return new TAstListNodeImpl(pos, {
- new TAstAtomNodeImpl(pos, "quote", TNodeFlags::Default),
- list
- });
- }
- struct TBuiltinFuncData {
- const TBuiltinFactoryCallbackMap BuiltinFuncs;
- const TAggrFuncFactoryCallbackMap AggrFuncs;
- const TCoreFuncMap CoreFuncs;
- TBuiltinFuncData():
- BuiltinFuncs(MakeBuiltinFuncs()),
- AggrFuncs(MakeAggrFuncs()),
- CoreFuncs(MakeCoreFuncs())
- {
- }
- TBuiltinFactoryCallbackMap MakeBuiltinFuncs() {
- TBuiltinFactoryCallbackMap builtinFuncs = {
- // Branching
- {"if", BuildSimpleBuiltinFactoryCallback<TYqlIf<false>>()},
- {"ifstrict", BuildSimpleBuiltinFactoryCallback<TYqlIf<true>>() },
- // String builtins
- {"len", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
- {"length", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
- {"charlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
- {"characterlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Size", 1, 1)},
- {"substring", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("Substring")},
- {"find", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("Find")},
- {"rfind", BuildNamedBuiltinFactoryCallback<TYqlSubstring>("RFind")},
- {"byteat", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ByteAt", 2, 2) },
- {"startswith", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StartsWith", 2, 2)},
- {"endswith", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EndsWith", 2, 2)},
- // Numeric builtins
- {"abs", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Abs", 1, 1) },
- {"tobytes", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ToBytes", 1, 1) },
- {"frombytes", BuildSimpleBuiltinFactoryCallback<TFromBytes>() },
- // Compare builtins
- {"minof", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Min", 1, -1)},
- {"maxof", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Max", 1, -1)},
- {"greatest", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Max", 1, -1)},
- {"least", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Min", 1, -1)},
- {"in", BuildSimpleBuiltinFactoryCallback<TYqlIn>()},
- // List builtins
- {"aslist", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AsListMayWarn", 0, -1)},
- {"asliststrict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AsListStrict", 0, -1) },
- {"listlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Length", 1, 1)},
- {"listhasitems", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("HasItems", 1, 1)},
- {"listextend", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListExtend", 0, -1)},
- {"listextendstrict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListExtendStrict", 0, -1)},
- {"listunionall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListUnionAll", 0, -1) },
- {"listzip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListZip", -1, -1)},
- {"listzipall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListZipAll", -1, -1)},
- {"listenumerate", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListEnumerate", 1, 3)},
- {"listreverse", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListReverse", 1, 1)},
- {"listskip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSkip", 2, 2)},
- {"listtake", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTake", 2, 2)},
- {"listhead", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListHead", 1, 1)},
- {"listlast", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListLast", 1, 1)},
- {"listsort", BuildBoolBuiltinFactoryCallback<TListSortBuiltin>(true)},
- {"listsortasc", BuildBoolBuiltinFactoryCallback<TListSortBuiltin>(true)},
- {"listsortdesc", BuildBoolBuiltinFactoryCallback<TListSortBuiltin>(false)},
- {"listmap", BuildBoolBuiltinFactoryCallback<TListMapBuiltin>(false)},
- {"listflatmap", BuildBoolBuiltinFactoryCallback<TListMapBuiltin>(true)},
- {"listfilter", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListFilter")},
- {"listany", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAny", 1, 1)},
- {"listall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAll", 1, 1)},
- {"listhas", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListHas", 2, 2)},
- {"listmax", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListMax", 1, 1)},
- {"listmin", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListMin", 1, 1)},
- {"listsum", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSum", 1, 1)},
- {"listfold", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFold", 3, 3)},
- {"listfold1", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFold1", 3, 3)},
- {"listfoldmap", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFoldMap", 3, 3)},
- {"listfold1map", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFold1Map", 3, 3)},
- {"listavg", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListAvg", 1, 1)},
- {"listconcat", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListConcat", 1, 2)},
- {"listextract", BuildSimpleBuiltinFactoryCallback<TListExtractBuiltin>()},
- {"listuniq", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListUniq", 1, 1)},
- {"listuniqstable", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListUniqStable", 1, 1)},
- {"listcreate", BuildSimpleBuiltinFactoryCallback<TListCreateBuiltin>()},
- {"listfromrange", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFromRange", 2, 3) },
- {"listreplicate", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Replicate", 2, 2) },
- {"listtakewhile", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListTakeWhile") },
- {"listskipwhile", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListSkipWhile") },
- {"listtakewhileinclusive", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListTakeWhileInclusive") },
- {"listskipwhileinclusive", BuildNamedBuiltinFactoryCallback<TListFilterBuiltin>("ListSkipWhileInclusive") },
- {"listcollect", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListCollect", 1, 1) },
- {"listnotnull", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListNotNull", 1, 1)},
- {"listflatten", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListFlatten", 1, 1)},
- {"listtop", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTop", 2, 3)},
- {"listtopasc", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopAsc", 2, 3)},
- {"listtopdesc", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopDesc", 2, 3)},
- {"listtopsort", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopSort", 2, 3)},
- {"listtopsortasc", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopSortAsc", 2, 3)},
- {"listtopsortdesc", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopSortDesc", 2, 3)},
- {"listsample", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSample", 2, 3)},
- {"listsamplen", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSampleN", 2, 3)},
- {"listshuffle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListShuffle", 1, 2)},
- // Dict builtins
- {"dictlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Length", 1, 1)},
- {"dicthasitems", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("HasItems", 1, 1)},
- {"dictcreate", BuildSimpleBuiltinFactoryCallback<TDictCreateBuiltin>()},
- {"setcreate", BuildSimpleBuiltinFactoryCallback<TSetCreateBuiltin>()},
- {"asdict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AsDictMayWarn", 0, -1)},
- {"asdictstrict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AsDictStrict", 0, -1)},
- {"asset", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AsSetMayWarn", 0, -1)},
- {"assetstrict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AsSetStrict", 0, -1)},
- {"todict", BuildNamedBuiltinFactoryCallback<TYqlToDict<false, false>>("One")},
- {"tomultidict", BuildNamedBuiltinFactoryCallback<TYqlToDict<false, false>>("Many")},
- {"tosorteddict", BuildNamedBuiltinFactoryCallback<TYqlToDict<true, false>>("One")},
- {"tosortedmultidict", BuildNamedBuiltinFactoryCallback<TYqlToDict<true, false>>("Many")},
- {"tohasheddict", BuildNamedBuiltinFactoryCallback<TYqlToDict<false, true>>("One")},
- {"tohashedmultidict", BuildNamedBuiltinFactoryCallback<TYqlToDict<false, true>>("Many")},
- {"dictkeys", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictKeys", 1, 1) },
- {"dictpayloads", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictPayloads", 1, 1) },
- {"dictitems", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictItems", 1, 1) },
- {"dictlookup", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Lookup", 2, 2) },
- {"dictcontains", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Contains", 2, 2) },
- // Atom builtins
- {"asatom", BuildSimpleBuiltinFactoryCallback<TYqlAsAtom>()},
- {"secureparam", BuildNamedBuiltinFactoryCallback<TYqlAtom>("SecureParam")},
- {"void", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Void", 0, 0)},
- {"emptylist", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EmptyList", 0, 0)},
- {"emptydict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EmptyDict", 0, 0)},
- {"callable", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Callable", 2, 2)},
- {"way", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Way", 1, 1) },
- {"dynamicvariant", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DynamicVariant", 3, 3) },
- {"variant", BuildSimpleBuiltinFactoryCallback<TYqlVariant>() },
- {"enum", BuildSimpleBuiltinFactoryCallback<TYqlEnum>() },
- {"asvariant", BuildSimpleBuiltinFactoryCallback<TYqlAsVariant>() },
- {"asenum", BuildSimpleBuiltinFactoryCallback<TYqlAsEnum>() },
- {"astagged", BuildSimpleBuiltinFactoryCallback<TYqlAsTagged>() },
- {"untag", BuildSimpleBuiltinFactoryCallback<TYqlUntag>() },
- {"parsetype", BuildSimpleBuiltinFactoryCallback<TYqlParseType>() },
- {"ensuretype", BuildSimpleBuiltinFactoryCallback<TYqlTypeAssert<true>>() },
- {"ensureconvertibleto", BuildSimpleBuiltinFactoryCallback<TYqlTypeAssert<false>>() },
- {"ensure", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Ensure", 2, 3) },
- {"evaluateexpr", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EvaluateExpr", 1, 1) },
- {"evaluateatom", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EvaluateAtom", 1, 1) },
- {"evaluatetype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EvaluateType", 1, 1) },
- {"unwrap", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Unwrap", 1, 2) },
- {"just", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Just", 1, 1) },
- {"nothing", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Nothing", 1, 1) },
- {"formattype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("FormatType", 1, 1) },
- {"formattypediff", BuildNamedBuiltinFactoryCallback<TFormatTypeDiff<false>>("FormatTypeDiff") },
- {"formattypediffpretty", BuildNamedBuiltinFactoryCallback<TFormatTypeDiff<true>>("FormatTypeDiffPretty") },
- {"pgtype", BuildSimpleBuiltinFactoryCallback<TYqlPgType>() },
- {"pgconst", BuildSimpleBuiltinFactoryCallback<TYqlPgConst>() },
- {"pgop", BuildSimpleBuiltinFactoryCallback<TYqlPgOp>() },
- {"pgcall", BuildSimpleBuiltinFactoryCallback<TYqlPgCall<false>>() },
- {"pgrangecall", BuildSimpleBuiltinFactoryCallback<TYqlPgCall<true>>() },
- {"pgcast", BuildSimpleBuiltinFactoryCallback<TYqlPgCast>() },
- {"frompg", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("FromPg", 1, 1) },
- {"topg", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ToPg", 1, 1) },
- {"pgor", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("PgOr", 2, 2) },
- {"pgand", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("PgAnd", 2, 2) },
- {"pgnot", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("PgNot", 1, 1) },
- {"pgarray", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("PgArray", 1, -1) },
- {"typeof", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TypeOf", 1, 1) },
- {"instanceof", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("InstanceOf", 1, 1) },
- {"datatype", BuildSimpleBuiltinFactoryCallback<TYqlDataType>() },
- {"optionaltype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("OptionalType", 1, 1) },
- {"listtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListType", 1, 1) },
- {"streamtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StreamType", 1, 1) },
- {"dicttype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictType", 2, 2) },
- {"tupletype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TupleType", 0, -1) },
- {"generictype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("GenericType", 0, 0) },
- {"unittype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("UnitType", 0, 0) },
- {"voidtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("VoidType", 0, 0) },
- {"resourcetype", BuildSimpleBuiltinFactoryCallback<TYqlResourceType>() },
- {"taggedtype", BuildSimpleBuiltinFactoryCallback<TYqlTaggedType>() },
- {"varianttype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("VariantType", 1, 1) },
- {"callabletype", BuildSimpleBuiltinFactoryCallback<TYqlCallableType>() },
- {"optionalitemtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("OptionalItemType", 1, 1) },
- {"listitemtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListItemType", 1, 1) },
- {"streamitemtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StreamItemType", 1, 1) },
- {"dictkeytype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictKeyType", 1, 1) },
- {"dictpayloadtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictPayloadType", 1, 1) },
- {"tupleelementtype", BuildSimpleBuiltinFactoryCallback<TYqlTupleElementType>() },
- {"structmembertype", BuildSimpleBuiltinFactoryCallback<TYqlStructMemberType>() },
- {"callableresulttype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("CallableResultType", 1, 1) },
- {"callableargumenttype", BuildSimpleBuiltinFactoryCallback<TYqlCallableArgumentType>() },
- {"variantunderlyingtype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("VariantUnderlyingType", 1, 1) },
- {"variantitem", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("SqlVariantItem", 1, 1) },
- {"fromysonsimpletype", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("FromYsonSimpleType", 2, 2) },
- {"currentutcdate", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(0, "CurrentUtcDate", 0, -1) },
- {"currentutcdatetime", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(0, "CurrentUtcDatetime", 0, -1) },
- {"currentutctimestamp", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(0, "CurrentUtcTimestamp", 0, -1) },
- { "currenttzdate", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(1, "CurrentTzDate", 1, -1) },
- { "currenttzdatetime", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(1, "CurrentTzDatetime", 1, -1) },
- { "currenttztimestamp", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(1, "CurrentTzTimestamp", 1, -1) },
- {"currentoperationid", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("CurrentOperationId", 0, 0) },
- {"currentoperationsharedid", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("CurrentOperationSharedId", 0, 0) },
- {"currentauthenticateduser", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("CurrentAuthenticatedUser", 0, 0) },
- {"addtimezone", BuildSimpleBuiltinFactoryCallback<TYqlAddTimezone>() },
- {"removetimezone", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("RemoveTimezone", 1, 1) },
- {"pickle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Pickle", 1, 1) },
- {"stablepickle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StablePickle", 1, 1) },
- {"unpickle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Unpickle", 2, 2) },
- {"typehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TypeHandle", 1, 1) },
- {"parsetypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ParseTypeHandle", 1, 1) },
- {"typekind", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TypeKind", 1, 1) },
- {"datatypecomponents", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DataTypeComponents", 1, 1) },
- {"datatypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DataTypeHandle", 1, 1) },
- {"optionaltypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("OptionalTypeHandle", 1, 1) },
- {"listtypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTypeHandle", 1, 1) },
- {"streamtypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StreamTypeHandle", 1, 1) },
- {"tupletypecomponents", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TupleTypeComponents", 1, 1) },
- {"tupletypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TupleTypeHandle", 1, 1) },
- {"structtypecomponents", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StructTypeComponents", 1, 1) },
- {"structtypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StructTypeHandle", 1, 1) },
- {"dicttypecomponents", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictTypeComponents", 1, 1) },
- {"dicttypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("DictTypeHandle", 2, 2) },
- {"resourcetypetag", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ResourceTypeTag", 1, 1) },
- {"resourcetypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ResourceTypeHandle", 1, 1) },
- {"taggedtypecomponents", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TaggedTypeComponents", 1, 1) },
- {"taggedtypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("TaggedTypeHandle", 2, 2) },
- {"varianttypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("VariantTypeHandle", 1, 1) },
- {"voidtypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("VoidTypeHandle", 0, 0) },
- {"nulltypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("NullTypeHandle", 0, 0) },
- {"emptylisttypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EmptyListTypeHandle", 0, 0) },
- {"emptydicttypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EmptyDictTypeHandle", 0, 0) },
- {"callabletypecomponents", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("CallableTypeComponents", 1, 1) },
- {"callableargument", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("CallableArgument", 1, 3) },
- {"callabletypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("CallableTypeHandle", 2, 4) },
- {"pgtypename", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("PgTypeName", 1, 1) },
- {"pgtypehandle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("PgTypeHandle", 1, 1) },
- {"formatcode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("FormatCode", 1, 1) },
- {"worldcode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("WorldCode", 0, 0) },
- {"atomcode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AtomCode", 1, 1) },
- {"listcode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListCode", 0, -1) },
- {"funccode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("FuncCode", 1, -1) },
- {"lambdacode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("LambdaCode", 1, 2) },
- {"evaluatecode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("EvaluateCode", 1, 1) },
- {"reprcode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ReprCode", 1, 1) },
- {"quotecode", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("QuoteCode", 1, 1) },
- {"lambdaargumentscount", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("LambdaArgumentsCount", 1, 1) },
- {"lambdaoptionalargumentscount", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("LambdaOptionalArgumentsCount", 1, 1) },
- {"subqueryextend", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("SubqueryExtend", 1, -1) },
- {"subqueryunionall", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("SubqueryUnionAll", 1, -1) },
- {"subquerymerge", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("SubqueryMerge", 1, -1) },
- {"subqueryunionmerge", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("SubqueryUnionMerge", 1, -1) },
- {"subqueryextendfor", BuildSimpleBuiltinFactoryCallback<TYqlSubqueryFor<SubqueryExtendFor>>() },
- {"subqueryunionallfor", BuildSimpleBuiltinFactoryCallback<TYqlSubqueryFor<SubqueryUnionAllFor>>() },
- {"subquerymergefor", BuildSimpleBuiltinFactoryCallback<TYqlSubqueryFor<SubqueryMergeFor>>() },
- {"subqueryunionmergefor", BuildSimpleBuiltinFactoryCallback<TYqlSubqueryFor<SubqueryUnionMergeFor>>() },
- {"subqueryorderby", BuildSimpleBuiltinFactoryCallback<TYqlSubqueryOrderBy<SubqueryOrderBy>>() },
- {"subqueryassumeorderby", BuildSimpleBuiltinFactoryCallback<TYqlSubqueryOrderBy<SubqueryAssumeOrderBy>>() },
- // Tuple builtins
- {"astuple", BuildSimpleBuiltinFactoryCallback<TTupleNode>()},
- // Struct builtins
- {"trymember", BuildNamedBuiltinFactoryCallback<TTryMember>("TryMember")},
- {"addmember", BuildNamedBuiltinFactoryCallback<TAddMember>("AddMember")},
- {"replacemember", BuildNamedBuiltinFactoryCallback<TAddMember>("ReplaceMember")},
- {"removemember", BuildNamedBuiltinFactoryCallback<TRemoveMember>("RemoveMember")},
- {"forceremovemember", BuildNamedBuiltinFactoryCallback<TRemoveMember>("ForceRemoveMember")},
- {"combinemembers", BuildNamedBuiltinFactoryCallback<TCombineMembers>("FlattenMembers")},
- {"flattenmembers", BuildNamedBuiltinFactoryCallback<TFlattenMembers>("FlattenMembers")},
- {"staticmap", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StaticMap", 2, 2) },
- {"staticzip", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StaticZip", 1, -1) },
- {"structunion", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StructUnion", 2, 3)},
- {"structintersection", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StructIntersection", 2, 3)},
- {"structdifference", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StructDifference", 2, 2)},
- {"structsymmetricdifference", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StructSymmetricDifference", 2, 2)},
- {"staticfold", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StaticFold", 3, 3)},
- {"staticfold1", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("StaticFold1", 3, 3)},
- // File builtins
- {"filepath", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("FilePath")},
- {"filecontent", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("FileContent")},
- {"folderpath", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("FolderPath") },
- {"files", BuildNamedBuiltinFactoryCallback<TFileYqlAtom>("Files")},
- {"parsefile", BuildSimpleBuiltinFactoryCallback<TYqlParseFileOp>()},
- // Misc builtins
- {"coalesce", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Coalesce", 1, -1)},
- {"nvl", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Coalesce", 1, -1) },
- {"nanvl", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Nanvl", 2, 2) },
- {"likely", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Likely", 1, -1)},
- {"assumestrict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AssumeStrict", 1, 1)},
- {"assumenonstrict", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("AssumeNonStrict", 1, 1)},
- {"random", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(0, "Random", 1, -1)},
- {"randomnumber", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(0, "RandomNumber", 1, -1)},
- {"randomuuid", BuildNamedDepsArgcBuiltinFactoryCallback<TCallNodeDepArgs>(0, "RandomUuid", 1, -1) },
- {"tablepath", BuildNamedBuiltinFactoryCallback<TCallDirectRow>("TablePath") },
- {"tablerecordindex", BuildNamedBuiltinFactoryCallback<TCallDirectRow>("TableRecord") },
- {"tablerow", BuildSimpleBuiltinFactoryCallback<TTableRow<false>>() },
- {"jointablerow", BuildSimpleBuiltinFactoryCallback<TTableRow<true>>() },
- {"tablerows", BuildSimpleBuiltinFactoryCallback<TTableRows>() },
- {"weakfield", BuildSimpleBuiltinFactoryCallback<TWeakFieldOp>()},
- {"version", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Version", 0, 0)},
- {"systemmetadata", BuildNamedArgcBuiltinFactoryCallback<TCallDirectRow>("SystemMetadata", 1, -1)},
- // Hint builtins
- {"grouping", BuildSimpleBuiltinFactoryCallback<TGroupingNode>()},
- // Window funcitons
- {"rownumber", BuildNamedArgcBuiltinFactoryCallback<TWinRowNumber>("RowNumber", 0, 0)},
- {"rank", BuildNamedArgcBuiltinFactoryCallback<TWinRank>("Rank", 0, 1)},
- {"denserank", BuildNamedArgcBuiltinFactoryCallback<TWinRank>("DenseRank", 0, 1)},
- {"lead", BuildNamedArgcBuiltinFactoryCallback<TWinLeadLag>("Lead", 1, 2)},
- {"lag", BuildNamedArgcBuiltinFactoryCallback<TWinLeadLag>("Lag", 1, 2)},
- {"percentrank", BuildNamedArgcBuiltinFactoryCallback<TWinRank>("PercentRank", 0, 1)},
- {"cumedist", BuildNamedArgcBuiltinFactoryCallback<TWinCumeDist>("CumeDist", 0, 0)},
- {"ntile", BuildNamedArgcBuiltinFactoryCallback<TWinNTile>("NTile", 1, 1)},
- // Session window
- {"sessionwindow", BuildSimpleBuiltinFactoryCallback<TSessionWindow>()},
- {"sessionstart", BuildSimpleBuiltinFactoryCallback<TSessionStart<true>>()},
- {"sessionstate", BuildSimpleBuiltinFactoryCallback<TSessionStart<false>>()},
- // New hopping
- {"hoppingwindow", BuildSimpleBuiltinFactoryCallback<THoppingWindow>()},
- // Hopping intervals time functions
- {"hopstart", BuildSimpleBuiltinFactoryCallback<THoppingTime<true>>()},
- {"hopend", BuildSimpleBuiltinFactoryCallback<THoppingTime<false>>()},
- };
- return builtinFuncs;
- }
- TAggrFuncFactoryCallbackMap MakeAggrFuncs() {
- constexpr auto OverWindow = EAggregateMode::OverWindow;
- TAggrFuncFactoryCallbackMap aggrFuncs = {
- {"min", BuildAggrFuncFactoryCallback("Min", "min_traits_factory")},
- {"max", BuildAggrFuncFactoryCallback("Max", "max_traits_factory")},
- {"minby", BuildAggrFuncFactoryCallback("MinBy", "min_by_traits_factory", KEY_PAYLOAD)},
- {"maxby", BuildAggrFuncFactoryCallback("MaxBy", "max_by_traits_factory", KEY_PAYLOAD)},
- {"sum", BuildAggrFuncFactoryCallback("Sum", "sum_traits_factory")},
- {"sumif", BuildAggrFuncFactoryCallback("SumIf", "sum_if_traits_factory", PAYLOAD_PREDICATE) },
- {"checked_sum", BuildAggrFuncFactoryCallback("CheckedSum", "checked_sum_traits_factory")},
- {"checked_sumif", BuildAggrFuncFactoryCallback("CheckedSumIf", "checked_sum_if_traits_factory", PAYLOAD_PREDICATE) },
- {"some", BuildAggrFuncFactoryCallback("Some", "some_traits_factory")},
- {"somevalue", BuildAggrFuncFactoryCallback("SomeValue", "some_traits_factory")},
- {"count", BuildAggrFuncFactoryCallback("Count", "count_traits_factory", COUNT)},
- {"countif", BuildAggrFuncFactoryCallback("CountIf", "count_if_traits_factory")},
- {"every", BuildAggrFuncFactoryCallback("Every", "and_traits_factory")},
- {"booland", BuildAggrFuncFactoryCallback("BoolAnd", "and_traits_factory")},
- {"boolor", BuildAggrFuncFactoryCallback("BoolOr", "or_traits_factory")},
- {"boolxor", BuildAggrFuncFactoryCallback("BoolXor", "xor_traits_factory")},
- {"bitand", BuildAggrFuncFactoryCallback("BitAnd", "bit_and_traits_factory")},
- {"bitor", BuildAggrFuncFactoryCallback("BitOr", "bit_or_traits_factory")},
- {"bitxor", BuildAggrFuncFactoryCallback("BitXor", "bit_xor_traits_factory")},
- {"avg", BuildAggrFuncFactoryCallback("Avg", "avg_traits_factory")},
- {"avgif", BuildAggrFuncFactoryCallback("AvgIf", "avg_if_traits_factory", PAYLOAD_PREDICATE) },
- {"agglist", BuildAggrFuncFactoryCallback("AggregateList", "list2_traits_factory", LIST)},
- {"aggrlist", BuildAggrFuncFactoryCallback("AggregateList", "list2_traits_factory", LIST)},
- {"aggregatelist", BuildAggrFuncFactoryCallback("AggregateList", "list2_traits_factory", LIST)},
- {"agglistdistinct", BuildAggrFuncFactoryCallback("AggregateListDistinct", "set_traits_factory", LIST)},
- {"aggrlistdistinct", BuildAggrFuncFactoryCallback("AggregateListDistinct", "set_traits_factory", LIST)},
- {"aggregatelistdistinct", BuildAggrFuncFactoryCallback("AggregateListDistinct", "set_traits_factory", LIST)},
- {"median", BuildAggrFuncFactoryCallback("Median", "percentile_traits_factory", PERCENTILE)},
- {"percentile", BuildAggrFuncFactoryCallback("Percentile", "percentile_traits_factory", PERCENTILE)},
- {"mode", BuildAggrFuncFactoryCallback("Mode", "topfreq_traits_factory", TOPFREQ) },
- {"topfreq", BuildAggrFuncFactoryCallback("TopFreq", "topfreq_traits_factory", TOPFREQ) },
- {"top", BuildAggrFuncFactoryCallback("Top", "top_traits_factory", TOP)},
- {"bottom", BuildAggrFuncFactoryCallback("Bottom", "bottom_traits_factory", TOP)},
- {"topby", BuildAggrFuncFactoryCallback("TopBy", "top_by_traits_factory", TOP_BY)},
- {"bottomby", BuildAggrFuncFactoryCallback("BottomBy", "bottom_by_traits_factory", TOP_BY)},
- {"histogram", BuildAggrFuncFactoryCallback("AdaptiveWardHistogram", "histogram_adaptive_ward_traits_factory", HISTOGRAM, "Histogram")},
- {"histogramcdf", BuildAggrFuncFactoryCallback("AdaptiveWardHistogramCDF", "histogram_cdf_adaptive_ward_traits_factory", HISTOGRAM, "HistogramCDF")},
- {"adaptivewardhistogram", BuildAggrFuncFactoryCallback("AdaptiveWardHistogram", "histogram_adaptive_ward_traits_factory", HISTOGRAM)},
- {"adaptivewardhistogramcdf", BuildAggrFuncFactoryCallback("AdaptiveWardHistogramCDF", "histogram_cdf_adaptive_ward_traits_factory", HISTOGRAM)},
- {"adaptiveweighthistogram", BuildAggrFuncFactoryCallback("AdaptiveWeightHistogram", "histogram_adaptive_weight_traits_factory", HISTOGRAM)},
- {"adaptiveweighthistogramcdf", BuildAggrFuncFactoryCallback("AdaptiveWeightHistogramCDF", "histogram_cdf_adaptive_weight_traits_factory", HISTOGRAM)},
- {"adaptivedistancehistogram", BuildAggrFuncFactoryCallback("AdaptiveDistanceHistogram", "histogram_adaptive_distance_traits_factory", HISTOGRAM)},
- {"adaptivedistancehistogramcdf", BuildAggrFuncFactoryCallback("AdaptiveDistanceHistogramCDF", "histogram_cdf_adaptive_distance_traits_factory", HISTOGRAM)},
- {"blockwardhistogram", BuildAggrFuncFactoryCallback("BlockWardHistogram", "histogram_block_ward_traits_factory", HISTOGRAM)},
- {"blockwardhistogramcdf", BuildAggrFuncFactoryCallback("BlockWardHistogramCDF", "histogram_cdf_block_ward_traits_factory", HISTOGRAM)},
- {"blockweighthistogram", BuildAggrFuncFactoryCallback("BlockWeightHistogram", "histogram_block_weight_traits_factory", HISTOGRAM)},
- {"blockweighthistogramcdf", BuildAggrFuncFactoryCallback("BlockWeightHistogramCDF", "histogram_cdf_block_weight_traits_factory", HISTOGRAM)},
- {"linearhistogram", BuildAggrFuncFactoryCallback("LinearHistogram", "histogram_linear_traits_factory", LINEAR_HISTOGRAM)},
- {"linearhistogramcdf", BuildAggrFuncFactoryCallback("LinearHistogramCDF", "histogram_cdf_linear_traits_factory", LINEAR_HISTOGRAM)},
- {"logarithmichistogram", BuildAggrFuncFactoryCallback("LogarithmicHistogram", "histogram_logarithmic_traits_factory", LINEAR_HISTOGRAM)},
- {"logarithmichistogramcdf", BuildAggrFuncFactoryCallback("LogarithmicHistogramCDF", "histogram_cdf_logarithmic_traits_factory", LINEAR_HISTOGRAM)},
- {"loghistogram", BuildAggrFuncFactoryCallback("LogarithmicHistogram", "histogram_logarithmic_traits_factory", LINEAR_HISTOGRAM, "LogHistogram")},
- {"loghistogramcdf", BuildAggrFuncFactoryCallback("LogarithmicHistogramCDF", "histogram_cdf_logarithmic_traits_factory", LINEAR_HISTOGRAM, "LogHistogramCDF")},
- {"hyperloglog", BuildAggrFuncFactoryCallback("HyperLogLog", "hyperloglog_traits_factory", COUNT_DISTINCT_ESTIMATE)},
- {"hll", BuildAggrFuncFactoryCallback("HyperLogLog", "hyperloglog_traits_factory", COUNT_DISTINCT_ESTIMATE, "HLL")},
- {"countdistinctestimate", BuildAggrFuncFactoryCallback("HyperLogLog", "hyperloglog_traits_factory", COUNT_DISTINCT_ESTIMATE, "CountDistinctEstimate")},
- {"variance", BuildAggrFuncFactoryCallback("Variance", "variance_0_1_traits_factory")},
- {"stddev", BuildAggrFuncFactoryCallback("StdDev", "variance_1_1_traits_factory")},
- {"populationvariance", BuildAggrFuncFactoryCallback("VariancePopulation", "variance_0_0_traits_factory")},
- {"variancepopulation", BuildAggrFuncFactoryCallback("VariancePopulation", "variance_0_0_traits_factory")},
- {"populationstddev", BuildAggrFuncFactoryCallback("StdDevPopulation", "variance_1_0_traits_factory")},
- {"stddevpopulation", BuildAggrFuncFactoryCallback("StdDevPopulation", "variance_1_0_traits_factory")},
- {"varpop", BuildAggrFuncFactoryCallback("VariancePopulation", "variance_0_0_traits_factory")},
- {"stddevpop", BuildAggrFuncFactoryCallback("StdDevPopulation", "variance_1_0_traits_factory")},
- {"varp", BuildAggrFuncFactoryCallback("VariancePopulation", "variance_0_0_traits_factory")},
- {"stddevp", BuildAggrFuncFactoryCallback("StdDevPopulation", "variance_1_0_traits_factory")},
- {"variancesample", BuildAggrFuncFactoryCallback("VarianceSample", "variance_0_1_traits_factory")},
- {"stddevsample", BuildAggrFuncFactoryCallback("StdDevSample", "variance_1_1_traits_factory")},
- {"varsamp", BuildAggrFuncFactoryCallback("VarianceSample", "variance_0_1_traits_factory")},
- {"stddevsamp", BuildAggrFuncFactoryCallback("StdDevSample", "variance_1_1_traits_factory")},
- {"vars", BuildAggrFuncFactoryCallback("VarianceSample", "variance_0_1_traits_factory")},
- {"stddevs", BuildAggrFuncFactoryCallback("StdDevSample", "variance_1_1_traits_factory")},
- {"correlation", BuildAggrFuncFactoryCallback("Correlation", "correlation_traits_factory", TWO_ARGS)},
- {"corr", BuildAggrFuncFactoryCallback("Correlation", "correlation_traits_factory", TWO_ARGS, "Corr")},
- {"covariance", BuildAggrFuncFactoryCallback("CovarianceSample", "covariance_sample_traits_factory", TWO_ARGS, "Covariance")},
- {"covariancesample", BuildAggrFuncFactoryCallback("CovarianceSample", "covariance_sample_traits_factory", TWO_ARGS)},
- {"covarsamp", BuildAggrFuncFactoryCallback("CovarianceSample", "covariance_sample_traits_factory", TWO_ARGS, "CovarSamp")},
- {"covar", BuildAggrFuncFactoryCallback("CovarianceSample", "covariance_sample_traits_factory", TWO_ARGS, "Covar")},
- {"covars", BuildAggrFuncFactoryCallback("CovarianceSample", "covariance_sample_traits_factory", TWO_ARGS, "CovarS")},
- {"covariancepopulation", BuildAggrFuncFactoryCallback("CovariancePopulation", "covariance_population_traits_factory", TWO_ARGS)},
- {"covarpop", BuildAggrFuncFactoryCallback("CovariancePopulation", "covariance_population_traits_factory", TWO_ARGS, "CovarPop")},
- {"covarp", BuildAggrFuncFactoryCallback("CovariancePopulation", "covariance_population_traits_factory", TWO_ARGS, "CovarP")},
- {"udaf", BuildAggrFuncFactoryCallback("UDAF", "udaf_traits_factory", UDAF)},
- // Window functions
- {"firstvalue", BuildAggrFuncFactoryCallback("FirstValue", "first_value_traits_factory", {OverWindow})},
- {"lastvalue", BuildAggrFuncFactoryCallback("LastValue", "last_value_traits_factory", {OverWindow})},
- {"nthvalue", BuildAggrFuncFactoryCallback("NthValue", "nth_value_traits_factory", {OverWindow}, NTH_VALUE)},
- {"firstvalueignorenulls", BuildAggrFuncFactoryCallback("FirstValueIgnoreNulls", "first_value_ignore_nulls_traits_factory", {OverWindow})},
- {"lastvalueignorenulls", BuildAggrFuncFactoryCallback("LastValueIgnoreNulls", "last_value_ignore_nulls_traits_factory", {OverWindow})},
- {"nthvalueignorenulls", BuildAggrFuncFactoryCallback("NthValueIgnoreNulls", "nth_value_ignore_nulls_traits_factory", {OverWindow}, NTH_VALUE)},
- // MatchRecognize navigation functions
- {"first", BuildAggrFuncFactoryCallback("First", "first_traits_factory")},
- {"last", BuildAggrFuncFactoryCallback("Last", "last_traits_factory")},
- };
- return aggrFuncs;
- }
- TCoreFuncMap MakeCoreFuncs() {
- TCoreFuncMap coreFuncs = {
- {"listindexof", { "IndexOf", 2, 2}},
- {"testbit", { "TestBit", 2, 2}},
- {"setbit", { "SetBit", 2, 2}},
- {"clearbit", { "ClearBit", 2, 2}},
- {"flipbit", { "FlipBit", 2, 2 }},
- {"toset", { "ToSet", 1, 1 }},
- {"setisdisjoint", { "SetIsDisjoint", 2, 2}},
- {"setintersection", { "SetIntersection", 2, 3}},
- {"setincludes", { "SetIncludes", 2, 2}},
- {"setunion", { "SetUnion", 2, 3}},
- {"setdifference", { "SetDifference", 2, 2}},
- {"setsymmetricdifference", { "SetSymmetricDifference", 2, 3}},
- {"listaggregate", { "ListAggregate", 2, 2}},
- {"dictaggregate", { "DictAggregate", 2, 2}},
- {"aggregatetransforminput", { "AggregateTransformInput", 2, 2}},
- {"aggregatetransformoutput", { "AggregateTransformOutput", 2, 2}},
- {"aggregateflatten", { "AggregateFlatten", 1, 1}},
- {"choosemembers", { "ChooseMembers", 2, 2}},
- {"removemembers", { "RemoveMembers", 2, 2}},
- {"forceremovemembers", { "ForceRemoveMembers", 2, 2}},
- {"structmembers", { "StructMembers", 1, 1}},
- {"gathermembers", { "GatherMembers", 1, 1}},
- {"renamemembers", { "RenameMembers", 2, 2}},
- {"forcerenamemembers", { "ForceRenameMembers", 2, 2}},
- {"spreadmembers", { "SpreadMembers", 2, 2}},
- {"forcespreadmembers", { "ForceSpreadMembers", 2, 2}},
- {"listfromtuple", { "ListFromTuple", 1, 1}},
- {"listtotuple", { "ListToTuple", 2, 2}},
- {"opaque", { "Opaque", 1, 1}},
- };
- return coreFuncs;
- }
- };
- TNodePtr BuildBuiltinFunc(TContext& ctx, TPosition pos, TString name, const TVector<TNodePtr>& args,
- const TString& originalNameSpace, EAggregateMode aggMode, bool* mustUseNamed, bool warnOnYqlNameSpace) {
- const TBuiltinFuncData* funcData = Singleton<TBuiltinFuncData>();
- const TBuiltinFactoryCallbackMap& builtinFuncs = funcData->BuiltinFuncs;
- const TAggrFuncFactoryCallbackMap& aggrFuncs = funcData->AggrFuncs;
- const TCoreFuncMap& coreFuncs = funcData->CoreFuncs;
- for (auto& arg: args) {
- if (!arg) {
- return nullptr;
- }
- }
- TString normalizedName(name);
- TString nameSpace(originalNameSpace);
- TString ns = to_lower(nameSpace);
- if (ns.empty()) {
- TMaybe<TIssue> error = NormalizeName(pos, normalizedName);
- if (!error.Empty()) {
- return new TInvalidBuiltin(pos, error->GetMessage());
- }
- auto coreFunc = coreFuncs.find(normalizedName);
- if (coreFunc != coreFuncs.end()) {
- ns = "core";
- name = coreFunc->second.Name;
- if (args.size() < coreFunc->second.MinArgs || args.size() > coreFunc->second.MaxArgs) {
- return new TInvalidBuiltin(pos, TStringBuilder() << name << " expected from "
- << coreFunc->second.MinArgs << " to " << coreFunc->second.MaxArgs << " arguments, but got: " << args.size());
- }
- if (coreFunc->second.MinArgs != coreFunc->second.MaxArgs) {
- name += ToString(args.size());
- }
- }
- }
- TString moduleResource;
- if (ctx.Settings.ModuleMapping.contains(ns)) {
- moduleResource = ctx.Settings.ModuleMapping.at(ns);
- }
- if (ns == "js") {
- ns = "javascript";
- nameSpace = "JavaScript";
- }
- if (ns == "datetime2") {
- ctx.Warning(pos, TIssuesIds::YQL_DEPRECATED_DATETIME2) << "DateTime2:: is a temporary alias for DateTime:: which will be removed in the future, use DateTime:: instead";
- }
- if (ns == "datetime") {
- ns = "datetime2";
- nameSpace = "DateTime2";
- }
- auto scriptType = NKikimr::NMiniKQL::ScriptTypeFromStr(ns);
- switch (scriptType) {
- case NKikimr::NMiniKQL::EScriptType::Python:
- case NKikimr::NMiniKQL::EScriptType::Python3:
- case NKikimr::NMiniKQL::EScriptType::ArcPython3:
- scriptType = NKikimr::NMiniKQL::EScriptType::Python3;
- break;
- case NKikimr::NMiniKQL::EScriptType::Python2:
- scriptType = NKikimr::NMiniKQL::EScriptType::ArcPython2;
- break;
- case NKikimr::NMiniKQL::EScriptType::SystemPython2:
- scriptType = NKikimr::NMiniKQL::EScriptType::Python2;
- break;
- default:
- break;
- }
- if (ns == "yql" || ns == "@yql") {
- if (warnOnYqlNameSpace && GetEnv("YQL_DETERMINISTIC_MODE").empty()) {
- ctx.Warning(pos, TIssuesIds::YQL_S_EXPRESSIONS_CALL)
- << "It is not recommended to directly access s-expressions functions via YQL::" << Endl
- << "This mechanism is mostly intended for temporary workarounds or internal testing purposes";
- }
- if (ns == "yql") {
- return new TCallNodeImpl(pos, name, -1, -1, args);
- }
- } else if (moduleResource) {
- auto exportName = ns == "core" ? name : "$" + name;
- TVector<TNodePtr> applyArgs = {
- new TCallNodeImpl(pos, "bind", {
- BuildAtom(pos, ns + "_module", 0), BuildQuotedAtom(pos, exportName)
- })
- };
- applyArgs.insert(applyArgs.end(), args.begin(), args.end());
- return new TCallNodeImpl(pos, "Apply", applyArgs);
- } else if (ns == "hyperscan" || ns == "pcre" || ns == "pire" || ns.StartsWith("re2")) {
- TString moduleName(nameSpace);
- moduleName.to_title();
- if ((args.size() == 1 || args.size() == 2) && (name.StartsWith("Multi") || (ns.StartsWith("re2") && name == "Capture"))) {
- TVector<TNodePtr> multiArgs{
- ns.StartsWith("re2") && name == "Capture" ? MakePair(pos, args) : args[0],
- new TCallNodeImpl(pos, "Void", 0, 0, {}),
- args[0]
- };
- auto fullName = moduleName + "." + name;
- return new TYqlTypeConfigUdf(pos, fullName, multiArgs, multiArgs.size() + 1);
- } else if (!(ns.StartsWith("re2") && name == "Options")) {
- auto newArgs = args;
- if (ns.StartsWith("re2")) {
- // convert run config is tuple of string and optional options
- if (args.size() == 1 || args.size() == 2) {
- newArgs[0] = MakePair(pos, args);
- if (args.size() == 2) {
- newArgs.pop_back();
- }
- } else {
- return new TInvalidBuiltin(pos, TStringBuilder() << ns << "." << name << " expected one or two arguments.");
- }
- }
- return BuildUdf(ctx, pos, moduleName, name, newArgs);
- }
- } else if (ns == "datetime2" && (name == "Parse")) {
- return BuildUdf(ctx, pos, nameSpace, name, args);
- } else if (ns == "pg" || ns == "pgagg" || ns == "pgproc") {
- bool isAggregateFunc = NYql::NPg::HasAggregation(name, NYql::NPg::EAggKind::Normal);
- bool isNormalFunc = NYql::NPg::HasProc(name, NYql::NPg::EProcKind::Function);
- if (!isAggregateFunc && !isNormalFunc) {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Unknown function: " << name);
- }
- if (isAggregateFunc && isNormalFunc) {
- if (ns == "pg") {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Ambigious function: " << name << ", use either PgAgg:: or PgProc:: namespace");
- } else if (ns == "pgagg") {
- isNormalFunc = false;
- } else {
- isAggregateFunc = false;
- }
- }
- if (isAggregateFunc && ns == "pgproc") {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Invalid namespace for aggregation function: " << name << ", use either Pg:: or PgAgg:: namespace");
- }
- if (isNormalFunc && ns == "pgagg") {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Invalid namespace for normal function: " << name << ", use either Pg:: or PgProc:: namespace");
- }
- if (isAggregateFunc) {
- if (aggMode == EAggregateMode::Distinct) {
- return new TInvalidBuiltin(pos, "Distinct is not supported yet for PG aggregation ");
- }
- return BuildAggrFuncFactoryCallback(name, "", EAggrFuncTypeCallback::PG)(pos, args, aggMode, false);
- } else {
- YQL_ENSURE(isNormalFunc);
- TVector<TNodePtr> pgCallArgs;
- pgCallArgs.push_back(BuildLiteralRawString(pos, name));
- pgCallArgs.insert(pgCallArgs.end(), args.begin(), args.end());
- return new TYqlPgCall<false>(pos, pgCallArgs);
- }
- } else if (name == "MakeLibraPreprocessor") {
- if (args.size() != 1) {
- return new TInvalidBuiltin(pos, TStringBuilder() << name << " requires exactly one argument");
- }
- auto settings = NYT::TNode::CreateMap();
- auto makeUdfArgs = [&args, &pos, &settings]() {
- return TVector<TNodePtr> {
- args[0],
- new TCallNodeImpl(pos, "Void", {}),
- BuildQuotedAtom(pos, NYT::NodeToYsonString(settings))
- };
- };
- auto structNode = args[0]->GetStructNode();
- if (!structNode) {
- if (auto callNode = args[0]->GetCallNode()) {
- if (callNode->GetOpName() == "AsStruct") {
- return BuildUdf(ctx, pos, nameSpace, name, makeUdfArgs());
- }
- }
- return new TInvalidBuiltin(pos, TStringBuilder() << name << " requires struct as argument");
- }
- for (const auto& item : structNode->GetExprs()) {
- const auto& label = item->GetLabel();
- if (label == "Entities") {
- auto callNode = item->GetCallNode();
- if (!callNode || callNode->GetOpName() != "AsListMayWarn") {
- return new TInvalidBuiltin(pos, TStringBuilder() << name << " entities must be list of strings");
- }
- auto entities = NYT::TNode::CreateList();
- for (const auto& entity : callNode->GetArgs()) {
- if (!entity->IsLiteral() || entity->GetLiteralType() != "String") {
- return new TInvalidBuiltin(pos, TStringBuilder() << name << " entity must be string literal");
- }
- entities.Add(entity->GetLiteralValue());
- }
- settings(label, std::move(entities));
- } else if (label == "EntitiesStrategy") {
- if (!item->IsLiteral() || item->GetLiteralType() != "String") {
- return new TInvalidBuiltin(
- pos, TStringBuilder() << name << " entities strategy must be string literal"
- );
- }
- if (!EqualToOneOf(item->GetLiteralValue(), "whitelist", "blacklist")) {
- return new TInvalidBuiltin(
- pos,
- TStringBuilder() << name << " got invalid entities strategy: expected 'whitelist' or 'blacklist'"
- );
- }
- settings(label, item->GetLiteralValue());
- } else if (label == "Mode") {
- if (!item->IsLiteral() || item->GetLiteralType() != "String") {
- return new TInvalidBuiltin(
- pos, TStringBuilder() << name << " mode must be string literal"
- );
- }
- settings(label, item->GetLiteralValue());
- } else if (EqualToOneOf(label, "BlockstatDict", "ParseWithFat")) {
- continue;
- } else {
- return new TInvalidBuiltin(
- pos,
- TStringBuilder()
- << name << " got unsupported setting: " << label
- << "; supported: Entities, EntitiesStrategy, BlockstatDict, ParseWithFat" );
- }
- }
- return BuildUdf(ctx, pos, nameSpace, name, makeUdfArgs());
- } else if (scriptType != NKikimr::NMiniKQL::EScriptType::Unknown) {
- auto scriptName = NKikimr::NMiniKQL::IsCustomPython(scriptType) ? nameSpace : TString(NKikimr::NMiniKQL::ScriptTypeAsStr(scriptType));
- return BuildScriptUdf(pos, scriptName, name, args, nullptr);
- } else if (ns.empty()) {
- if (auto simpleType = LookupSimpleType(normalizedName, ctx.FlexibleTypes, /* isPgType = */ false)) {
- const auto type = *simpleType;
- if (NUdf::FindDataSlot(type)) {
- YQL_ENSURE(type != "Decimal");
- return new TYqlData(pos, type, args);
- }
- if (type.StartsWith("pg") || type.StartsWith("_pg")) {
- TVector<TNodePtr> pgConstArgs;
- if (!args.empty()) {
- pgConstArgs.push_back(args.front());
- pgConstArgs.push_back(new TCallNodeImpl(pos, "PgType", { BuildQuotedAtom(pos,
- TString(type.StartsWith("pg") ? "" : "_") + type.substr(type.StartsWith("pg") ? 2 : 3), TNodeFlags::Default) }));
- pgConstArgs.insert(pgConstArgs.end(), args.begin() + 1, args.end());
- }
- return new TYqlPgConst(pos, pgConstArgs);
- } else if (type == "Void" || type == "EmptyList" || type == "EmptyDict") {
- return new TCallNodeImpl(pos, type, 0, 0, args);
- } else {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Can not create objects of type " << type);
- }
- }
- if (normalizedName == "decimal") {
- if (args.size() == 2) {
- TVector<TNodePtr> dataTypeArgs = { BuildQuotedAtom(pos, "Decimal", TNodeFlags::Default) };
- for (auto& arg : args) {
- if (auto literal = arg->GetLiteral("Int32")) {
- dataTypeArgs.push_back(BuildQuotedAtom(pos, *literal, TNodeFlags::Default));
- } else {
- dataTypeArgs.push_back(MakeAtomFromExpression(ctx.Pos(), ctx, arg).Build());
- }
- }
- return new TCallNodeImpl(pos, "DataType", dataTypeArgs);
- }
- return new TYqlData(pos, "Decimal", args);
- }
- if (normalizedName == "tablename") {
- return new TTableName(pos, args, ctx.Scoped->CurrService);
- }
- if (normalizedName == "aggregationfactory") {
- if (args.size() < 1 || !args[0]->GetLiteral("String")) {
- return new TInvalidBuiltin(pos, "AGGREGATION_FACTORY requries a function name");
- }
- auto aggNormalizedName = *args[0]->GetLiteral("String");
- auto error = NormalizeName(pos, aggNormalizedName);
- if (!error.Empty()) {
- return new TInvalidBuiltin(pos, error->GetMessage());
- }
- if (aggNormalizedName == "aggregateby") {
- return new TInvalidBuiltin(pos, "AGGREGATE_BY is not allowed to use with AGGREGATION_FACTORY");
- }
- if (aggNormalizedName == "multiaggregateby") {
- return new TInvalidBuiltin(pos, "MULTI_AGGREGATE_BY is not allowed to use with AGGREGATION_FACTORY");
- }
- if (aggMode == EAggregateMode::Distinct || aggMode == EAggregateMode::OverWindowDistinct) {
- return new TInvalidBuiltin(pos, "DISTINCT can only be used in aggregation functions");
- }
- if (to_lower(*args[0]->GetLiteral("String")).StartsWith("pg::")) {
- auto name = args[0]->GetLiteral("String")->substr(4);
- const bool isAggregateFunc = NYql::NPg::HasAggregation(name, NYql::NPg::EAggKind::Normal);
- if (!isAggregateFunc) {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Unknown aggregation function: " << *args[0]->GetLiteral("String"));
- }
- return BuildAggrFuncFactoryCallback(name, "", EAggrFuncTypeCallback::PG)(pos, args, aggMode, true);
- }
- AdjustCheckedAggFuncName(aggNormalizedName, ctx);
- auto aggrCallback = aggrFuncs.find(aggNormalizedName);
- if (aggrCallback == aggrFuncs.end()) {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Unknown aggregation function: " << *args[0]->GetLiteral("String"));
- }
- switch (ctx.GetColumnReferenceState()) {
- case EColumnRefState::MatchRecognizeMeasures:
- [[fallthrough]];
- case EColumnRefState::MatchRecognizeDefine:
- return new TInvalidBuiltin(pos, "Cannot use aggregation factory inside the MATCH_RECOGNIZE context");
- default:
- if ("first" == aggNormalizedName || "last" == aggNormalizedName) {
- return new TInvalidBuiltin(pos, "Cannot use FIRST and LAST outside the MATCH_RECOGNIZE context");
- }
- return (*aggrCallback).second(pos, args, aggMode, true);
- }
- }
- if (normalizedName == "aggregateby" || normalizedName == "multiaggregateby") {
- const bool multi = (normalizedName == "multiaggregateby");
- if (args.size() != 2) {
- return new TInvalidBuiltin(pos, TStringBuilder() << (multi ? "MULTI_AGGREGATE_BY" : "AGGREGATE_BY") << " requries two arguments");
- }
- auto name = multi ? "MultiAggregateBy" : "AggregateBy";
- auto aggr = BuildFactoryAggregation(pos, name, "", aggMode, multi);
- return new TBasicAggrFunc(pos, name, aggr, args);
- }
- AdjustCheckedAggFuncName(normalizedName, ctx);
- auto aggrCallback = aggrFuncs.find(normalizedName);
- if (aggrCallback != aggrFuncs.end()) {
- switch (ctx.GetColumnReferenceState()) {
- case EColumnRefState::MatchRecognizeMeasures: {
- auto result = (*aggrCallback).second(pos, args, aggMode, false);
- return BuildMatchRecognizeVarAccess(pos, std::move(result));
- }
- case EColumnRefState::MatchRecognizeDefine:
- return BuildMatchRecognizeDefineAggregate(ctx.Pos(), normalizedName, args);
- default:
- if ("first" == normalizedName || "last" == normalizedName) {
- return new TInvalidBuiltin(pos, "Cannot use FIRST and LAST outside the MATCH_RECOGNIZE context");
- }
- return (*aggrCallback).second(pos, args, aggMode, false);
- }
- }
- if (aggMode == EAggregateMode::Distinct || aggMode == EAggregateMode::OverWindowDistinct) {
- return new TInvalidBuiltin(pos, "DISTINCT can only be used in aggregation functions");
- }
- auto builtinCallback = builtinFuncs.find(normalizedName);
- if (builtinCallback != builtinFuncs.end()) {
- return (*builtinCallback).second(pos, args);
- } else if (normalizedName == "udf") {
- if (mustUseNamed && *mustUseNamed) {
- *mustUseNamed = false;
- }
- return new TUdfNode(pos, args);
- } else if (normalizedName == "asstruct" || normalizedName == "structtype") {
- if (args.empty()) {
- return new TCallNodeImpl(pos, normalizedName == "asstruct" ? "AsStruct" : "StructType", 0, 0, args);
- }
- if (mustUseNamed && *mustUseNamed) {
- *mustUseNamed = false;
- YQL_ENSURE(args.size() == 2);
- Y_DEBUG_ABORT_UNLESS(args[0]->GetTupleNode());
- auto posArgs = args[0]->GetTupleNode();
- if (posArgs->IsEmpty()) {
- if (normalizedName == "asstruct") {
- return args[1];
- } else {
- Y_DEBUG_ABORT_UNLESS(args[1]->GetStructNode());
- auto namedArgs = args[1]->GetStructNode();
- return new TStructTypeNode(pos, namedArgs->GetExprs());
- }
- }
- }
- return new TInvalidBuiltin(pos, TStringBuilder() <<
- (normalizedName == "asstruct" ? "AsStruct" : "StructType") <<
- " requires all argument to be named");
- } else if (normalizedName == "expandstruct") {
- if (mustUseNamed) {
- if (!*mustUseNamed) {
- return new TInvalidBuiltin(pos, TStringBuilder() << "ExpandStruct requires at least one named argument");
- }
- *mustUseNamed = false;
- }
- YQL_ENSURE(args.size() == 2);
- Y_DEBUG_ABORT_UNLESS(args[0]->GetTupleNode());
- Y_DEBUG_ABORT_UNLESS(args[1]->GetStructNode());
- auto posArgs = args[0]->GetTupleNode();
- if (posArgs->GetTupleSize() != 1) {
- return new TInvalidBuiltin(pos, TStringBuilder() << "ExpandStruct requires all arguments except first to be named");
- }
- TVector<TNodePtr> flattenMembersArgs = {
- BuildTuple(pos, {BuildQuotedAtom(pos, ""), posArgs->GetTupleElement(0)}),
- BuildTuple(pos, {BuildQuotedAtom(pos, ""), args[1]}),
- };
- return new TCallNodeImpl(pos, "FlattenMembers", 2, 2, flattenMembersArgs);
- } else if (normalizedName == "visit" || normalizedName == "visitordefault") {
- bool withDefault = normalizedName == "visitordefault";
- TNodePtr variant;
- TVector<TNodePtr> labels, handlers;
- TMaybe<TNodePtr> dflt;
- if (mustUseNamed && *mustUseNamed) {
- *mustUseNamed = false;
- auto &positional = *args[0]->GetTupleNode();
- if (positional.GetTupleSize() != (withDefault ? 2 : 1)) {
- return new TInvalidBuiltin(pos, TStringBuilder() << name
- << " requires exactly " << (withDefault ? 2 : 1) << " positional arguments when named args are used");
- }
- auto &named = *args[1]->GetStructNode();
- variant = positional.GetTupleElement(0);
- auto &namedExprs = named.GetExprs();
- labels.reserve(namedExprs.size());
- handlers.reserve(namedExprs.size());
- for (size_t idx = 0; idx < namedExprs.size(); idx++) {
- labels.push_back(BuildQuotedAtom(pos, namedExprs[idx]->GetLabel()));
- handlers.push_back(namedExprs[idx]);
- }
- if (withDefault) {
- dflt = positional.GetTupleElement(positional.GetTupleSize() - 1);
- }
- } else {
- size_t minArgs = withDefault ? 2 : 1;
- if (args.size() < minArgs) {
- return new TInvalidBuiltin(pos, TStringBuilder() << name
- << " requires at least " << minArgs << " positional arguments");
- }
- variant = args[0];
- labels.reserve(args.size() - minArgs);
- handlers.reserve(args.size() - minArgs);
- for (size_t idx = 0; idx < args.size() - minArgs; idx++) {
- labels.push_back(BuildQuotedAtom(pos, ToString(idx)));
- handlers.push_back(args[minArgs + idx]);
- }
- if (withDefault) {
- dflt = args[1];
- }
- }
- TVector<TNodePtr> resultArgs;
- resultArgs.reserve(1 + labels.size() + handlers.size());
- resultArgs.emplace_back(std::move(variant));
- for (size_t idx = 0; idx < labels.size(); idx++) {
- resultArgs.emplace_back(std::move(labels[idx]));
- resultArgs.emplace_back(std::move(handlers[idx]));
- }
- if (dflt.Defined()) {
- resultArgs.emplace_back(std::move(dflt->Get()));
- }
- return new TCallNodeImpl(pos, "SqlVisit", 1, -1, resultArgs);
- } else if (normalizedName == "sqlexternalfunction") {
- return new TCallNodeImpl(pos, "SqlExternalFunction", args);
- } else {
- return new TInvalidBuiltin(pos, TStringBuilder() << "Unknown builtin: " << name);
- }
- }
- TNodePtr positionalArgs;
- TNodePtr namedArgs;
- if (mustUseNamed && *mustUseNamed) {
- YQL_ENSURE(args.size() == 2);
- positionalArgs = args[0];
- namedArgs = args[1];
- *mustUseNamed = false;
- }
- TVector<TNodePtr> usedArgs = args;
- TNodePtr customUserType = nullptr;
- if (ns == "json") {
- ctx.Warning(pos, TIssuesIds::YQL_DEPRECATED_JSON_UDF) << "Json UDF is deprecated. Please use JSON API instead";
- ns = "yson";
- nameSpace = "Yson";
- if (name == "Serialize") {
- name = "SerializeJson";
- }
- else if (name == "Parse") {
- name = "ParseJson";
- }
- }
- if (ctx.PragmaYsonFast && ns == "yson") {
- ns.append('2');
- nameSpace.append('2');
- }
- if (ns.StartsWith("yson")) {
- if (name == "ConvertTo" && usedArgs.size() > 1) {
- customUserType = usedArgs[1];
- usedArgs.erase(usedArgs.begin() + 1);
- }
- if (name == "Serialize") {
- if (usedArgs) {
- usedArgs.resize(1U);
- }
- } else if (ctx.PragmaYsonFast && name == "SerializeJsonEncodeUtf8") {
- name = "SerializeJson";
- if (usedArgs.size() < 2U) {
- usedArgs.emplace_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
- }
- positionalArgs = BuildTuple(pos, usedArgs);
- auto encodeUtf8 = BuildLiteralBool(pos, true);
- encodeUtf8->SetLabel("EncodeUtf8");
- namedArgs = BuildStructure(pos, {encodeUtf8});
- usedArgs = {positionalArgs, namedArgs};
- } else if (name.StartsWith("From")) {
- name = "From";
- } else if (name == "GetLength" || name.StartsWith("ConvertTo") || name.StartsWith("Parse") || name.StartsWith("SerializeJson")) {
- if (usedArgs.size() < 2U) {
- usedArgs.emplace_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
- }
- } else if (name == "Contains" || name.StartsWith("Lookup") || name.StartsWith("YPath")) {
- if (usedArgs.size() < 3U) {
- usedArgs.push_back(BuildYsonOptionsNode(pos, ctx.PragmaYsonAutoConvert, ctx.PragmaYsonStrict, ctx.PragmaYsonFast));
- }
- }
- }
- if (ns == "datetime2" && name == "Update") {
- if (namedArgs) {
- TStructNode* castedNamedArgs = namedArgs->GetStructNode();
- Y_DEBUG_ABORT_UNLESS(castedNamedArgs);
- auto exprs = castedNamedArgs->GetExprs();
- for (auto& arg : exprs) {
- if (arg->GetLabel() == "Timezone") {
- arg = new TCallNodeImpl(pos, "TimezoneId", 1, 1, { arg });
- arg->SetLabel("TimezoneId");
- }
- }
- namedArgs = BuildStructure(pos, exprs);
- usedArgs.pop_back();
- usedArgs.push_back(namedArgs);
- };
- }
- TNodePtr typeConfig = MakeTypeConfig(pos, ns, usedArgs);
- return BuildSqlCall(ctx, pos, nameSpace, name, usedArgs, positionalArgs, namedArgs, customUserType,
- TDeferredAtom(typeConfig, ctx), nullptr, nullptr);
- }
- } // namespace NSQLTranslationV1
|