1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877 |
- #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)
- {
- 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()) {
- sqlCallArgs.push_back(new TCallNodeImpl(pos, "TupleType", {}));
- }
- if (!typeConfig.Empty()) {
- sqlCallArgs.push_back(typeConfig.Build());
- } else if (runConfig) {
- sqlCallArgs.push_back(BuildQuotedAtom(pos, ""));
- }
- if (runConfig) {
- sqlCallArgs.push_back(runConfig);
- }
- 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)
- : INode(pos)
- , ModuleName(moduleName)
- , FuncName(funcName)
- , Args(args)
- {}
- 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);
- 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));
- }
- void DoVisitChildren(const TVisitFunc& func, TVisitNodeSet& visited) const final {
- Y_DEBUG_ABORT_UNLESS(Node);
- Node->VisitTree(func, visited);
- }
- private:
- TString ModuleName;
- TString FuncName;
- TVector<TNodePtr> Args;
- TNodePtr Node;
- };
- 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 new TScriptUdf(pos, scriptName, name, args);
- } 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);
- }
- } // namespace NSQLTranslationV1
|