hqltrans.cpp 147 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "jliball.hpp"
  14. #if defined(_DEBUG) && defined(_WIN32) && !defined(USING_MPATROL)
  15. #undef new
  16. #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
  17. #endif
  18. #include "hql.hpp"
  19. #include "platform.h"
  20. #include "jlib.hpp"
  21. #include "jmisc.hpp"
  22. #include "jstream.ipp"
  23. #include "hql.hpp"
  24. #include "hqlexpr.hpp"
  25. #include "hqlexpr.ipp"
  26. #include "hqltrans.ipp"
  27. #include "hqlthql.hpp"
  28. #include "hqlutil.hpp"
  29. #include "hqlpmap.hpp"
  30. #include "hqlerrors.hpp"
  31. #include "hqlerror.hpp"
  32. //#define VERYIFY_OPTIMIZE
  33. #ifdef _DEBUG
  34. #define TRACK_ACTIVE_EXPRESSIONS // Useful for examining the transform path in a debugger
  35. #endif
  36. static unsigned transformerDepth;
  37. static CLargeMemoryAllocator * transformerHeap;
  38. #define ALLOCATOR_MIN_PAGES 10
  39. static IHqlExpression * alreadyVisitedMarker;
  40. static unsigned maxMapCount;
  41. static PointerArrayOf<HqlTransformerInfo> allTransformers;
  42. #ifdef TRACK_ACTIVE_EXPRESSIONS
  43. HqlExprCopyArray activeExprStack;
  44. #endif
  45. MODULE_INIT(INIT_PRIORITY_STANDARD)
  46. {
  47. #ifdef OPTIMIZE_TRANSFORM_ALLOCATOR
  48. transformerHeap = new CLargeMemoryAllocator(0xffffffff, 0xff00, false);
  49. #endif
  50. alreadyVisitedMarker = createAttribute(_alreadyVisitedMarker_Atom);
  51. return true;
  52. }
  53. MODULE_EXIT()
  54. {
  55. if (maxMapCount)
  56. printf("MaxMap = %d\n", maxMapCount);
  57. ::Release(alreadyVisitedMarker);
  58. #ifdef OPTIMIZE_TRANSFORM_ALLOCATOR
  59. delete transformerHeap;
  60. #endif
  61. }
  62. unsigned HqlTransformStats::globalDepth;
  63. HqlTransformStats::HqlTransformStats()
  64. {
  65. clear();
  66. }
  67. void HqlTransformStats::clear()
  68. {
  69. numAnalyse = 0;
  70. numAnalyseCalls = 0;
  71. numTransforms = 0;
  72. numTransformsSame = 0;
  73. numTransformCalls = 0;
  74. numTransformCallsSame = 0;
  75. numTransformSelects = 0;
  76. numTransformSelectsSame = 0;
  77. depth = 0;
  78. maxDepth = 0;
  79. maxGlobalDepth = 0;
  80. #ifdef TRANSFORM_STATS_TIME
  81. totalTime = 0;
  82. childTime = 0;
  83. recursiveTime = 0;
  84. #endif
  85. #ifdef TRANSFORM_STATS_OPS
  86. _clear(transformCount);
  87. #endif
  88. }
  89. void HqlTransformStats::beginTransform()
  90. {
  91. numTransformCalls++;
  92. depth++;
  93. if (depth > maxDepth)
  94. maxDepth = depth;
  95. globalDepth++;
  96. if (globalDepth > maxGlobalDepth)
  97. {
  98. maxGlobalDepth = globalDepth;
  99. }
  100. }
  101. void HqlTransformStats::endMatchTransform(IHqlExpression * expr, IHqlExpression * match)
  102. {
  103. if (expr == match)
  104. numTransformCallsSame++;
  105. depth--;
  106. globalDepth--;
  107. }
  108. void HqlTransformStats::endNewTransform(IHqlExpression * expr, IHqlExpression * transformed)
  109. {
  110. numTransforms++;
  111. depth--;
  112. globalDepth--;
  113. if (expr == transformed)
  114. numTransformsSame++;
  115. #ifdef TRANSFORM_STATS_OPS
  116. transformCount[expr->getOperator()]++;
  117. #endif
  118. }
  119. void HqlTransformStats::add(const HqlTransformStats & other)
  120. {
  121. numAnalyse += other.numAnalyse;
  122. numAnalyseCalls += other.numAnalyseCalls;
  123. numTransforms += other.numTransforms;
  124. numTransformsSame += other.numTransformsSame;
  125. numTransformCalls += other.numTransformCalls;
  126. numTransformCallsSame += other.numTransformCallsSame;
  127. numTransformSelects += other.numTransformSelects;
  128. numTransformSelectsSame += other.numTransformSelectsSame;
  129. if (maxDepth < other.maxDepth)
  130. maxDepth = other.maxDepth;
  131. if (maxGlobalDepth < other.maxGlobalDepth)
  132. maxGlobalDepth = other.maxGlobalDepth;
  133. #ifdef TRANSFORM_STATS_TIME
  134. totalTime += other.totalTime;
  135. childTime += other.childTime;
  136. recursiveTime += other.recursiveTime;
  137. #endif
  138. #ifdef TRANSFORM_STATS_OPS
  139. for (unsigned i=0; i < no_last_pseudoop; i++)
  140. transformCount[i] += other.transformCount[i];
  141. #endif
  142. }
  143. StringBuffer & HqlTransformStats::getText(StringBuffer & out) const
  144. {
  145. #ifdef TRANSFORM_STATS_TIME
  146. out.append(" ti:").append(totalTime-(childTime-recursiveTime)).append(" tt:").append(totalTime).append(" tr:").append(recursiveTime);
  147. #endif
  148. out.append(" a:").append(numAnalyse);
  149. out.append(" ac:").append(numAnalyseCalls);
  150. out.append(" t:").append(numTransforms).append(" ts:").append(numTransformsSame);
  151. out.append(" tc:").append(numTransformCalls).append(" tcs:").append(numTransformsSame+numTransformCallsSame);
  152. out.append(" ts:").append(numTransformSelects).append(" tss:").append(numTransformSelectsSame);
  153. out.append(" md:").append(maxDepth).append(" mgd:").append(maxGlobalDepth);
  154. #ifdef TRANSFORM_STATS_OPS
  155. if (numAnalyse || numTransforms)
  156. {
  157. for (unsigned i=0; i < no_last_pseudoop; i++)
  158. {
  159. if (transformCount[i])
  160. out.appendf("\"%s\",%d", getOpString((node_operator)i), transformCount[i]).newline();
  161. }
  162. }
  163. #endif
  164. return out;
  165. }
  166. IHqlExpression * lookupNewSelectedField(IHqlExpression * ds, IHqlExpression * field)
  167. {
  168. IHqlExpression * record = ds->queryRecord();
  169. if (record)
  170. {
  171. IHqlExpression * matched = record->querySimpleScope()->lookupSymbol(field->queryId());
  172. if (matched)
  173. return matched;
  174. }
  175. return LINK(field);
  176. }
  177. HqlTransformerInfo::HqlTransformerInfo(const char * _name)
  178. {
  179. #ifdef TRANSFORM_STATS
  180. allTransformers.append(this);
  181. #endif
  182. name = _name;
  183. }
  184. HqlTransformerInfo::~HqlTransformerInfo()
  185. {
  186. #ifdef TRANSFORM_STATS
  187. StringBuffer s;
  188. if (getStatsText(s))
  189. printf(s.newline().str());
  190. #endif
  191. }
  192. bool HqlTransformerInfo::getStatsText(StringBuffer & s) const
  193. {
  194. #ifdef TRANSFORM_STATS
  195. if (numInstances)
  196. {
  197. s.append("Transform: ").append(name).append(": i:").append(numInstances);
  198. stats.getText(s);
  199. return true;
  200. }
  201. #endif
  202. return false;
  203. }
  204. void HqlTransformerInfo::resetStats()
  205. {
  206. #ifdef TRANSFORM_STATS
  207. numInstances = 0;
  208. stats.clear();
  209. #endif
  210. }
  211. void dbglogTransformStats(bool reset)
  212. {
  213. //Not at all thread safe, only meant for profiling
  214. StringBuffer s;
  215. ForEachItemIn(i, allTransformers)
  216. {
  217. HqlTransformerInfo * cur = allTransformers.item(i);
  218. if (cur->getStatsText(s.clear()))
  219. {
  220. DBGLOG("%s", s.str());
  221. if (reset)
  222. cur->resetStats();
  223. }
  224. }
  225. }
  226. static bool tracing = false;
  227. extern HQL_API void setTransformTracing(bool ok) { tracing = ok; }
  228. extern HQL_API bool isTransformTracing() { return tracing; }
  229. //-----------------------------------------------------------------------------------------
  230. //weird semantics for efficiency
  231. //if the expression doesn't hide the selector then return 0
  232. //if it does return the number of arguments that aren't hidden
  233. unsigned activityHidesSelectorGetNumNonHidden(IHqlExpression * expr, IHqlExpression * selector)
  234. {
  235. if (!selector)
  236. return 0;
  237. node_operator op = selector->getOperator();
  238. if ((op != no_left) && (op != no_right))
  239. {
  240. switch (getChildDatasetType(expr))
  241. {
  242. case childdataset_dataset:
  243. case childdataset_datasetleft:
  244. case childdataset_top_left_right:
  245. if (expr->queryChild(0)->queryBody() == selector)
  246. return 1;
  247. break;
  248. }
  249. return 0;
  250. }
  251. switch (getChildDatasetType(expr))
  252. {
  253. case childdataset_none:
  254. case childdataset_many_noscope:
  255. case childdataset_many:
  256. case childdataset_map:
  257. case childdataset_dataset_noscope:
  258. case childdataset_if:
  259. case childdataset_case:
  260. case childdataset_dataset:
  261. case childdataset_evaluate:
  262. return 0;
  263. case childdataset_datasetleft:
  264. case childdataset_left:
  265. if (querySelSeq(expr) != selector->queryChild(1))
  266. return 0;
  267. if ((op == no_left) && recordTypesMatch(selector, expr->queryChild(0)))
  268. {
  269. switch (expr->getOperator())
  270. {
  271. case no_loop: case no_graphloop:
  272. return 2;
  273. }
  274. return 1;
  275. }
  276. return 0;
  277. case childdataset_leftright:
  278. if (querySelSeq(expr) != selector->queryChild(1))
  279. return 0;
  280. if (op == no_left)
  281. {
  282. if (recordTypesMatch(selector, expr->queryChild(0)))
  283. {
  284. if (expr->getOperator() == no_normalize)
  285. return 1;
  286. return 2;
  287. }
  288. }
  289. else
  290. {
  291. if (recordTypesMatch(selector, expr->queryChild(1)))
  292. return 2;
  293. }
  294. return 0;
  295. case childdataset_same_left_right:
  296. case childdataset_top_left_right:
  297. case childdataset_nway_left_right:
  298. if (querySelSeq(expr) != selector->queryChild(1))
  299. return 0;
  300. if (recordTypesMatch(selector, expr->queryChild(0)))
  301. return 1;
  302. return 0;
  303. default:
  304. UNIMPLEMENTED;
  305. }
  306. }
  307. bool activityHidesRows(IHqlExpression * expr, IHqlExpression * selector)
  308. {
  309. if (!selector)
  310. return 0;
  311. node_operator selectOp = selector->getOperator();
  312. switch (expr->getOperator())
  313. {
  314. case no_rollupgroup:
  315. case no_loop:
  316. case no_graphloop:
  317. case no_filtergroup:
  318. return (selectOp == no_left);
  319. case no_combinegroup:
  320. case no_denormalizegroup:
  321. return (selectOp == no_right);
  322. }
  323. return false;
  324. }
  325. //---------------------------------------------------------------------------
  326. static void insertScopeSymbols(IHqlScope * newScope, HqlExprArray const & symbols)
  327. {
  328. ForEachItemIn(i, symbols)
  329. newScope->defineSymbol(LINK(&symbols.item(i)));
  330. }
  331. //---------------------------------------------------------------------------
  332. static HqlTransformerBase * activeTransformer; // not thread safe
  333. #ifdef TRANSFORM_STATS_TIME
  334. void HqlTransformerBase::beginTime()
  335. {
  336. startTime = msTick();
  337. prev = activeTransformer;
  338. activeTransformer = this;
  339. }
  340. void HqlTransformerBase::endTime()
  341. {
  342. stats.totalTime = (msTick() - startTime);
  343. if (prev)
  344. prev->noteChildTime(stats.totalTime, &info==&prev->info);
  345. activeTransformer = prev;
  346. }
  347. #endif
  348. void HqlTransformerBase::noteMemory()
  349. {
  350. #ifdef TRANSFORM_STATS_MEMORY
  351. PROGLOG("Finish %s", info.name);
  352. PrintMemoryReport();
  353. #endif
  354. }
  355. bool HqlTransformerBase::optimizedTransformChildren(IHqlExpression * expr, HqlExprArray & children)
  356. {
  357. //Same as transformChildren(), but avoid appending to children array unless something has changed.
  358. unsigned numDone = children.ordinality();
  359. unsigned max = expr->numChildren();
  360. unsigned idx;
  361. for (idx = 0; idx < numDone; idx++)
  362. {
  363. if (&children.item(idx) != expr->queryChild(idx))
  364. break;
  365. }
  366. if (idx == numDone)
  367. {
  368. OwnedHqlExpr lastTransformedChild;
  369. for (;idx < max; idx++)
  370. {
  371. IHqlExpression * child = expr->queryChild(idx);
  372. lastTransformedChild.setown(transform(child));
  373. if (child != lastTransformedChild)
  374. break;
  375. }
  376. if (idx == max)
  377. return true;
  378. children.ensure(max);
  379. for (unsigned i=numDone; i < idx; i++)
  380. children.append(*LINK(expr->queryChild(i)));
  381. children.append(*lastTransformedChild.getClear());
  382. idx++;
  383. }
  384. else
  385. {
  386. children.ensure(max);
  387. idx = numDone;
  388. }
  389. for (;idx < max; idx++)
  390. {
  391. IHqlExpression * child = expr->queryChild(idx);
  392. children.append(*transform(child));
  393. }
  394. return false;
  395. }
  396. IHqlExpression * HqlTransformerBase::transformAlienType(IHqlExpression * expr)
  397. {
  398. HqlExprArray newSymbols;
  399. HqlExprArray children;
  400. Linked<IHqlScope> scope = expr->queryScope();
  401. bool scopeSame = transformScope(newSymbols, scope);
  402. bool same = transformChildren(expr, children);
  403. if (!same || !scopeSame)
  404. {
  405. if (!scopeSame)
  406. {
  407. Owned<IHqlScope> newScope = createScope();
  408. insertScopeSymbols(newScope, newSymbols);
  409. scope.setown(closeScope(newScope.getClear()));
  410. }
  411. return createAlienType(expr->queryId(), scope.getClear(), children, LINK(expr->queryFunctionDefinition()));
  412. }
  413. return LINK(expr);
  414. }
  415. bool HqlTransformerBase::transformChildren(IHqlExpression * expr, HqlExprArray & children)
  416. {
  417. unsigned numDone = children.ordinality();
  418. unsigned max = expr->numChildren();
  419. unsigned idx;
  420. bool same = true;
  421. for (idx = 0; idx < numDone; idx++)
  422. if (&children.item(idx) != expr->queryChild(idx))
  423. same = false;
  424. children.ensure(max);
  425. for (idx=numDone;idx<max;idx++)
  426. {
  427. IHqlExpression * child = expr->queryChild(idx);
  428. IHqlExpression * tchild = transform(child);
  429. children.append(*tchild);
  430. if (child != tchild)
  431. same = false;
  432. }
  433. return same;
  434. }
  435. IHqlExpression * HqlTransformerBase::transformField(IHqlExpression * expr)
  436. {
  437. ITypeInfo * type = expr->queryType();
  438. OwnedITypeInfo newType = transformType(type);
  439. HqlExprArray children;
  440. if (type != newType)
  441. {
  442. transformChildren(expr, children);
  443. return createField(expr->queryId(), LINK(newType), children);
  444. }
  445. return completeTransform(expr, children);
  446. }
  447. bool HqlTransformerBase::transformScope(HqlExprArray & newSymbols, IHqlScope * scope)
  448. {
  449. HqlExprArray symbols;
  450. scope->getSymbols(symbols);
  451. // symbols.sort(compareSymbolsByName);
  452. bool same = true;
  453. ForEachItemIn(idx, symbols)
  454. {
  455. IHqlExpression & cur = symbols.item(idx);
  456. OwnedHqlExpr transformed = transform(&cur);
  457. //Ensure the named symbol associated with the symbol is preserved (can be stripped by normalizer)
  458. if (!hasNamedSymbol(transformed) || (transformed->queryName() != cur.queryName()))
  459. transformed.setown(forceCloneSymbol(&cur, transformed));
  460. if (transformed != &cur)
  461. same = false;
  462. newSymbols.append(*transformed.getClear());
  463. }
  464. return same;
  465. }
  466. bool HqlTransformerBase::transformScope(IHqlScope * newScope, IHqlScope * oldScope)
  467. {
  468. HqlExprArray newSymbols;
  469. bool same = transformScope(newSymbols, oldScope);
  470. insertScopeSymbols(newScope, newSymbols);
  471. return same;
  472. }
  473. IHqlExpression * HqlTransformerBase::transformScope(IHqlExpression * expr)
  474. {
  475. IHqlScope * scope = expr->queryScope();
  476. HqlExprArray symbols, children;
  477. bool same = transformScope(symbols, scope);
  478. if (!transformChildren(expr, children))
  479. same = false;
  480. if (same)
  481. return LINK(expr);
  482. return queryExpression(scope->clone(children, symbols));
  483. }
  484. ITypeInfo * HqlTransformerBase::transformType(ITypeInfo * type)
  485. {
  486. switch (type->queryModifier())
  487. {
  488. case typemod_original:
  489. {
  490. ITypeInfo * typeBase = type->queryTypeBase();
  491. Owned<ITypeInfo> newTypeBase = transformType(typeBase);
  492. IHqlExpression * original = static_cast<IHqlExpression *>(type->queryModifierExtra());
  493. OwnedHqlExpr transformedOriginal = transform(original);
  494. if ((typeBase == newTypeBase) && (original == transformedOriginal))
  495. return LINK(type);
  496. return makeOriginalModifier(newTypeBase.getClear(), transformedOriginal.getClear());
  497. }
  498. case typemod_indirect:
  499. {
  500. IHqlExpression * original = static_cast<IHqlExpression *>(type->queryModifierExtra());
  501. OwnedHqlExpr transformedOriginal = transform(original);
  502. if (original == transformedOriginal)
  503. return LINK(type);
  504. return makeModifier(transformedOriginal->getType(), typemod_indirect, LINK(transformedOriginal));
  505. }
  506. case typemod_none:
  507. break;
  508. default:
  509. {
  510. ITypeInfo * typeBase = type->queryTypeBase();
  511. Owned<ITypeInfo> newType = transformType(typeBase);
  512. if (typeBase == newType)
  513. return LINK(type);
  514. return cloneModifier(type, newType);
  515. }
  516. }
  517. switch (type->getTypeCode())
  518. {
  519. case type_alien:
  520. {
  521. IHqlExpression * typeExpr = queryExpression(type);
  522. OwnedHqlExpr newTypeExpr = transform(typeExpr);
  523. return newTypeExpr->getType();
  524. }
  525. break;
  526. case type_record:
  527. {
  528. IHqlExpression * record = queryExpression(type);
  529. OwnedHqlExpr newRecord = transform(record);
  530. return newRecord->getType();
  531. }
  532. case type_set:
  533. {
  534. ITypeInfo * childType = type->queryChildType();
  535. if (childType)
  536. {
  537. Owned<ITypeInfo> newChild = transformType(childType);
  538. if (childType != newChild)
  539. return makeSetType(newChild.getClear());
  540. }
  541. break;
  542. }
  543. case type_scope:
  544. {
  545. IHqlExpression * scope = queryExpression(type);
  546. OwnedHqlExpr newScope = transform(scope);
  547. return newScope->getType();
  548. }
  549. case type_row:
  550. case type_transform:
  551. case type_pattern:
  552. case type_rule:
  553. case type_token:
  554. case type_groupedtable:
  555. case type_table:
  556. case type_dictionary:
  557. {
  558. ITypeInfo * childType = type->queryChildType();
  559. OwnedITypeInfo newChildType = safeTransformType(childType);
  560. return replaceChildType(type, newChildType);
  561. }
  562. }
  563. return LINK(type);
  564. }
  565. //---------------------------------------------------------------------------
  566. QuickHqlTransformer::QuickHqlTransformer(HqlTransformerInfo & _info, IErrorReceiver * _errors) : HqlTransformerBase(_info)
  567. {
  568. errors = _errors;
  569. }
  570. void QuickHqlTransformer::analyse(IHqlExpression * expr)
  571. {
  572. #ifdef TRANSFORM_STATS
  573. stats.numAnalyseCalls++;
  574. #endif
  575. IHqlExpression * match = static_cast<IHqlExpression *>(expr->queryTransformExtra());
  576. if (match)
  577. return;
  578. #ifdef TRANSFORM_STATS
  579. stats.numAnalyse++;
  580. #endif
  581. doAnalyse(expr);
  582. expr->setTransformExtraUnlinked(alreadyVisitedMarker);
  583. }
  584. void QuickHqlTransformer::doAnalyse(IHqlExpression * expr)
  585. {
  586. IHqlExpression * body = expr->queryBody(true);
  587. if (expr != body)
  588. {
  589. if (body)
  590. analyse(body);
  591. }
  592. else
  593. {
  594. #ifdef TRANSFORM_STATS_OPS
  595. stats.transformCount[expr->getOperator()]++;
  596. #endif
  597. doAnalyseBody(expr);
  598. }
  599. }
  600. void QuickHqlTransformer::doAnalyseBody(IHqlExpression * expr)
  601. {
  602. unsigned max = expr->numChildren();
  603. for (unsigned i=0; i < max; i++)
  604. analyse(expr->queryChild(i));
  605. node_operator op = expr->getOperator();
  606. switch (op)
  607. {
  608. case no_call:
  609. case no_libraryscopeinstance:
  610. analyse(expr->queryDefinition());
  611. break;
  612. case no_getresult:
  613. case no_newtransform:
  614. case no_transform:
  615. {
  616. IHqlExpression * oldRecord = queryOriginalRecord(expr);
  617. if (oldRecord)
  618. analyse(oldRecord);
  619. break;
  620. }
  621. case no_scope:
  622. case no_virtualscope:
  623. case no_concretescope:
  624. case no_libraryscope:
  625. case no_forwardscope:
  626. {
  627. IHqlScope * scope = expr->queryScope();
  628. HqlExprArray oldsyms;
  629. scope->getSymbols(oldsyms);
  630. oldsyms.sort(compareSymbolsByName);
  631. for (unsigned idx = 0; idx < oldsyms.length(); idx++)
  632. {
  633. IHqlExpression *oldkid = &oldsyms.item(idx);
  634. analyse(oldkid);
  635. }
  636. break;
  637. }
  638. case no_type:
  639. {
  640. IHqlScope * scope = expr->queryScope();
  641. if (scope)
  642. analyse(scope);
  643. break;
  644. }
  645. case no_enum:
  646. analyse(expr->queryScope());
  647. break;
  648. case no_field:
  649. {
  650. ITypeInfo * type = expr->queryType();
  651. switch (type->getTypeCode())
  652. {
  653. case type_alien:
  654. analyse(queryExpression(type));
  655. break;
  656. case type_record:
  657. throwUnexpected();
  658. case type_row:
  659. case type_table:
  660. case type_groupedtable:
  661. analyse(queryOriginalRecord(expr));
  662. break;
  663. }
  664. }
  665. break;
  666. }
  667. }
  668. void QuickHqlTransformer::analyse(IHqlScope * scope)
  669. {
  670. analyse(queryExpression(scope));
  671. }
  672. void QuickHqlTransformer::analyseArray(const HqlExprArray & exprs)
  673. {
  674. ForEachItemIn(i, exprs)
  675. analyse(&exprs.item(i));
  676. }
  677. IHqlExpression * QuickHqlTransformer::transform(IHqlExpression * expr)
  678. {
  679. #ifdef TRANSFORM_STATS
  680. stats.beginTransform();
  681. #endif
  682. IHqlExpression * match = static_cast<IHqlExpression *>(expr->queryTransformExtra());
  683. if (match && (match != alreadyVisitedMarker))
  684. {
  685. #ifdef TRANSFORM_STATS
  686. stats.endMatchTransform(expr, match);
  687. #endif
  688. return LINK(match);
  689. }
  690. IHqlExpression * ret = createTransformed(expr);
  691. #ifdef TRANSFORM_STATS
  692. stats.endNewTransform(expr, ret);
  693. #endif
  694. expr->setTransformExtra(ret);
  695. return ret;
  696. }
  697. void QuickHqlTransformer::transformArray(const HqlExprArray & in, HqlExprArray & out)
  698. {
  699. ForEachItemIn(idx, in)
  700. {
  701. OwnedHqlExpr ret = transform(&in.item(idx));
  702. if (ret)
  703. unwindCommaCompound(out, ret);
  704. }
  705. }
  706. IHqlExpression * QuickHqlTransformer::createTransformed(IHqlExpression * expr)
  707. {
  708. IHqlExpression * body = expr->queryBody(true);
  709. if (expr != body)
  710. {
  711. OwnedHqlExpr newbody = transform(body);
  712. if (body == newbody)
  713. return LINK(expr);
  714. return expr->cloneAnnotation(newbody);
  715. }
  716. return createTransformedBody(expr);
  717. }
  718. IHqlExpression * QuickHqlTransformer::doCreateTransformedScope(IHqlExpression * expr)
  719. {
  720. HqlExprArray children;
  721. IHqlScope * scope = expr->queryScope();
  722. bool same = transformChildren(expr, children);
  723. if (expr->getOperator() == no_forwardscope)
  724. {
  725. scope = scope->queryResolvedScope(NULL);
  726. same = false;
  727. }
  728. HqlExprArray newsyms;
  729. if (!transformScope(newsyms, scope))
  730. same = false;
  731. if (same)
  732. return LINK(expr);
  733. return queryExpression(scope->clone(children, newsyms));
  734. }
  735. IHqlExpression * QuickHqlTransformer::createTransformedBody(IHqlExpression * expr)
  736. {
  737. node_operator op = expr->getOperator();
  738. unsigned max = expr->numChildren();
  739. if (max == 0)
  740. {
  741. switch (op)
  742. {
  743. case no_scope:
  744. case no_privatescope:
  745. case no_virtualscope:
  746. case no_concretescope:
  747. case no_forwardscope:
  748. case no_type:
  749. case no_enum:
  750. case no_field:
  751. case no_call:
  752. case no_libraryscopeinstance:
  753. case no_param:
  754. break;
  755. default:
  756. return LINK(expr);
  757. }
  758. }
  759. HqlExprArray children;
  760. switch (op)
  761. {
  762. case no_call:
  763. case no_libraryscopeinstance:
  764. {
  765. IHqlExpression * funcDef = expr->queryDefinition();
  766. Owned<IHqlExpression> newFuncDef = transform(funcDef);
  767. if (funcDef != newFuncDef)
  768. {
  769. transformChildren(expr, children);
  770. return createReboundFunction(newFuncDef, children);
  771. }
  772. break;
  773. }
  774. case no_getresult:
  775. if (!expr->queryRecord())
  776. break;
  777. case no_newtransform:
  778. case no_transform:
  779. case no_rowsetrange:
  780. case no_datasetlist:
  781. case no_rowset:
  782. {
  783. ITypeInfo * type = expr->queryType();
  784. OwnedITypeInfo newType = transformType(type);
  785. if (type != newType)
  786. {
  787. transformChildren(expr, children);
  788. return createValue(op, newType.getClear(), children);
  789. }
  790. break;
  791. }
  792. case no_privatescope:
  793. throwUnexpected();
  794. case no_scope:
  795. case no_virtualscope:
  796. case no_concretescope:
  797. case no_libraryscope:
  798. case no_forwardscope:
  799. return doCreateTransformedScope(expr);
  800. case no_delayedscope:
  801. {
  802. OwnedHqlExpr newScope = transform(expr->queryChild(0));
  803. if (newScope->queryScope())
  804. return newScope.getClear();
  805. break;
  806. }
  807. case no_assertconcrete:
  808. {
  809. OwnedHqlExpr newScope = transform(expr->queryChild(0));
  810. IHqlScope * scope = newScope->queryScope();
  811. if (scope)
  812. {
  813. IHqlScope * concrete = scope->queryConcreteScope();
  814. if (concrete)
  815. return newScope.getClear();
  816. }
  817. break;
  818. }
  819. case no_type:
  820. return transformAlienType(expr);
  821. case no_enum:
  822. {
  823. IHqlScope * scope = expr->queryScope();
  824. Owned<IHqlScope> newScope = transform(scope);
  825. if (scope == newScope)
  826. return LINK(expr);
  827. return createEnumType(expr->getType(), newScope.getClear());
  828. }
  829. case no_field:
  830. {
  831. ITypeInfo * type = expr->queryType();
  832. OwnedITypeInfo newType = transformType(type);
  833. if (type != newType)
  834. {
  835. transformChildren(expr, children);
  836. return createField(expr->queryId(), LINK(newType), children);
  837. }
  838. break;
  839. }
  840. case no_funcdef:
  841. {
  842. if (transformChildren(expr, children))
  843. return LINK(expr);
  844. return createFunctionDefinition(expr->queryId(), children);
  845. }
  846. case no_param:
  847. {
  848. ITypeInfo * type = expr->queryType();
  849. Owned<ITypeInfo> newType = transformType(type);
  850. transformChildren(expr, children);
  851. if (type != newType)
  852. return createParameter(expr->queryId(), (unsigned)expr->querySequenceExtra(), newType.getClear(), children);
  853. break;
  854. }
  855. case no_delayedselect:
  856. {
  857. IHqlExpression * oldModule = expr->queryChild(1);
  858. OwnedHqlExpr newModule = transform(oldModule);
  859. if (oldModule != newModule)
  860. {
  861. IIdAtom * selectedName = expr->queryChild(3)->queryId();
  862. HqlDummyLookupContext dummyctx(errors);
  863. IHqlScope * newScope = newModule->queryScope();
  864. if (newScope)
  865. return newScope->lookupSymbol(selectedName, makeLookupFlags(true, expr->hasAttribute(ignoreBaseAtom), false), dummyctx);
  866. }
  867. break;
  868. }
  869. case no_select:
  870. {
  871. IHqlExpression * field = expr->queryChild(1);
  872. OwnedHqlExpr newDs = transform(expr->queryChild(0));
  873. children.append(*LINK(newDs));
  874. children.append(*lookupNewSelectedField(newDs, field));
  875. break;
  876. }
  877. }
  878. return completeTransform(expr, children);
  879. }
  880. IHqlScope * QuickHqlTransformer::transform(IHqlScope * scope)
  881. {
  882. IHqlExpression * scopeExpr = queryExpression(scope);
  883. return transform(scopeExpr)->queryScope();
  884. }
  885. void QuickHqlTransformer::setMapping(IHqlExpression * oldValue, IHqlExpression * newValue)
  886. {
  887. loop
  888. {
  889. oldValue->setTransformExtra(newValue);
  890. IHqlExpression * body = oldValue->queryBody(true);
  891. if (oldValue == body)
  892. break;
  893. oldValue = body;
  894. newValue = newValue->queryBody(true);
  895. }
  896. }
  897. //-------------------------------------------------------------------------------------------------
  898. //NB: Derived from QuickHqlTransformer since it is called before the tree is normalised
  899. static HqlTransformerInfo quickExpressionReplacerInfo("QuickExpressionReplacer");
  900. QuickExpressionReplacer::QuickExpressionReplacer()
  901. : QuickHqlTransformer(quickExpressionReplacerInfo, NULL)
  902. {
  903. }
  904. void QuickExpressionReplacer::setMapping(IHqlExpression * oldValue, IHqlExpression * newValue)
  905. {
  906. loop
  907. {
  908. oldValue->setTransformExtra(newValue);
  909. IHqlExpression * body = oldValue->queryBody(true);
  910. if (body == oldValue)
  911. break;
  912. oldValue = body;
  913. newValue = newValue->queryBody(true);
  914. }
  915. }
  916. IHqlExpression * quickFullReplaceExpression(IHqlExpression * expr, IHqlExpression * oldValue, IHqlExpression * newValue)
  917. {
  918. if (oldValue == newValue)
  919. return LINK(expr);
  920. if (expr == oldValue)
  921. return LINK(newValue);
  922. QuickExpressionReplacer map;
  923. map.setMapping(oldValue, newValue);
  924. return map.transform(expr);
  925. }
  926. IHqlExpression * quickFullReplaceExpressions(IHqlExpression * expr, const HqlExprArray & oldValues, const HqlExprArray & newValues)
  927. {
  928. QuickExpressionReplacer map;
  929. ForEachItemIn(i, oldValues)
  930. map.setMapping(&oldValues.item(i), &newValues.item(i));
  931. return map.transform(expr);
  932. }
  933. //-------------------------------------------------------------------------------------------------
  934. static HqlTransformerInfo quickExpressionLocatorInfo("QuickExpressionLocator");
  935. class HQL_API QuickExpressionLocator : public QuickHqlTransformer
  936. {
  937. public:
  938. QuickExpressionLocator(IHqlExpression * _search)
  939. : QuickHqlTransformer(quickExpressionLocatorInfo, NULL), search(_search)
  940. {
  941. }
  942. virtual IHqlExpression * createTransformedBody(IHqlExpression * expr)
  943. {
  944. assertex(expr != search);
  945. return QuickHqlTransformer::createTransformedBody(expr);
  946. }
  947. protected:
  948. HqlExprAttr search;
  949. };
  950. extern void assertNoMatchingExpression(IHqlExpression * expr, IHqlExpression * search)
  951. {
  952. QuickExpressionLocator locator(search->queryBody());
  953. OwnedHqlExpr ret = locator.transform(expr);
  954. }
  955. //-------------------------------------------------------------------------------------------------
  956. static HqlTransformerInfo debugDifferenceAnalyserInfo("DebugDifferenceAnalyser");
  957. DebugDifferenceAnalyser::DebugDifferenceAnalyser(IIdAtom * _search) : QuickHqlTransformer(debugDifferenceAnalyserInfo, NULL)
  958. {
  959. prev = NULL;
  960. search = _search;
  961. }
  962. void DebugDifferenceAnalyser::doAnalyse(IHqlExpression * expr)
  963. {
  964. if (expr->queryName() == createAtom("f_fuzzy") || expr->queryName() == createAtom("f_exact"))
  965. {
  966. if (prev && prev->queryBody() != expr->queryBody())
  967. {
  968. debugFindFirstDifference(expr, prev);
  969. return;
  970. }
  971. else
  972. prev = expr;
  973. }
  974. QuickHqlTransformer::doAnalyse(expr);
  975. }
  976. //-------------------------------------------------------------------------------------------------
  977. //NB: Derived from QuickHqlTransformer since it is called before the tree is normalised
  978. static HqlTransformerInfo hqlSectionAnnotatorInfo("HqlSectionAnnotator");
  979. HqlSectionAnnotator::HqlSectionAnnotator(IHqlExpression * sectionWorkflow)
  980. : QuickHqlTransformer(hqlSectionAnnotatorInfo, NULL)
  981. {
  982. HqlExprArray args;
  983. args.append(*LINK(sectionWorkflow->queryChild(0)));
  984. ForEachChildFrom(i, sectionWorkflow, 1)
  985. {
  986. IHqlExpression * cur = sectionWorkflow->queryChild(i);
  987. if (cur->isAttribute())
  988. args.append(*LINK(cur));
  989. }
  990. sectionAttr.setown(createExprAttribute(sectionAtom, args));
  991. }
  992. void HqlSectionAnnotator::noteInput(IHqlExpression * expr)
  993. {
  994. setMapping(expr, expr);
  995. }
  996. IHqlExpression * HqlSectionAnnotator::createTransformedBody(IHqlExpression * expr)
  997. {
  998. OwnedHqlExpr ret = QuickHqlTransformer::createTransformedBody(expr);
  999. if (!ret->isDataset() || !okToAddAnnotation(expr))
  1000. return ret.getClear();
  1001. HqlExprArray args;
  1002. args.append(*LINK(sectionAttr));
  1003. return createMetaAnnotation(ret.getClear(), args);
  1004. }
  1005. //---------------------------------------------------------------------------
  1006. ANewTransformInfo::ANewTransformInfo(IHqlExpression * _original)
  1007. {
  1008. original = _original;
  1009. lastPass = (byte) -1;
  1010. flags = 0;
  1011. spareByte1 = 0;
  1012. spareByte2 = 0;
  1013. }
  1014. //---------------------------------------------------------------------------
  1015. inline bool quickTransformMustTraverse(IHqlExpression * expr)
  1016. {
  1017. return containsNonActiveDataset(expr) || containsActiveNonSelector(expr) || containsMustHoist(expr);
  1018. }
  1019. NewHqlTransformer::NewHqlTransformer(HqlTransformerInfo & _info) : ANewHqlTransformer(_info)
  1020. {
  1021. analyseFlags = TFunconditional;
  1022. optimizeFlags = 0;
  1023. pass = (unsigned) -2;
  1024. }
  1025. bool NewHqlTransformer::alreadyVisited(ANewTransformInfo * extra)
  1026. {
  1027. if (extra->lastPass == pass)
  1028. return true;
  1029. #ifdef TRANSFORM_STATS
  1030. stats.numAnalyse++;
  1031. #endif
  1032. extra->lastPass = pass;
  1033. return false;
  1034. }
  1035. bool NewHqlTransformer::alreadyVisited(IHqlExpression * expr)
  1036. {
  1037. return alreadyVisited(queryTransformExtra(expr));
  1038. }
  1039. void NewHqlTransformer::analyse(IHqlExpression * expr, unsigned _pass)
  1040. {
  1041. pass = _pass;
  1042. analyseExpr(expr);
  1043. pass = (unsigned) -1;
  1044. }
  1045. void NewHqlTransformer::analyseArray(const HqlExprArray & exprs, unsigned _pass)
  1046. {
  1047. pass = _pass;
  1048. ForEachItemIn(idx, exprs)
  1049. analyseExpr(&exprs.item(idx));
  1050. pass = (unsigned) -1;
  1051. }
  1052. void NewHqlTransformer::analyseChildren(IHqlExpression * expr)
  1053. {
  1054. ForEachChild(idx, expr)
  1055. analyseExpr(expr->queryChild(idx));
  1056. }
  1057. void NewHqlTransformer::doAnalyseChildren(IHqlExpression * expr, unsigned first)
  1058. {
  1059. unsigned max = expr->numChildren();
  1060. for (unsigned idx = first; idx < max; idx++)
  1061. analyseExpr(expr->queryChild(idx));
  1062. }
  1063. void NewHqlTransformer::doAnalyseChildren(IHqlExpression * expr, unsigned first, unsigned last)
  1064. {
  1065. for (unsigned idx = first; idx < last; idx++)
  1066. analyseExpr(expr->queryChild(idx));
  1067. }
  1068. void NewHqlTransformer::quickAnalyseTransform(IHqlExpression * expr)
  1069. {
  1070. ForEachChild(i, expr)
  1071. {
  1072. IHqlExpression * cur = expr->queryChild(i);
  1073. switch (cur->getOperator())
  1074. {
  1075. case no_assignall:
  1076. quickAnalyseTransform(cur);
  1077. break;
  1078. case no_assign:
  1079. if (quickTransformMustTraverse(cur->queryChild(1)))
  1080. analyseAssign(cur);
  1081. break;
  1082. default:
  1083. analyseExpr(cur);
  1084. break;
  1085. }
  1086. }
  1087. }
  1088. void NewHqlTransformer::analyseExpr(IHqlExpression * expr)
  1089. {
  1090. #ifdef TRANSFORM_STATS
  1091. stats.numAnalyseCalls++;
  1092. #endif
  1093. node_operator op = expr->getOperator();
  1094. switch (op)
  1095. {
  1096. case no_field:
  1097. case no_record:
  1098. break;
  1099. case no_attr:
  1100. case no_attr_expr:
  1101. case no_attr_link:
  1102. case no_constant:
  1103. case no_translated:
  1104. case no_getresult:
  1105. break;
  1106. case no_newkeyindex:
  1107. //by default only look at the filename
  1108. analyseExpr(expr->queryChild(3));
  1109. break;
  1110. case no_select:
  1111. {
  1112. IHqlExpression * ds = expr->queryChild(0);
  1113. #ifdef _DEBUG
  1114. IHqlExpression * field = expr->queryChild(1);
  1115. #endif
  1116. if (isNewSelector(expr))
  1117. analyseExpr(ds);
  1118. else
  1119. analyseSelector(ds);
  1120. break;
  1121. }
  1122. case no_filepos:
  1123. case no_file_logicalname:
  1124. case no_offsetof:
  1125. case no_joined:
  1126. analyseSelector(expr->queryChild(0));
  1127. break;
  1128. case no_activerow:
  1129. analyseSelector(expr->queryChild(0));
  1130. break;
  1131. case no_assign:
  1132. analyseAssign(expr);
  1133. break;
  1134. case no_newtransform:
  1135. case no_transform:
  1136. if (optimizeFlags & TCOtransformNonActive)
  1137. quickAnalyseTransform(expr);
  1138. else
  1139. analyseChildren(expr);
  1140. break;
  1141. case no_sequential:
  1142. {
  1143. unsigned oldFlags = analyseFlags;
  1144. analyseFlags |= TFsequential;
  1145. analyseChildren(expr);
  1146. analyseFlags = oldFlags;
  1147. break;
  1148. }
  1149. case no_if:
  1150. {
  1151. analyseExpr(expr->queryChild(0));
  1152. unsigned oldFlags = analyseFlags;
  1153. analyseFlags = (analyseFlags & ~TFunconditional) | TFconditional;
  1154. analyseExpr(expr->queryChild(1));
  1155. if (expr->queryChild(2))
  1156. analyseExpr(expr->queryChild(2));
  1157. analyseFlags = oldFlags;
  1158. break;
  1159. }
  1160. default:
  1161. analyseChildren(expr);
  1162. break;
  1163. }
  1164. }
  1165. void NewHqlTransformer::analyseAssign(IHqlExpression * expr)
  1166. {
  1167. //optimization: don't traverse LHS of an assignment
  1168. analyseExpr(expr->queryChild(1));
  1169. }
  1170. void NewHqlTransformer::analyseSelector(IHqlExpression * expr)
  1171. {
  1172. if ((expr->getOperator() == no_select) && !expr->hasAttribute(newAtom))
  1173. analyseSelector(expr->queryChild(0));
  1174. }
  1175. IHqlExpression * NewHqlTransformer::quickTransformTransform(IHqlExpression * expr)
  1176. {
  1177. bool same = true;
  1178. unsigned max = expr->numChildren();
  1179. HqlExprArray children;
  1180. children.ensure(max);
  1181. for (unsigned i=0; i < max; i++)
  1182. {
  1183. IHqlExpression * cur = expr->queryChild(i);
  1184. IHqlExpression * tr;
  1185. switch (cur->getOperator())
  1186. {
  1187. case no_assignall:
  1188. tr = quickTransformTransform(cur);
  1189. break;
  1190. case no_assign:
  1191. {
  1192. IHqlExpression * src = cur->queryChild(1);
  1193. if (quickTransformMustTraverse(src))
  1194. tr = transformAssign(cur);
  1195. else
  1196. {
  1197. #ifdef VERYIFY_OPTIMIZE
  1198. tr = transformAssign(cur);
  1199. assertex(tr == cur);
  1200. #else
  1201. tr = LINK(cur);
  1202. #endif
  1203. }
  1204. break;
  1205. }
  1206. default:
  1207. tr = transform(cur);
  1208. break;
  1209. }
  1210. children.append(*tr);
  1211. if (cur != tr)
  1212. same = false;
  1213. }
  1214. IHqlExpression * oldRecord = expr->queryRecord();
  1215. if (oldRecord)
  1216. {
  1217. LinkedHqlExpr newRecord = queryTransformed(oldRecord);
  1218. if (oldRecord != newRecord)
  1219. {
  1220. ITypeInfo * newRecordType = newRecord->queryRecordType();
  1221. OwnedHqlExpr ret = createValue(expr->getOperator(), makeRowType(LINK(newRecordType)), children);
  1222. return expr->cloneAllAnnotations(ret);
  1223. }
  1224. }
  1225. if (same)
  1226. return LINK(expr);
  1227. return expr->clone(children);
  1228. }
  1229. //optimization: don't traverse LHS of an assignment, and minimise
  1230. IHqlExpression * NewHqlTransformer::transformAssign(IHqlExpression * expr)
  1231. {
  1232. IHqlExpression * rhs = expr->queryChild(1);
  1233. OwnedHqlExpr newRhs = transform(rhs);
  1234. if (rhs == newRhs)
  1235. return LINK(expr);
  1236. return createAssign(LINK(expr->queryChild(0)), newRhs.getClear());
  1237. }
  1238. /* In expr: not linked. return: linked */
  1239. IHqlExpression * NewHqlTransformer::createTransformed(IHqlExpression * expr)
  1240. {
  1241. node_operator op = expr->getOperator();
  1242. HqlExprArray children;
  1243. bool same = true;
  1244. switch (op)
  1245. {
  1246. case no_field:
  1247. case no_record:
  1248. return LINK(queryTransformed(expr));
  1249. case no_cloned:
  1250. case no_cachealias:
  1251. break;
  1252. case no_constant:
  1253. case no_attr:
  1254. return LINK(expr);
  1255. // case no_attr_link:
  1256. // return getTransformedChildren(expr);
  1257. case no_newtransform:
  1258. if (!expr->queryRecord())
  1259. return completeTransform(expr, children);
  1260. //fall through
  1261. case no_transform:
  1262. if ((op == no_transform) && (optimizeFlags & TCOtransformNonActive))
  1263. return quickTransformTransform(expr);
  1264. //fall through...
  1265. case no_rowsetrange:
  1266. case no_datasetlist:
  1267. case no_rowset:
  1268. //Another nasty: The type may have changed - but does not depend on any parameters...
  1269. {
  1270. same = transformChildren(expr, children);
  1271. //NB: Check if type has changed after transforming children!
  1272. ITypeInfo * type = expr->queryType();
  1273. OwnedITypeInfo newType = transformType(type);
  1274. if (type != newType)
  1275. {
  1276. OwnedHqlExpr ret = createValue(op, newType.getClear(), children);
  1277. return expr->cloneAllAnnotations(ret);
  1278. }
  1279. }
  1280. break;
  1281. case no_select:
  1282. if (isNewSelector(expr))
  1283. {
  1284. same = transformChildren(expr, children);
  1285. IHqlExpression & ds = children.item(0);
  1286. node_operator dsOp = ds.getOperator();
  1287. if (dsOp == no_activetable)
  1288. {
  1289. children.replace(*LINK(ds.queryChild(0)), 0);
  1290. removeAttribute(children, newAtom);
  1291. }
  1292. else if (!expr->hasAttribute(newAtom))
  1293. {
  1294. //unusual situation x.a<new>.b; x.a<new> is converted to d, but d.b is not right, it should now be d.b<new>
  1295. assertex(ds.isDatarow());
  1296. if ((dsOp != no_select) || !isNewSelector(&ds))
  1297. children.append(*LINK(queryNewSelectAttrExpr()));
  1298. }
  1299. if (children.ordinality() > 2)
  1300. {
  1301. if (isAlwaysActiveRow(&ds) || ((dsOp == no_select) && ds.isDatarow()))
  1302. removeAttribute(children, newAtom);
  1303. }
  1304. }
  1305. else
  1306. return createTransformedActiveSelect(expr);
  1307. break;
  1308. case no_filepos:
  1309. case no_file_logicalname:
  1310. case no_offsetof:
  1311. case no_nameof:
  1312. {
  1313. IHqlExpression * selector = expr->queryChild(0);
  1314. IHqlExpression * newSelector = transformSelector(selector);
  1315. children.append(*newSelector);
  1316. if (selector != newSelector)
  1317. same = false;
  1318. if (!transformChildren(expr, children))
  1319. same = false;
  1320. break;
  1321. }
  1322. case no_activerow:
  1323. {
  1324. IHqlExpression * ds = expr->queryChild(0);
  1325. OwnedHqlExpr newDs = transformSelector(ds);
  1326. if (ds != newDs)
  1327. {
  1328. if (newDs->getOperator() == no_newrow)
  1329. return LINK(newDs->queryChild(0));
  1330. same = false;
  1331. children.append(*newDs.getClear());
  1332. }
  1333. break;
  1334. }
  1335. case no_virtualscope:
  1336. return transformScope(expr);
  1337. case no_libraryscopeinstance:
  1338. {
  1339. IHqlExpression * oldFunction = expr->queryDefinition();
  1340. OwnedHqlExpr newFunction = transform(oldFunction);
  1341. HqlExprArray children;
  1342. bool same = transformChildren(expr, children);
  1343. if (!same || (newFunction != oldFunction))
  1344. return createLibraryInstance(newFunction.getClear(), children);
  1345. return LINK(expr);
  1346. }
  1347. case no_assign:
  1348. return transformAssign(expr);
  1349. case no_newkeyindex:
  1350. {
  1351. //Default action is to leave the (null) input dataset, record and transform untouched
  1352. IHqlExpression * filename = expr->queryChild(3);
  1353. OwnedHqlExpr newFilename = transform(filename);
  1354. if (filename == newFilename)
  1355. return LINK(expr);
  1356. unwindChildren(children, expr);
  1357. children.replace(*newFilename.getClear(), 3);
  1358. return expr->clone(children);
  1359. }
  1360. case no_getgraphresult:
  1361. case no_getgraphloopresult:
  1362. case no_translated:
  1363. case no_rows:
  1364. case no_left:
  1365. case no_right:
  1366. return LINK(expr);
  1367. case no_funcdef:
  1368. {
  1369. if (transformChildren(expr, children))
  1370. return LINK(expr);
  1371. return createFunctionDefinition(expr->queryId(), children);
  1372. }
  1373. default:
  1374. return completeTransform(expr, children);
  1375. }
  1376. if (!same)
  1377. return expr->clone(children);
  1378. return LINK(expr);
  1379. }
  1380. IHqlExpression * NewHqlTransformer::transformSelector(IHqlExpression * expr)
  1381. {
  1382. #ifdef TRANSFORM_STATS
  1383. stats.numTransformSelects++;
  1384. #endif
  1385. expr = expr->queryNormalizedSelector();
  1386. IHqlExpression * transformed = queryAlreadyTransformedSelector(expr);
  1387. if (transformed)
  1388. {
  1389. #ifdef TRANSFORM_STATS
  1390. if (expr == transformed)
  1391. stats.numTransformSelectsSame++;
  1392. #endif
  1393. if (transformed->getOperator() == no_activerow)
  1394. return LINK(transformed->queryChild(0));
  1395. return LINK(transformed);
  1396. }
  1397. transformed = queryAlreadyTransformed(expr);
  1398. if (transformed)
  1399. transformed = LINK(transformed->queryNormalizedSelector());
  1400. else
  1401. transformed = createTransformedSelector(expr);
  1402. #ifdef TRANSFORM_STATS
  1403. if (expr == transformed)
  1404. stats.numTransformSelectsSame++;
  1405. #endif
  1406. setTransformedSelector(expr, transformed);
  1407. return transformed;
  1408. }
  1409. IHqlExpression * NewHqlTransformer::createTransformedSelector(IHqlExpression * expr)
  1410. {
  1411. node_operator op = expr->getOperator();
  1412. switch (op)
  1413. {
  1414. case no_select:
  1415. return createTransformedActiveSelect(expr);
  1416. default:
  1417. //NB: no_if etc. should have gone down the transform branch, and then met a no_activerow if in scope.
  1418. //NB: queryTransformed etc. have already been called.
  1419. return LINK(expr->queryNormalizedSelector());
  1420. }
  1421. }
  1422. IHqlExpression * NewHqlTransformer::createTransformedActiveSelect(IHqlExpression * expr)
  1423. {
  1424. IHqlExpression * left = expr->queryChild(0);
  1425. IHqlExpression * right = expr->queryChild(1);
  1426. OwnedHqlExpr newLeft = transformSelector(left);
  1427. IHqlExpression * newRight = right; // NB: Assumes fields don't change - unless transform for no_select overridden [queryTransformed(right)]
  1428. IHqlExpression * normLeft = left->queryNormalizedSelector();
  1429. if ((normLeft == newLeft) && (newRight == right))
  1430. return LINK(expr->queryNormalizedSelector());
  1431. OwnedHqlExpr mappedRight = lookupNewSelectedField(newLeft, right);
  1432. if (mappedRight && newRight != mappedRight)
  1433. {
  1434. assertex(normLeft->queryNormalizedSelector() != newLeft->queryNormalizedSelector());
  1435. newRight = mappedRight;
  1436. }
  1437. if (newLeft->getOperator() == no_newrow)
  1438. return createNewSelectExpr(LINK(newLeft->queryChild(0)), LINK(newRight));
  1439. //NOTE: In very obscure situations: ds[1].x.ds<new>.y -> z.ds<new>.y (newLeft != normalizeSelector)
  1440. //NB: newLeft.get() == newLeft->queryNormalizedSelector() - asserted above
  1441. return createSelectExpr(LINK(newLeft->queryNormalizedSelector()), LINK(newRight));
  1442. }
  1443. ANewTransformInfo * NewHqlTransformer::createTransformInfo(IHqlExpression * expr)
  1444. {
  1445. return CREATE_NEWTRANSFORMINFO(NewTransformInfo, expr);
  1446. }
  1447. IHqlExpression * NewHqlTransformer::getTransformedChildren(IHqlExpression * expr)
  1448. {
  1449. IHqlExpression * transformed = queryAlreadyTransformed(expr);
  1450. if (transformed)
  1451. return LINK(transformed);
  1452. HqlExprArray children;
  1453. unsigned max = expr->numChildren();
  1454. unsigned idx;
  1455. bool same = true;
  1456. children.ensure(max);
  1457. for (idx=0;idx<max;idx++)
  1458. {
  1459. IHqlExpression * child = expr->queryChild(idx);
  1460. IHqlExpression * tchild = getTransformedChildren(child);
  1461. children.append(*tchild);
  1462. if (child != tchild)
  1463. same = false;
  1464. }
  1465. //MORE: Need to have similar code to transform... to map the bodies.
  1466. if (!same)
  1467. transformed = expr->clone(children);
  1468. else
  1469. transformed = LINK(expr);
  1470. //I'm not sure that this should really call setTransformed
  1471. //worry about it later... - really should cache in a separate thing like transformedSelector
  1472. setTransformed(expr, transformed);
  1473. return transformed;
  1474. }
  1475. void NewHqlTransformer::initializeActiveSelector(IHqlExpression * expr, IHqlExpression * transformed)
  1476. {
  1477. loop
  1478. {
  1479. setTransformedSelector(expr->queryNormalizedSelector(), transformed->queryNormalizedSelector());
  1480. if (!expr->queryDataset()) // parent could be a row. e.g., LEFT.childDataset
  1481. return;
  1482. IHqlExpression * root = queryExpression(expr->queryDataset()->queryRootTable());
  1483. if (!root || root->getOperator() != no_select)
  1484. return;
  1485. IHqlExpression * transformedRoot = queryExpression(transformed->queryDataset()->queryRootTable());
  1486. assertex(transformedRoot);
  1487. while (transformedRoot->getOperator() == no_alias)
  1488. transformedRoot = queryExpression(transformedRoot->queryChild(0)->queryDataset()->queryRootTable());
  1489. if (transformedRoot->getOperator() != no_select)
  1490. {
  1491. //What was a select has now become something else - e.g., if resourcing
  1492. //may well cause dataset out of scope problems problems later.
  1493. DBGLOG("Warning: a normalized select was replaced with a non-select. This may cause unresolved datasets later");
  1494. return;
  1495. }
  1496. expr = root->queryChild(0);
  1497. transformed = transformedRoot->queryChild(0);
  1498. }
  1499. }
  1500. IHqlExpression * NewHqlTransformer::queryTransformed(IHqlExpression * expr)
  1501. {
  1502. IHqlExpression * transformed = queryAlreadyTransformed(expr);
  1503. if (transformed)
  1504. return transformed;
  1505. return expr;
  1506. }
  1507. ANewTransformInfo * NewHqlTransformer::queryTransformExtra(IHqlExpression * expr)
  1508. {
  1509. IInterface * extra = expr->queryTransformExtra();
  1510. if (extra)
  1511. return (NewTransformInfo *)extra;
  1512. ANewTransformInfo * newExtra = createTransformInfo(expr);
  1513. expr->setTransformExtraOwned(newExtra);
  1514. return newExtra;
  1515. }
  1516. void NewHqlTransformer::stopDatasetTransform(IHqlExpression * expr)
  1517. {
  1518. loop
  1519. {
  1520. IHqlExpression * prev;
  1521. do
  1522. {
  1523. setTransformed(expr, expr);
  1524. prev = expr;
  1525. expr = expr->queryBody(true);
  1526. } while (expr != prev);
  1527. if (definesColumnList(expr))
  1528. break;
  1529. expr = expr->queryChild(0);
  1530. }
  1531. }
  1532. void NewHqlTransformer::transformRoot(const HqlExprArray & in, HqlExprArray & out)
  1533. {
  1534. ForEachItemIn(idx, in)
  1535. {
  1536. OwnedHqlExpr ret = doTransformRootExpr(&in.item(idx));
  1537. if (ret)
  1538. unwindCommaCompound(out, ret);
  1539. }
  1540. }
  1541. IHqlExpression * NewHqlTransformer::doTransformRootExpr(IHqlExpression * expr)
  1542. {
  1543. return transform(expr);
  1544. }
  1545. IHqlExpression * NewHqlTransformer::queryAlreadyTransformed(IHqlExpression * expr)
  1546. {
  1547. IInterface * extra = expr->queryTransformExtra();
  1548. if (extra)
  1549. return ((NewTransformInfo *)extra)->queryTransformed();
  1550. return NULL;
  1551. }
  1552. IHqlExpression * NewHqlTransformer::queryAlreadyTransformedSelector(IHqlExpression * expr)
  1553. {
  1554. IInterface * extra = expr->queryTransformExtra();
  1555. if (extra)
  1556. return ((NewTransformInfo *)extra)->queryTransformedSelector();
  1557. return NULL;
  1558. }
  1559. void NewHqlTransformer::setTransformed(IHqlExpression * expr, IHqlExpression * transformed)
  1560. {
  1561. #ifdef _DEBUG
  1562. //Following test doesn't work because of call to setTransformed() in getTransformedChildren()
  1563. //which doesn't seem a good idea - should revisit it.
  1564. //assertex(!queryAlreadyTransformed(expr));
  1565. #endif
  1566. queryTransformExtra(expr)->setTransformed(transformed);
  1567. }
  1568. void NewHqlTransformer::setTransformedSelector(IHqlExpression * expr, IHqlExpression * transformed)
  1569. {
  1570. assertex(expr == expr->queryNormalizedSelector());
  1571. //in rare situations a selector could get converted to a non-selector e.g, when replace self-ref with a new dataset.
  1572. assertex(!transformed || transformed == transformed->queryNormalizedSelector() || transformed->hasAttribute(newAtom));
  1573. queryTransformExtra(expr)->setTransformedSelector(transformed);
  1574. }
  1575. /* In expr: not linked. Return: linked */
  1576. IHqlExpression * NewHqlTransformer::transform(IHqlExpression * expr)
  1577. {
  1578. #ifdef TRANSFORM_STATS
  1579. stats.beginTransform();
  1580. #endif
  1581. IHqlExpression * transformed = queryAlreadyTransformed(expr);
  1582. if (transformed)
  1583. {
  1584. #ifdef _DEBUG
  1585. assertex(!(expr->isDatarow() && transformed->isDataset())); // spot converting RIGHT to dataset without active row wrapper.
  1586. #endif
  1587. #ifdef TRANSFORM_STATS
  1588. stats.endMatchTransform(expr, transformed);
  1589. #endif
  1590. return LINK(transformed);
  1591. }
  1592. #ifdef TRACK_ACTIVE_EXPRESSIONS
  1593. activeExprStack.append(*expr);
  1594. #endif
  1595. transformed = createTransformed(expr);
  1596. #ifdef TRACK_ACTIVE_EXPRESSIONS
  1597. activeExprStack.pop();
  1598. #endif
  1599. #ifdef TRANSFORM_STATS
  1600. stats.endNewTransform(expr, transformed);
  1601. #endif
  1602. #ifdef _DEBUG
  1603. assertex(!(expr->isDatarow() && transformed->isDataset()));
  1604. #endif
  1605. setTransformed(expr, transformed);
  1606. //Need to map the bodies of this expression to the corresponding children, otherwise
  1607. //the type of a transform doesn't change, even though the named record has.
  1608. IHqlExpression * body = expr->queryBody(true);
  1609. if (body != expr)
  1610. {
  1611. IHqlExpression * transformedBody = transformed->queryBody(true);
  1612. do
  1613. {
  1614. //If child body is already mapped then don't remap it, otherwise tree can become inconsistent
  1615. if (queryAlreadyTransformed(body))
  1616. break;
  1617. setTransformed(body, transformedBody);
  1618. expr = body;
  1619. body = body->queryBody(true);
  1620. transformedBody = transformedBody->queryBody(true);
  1621. } while (expr != body);
  1622. }
  1623. return transformed;
  1624. }
  1625. IHqlExpression * NewHqlTransformer::queryTransformAnnotation(IHqlExpression * expr)
  1626. {
  1627. IHqlExpression * body = expr->queryBody(true);
  1628. if (expr == body)
  1629. return NULL;
  1630. return createTransformedAnnotation(expr);
  1631. }
  1632. IHqlExpression * NewHqlTransformer::createTransformedAnnotation(IHqlExpression * expr)
  1633. {
  1634. annotate_kind kind = expr->getAnnotationKind();
  1635. IHqlExpression * body = expr->queryBody(true);
  1636. if (kind == annotate_symbol || kind == annotate_location)
  1637. locations.append(*expr);
  1638. OwnedHqlExpr newBody = transform(body);
  1639. if (kind == annotate_symbol || kind == annotate_location)
  1640. locations.pop();
  1641. if (body == newBody)
  1642. return LINK(expr);
  1643. if (hasNamedSymbol(newBody) && expr->isNamedSymbol())
  1644. return newBody.getClear();
  1645. return expr->cloneAnnotation(newBody);
  1646. }
  1647. IHqlExpression * NewHqlTransformer::queryActiveSymbol() const
  1648. {
  1649. ForEachItemInRev(i, locations)
  1650. {
  1651. IHqlExpression & cur = locations.item(i);
  1652. if (cur.getAnnotationKind() == annotate_symbol)
  1653. return &cur;
  1654. }
  1655. return NULL;
  1656. }
  1657. IHqlExpression * NewHqlTransformer::queryActiveLocation() const
  1658. {
  1659. if (locations.ordinality() == 0)
  1660. return NULL;
  1661. return &locations.tos();
  1662. }
  1663. IHqlExpression * NewHqlTransformer::queryActiveLocation(IHqlExpression * expr) const
  1664. {
  1665. if (expr)
  1666. {
  1667. IHqlExpression * location = queryLocation(expr);
  1668. if (location)
  1669. return location;
  1670. }
  1671. return queryActiveLocation();
  1672. }
  1673. IHqlExpression * NewHqlTransformer::transformExternalCall(IHqlExpression * expr)
  1674. {
  1675. IHqlExpression * body = expr->queryBody();
  1676. IHqlExpression * oldFuncdef = body->queryExternalDefinition();
  1677. OwnedHqlExpr newFuncdef = transform(oldFuncdef);
  1678. HqlExprArray args;
  1679. bool same = transformChildren(body, args);
  1680. if (same && (oldFuncdef == newFuncdef))
  1681. return LINK(expr);
  1682. OwnedHqlExpr newCall = CHqlExternalCall::makeExternalCall(LINK(newFuncdef), newFuncdef->queryChild(0)->getType(), args);
  1683. return expr->cloneAllAnnotations(newCall);
  1684. }
  1685. IHqlExpression * NewHqlTransformer::transformCall(IHqlExpression * expr)
  1686. {
  1687. IHqlExpression * body = expr->queryBody();
  1688. IHqlExpression * oldFuncdef = body->queryFunctionDefinition();
  1689. OwnedHqlExpr newFuncdef = transform(oldFuncdef);
  1690. HqlExprArray args;
  1691. bool same = transformChildren(body, args);
  1692. if (same && (oldFuncdef == newFuncdef))
  1693. return LINK(expr);
  1694. OwnedHqlExpr newCall = createBoundFunction(NULL, newFuncdef, args, NULL, DEFAULT_EXPAND_CALL);
  1695. return expr->cloneAllAnnotations(newCall);
  1696. }
  1697. void NewHqlTransformer::setMapping(IHqlExpression * oldValue, IHqlExpression * newValue)
  1698. {
  1699. setSelectorMapping(oldValue, newValue);
  1700. setMappingOnly(oldValue, newValue);
  1701. }
  1702. void NewHqlTransformer::setMappingOnly(IHqlExpression * oldValue, IHqlExpression * newValue)
  1703. {
  1704. loop
  1705. {
  1706. setTransformed(oldValue, newValue);
  1707. IHqlExpression * body = oldValue->queryBody(true);
  1708. if (oldValue == body)
  1709. break;
  1710. oldValue = body;
  1711. newValue = newValue->queryBody(true);
  1712. }
  1713. }
  1714. void NewHqlTransformer::setSelectorMapping(IHqlExpression * oldValue, IHqlExpression * newValue)
  1715. {
  1716. setTransformedSelector(oldValue->queryNormalizedSelector(), newValue->queryNormalizedSelector());
  1717. }
  1718. IHqlExpression * NewHqlTransformer::doUpdateOrphanedSelectors(IHqlExpression * expr, IHqlExpression * transformed)
  1719. {
  1720. //If the parent has changed to then the active selector may have changed out of step with the parent dataset
  1721. //so need to explicitly remap the dataset.
  1722. //Happens in constant folding when filters etc. are replaced with a very different child
  1723. //Happens when also hoisting a non-table expression e.g, globalAutoHoist
  1724. IHqlExpression * newDs = transformed->queryChild(0);
  1725. if (!newDs || !newDs->isDataset())
  1726. return LINK(transformed);
  1727. childDatasetType childType = getChildDatasetType(expr);
  1728. if (!(childType & childdataset_hasdataset))
  1729. return LINK(transformed);
  1730. LinkedHqlExpr updated = transformed;
  1731. IHqlExpression * ds = expr->queryChild(0);
  1732. loop
  1733. {
  1734. if (newDs == ds)
  1735. return updated.getClear();
  1736. OwnedHqlExpr transformedSelector = transformSelector(ds->queryNormalizedSelector());
  1737. IHqlExpression * newSelector = newDs->queryNormalizedSelector();
  1738. if (transformedSelector != newSelector)
  1739. {
  1740. HqlExprArray args;
  1741. args.append(*LINK(updated->queryChild(0)));
  1742. replaceSelectors(args, updated, 1, transformedSelector, newSelector);
  1743. updated.setown(updated->clone(args));
  1744. }
  1745. //In unusual situations we also need to map selectors for any parent datasets that are in scope
  1746. IHqlExpression * newRoot = queryRoot(newDs);
  1747. if (!newRoot || newRoot->getOperator() != no_select)
  1748. break;
  1749. IHqlExpression * oldRoot = queryRoot(ds);
  1750. if (!oldRoot || oldRoot->getOperator() != no_select)
  1751. break;
  1752. if (oldRoot == newRoot)
  1753. break;
  1754. //ds.x has changed to ds'.x - need to map any selectors from ds to ds'
  1755. newDs = queryDatasetCursor(newRoot->queryChild(0));
  1756. ds = queryDatasetCursor(oldRoot->queryChild(0));
  1757. }
  1758. return updated.getClear();
  1759. }
  1760. //---------------------------------------------------------------------------
  1761. static HqlTransformerInfo hqlMapTransformerInfo("HqlMapTransformer");
  1762. HqlMapTransformer::HqlMapTransformer() : NewHqlTransformer(hqlMapTransformerInfo)
  1763. {
  1764. }
  1765. IHqlExpression * HqlMapTransformer::queryMapping(IHqlExpression * oldValue)
  1766. {
  1767. return queryTransformed(oldValue);
  1768. }
  1769. static HqlTransformerInfo hqlMapDatasetTransformerInfo("HqlMapDatasetTransformer");
  1770. HqlMapDatasetTransformer::HqlMapDatasetTransformer() : NewHqlTransformer(hqlMapDatasetTransformerInfo)
  1771. {
  1772. }
  1773. IHqlExpression * replaceExpression(IHqlExpression * expr, IHqlExpression * original, IHqlExpression * replacement)
  1774. {
  1775. if (expr == original)
  1776. return LINK(replacement);
  1777. //if dataset that doesn't define columns is replaced with an expression that does then you need to remap any
  1778. //specially update selectors in nested expressions.
  1779. if (original->isDataset())
  1780. {
  1781. if (!definesColumnList(original) && definesColumnList(replacement))
  1782. {
  1783. HqlMapDatasetTransformer simpleTransformer;
  1784. simpleTransformer.setMapping(original, replacement);
  1785. return simpleTransformer.transformRoot(expr);
  1786. }
  1787. }
  1788. HqlMapTransformer simpleTransformer;
  1789. simpleTransformer.setMapping(original, replacement);
  1790. return simpleTransformer.transformRoot(expr);
  1791. }
  1792. //---------------------------------------------------------------------------
  1793. IHqlExpression * replaceDataset(IHqlExpression * expr, IHqlExpression * original, IHqlExpression * replacement)
  1794. {
  1795. return replaceExpression(expr, original, replacement);
  1796. }
  1797. //---------------------------------------------------------------------------
  1798. HqlMapSelectorTransformer::HqlMapSelectorTransformer(IHqlExpression * oldDataset, IHqlExpression * newValue)
  1799. {
  1800. oldSelector.set(oldDataset);
  1801. LinkedHqlExpr newSelector = newValue;
  1802. LinkedHqlExpr newDataset = newValue;
  1803. if (newDataset->getOperator() == no_newrow)
  1804. newDataset.set(newDataset->queryChild(0));
  1805. else if (newDataset->isDataset())
  1806. newDataset.setown(ensureActiveRow(newDataset));
  1807. node_operator op = oldDataset->getOperator();
  1808. assertex(op != no_left && op != no_right);
  1809. if (oldDataset->isDatarow() || (op == no_activetable) || (op == no_selfref))
  1810. {
  1811. setMappingOnly(oldDataset, newDataset);
  1812. }
  1813. else
  1814. {
  1815. assertex(op != no_self);
  1816. setMappingOnly(oldDataset, oldDataset); // Don't change any new references to the dataset
  1817. }
  1818. setSelectorMapping(oldDataset, newSelector);
  1819. }
  1820. IHqlExpression * HqlMapSelectorTransformer::createTransformed(IHqlExpression * expr)
  1821. {
  1822. switch (getChildDatasetType(expr))
  1823. {
  1824. case childdataset_none:
  1825. case childdataset_many_noscope:
  1826. case childdataset_many:
  1827. case childdataset_map:
  1828. case childdataset_dataset_noscope:
  1829. case childdataset_if:
  1830. case childdataset_case:
  1831. case childdataset_evaluate:
  1832. case childdataset_left:
  1833. case childdataset_leftright:
  1834. case childdataset_same_left_right:
  1835. case childdataset_nway_left_right:
  1836. return HqlMapTransformer::createTransformed(expr);
  1837. case childdataset_dataset:
  1838. case childdataset_datasetleft:
  1839. case childdataset_top_left_right:
  1840. break;
  1841. default:
  1842. UNIMPLEMENTED;
  1843. }
  1844. //If this expression is a child dataset with a filter on the same dataset that is being replaced,
  1845. //then ensure the selectors aren't replaced in this operator's arguments.
  1846. IHqlExpression * dataset = expr->queryChild(0);
  1847. IHqlExpression * walker = dataset;
  1848. loop
  1849. {
  1850. IHqlExpression * table = queryTable(walker);
  1851. if (table)
  1852. {
  1853. if (table->queryNormalizedSelector() == oldSelector)
  1854. break;
  1855. if (table->getOperator() == no_select)
  1856. {
  1857. bool isNew;
  1858. walker = querySelectorDataset(table, isNew);
  1859. if (isNew)
  1860. continue;
  1861. }
  1862. }
  1863. return HqlMapTransformer::createTransformed(expr);
  1864. }
  1865. OwnedHqlExpr transformedDataset = transform(dataset);
  1866. //optimization to avoid the clone
  1867. if (dataset == transformedDataset)
  1868. return LINK(expr);
  1869. HqlExprArray args;
  1870. args.append(*transformedDataset.getClear());
  1871. unwindChildren(args, expr, 1);
  1872. return expr->clone(args);
  1873. }
  1874. static HqlTransformerInfo hqlScopedMapSelectorTransformerInfo("HqlScopedMapSelectorTransformer");
  1875. HqlScopedMapSelectorTransformer::HqlScopedMapSelectorTransformer(IHqlExpression * oldDataset, IHqlExpression * newDataset)
  1876. : MergingHqlTransformer(hqlScopedMapSelectorTransformerInfo)
  1877. {
  1878. IHqlExpression * newSelector = newDataset;
  1879. if (newDataset->getOperator() == no_newrow)
  1880. newDataset = newDataset->queryChild(0);
  1881. node_operator op = oldDataset->getOperator();
  1882. if (oldDataset->isDatarow() || op == no_activetable || op == no_self || op == no_selfref)
  1883. {
  1884. setMappingOnly(oldDataset, newDataset); // A row, so Don't change any new references to the dataset
  1885. //MORE: We should be very
  1886. }
  1887. else
  1888. {
  1889. setMappingOnly(oldDataset, oldDataset); // Don't change any new references to the dataset
  1890. }
  1891. setSelectorMapping(oldDataset, newSelector);
  1892. }
  1893. static HqlTransformerInfo nestedHqlMapTransformerInfo("NestedHqlMapTransformer");
  1894. NestedHqlMapTransformer::NestedHqlMapTransformer() : NestedHqlTransformer(nestedHqlMapTransformerInfo)
  1895. {
  1896. }
  1897. //---------------------------------------------------------------------------
  1898. ConditionalHqlTransformer::ConditionalHqlTransformer(HqlTransformerInfo & _info, unsigned _flags) : NewHqlTransformer(_info)
  1899. {
  1900. flags = _flags;
  1901. conditionDepth = 0;
  1902. containsUnknownIndependentContents = false;
  1903. }
  1904. ANewTransformInfo * ConditionalHqlTransformer::createTransformInfo(IHqlExpression * expr)
  1905. {
  1906. return CREATE_NEWTRANSFORMINFO(ConditionalTransformInfo, expr);
  1907. }
  1908. bool ConditionalHqlTransformer::analyseThis(IHqlExpression * expr)
  1909. {
  1910. if (pass == 0)
  1911. {
  1912. ConditionalTransformInfo * extra = queryBodyExtra(expr);
  1913. if (alreadyVisited(extra))
  1914. {
  1915. if (extra->isUnconditional() || (conditionDepth > 0))
  1916. return false;
  1917. extra->setUnconditional();
  1918. }
  1919. else
  1920. {
  1921. if (conditionDepth == 0)
  1922. extra->setFirstUnconditional();
  1923. }
  1924. return true;
  1925. }
  1926. return !alreadyVisited(expr);
  1927. }
  1928. void ConditionalHqlTransformer::analyseExpr(IHqlExpression * expr)
  1929. {
  1930. if (!analyseThis(expr))
  1931. return;
  1932. doAnalyseExpr(expr);
  1933. }
  1934. void ConditionalHqlTransformer::doAnalyseExpr(IHqlExpression * expr)
  1935. {
  1936. node_operator op = expr->getOperator();
  1937. switch (op)
  1938. {
  1939. case no_colon:
  1940. //Hoisting transforms need to happen after the workflow separation - otherwise
  1941. //you can end up with an exponential expansion of persist points.
  1942. throwUnexpected();
  1943. case no_cluster:
  1944. case no_sequential:
  1945. containsUnknownIndependentContents = true;
  1946. return;
  1947. case no_allnodes:
  1948. case no_thisnode:
  1949. if (!(flags & CTFtraverseallnodes))
  1950. return;
  1951. break;
  1952. case no_globalscope:
  1953. if (!expr->hasAttribute(localAtom))
  1954. {
  1955. unsigned savedDepth = conditionDepth;
  1956. conditionDepth = 0;
  1957. analyseExpr(expr->queryChild(0));
  1958. conditionDepth = savedDepth;
  1959. return;
  1960. }
  1961. break;
  1962. case no_if:
  1963. case no_and:
  1964. case no_or:
  1965. case no_mapto:
  1966. case no_map:
  1967. case no_which:
  1968. case no_rejected:
  1969. case no_choose:
  1970. case no_chooseds:
  1971. if (treatAsConditional(expr))
  1972. {
  1973. analyseExpr(expr->queryChild(0));
  1974. conditionDepth++;
  1975. ForEachChildFrom(idx, expr, 1)
  1976. analyseExpr(expr->queryChild(idx));
  1977. conditionDepth--;
  1978. return;
  1979. }
  1980. break;
  1981. case no_case:
  1982. if (treatAsConditional(expr))
  1983. {
  1984. analyseExpr(expr->queryChild(0));
  1985. analyseExpr(expr->queryChild(1));
  1986. conditionDepth++;
  1987. ForEachChildFrom(idx, expr, 2)
  1988. analyseExpr(expr->queryChild(idx));
  1989. conditionDepth--;
  1990. return;
  1991. }
  1992. break;
  1993. case no_attr_expr:
  1994. analyseChildren(expr);
  1995. return;
  1996. }
  1997. NewHqlTransformer::analyseExpr(expr);
  1998. }
  1999. bool ConditionalHqlTransformer::treatAsConditional(IHqlExpression * expr)
  2000. {
  2001. switch (expr->getOperator())
  2002. {
  2003. case no_if:
  2004. return ((flags & CTFnoteifall) ||
  2005. ((flags & CTFnoteifactions) && expr->isAction()) ||
  2006. ((flags & CTFnoteifdatasets) && expr->isDataset()) ||
  2007. ((flags & CTFnoteifdatarows) && expr->isDatarow()));
  2008. case no_or:
  2009. return (flags & CTFnoteor) != 0;
  2010. case no_and:
  2011. return (flags & CTFnoteor) != 0;
  2012. case no_case:
  2013. case no_map:
  2014. case no_mapto:
  2015. return (flags & CTFnotemap) != 0;
  2016. case no_which:
  2017. case no_rejected:
  2018. case no_choose:
  2019. return (flags & CTFnotewhich) != 0;
  2020. }
  2021. return false;
  2022. }
  2023. //---------------------------------------------------------------------------
  2024. HoistingHqlTransformer::HoistingHqlTransformer(HqlTransformerInfo & _info, unsigned _flags) : ConditionalHqlTransformer(_info, _flags)
  2025. {
  2026. target = NULL;
  2027. }
  2028. void HoistingHqlTransformer::setParent(const HoistingHqlTransformer * parent)
  2029. {
  2030. assertex(parent->independentCache);
  2031. independentCache.set(parent->independentCache);
  2032. }
  2033. void HoistingHqlTransformer::transformRoot(const HqlExprArray & in, HqlExprArray & out)
  2034. {
  2035. HqlExprArray * savedTarget = target;
  2036. target = &out;
  2037. //If there is a single ensureresult, then transform it specially, so that any hoisted values are
  2038. //only inside the ensure result. If multiple assume we want to create cses globally (e.g., shared stored)
  2039. if ((in.ordinality() == 1) && (in.item(0).getOperator() == no_ensureresult))
  2040. out.append(*transformEnsureResult(&in.item(0)));
  2041. else
  2042. NewHqlTransformer::transformRoot(in, out);
  2043. target = savedTarget;
  2044. }
  2045. void HoistingHqlTransformer::appendToTarget(IHqlExpression & cur)
  2046. {
  2047. target->append(cur);
  2048. }
  2049. void HoistingHqlTransformer::transformArray(const HqlExprArray & in, HqlExprArray & out)
  2050. {
  2051. HqlExprArray * savedTarget = target;
  2052. target = &out;
  2053. ForEachItemIn(idx, in)
  2054. out.append(*transform(&in.item(idx)));
  2055. target = savedTarget;
  2056. }
  2057. IHqlExpression * HoistingHqlTransformer::transformRoot(IHqlExpression * expr)
  2058. {
  2059. HqlExprArray args, transformed;
  2060. unwindCommaCompound(args, expr);
  2061. transformRoot(args, transformed);
  2062. return createActionList(transformed);
  2063. }
  2064. //A good idea, but I need to get my head around roxie/thor differences and see if we can execute graphs more dynamically.
  2065. IHqlExpression * HoistingHqlTransformer::createTransformed(IHqlExpression * expr)
  2066. {
  2067. //#ifdef _DEBUG
  2068. // assertex(expr->queryBody() == expr);
  2069. //#endif
  2070. node_operator op = expr->getOperator();
  2071. switch (op)
  2072. {
  2073. case no_allnodes: // MORE: This needs really needs to recurse, and substitute within no_thisnode - not quite sure how that would happen
  2074. case no_thisnode:
  2075. //I'm not sure this is a good solution - really contents of no_thisnode should be hoisted in common, would require dependence on insideAllNodes
  2076. if (!(flags & CTFtraverseallnodes))
  2077. return LINK(expr);
  2078. break;
  2079. case no_cluster:
  2080. {
  2081. HqlExprArray args;
  2082. args.append(*transformIndependent(expr->queryChild(0)));
  2083. return completeTransform(expr, args);
  2084. }
  2085. case no_colon:
  2086. case no_sequential:
  2087. {
  2088. HqlExprArray args;
  2089. ForEachChild(i, expr)
  2090. args.append(*transformIndependent(expr->queryChild(i)));
  2091. return expr->clone(args);
  2092. }
  2093. case no_apply:
  2094. {
  2095. //Temporary fix for bug #30255
  2096. OwnedHqlExpr transformed = NewHqlTransformer::createTransformed(expr);
  2097. IHqlExpression * child = expr->queryChild(0);
  2098. IHqlExpression * transformedChild = transformed->queryChild(0);
  2099. if (child->queryNormalizedSelector() != transformedChild->queryNormalizedSelector())
  2100. {
  2101. HqlExprArray args;
  2102. args.append(*LINK(transformedChild));
  2103. ForEachChildFrom(i, transformed, 1)
  2104. args.append(*replaceSelector(transformed->queryChild(i), child->queryNormalizedSelector(), transformedChild->queryNormalizedSelector()));
  2105. return transformed->clone(args);
  2106. }
  2107. return transformed.getClear();
  2108. }
  2109. case no_subgraph:
  2110. {
  2111. HqlExprArray args, transformedArgs;
  2112. unwindChildren(args, expr);
  2113. transformArray(args, transformedArgs);
  2114. return completeTransform(expr, transformedArgs);
  2115. }
  2116. case no_if:
  2117. if (treatAsConditional(expr))
  2118. {
  2119. HqlExprArray args;
  2120. args.append(*transform(expr->queryChild(0)));
  2121. {
  2122. OwnedHqlExpr transformedTrue = transform(expr->queryChild(1));
  2123. args.append(*transformIndependent(transformedTrue));
  2124. }
  2125. if (queryRealChild(expr, 2))
  2126. {
  2127. OwnedHqlExpr transformedFalse = transform(expr->queryChild(2));
  2128. args.append(*transformIndependent(transformedFalse));
  2129. }
  2130. return completeTransform(expr, args);
  2131. }
  2132. break;
  2133. }
  2134. return NewHqlTransformer::createTransformed(expr);
  2135. }
  2136. IHqlExpression * HoistingHqlTransformer::transformEnsureResult(IHqlExpression * expr)
  2137. {
  2138. OwnedHqlExpr transformed = transformRoot(expr->queryChild(0));
  2139. HqlExprArray args;
  2140. unwindCommaCompound(args, transformed);
  2141. unsigned max = args.ordinality();
  2142. OwnedHqlExpr value;
  2143. if (!args.item(max-1).isAction())
  2144. {
  2145. value.setown(&args.popGet());
  2146. if (args.ordinality())
  2147. {
  2148. OwnedHqlExpr actions = createActionList(args);
  2149. value.setown(createCompound(actions.getClear(), LINK(value)));
  2150. }
  2151. }
  2152. else
  2153. value.setown(createActionList(args));
  2154. return replaceChild(expr, 0, value);
  2155. }
  2156. IHqlExpression * HoistingHqlTransformer::IndependentTransformMap::getTransformed(IHqlExpression * expr)
  2157. {
  2158. for (unsigned i=0; i < cache.ordinality(); i+=2)
  2159. {
  2160. if (expr == &cache.item(i))
  2161. return LINK(&cache.item(i+1));
  2162. }
  2163. return NULL;
  2164. }
  2165. void HoistingHqlTransformer::IndependentTransformMap::setTransformed(IHqlExpression * expr, IHqlExpression * transformed)
  2166. {
  2167. cache.append(*LINK(expr));
  2168. cache.append(*LINK(transformed));
  2169. }
  2170. IHqlExpression * HoistingHqlTransformer::transformIndependent(IHqlExpression * expr)
  2171. {
  2172. if (!independentCache)
  2173. independentCache.setown(new IndependentTransformMap);
  2174. //Separately cache all transformations of independent expressions. Otherwise highly nested independent
  2175. //expressions can cause a combinatorial explosion in the number of times the leaves are transformed.
  2176. IHqlExpression * prev = independentCache->getTransformed(expr);
  2177. if (prev)
  2178. return prev;
  2179. OwnedHqlExpr transformed = doTransformIndependent(expr);
  2180. independentCache->setTransformed(expr, transformed);
  2181. return transformed.getClear();
  2182. }
  2183. //---------------------------------------------------------------------------
  2184. void NestedHqlTransformer::beginNestedScope()
  2185. {
  2186. depthStack.append(savedSelectors.ordinality());
  2187. depthStack.append(savedTransformed.ordinality());
  2188. }
  2189. void NestedHqlTransformer::endNestedScope()
  2190. {
  2191. unsigned prevTransforms = depthStack.pop();
  2192. unsigned prevSelectors = depthStack.pop();
  2193. while (savedSelectors.ordinality() != prevSelectors)
  2194. {
  2195. IHqlExpression & cur = savedSelectors.pop();
  2196. NewHqlTransformer::setTransformedSelector(&cur, NULL);
  2197. }
  2198. while (savedTransformed.ordinality() != prevTransforms)
  2199. {
  2200. OwnedHqlExpr prev = &savedTransformedValue.popGet();
  2201. if (prev == savedNull)
  2202. prev.clear();
  2203. IHqlExpression & cur = savedTransformed.pop();
  2204. NewHqlTransformer::setTransformed(&cur, prev);
  2205. }
  2206. }
  2207. void NestedHqlTransformer::setTransformed(IHqlExpression * expr, IHqlExpression * transformed)
  2208. {
  2209. if (depthStack.ordinality() != 0)
  2210. {
  2211. savedTransformed.append(*expr);
  2212. IHqlExpression * saved = queryTransformed(expr);
  2213. if (!saved) saved = savedNull;
  2214. savedTransformedValue.append(*LINK(saved));
  2215. }
  2216. NewHqlTransformer::setTransformed(expr, transformed);
  2217. }
  2218. void NestedHqlTransformer::setTransformedSelector(IHqlExpression * expr, IHqlExpression * transformed)
  2219. {
  2220. if (depthStack.ordinality() != 0)
  2221. savedSelectors.append(*expr);
  2222. NewHqlTransformer::setTransformedSelector(expr, transformed);
  2223. }
  2224. //---------------------------------------------------------------------------
  2225. bool onlyTransformOnce(IHqlExpression * expr)
  2226. {
  2227. switch (expr->getOperator())
  2228. {
  2229. case no_field:
  2230. case no_constant:
  2231. case no_record:
  2232. case no_param:
  2233. case no_translated:
  2234. case no_attr:
  2235. case no_all:
  2236. case no_counter:
  2237. case no_sequence:
  2238. case no_self:
  2239. case no_selfref:
  2240. case no_flat:
  2241. case no_any:
  2242. case no_existsgroup:
  2243. case no_countgroup:
  2244. return true;
  2245. case no_pat_const:
  2246. //Many more patterns could go here. Would be safer if I had a flag to indicate they contained validators/transforms.
  2247. return true;
  2248. case no_skip:
  2249. case no_thor:
  2250. case no_csv:
  2251. case no_xml:
  2252. case no_list:
  2253. return (expr->numChildren() == 0);
  2254. case no_select:
  2255. if (expr->queryChild(0)->getOperator() == no_self)
  2256. return true;
  2257. break;
  2258. case no_assign:
  2259. //return onlyTransformOnce(expr->queryChild(1));
  2260. if (onlyTransformOnce(expr->queryChild(1)))
  2261. return true;
  2262. break;
  2263. default:
  2264. // is this valid?
  2265. // if (original->isConstant())
  2266. // onlyTransformOnce = true;
  2267. break;
  2268. }
  2269. return false;
  2270. }
  2271. //---------------------------------------------------------------------------
  2272. MergingTransformSimpleInfo::MergingTransformSimpleInfo(IHqlExpression * _expr) : AMergingTransformInfo(_expr)
  2273. {
  2274. }
  2275. IHqlExpression * MergingTransformSimpleInfo::queryAlreadyTransformed(IHqlExpression * childScope)
  2276. {
  2277. return inlineQueryTransformed();
  2278. }
  2279. void MergingTransformSimpleInfo::setTransformed(IHqlExpression * childScope, IHqlExpression * value)
  2280. {
  2281. inlineSetTransformed(value);
  2282. }
  2283. IHqlExpression * MergingTransformSimpleInfo::queryAlreadyTransformedSelector(IHqlExpression * childScope)
  2284. {
  2285. return inlineQueryTransformedSelector();
  2286. }
  2287. void MergingTransformSimpleInfo::setTransformedSelector(IHqlExpression * childScope, IHqlExpression * value)
  2288. {
  2289. inlineSetTransformedSelector(value);
  2290. }
  2291. #if 0
  2292. //---------------------------------------------------------------------------
  2293. MergingTransformComplexCache::MergingTransformComplexCache()
  2294. {
  2295. mapped = NULL;
  2296. mappedSelector = NULL;
  2297. }
  2298. IHqlExpression * MergingTransformComplexCache::queryAlreadyTransformed(AMergingTransformInfo & baseInfo, IHqlExpression * childScope)
  2299. {
  2300. IHqlExpression * curTransformed = baseInfo.queryTransformed();
  2301. if (!curTransformed)
  2302. return NULL;
  2303. if (transformedScope == childScope || onlyTransformOnce())
  2304. return curTransformed;
  2305. if (!mapped)
  2306. return NULL;
  2307. OwnedHqlExpr * matched = mapped->getValue(childScope);
  2308. if (matched)
  2309. {
  2310. transformedScope.set(childScope);
  2311. IHqlExpression * prevTransformed = matched->get();
  2312. baseInfo.setTransformed(prevTransformed, childScope);
  2313. return prevTransformed;
  2314. }
  2315. return NULL;
  2316. }
  2317. void MergingTransformComplexCache::setTransformed(AMergingTransformInfo & baseInfo, IHqlExpression * childScope, IHqlExpression * value)
  2318. {
  2319. IHqlExpression * curTransformed = baseInfo.queryTransformed();
  2320. if (curTransformed)
  2321. {
  2322. assertex(!onlyTransformOnce());
  2323. if (!mapped)
  2324. {
  2325. mapped = new MapOwnedToOwned<IHqlExpression, IHqlExpression>;
  2326. mapped->setValue(transformedScope, curTransformed);
  2327. }
  2328. mapped->setValue(childScope, value);
  2329. }
  2330. transformedScope.set(childScope);
  2331. baseInfo.setTransformed(value, childScope);
  2332. }
  2333. IHqlExpression * MergingTransformComplexCache::queryAlreadyTransformedSelector(AMergingTransformInfo & baseInfo, IHqlExpression * childScope)
  2334. {
  2335. IHqlExpression * curTransformedSelector = baseInfo.queryTransformedSelector();
  2336. if (!curTransformedSelector)
  2337. return NULL;
  2338. if (transformedSelectorScope == childScope || onlyTransformOnce())
  2339. return curTransformedSelector;
  2340. if (!mappedSelector)
  2341. {
  2342. if (!baseInfo.recurseParentScopes())
  2343. return NULL;
  2344. IHqlExpression * curTransformed = queryAlreadyTransformed(baseInfo, childScope);
  2345. if (curTransformed)
  2346. return curTransformed->queryNormalizedSelector();
  2347. while (childScope)
  2348. {
  2349. if (childScope->getOperator() == no_comma)
  2350. childScope = childScope->queryChild(1);
  2351. else
  2352. childScope = NULL;
  2353. if (transformedSelectorScope == childScope)
  2354. return curTransformedSelector;
  2355. }
  2356. return NULL;
  2357. }
  2358. OwnedHqlExpr * matched = mappedSelector->getValue(childScope);
  2359. if (matched)
  2360. {
  2361. transformedSelectorScope.set(childScope);
  2362. IHqlExpression * prevTransformedSelector = matched->get();
  2363. baseInfo.setTransformedSelector(prevTransformedSelector, childScope);
  2364. return prevTransformedSelector;
  2365. }
  2366. if (childScope)
  2367. {
  2368. if (!baseInfo.recurseParentScopes())
  2369. return NULL;
  2370. //This is quite similar in intent to the code in initializeActiveSelector, which really acts as an
  2371. //optimization by inserting translations from a previous scope into the current scope.
  2372. //However it doesn't always do enough - e.g., when converting a dataset to NULL, hence the need for the
  2373. //full search. See sqaggds3 for and example that requires it.
  2374. IHqlExpression * curTransformed = queryAlreadyTransformed(baseInfo, childScope);
  2375. if (curTransformed)
  2376. return curTransformed->queryNormalizedSelector();
  2377. while (childScope)
  2378. {
  2379. if (childScope->getOperator() == no_comma)
  2380. childScope = childScope->queryChild(1);
  2381. else
  2382. childScope = NULL;
  2383. OwnedHqlExpr * matched = mappedSelector->getValue(childScope);
  2384. if (matched)
  2385. return matched->get();
  2386. if (mapped)
  2387. {
  2388. matched = mapped->getValue(childScope);
  2389. if (matched)
  2390. return matched->get();
  2391. }
  2392. }
  2393. }
  2394. return NULL;
  2395. }
  2396. void MergingTransformComplexCache::setTransformedSelector(AMergingTransformInfo & baseInfo, IHqlExpression * childScope, IHqlExpression * value)
  2397. {
  2398. IHqlExpression * curTransformedSelector = baseInfo.queryTransformedSelector();
  2399. if (curTransformedSelector)
  2400. {
  2401. if (onlyTransformOnce())
  2402. {
  2403. assertex(value == curTransformedSelector);
  2404. return;
  2405. }
  2406. if (!mappedSelector)
  2407. {
  2408. mappedSelector = new MapOwnedToOwned<IHqlExpression, IHqlExpression>;
  2409. mappedSelector->setValue(transformedSelectorScope, curTransformedSelector);
  2410. }
  2411. mappedSelector->setValue(childScope, value);
  2412. }
  2413. transformedSelectorScope.set(childScope);
  2414. baseInfo.setTransformedSelector(value, childScope);
  2415. }
  2416. #endif
  2417. //---------------------------------------------------------------------------
  2418. MergingTransformInfo::MergingTransformInfo(IHqlExpression * _expr) : AMergingTransformInfo(_expr)
  2419. {
  2420. mapped = NULL;
  2421. mappedSelector = NULL;
  2422. setOnlyTransformOnce(::onlyTransformOnce(original));
  2423. }
  2424. IHqlExpression * MergingTransformInfo::queryAlreadyTransformed(IHqlExpression * childScope)
  2425. {
  2426. IHqlExpression * curTransformed = inlineQueryTransformed();
  2427. if (!curTransformed)
  2428. return NULL;
  2429. if (transformedScope == childScope || onlyTransformOnce())
  2430. return curTransformed;
  2431. if (!mapped)
  2432. return NULL;
  2433. IHqlExpression * matched = mapped->getValue(childScope);
  2434. if (matched)
  2435. {
  2436. transformedScope.set(childScope);
  2437. IHqlExpression * prevTransformed = matched;
  2438. inlineSetTransformed(prevTransformed);
  2439. return prevTransformed;
  2440. }
  2441. return NULL;
  2442. }
  2443. void MergingTransformInfo::setTransformed(IHqlExpression * childScope, IHqlExpression * value)
  2444. {
  2445. IHqlExpression * curTransformed = inlineQueryTransformed();
  2446. if (curTransformed)
  2447. {
  2448. assertex(!onlyTransformOnce());
  2449. if (!mapped)
  2450. {
  2451. mapped = new MAPPINGCLASS;
  2452. mapped->setValue(transformedScope, curTransformed);
  2453. }
  2454. mapped->setValue(childScope, value);
  2455. #if 0
  2456. if (mapped->map.count() > maxMapCount)
  2457. maxMapCount = mapped->map.count();
  2458. static HqlExprArray seen;
  2459. if (mapped->map.count() >= 84 && !seen.contains(*original))
  2460. {
  2461. seen.append(*LINK(original));
  2462. DBGLOG(getOpString(original->getOperator()));
  2463. // dbglogExpr(original);
  2464. void * cur = NULL;
  2465. while ((cur = mapped->map.next(cur)) != NULL)
  2466. {
  2467. MappingOwnedToOwned<IHqlExpression,IHqlExpression> * x = (MappingOwnedToOwned<IHqlExpression,IHqlExpression>*)(IInterface *)cur;
  2468. Owned<IHqlExpression> * scope = (Owned<IHqlExpression>*)x->getKey();
  2469. StringBuffer txt;
  2470. HqlExprArray z;
  2471. if (*scope)
  2472. (*scope)->unwindList(z, no_comma);
  2473. ForEachItemIn(i, z)
  2474. txt.append(" ").append(getOpString(z.item(i).getOperator()));
  2475. DBGLOG("@%s", txt.str());
  2476. // dbglogExpr(*scope);
  2477. x = NULL;
  2478. }
  2479. cur = NULL;
  2480. }
  2481. #endif
  2482. }
  2483. transformedScope.set(childScope);
  2484. inlineSetTransformed(value);
  2485. }
  2486. IHqlExpression * MergingTransformInfo::queryAlreadyTransformedSelector(IHqlExpression * childScope)
  2487. {
  2488. IHqlExpression * curTransformedSelector = inlineQueryTransformedSelector();
  2489. if (!curTransformedSelector)
  2490. return NULL;
  2491. if (transformedSelectorScope == childScope || onlyTransformOnce())
  2492. return curTransformedSelector;
  2493. if (!mappedSelector)
  2494. {
  2495. if (!recurseParentScopes())
  2496. return NULL;
  2497. IHqlExpression * curTransformed = queryAlreadyTransformed(childScope);
  2498. if (curTransformed)
  2499. return curTransformed->queryNormalizedSelector();
  2500. while (childScope)
  2501. {
  2502. if (childScope->getOperator() == no_comma)
  2503. childScope = childScope->queryChild(1);
  2504. else
  2505. childScope = NULL;
  2506. if (transformedSelectorScope == childScope)
  2507. return curTransformedSelector;
  2508. }
  2509. return NULL;
  2510. }
  2511. IHqlExpression * matched = mappedSelector->getValue(childScope);
  2512. if (matched)
  2513. {
  2514. transformedSelectorScope.set(childScope);
  2515. IHqlExpression * prevTransformedSelector = matched;
  2516. inlineSetTransformedSelector(prevTransformedSelector);
  2517. return prevTransformedSelector;
  2518. }
  2519. if (childScope)
  2520. {
  2521. if (!recurseParentScopes())
  2522. return NULL;
  2523. //This is quite similar in intent to the code in initializeActiveSelector, which really acts as an
  2524. //optimization by inserting translations from a previous scope into the current scope.
  2525. //However it doesn't always do enough - e.g., when converting a dataset to NULL, hence the need for the
  2526. //full search. See sqaggds3 for and example that requires it.
  2527. IHqlExpression * curTransformed = queryAlreadyTransformed(childScope);
  2528. if (curTransformed)
  2529. return curTransformed->queryNormalizedSelector();
  2530. while (childScope)
  2531. {
  2532. if (childScope->getOperator() == no_comma)
  2533. childScope = childScope->queryChild(1);
  2534. else
  2535. childScope = NULL;
  2536. IHqlExpression * matched = mappedSelector->getValue(childScope);
  2537. if (matched)
  2538. return matched;
  2539. if (mapped)
  2540. {
  2541. matched = mapped->getValue(childScope);
  2542. if (matched)
  2543. return matched;
  2544. }
  2545. }
  2546. }
  2547. return NULL;
  2548. }
  2549. void MergingTransformInfo::setTransformedSelector(IHqlExpression * childScope, IHqlExpression * value)
  2550. {
  2551. IHqlExpression * curTransformedSelector = inlineQueryTransformedSelector();
  2552. if (curTransformedSelector)
  2553. {
  2554. if (onlyTransformOnce())
  2555. {
  2556. assertex(value == curTransformedSelector);
  2557. return;
  2558. }
  2559. if (!mappedSelector)
  2560. {
  2561. mappedSelector = new MAPPINGCLASS;
  2562. mappedSelector->setValue(transformedSelectorScope, curTransformedSelector);
  2563. }
  2564. mappedSelector->setValue(childScope, value);
  2565. }
  2566. transformedSelectorScope.set(childScope);
  2567. inlineSetTransformedSelector(value);
  2568. }
  2569. //---------------------------------------------------------------------------
  2570. IHqlExpression * MergingHqlTransformer::createTransformed(IHqlExpression * expr)
  2571. {
  2572. node_operator op = expr->getOperator();
  2573. switch (op)
  2574. {
  2575. case no_activerow:
  2576. return NewHqlTransformer::createTransformed(expr);
  2577. case no_select:
  2578. if (!isNewSelector(expr))
  2579. return createTransformedActiveSelect(expr);
  2580. return NewHqlTransformer::createTransformed(expr);
  2581. }
  2582. switch (getChildDatasetType(expr))
  2583. {
  2584. case childdataset_dataset:
  2585. case childdataset_datasetleft:
  2586. case childdataset_top_left_right:
  2587. {
  2588. IHqlExpression * arg0 = expr->queryChild(0);
  2589. OwnedHqlExpr child = transform(arg0);
  2590. HqlExprArray children;
  2591. children.append(*LINK(child));
  2592. pushChildContext(arg0, child);
  2593. bool same = optimizedTransformChildren(expr, children);
  2594. popChildContext();
  2595. if (!same)
  2596. {
  2597. if ((children.ordinality() > 2) && isAlwaysActiveRow(child))
  2598. removeAttribute(children, newAtom);
  2599. return expr->clone(children);
  2600. }
  2601. return LINK(expr);
  2602. }
  2603. case childdataset_many:
  2604. {
  2605. unsigned firstAttr = getNumChildTables(expr);
  2606. IHqlExpression * arg0 = expr->queryChild(0);
  2607. OwnedHqlExpr child = transform(arg0);
  2608. HqlExprArray children;
  2609. children.append(*LINK(child));
  2610. for (unsigned i=1; i < firstAttr; i++)
  2611. children.append(*transform(expr->queryChild(i)));
  2612. pushChildContext(arg0, child);
  2613. bool same = optimizedTransformChildren(expr, children);
  2614. popChildContext();
  2615. if (!same)
  2616. return expr->clone(children);
  2617. return LINK(expr);
  2618. }
  2619. case childdataset_evaluate:
  2620. throwUnexpected();
  2621. default:
  2622. return NewHqlTransformer::createTransformed(expr);
  2623. }
  2624. }
  2625. ANewTransformInfo * MergingHqlTransformer::createTransformInfo(IHqlExpression * expr)
  2626. {
  2627. if (onlyTransformOnce(expr))
  2628. return CREATE_NEWTRANSFORMINFO(MergingTransformSimpleInfo, expr);
  2629. return CREATE_NEWTRANSFORMINFO(MergingTransformInfo, expr);
  2630. }
  2631. void MergingHqlTransformer::pushChildContext(IHqlExpression * expr, IHqlExpression * transformed)
  2632. {
  2633. assert(expr->getOperator() != no_comma);
  2634. IHqlExpression * scope = expr;
  2635. //NB: Do no call createComma because that calls createDataset which unwinds a comma list!
  2636. if (childScope)
  2637. childScope.setown(createValue(no_comma,LINK(scope), childScope.getClear()));
  2638. else
  2639. childScope.set(scope);
  2640. initializeActiveSelector(expr, transformed);
  2641. }
  2642. void MergingHqlTransformer::popChildContext()
  2643. {
  2644. if (childScope->getOperator() == no_comma)
  2645. childScope.set(childScope->queryChild(1));
  2646. else
  2647. childScope.clear();
  2648. }
  2649. IHqlExpression * MergingHqlTransformer::queryAlreadyTransformed(IHqlExpression * expr)
  2650. {
  2651. AMergingTransformInfo * extra = queryExtra(expr);
  2652. return extra->queryAlreadyTransformed(childScope);
  2653. }
  2654. void MergingHqlTransformer::setTransformed(IHqlExpression * expr, IHqlExpression * transformed)
  2655. {
  2656. AMergingTransformInfo * extra = queryExtra(expr);
  2657. extra->setTransformed(childScope, transformed);
  2658. }
  2659. IHqlExpression * MergingHqlTransformer::queryAlreadyTransformedSelector(IHqlExpression * expr)
  2660. {
  2661. AMergingTransformInfo * extra = queryExtra(expr->queryNormalizedSelector());
  2662. return extra->queryAlreadyTransformedSelector(childScope);
  2663. }
  2664. void MergingHqlTransformer::setTransformedSelector(IHqlExpression * expr, IHqlExpression * transformed)
  2665. {
  2666. assertex(expr == expr->queryNormalizedSelector());
  2667. assertex(transformed == transformed->queryNormalizedSelector());
  2668. AMergingTransformInfo * extra = queryExtra(expr->queryNormalizedSelector());
  2669. extra->setTransformedSelector(childScope, transformed);
  2670. }
  2671. //---------------------------------------------------------------------------
  2672. #if 0
  2673. SelectorReplacingTransformer::SelectorReplacingTransformer()
  2674. {
  2675. introducesAmbiguity = false;
  2676. savedNewDataset = NULL;
  2677. isHidden = false;
  2678. }
  2679. void SelectorReplacingTransformer::initSelectorMapping(IHqlExpression * _oldDataset, IHqlExpression * _newDataset)
  2680. {
  2681. oldDataset.set(_oldDataset);
  2682. newSelector.set(_newDataset);
  2683. if (_newDataset->getOperator() == no_newrow)
  2684. newDataset.set(_newDataset->queryChild(0));
  2685. else
  2686. newDataset.set(_newDataset);
  2687. if (newDataset->getOperator() == no_activerow)
  2688. savedNewDataset = newDataset->queryChild(0)->queryNormalizedSelector();
  2689. node_operator op = oldDataset->getOperator();
  2690. if (op == no_left || op == no_right)
  2691. oldSelector.set(oldDataset);
  2692. updateMapping();
  2693. }
  2694. void SelectorReplacingTransformer::updateMapping()
  2695. {
  2696. node_operator op = oldDataset->getOperator();
  2697. if (oldDataset->isDatarow() || op == no_activetable || op == no_self || op == no_selfref)
  2698. {
  2699. if (isAlwaysActiveRow(newDataset) || newDataset->isDatarow())
  2700. setMappingOnly(oldDataset, newDataset); // A row, so Don't change any new references to the dataset
  2701. else
  2702. {
  2703. OwnedHqlExpr newActive = ensureActiveRow(newDataset);
  2704. setMappingOnly(oldDataset, newActive); // A row, so Don't change any new references to the dataset
  2705. }
  2706. }
  2707. else
  2708. {
  2709. setMappingOnly(oldDataset, oldDataset); // Don't change any new references to the dataset
  2710. }
  2711. setSelectorMapping(oldDataset, newSelector);
  2712. }
  2713. IHqlExpression * SelectorReplacingTransformer::createTransformed(IHqlExpression * expr)
  2714. {
  2715. if (expr->queryNormalizedSelector() == savedNewDataset)
  2716. introducesAmbiguity = true;
  2717. unsigned numNonHidden = activityHidesSelectorGetNumNonHidden(expr, oldSelector);
  2718. if (numNonHidden == 0)
  2719. return MergingHqlTransformer::createTransformed(expr);
  2720. LinkedHqlExpr oldChildContext = oldSelector.get();
  2721. LinkedHqlExpr newChildContext = oldSelector.get();
  2722. HqlExprArray children;
  2723. switch (getChildDatasetType(expr))
  2724. {
  2725. case childdataset_dataset:
  2726. throwUnexpected();
  2727. case childdataset_datasetleft:
  2728. case childdataset_top_left_right:
  2729. {
  2730. assertex(numNonHidden == 1);
  2731. IHqlExpression * arg0 = expr->queryChild(0);
  2732. OwnedHqlExpr child = transform(arg0);
  2733. oldChildContext.set(arg0);
  2734. newChildContext.set(child);
  2735. children.append(*LINK(child));
  2736. break;
  2737. }
  2738. default:
  2739. {
  2740. for (unsigned i=0; i < numNonHidden; i++)
  2741. children.append(*transform(expr->queryChild(i)));
  2742. break;
  2743. }
  2744. }
  2745. bool wasHidden = isHidden;
  2746. isHidden = true;
  2747. pushChildContext(oldChildContext, newChildContext);
  2748. bool same = transformChildren(expr, children);
  2749. popChildContext();
  2750. isHidden = wasHidden;
  2751. if (!same)
  2752. return expr->clone(children);
  2753. return LINK(expr);
  2754. }
  2755. void SelectorReplacingTransformer::pushChildContext(IHqlExpression * expr, IHqlExpression * transformed)
  2756. {
  2757. MergingHqlTransformer::pushChildContext(expr, transformed);
  2758. if (isHidden)
  2759. setTransformedSelector(oldSelector, oldSelector);
  2760. else
  2761. updateMapping();
  2762. }
  2763. #endif
  2764. //---------------------------------------------------------------------------
  2765. static HqlTransformerInfo newSelectorReplacingTransformerInfo("NewSelectorReplacingTransformer");
  2766. NewSelectorReplacingTransformer::NewSelectorReplacingTransformer() : NewHqlTransformer(newSelectorReplacingTransformerInfo)
  2767. {
  2768. introducesAmbiguity = false;
  2769. savedNewDataset = NULL;
  2770. isHidden=false;
  2771. }
  2772. void NewSelectorReplacingTransformer::initSelectorMapping(IHqlExpression * oldDataset, IHqlExpression * newDataset)
  2773. {
  2774. IHqlExpression * newSelector = newDataset;
  2775. if (newDataset->getOperator() == no_newrow)
  2776. newDataset = newDataset->queryChild(0);
  2777. if (newDataset->getOperator() == no_activerow)
  2778. savedNewDataset = newDataset->queryChild(0)->queryNormalizedSelector();
  2779. node_operator op = oldDataset->getOperator();
  2780. if (oldDataset->isDatarow() || op == no_activetable || op == no_self || op == no_selfref)
  2781. {
  2782. if (isAlwaysActiveRow(newDataset) || newDataset->isDatarow())
  2783. setRootMapping(oldDataset, newDataset, false); // A row, so Don't change any new references to the dataset
  2784. else
  2785. {
  2786. OwnedHqlExpr newActive = ensureActiveRow(newDataset);
  2787. setRootMapping(oldDataset, newActive, false); // A row, so Don't change any new references to the dataset
  2788. }
  2789. }
  2790. else
  2791. {
  2792. setRootMapping(oldDataset, oldDataset, false); // Don't change any new references to the dataset
  2793. }
  2794. setRootMapping(oldDataset, newSelector, true);
  2795. if (op == no_left || op == no_right)
  2796. oldSelector.set(oldDataset);
  2797. }
  2798. void NewSelectorReplacingTransformer::setNestedMapping(IHqlExpression * oldSel, IHqlExpression * newSel, IHqlSimpleScope * oldScope, IHqlExpression * newRecord, bool isSelector)
  2799. {
  2800. ForEachChild(i, newRecord)
  2801. {
  2802. IHqlExpression * cur = newRecord->queryChild(i);
  2803. switch (cur->getOperator())
  2804. {
  2805. case no_record:
  2806. setNestedMapping(oldSel, newSel, oldScope, cur, isSelector);
  2807. break;
  2808. case no_ifblock:
  2809. setNestedMapping(oldSel, newSel, oldScope, cur->queryChild(1), isSelector);
  2810. break;
  2811. case no_field:
  2812. {
  2813. OwnedHqlExpr oldField = oldScope->lookupSymbol(cur->queryId());
  2814. assertex(oldField);
  2815. if (cur != oldField)
  2816. {
  2817. OwnedHqlExpr oldSelected = createSelectExpr(LINK(oldSel), LINK(oldField));
  2818. OwnedHqlExpr newSelected = createSelectExpr(LINK(newSel), LINK(cur));
  2819. setRootMapping(oldSelected, newSelected, oldField->queryRecord(), isSelector);
  2820. }
  2821. }
  2822. }
  2823. }
  2824. }
  2825. void NewSelectorReplacingTransformer::setRootMapping(IHqlExpression * oldSel, IHqlExpression * newSel, IHqlExpression * oldRecord, bool isSelector)
  2826. {
  2827. if (isSelector)
  2828. setSelectorMapping(oldSel, newSel);
  2829. else
  2830. setMappingOnly(oldSel, newSel);
  2831. IHqlExpression * newRecord = newSel->queryRecord();
  2832. if (oldRecord != newRecord)
  2833. {
  2834. if (oldRecord != queryNullRecord() && newRecord != queryNullRecord())
  2835. {
  2836. setNestedMapping(oldSel, newSel, oldRecord->querySimpleScope(), newRecord, isSelector);
  2837. }
  2838. }
  2839. }
  2840. void NewSelectorReplacingTransformer::setRootMapping(IHqlExpression * oldSel, IHqlExpression * newSel, bool isSelector)
  2841. {
  2842. setRootMapping(oldSel, newSel, oldSel->queryRecord(), isSelector);
  2843. }
  2844. IHqlExpression * NewSelectorReplacingTransformer::createTransformed(IHqlExpression * expr)
  2845. {
  2846. if (!isHidden && expr->queryNormalizedSelector() == savedNewDataset)
  2847. introducesAmbiguity = true;
  2848. unsigned numNonHidden = activityHidesSelectorGetNumNonHidden(expr, oldSelector);
  2849. if (numNonHidden == 0)
  2850. return NewHqlTransformer::createTransformed(expr);
  2851. HqlExprArray children;
  2852. for (unsigned i=0; i < numNonHidden; i++)
  2853. children.append(*transform(expr->queryChild(i)));
  2854. bool wasHidden = isHidden;
  2855. isHidden = true;
  2856. bool same = optimizedTransformChildren(expr, children);
  2857. isHidden = wasHidden;
  2858. if (!same)
  2859. return expr->clone(children);
  2860. return LINK(expr);
  2861. }
  2862. IHqlExpression * NewSelectorReplacingTransformer::queryAlreadyTransformedSelector(IHqlExpression * expr)
  2863. {
  2864. NewSelectorReplacingInfo * extra = queryExtra(expr);
  2865. return extra->queryTransformedSelector(isHidden);
  2866. }
  2867. IHqlExpression * newReplaceSelector(IHqlExpression * expr, IHqlExpression * oldSelector, IHqlExpression * newSelector)
  2868. {
  2869. NewSelectorReplacingTransformer transformer;
  2870. transformer.initSelectorMapping(oldSelector, newSelector);
  2871. OwnedHqlExpr ret = transformer.transformRoot(expr);
  2872. if (transformer.foundAmbiguity())
  2873. DBGLOG("Mapping introduces potential ambiguity into expression");
  2874. return ret.getClear();
  2875. }
  2876. void newReplaceSelector(HqlExprArray & target, const HqlExprArray & source, IHqlExpression * oldSelector, IHqlExpression * newSelector)
  2877. {
  2878. NewSelectorReplacingTransformer transformer;
  2879. transformer.initSelectorMapping(oldSelector, newSelector);
  2880. ForEachItemIn(i, source)
  2881. target.append(*transformer.transformRoot(&source.item(i)));
  2882. if (transformer.foundAmbiguity())
  2883. DBGLOG("Mapping introduces potential ambiguity into expression");
  2884. }
  2885. IHqlExpression * queryNewReplaceSelector(IHqlExpression * expr, IHqlExpression * oldSelector, IHqlExpression * newSelector)
  2886. {
  2887. NewSelectorReplacingTransformer transformer;
  2888. transformer.initSelectorMapping(oldSelector, newSelector);
  2889. OwnedHqlExpr ret = transformer.transformRoot(expr);
  2890. if (transformer.foundAmbiguity())
  2891. return NULL;
  2892. return ret.getClear();
  2893. }
  2894. //---------------------------------------------------------------------------------------------------------------------
  2895. IHqlExpression * updateChildSelectors(IHqlExpression * expr, IHqlExpression * oldSelector, IHqlExpression * newSelector, unsigned firstChild)
  2896. {
  2897. if (oldSelector == newSelector)
  2898. return LINK(expr);
  2899. unsigned max = expr->numChildren();
  2900. unsigned i;
  2901. HqlExprArray args;
  2902. args.ensure(max);
  2903. for (i = 0; i < firstChild; i++)
  2904. args.append(*LINK(expr->queryChild(i)));
  2905. NewSelectorReplacingTransformer transformer;
  2906. transformer.initSelectorMapping(oldSelector, newSelector);
  2907. bool same = true;
  2908. for (; i < max; i++)
  2909. {
  2910. IHqlExpression * cur = expr->queryChild(i);
  2911. IHqlExpression * transformed = transformer.transformRoot(cur);
  2912. args.append(*transformed);
  2913. if (cur != transformed)
  2914. same = false;
  2915. }
  2916. if (same)
  2917. return LINK(expr);
  2918. return expr->clone(args);
  2919. }
  2920. IHqlExpression * updateMappedFields(IHqlExpression * expr, IHqlExpression * oldSelector, IHqlExpression * newSelector, unsigned firstChild)
  2921. {
  2922. if (oldSelector->queryRecord() == newSelector->queryRecord())
  2923. return LINK(expr);
  2924. unsigned max = expr->numChildren();
  2925. unsigned i;
  2926. HqlExprArray args;
  2927. args.ensure(max);
  2928. for (i = 0; i < firstChild; i++)
  2929. args.append(*LINK(expr->queryChild(i)));
  2930. NewSelectorReplacingTransformer transformer;
  2931. if (oldSelector != newSelector)
  2932. transformer.initSelectorMapping(oldSelector, newSelector);
  2933. transformer.setRootMapping(newSelector, newSelector, newSelector->queryRecord(), false);
  2934. bool same = true;
  2935. for (; i < max; i++)
  2936. {
  2937. IHqlExpression * cur = expr->queryChild(i);
  2938. IHqlExpression * transformed = transformer.transformRoot(cur);
  2939. args.append(*transformed);
  2940. if (cur != transformed)
  2941. same = false;
  2942. }
  2943. if (same)
  2944. return LINK(expr);
  2945. return expr->clone(args);
  2946. }
  2947. //---------------------------------------------------------------------------
  2948. /*
  2949. Scoping following is tricky....
  2950. Need to know following:
  2951. o What scopes are surrounding me?
  2952. - a list of activity scopes is maintained.
  2953. o Am in the process of creating a new dataset?
  2954. - examples that create a new dataset are sum(ds) output(x)
  2955. - selectnth creates a new scope for its first child, but not the others.
  2956. - evaluate(x) is a bit strange - it creates a temporary scope, but doesn't create a new dataset.
  2957. - x := y where y is a dataset needs to be handled specially. (Similarly for compare/order)
  2958. So:
  2959. A new scope is created whenever something is introducing a new line of scopes.
  2960. Each operator sets the scope for it's children, and then clears it at the end.
  2961. */
  2962. IHqlDataset * ScopeInfo::queryActiveDataset()
  2963. {
  2964. if (dataset)
  2965. return dataset->queryDataset()->queryRootTable();
  2966. return NULL;
  2967. }
  2968. //---------------------------------------------------------------------------
  2969. ScopedTransformer::ScopedTransformer(HqlTransformerInfo & _info) : NewHqlTransformer(_info)
  2970. {
  2971. innerScope = NULL;
  2972. emptyScopeMarker.setown(createAttribute(scopeAtom));
  2973. }
  2974. void ScopedTransformer::analyseAssign(IHqlExpression * expr)
  2975. {
  2976. //optimization: don't traverse LHS of an assignment
  2977. IHqlExpression * left = expr->queryChild(0);
  2978. IHqlExpression * right = expr->queryChild(1);
  2979. if (left->isDataset() || left->isDatarow())
  2980. {
  2981. pushScope();
  2982. analyseExpr(right);
  2983. popScope();
  2984. }
  2985. else
  2986. {
  2987. analyseExpr(right);
  2988. }
  2989. }
  2990. void ScopedTransformer::analyseChildren(IHqlExpression * expr)
  2991. {
  2992. node_operator op = expr->getOperator();
  2993. unsigned idx;
  2994. switch (op)
  2995. {
  2996. case no_joined: // A couple of weird exceptions....
  2997. analyseSelector(expr->queryChild(0));
  2998. break;
  2999. case no_sizeof:
  3000. case no_offsetof:
  3001. case no_nameof:
  3002. if (!expr->queryChild(0)->isDataset())
  3003. {
  3004. NewHqlTransformer::analyseChildren(expr);
  3005. return;
  3006. }
  3007. //fallthrough
  3008. case NO_AGGREGATE:
  3009. case no_buildindex:
  3010. case no_apply:
  3011. case no_distributer:
  3012. case no_distribution:
  3013. case no_within:
  3014. case no_notwithin:
  3015. case no_output:
  3016. case no_writespill:
  3017. case no_createset:
  3018. case no_soapaction_ds:
  3019. case no_newsoapaction_ds:
  3020. case no_returnresult:
  3021. case no_setgraphresult:
  3022. case no_setgraphloopresult:
  3023. case no_extractresult:
  3024. case no_createdictionary:
  3025. {
  3026. IHqlExpression * dataset = expr->queryChild(0);
  3027. pushScope();
  3028. if ((op == no_within) || (op == no_notwithin))
  3029. innerScope->isWithin = true;
  3030. analyseExpr(dataset);
  3031. bool nested = setDataset(dataset, dataset);
  3032. unsigned numChildren = expr->numChildren();
  3033. for (idx = 1; idx < numChildren; idx++)
  3034. analyseExpr(expr->queryChild(idx));
  3035. clearDataset(nested);
  3036. popScope();
  3037. break;
  3038. }
  3039. case no_projectrow:
  3040. {
  3041. //Ugly - should probably try and remove these from the parse tree
  3042. IHqlExpression * dataset = expr->queryChild(0);
  3043. pushScope();
  3044. analyseExpr(dataset);
  3045. bool nested = setLeft(dataset, querySelSeq(expr));
  3046. unsigned numChildren = expr->numChildren();
  3047. for (idx = 1; idx < numChildren; idx++)
  3048. analyseExpr(expr->queryChild(idx));
  3049. clearDataset(nested);
  3050. popScope();
  3051. break;
  3052. }
  3053. case no_keydiff:
  3054. case no_rowdiff:
  3055. {
  3056. pushScope();
  3057. analyseExpr(expr->queryChild(0));
  3058. analyseExpr(expr->queryChild(1));
  3059. popScope();
  3060. unsigned numChildren = expr->numChildren();
  3061. for (idx = 2; idx < numChildren; idx++)
  3062. analyseExpr(expr->queryChild(idx));
  3063. break;
  3064. }
  3065. case no_setresult:
  3066. case no_blob2id:
  3067. {
  3068. IHqlExpression * value = expr->queryChild(0);
  3069. unsigned first = 0;
  3070. if (value->isDataset())
  3071. {
  3072. pushScope();
  3073. analyseExpr(value);
  3074. popScope();
  3075. first++;
  3076. }
  3077. unsigned numChildren = expr->numChildren();
  3078. for (idx=first; idx < numChildren; idx++)
  3079. analyseExpr(expr->queryChild(idx));
  3080. break;
  3081. }
  3082. case no_keypatch:
  3083. case no_selectnth:
  3084. {
  3085. pushScope();
  3086. analyseExpr(expr->queryChild(0));
  3087. popScope();
  3088. unsigned numChildren = expr->numChildren();
  3089. for (idx = 1; idx < numChildren; idx++)
  3090. analyseExpr(expr->queryChild(idx));
  3091. break;
  3092. }
  3093. case no_evaluate:
  3094. {
  3095. IHqlExpression * scope = expr->queryChild(0);
  3096. analyseExpr(scope);
  3097. pushEvaluateScope(scope, scope);
  3098. analyseExpr(expr->queryChild(1));
  3099. popEvaluateScope();
  3100. break;
  3101. }
  3102. case no_assign:
  3103. analyseAssign(expr);
  3104. break;
  3105. case no_lt:
  3106. case no_le:
  3107. case no_gt:
  3108. case no_ge:
  3109. case no_ne:
  3110. case no_eq:
  3111. case no_order:
  3112. {
  3113. IHqlExpression * left = expr->queryChild(0);
  3114. IHqlExpression * right = expr->queryChild(1);
  3115. if (left->isDataset() || left->isDatarow())
  3116. {
  3117. pushScope();
  3118. analyseExpr(left);
  3119. analyseExpr(right);
  3120. popScope();
  3121. }
  3122. else
  3123. {
  3124. analyseExpr(left);
  3125. analyseExpr(right);
  3126. }
  3127. break;
  3128. }
  3129. case no_keyed:
  3130. case no_loopbody:
  3131. {
  3132. pushScope();
  3133. ForEachChild(idx, expr)
  3134. analyseExpr(expr->queryChild(idx));
  3135. popScope();
  3136. break;
  3137. }
  3138. case no_compound:
  3139. case no_mapto:
  3140. {
  3141. if (innerScope && innerScope->isEmpty())
  3142. {
  3143. suspendScope();
  3144. analyseExpr(expr->queryChild(0));
  3145. restoreScope();
  3146. }
  3147. else
  3148. analyseExpr(expr->queryChild(0));
  3149. analyseExpr(expr->queryChild(1));
  3150. break;
  3151. }
  3152. case no_table:
  3153. {
  3154. unsigned max = expr->numChildren();
  3155. unsigned idx = 0;
  3156. suspendScope();
  3157. for (; idx < 3; idx++)
  3158. analyseExpr(expr->queryChild(idx));
  3159. restoreScope();
  3160. if (max >= 4)
  3161. {
  3162. IHqlExpression * ds = expr->queryChild(idx++);
  3163. analyseExpr(ds);
  3164. bool nested = setDataset(ds, ds);
  3165. for (; idx < max; idx++)
  3166. analyseExpr(expr->queryChild(idx));
  3167. clearDataset(nested);
  3168. }
  3169. break;
  3170. }
  3171. case no_select:
  3172. {
  3173. if (expr->hasAttribute(newAtom))
  3174. {
  3175. IHqlExpression * dataset = expr->queryChild(0);
  3176. pushScope();
  3177. analyseExpr(dataset);
  3178. bool nested = setDataset(dataset, dataset);
  3179. analyseExpr(expr->queryChild(1));
  3180. clearDataset(nested);
  3181. popScope();
  3182. }
  3183. else
  3184. NewHqlTransformer::analyseChildren(expr);
  3185. break;
  3186. }
  3187. case no_globalscope:
  3188. if (expr->hasAttribute(optAtom))
  3189. {
  3190. NewHqlTransformer::analyseChildren(expr);
  3191. break;
  3192. }
  3193. //fall through
  3194. case no_colon:
  3195. case no_cluster:
  3196. {
  3197. // By definition no_colon is evaluated globally, so no tables are in scope for its children
  3198. ScopeSuspendInfo info;
  3199. suspendAllScopes(info);
  3200. if (expr->isDataset())
  3201. pushScope();
  3202. analyseExpr(expr->queryChild(0));
  3203. if (expr->isDataset())
  3204. popScope();
  3205. unsigned numChildren = expr->numChildren();
  3206. for (idx = 1; idx < numChildren; idx++)
  3207. analyseExpr(expr->queryChild(idx));
  3208. restoreScopes(info);
  3209. break;
  3210. }
  3211. case no_keyindex:
  3212. case no_newkeyindex:
  3213. {
  3214. IHqlExpression * dataset = expr->queryChild(0);
  3215. analyseSelector(dataset);
  3216. bool nested = setDataset(dataset, dataset);
  3217. unsigned max = expr->numChildren();
  3218. for (unsigned idx=1; idx < max; idx++)
  3219. analyseExpr(expr->queryChild(idx));
  3220. clearDataset(nested);
  3221. break;
  3222. }
  3223. case no_activerow:
  3224. analyseSelector(expr->queryChild(0));
  3225. break;
  3226. case no_attr_expr:
  3227. case no_call:
  3228. case no_externalcall:
  3229. case no_rowvalue:
  3230. case no_setmeta:
  3231. case no_typetransfer:
  3232. case no_subgraph:
  3233. case no_libraryscopeinstance:
  3234. {
  3235. if (expr->isDataset())
  3236. suspendScope();
  3237. unsigned max = expr->numChildren();
  3238. for (unsigned idx=0; idx < max; idx++)
  3239. {
  3240. IHqlExpression * cur = expr->queryChild(idx);
  3241. if (cur->isDataset())
  3242. pushScope();
  3243. analyseExpr(cur);
  3244. if (cur->isDataset())
  3245. popScope();
  3246. }
  3247. if (expr->isDataset())
  3248. restoreScope();
  3249. break;
  3250. }
  3251. default:
  3252. {
  3253. unsigned numChildren = expr->numChildren();
  3254. unsigned first = (unsigned) -1;
  3255. bool nested = false;
  3256. switch (getChildDatasetType(expr))
  3257. {
  3258. case childdataset_none:
  3259. case childdataset_many_noscope:
  3260. case childdataset_map:
  3261. case childdataset_dataset_noscope:
  3262. {
  3263. //Don't change scope.
  3264. NewHqlTransformer::analyseChildren(expr);
  3265. return;
  3266. }
  3267. case childdataset_many:
  3268. {
  3269. first = getNumChildTables(expr);
  3270. for (idx = 0; idx < first; idx++)
  3271. analyseExpr(expr->queryChild(idx));
  3272. IHqlExpression * dataset = expr->queryChild(0);
  3273. nested = setDataset(dataset, dataset);
  3274. break;
  3275. }
  3276. case childdataset_if:
  3277. case childdataset_case:
  3278. {
  3279. assertex(innerScope && innerScope->isEmpty());
  3280. suspendScope();
  3281. analyseExpr(expr->queryChild(0));
  3282. restoreScope();
  3283. for (idx = 1; idx < numChildren; idx++)
  3284. analyseExpr(expr->queryChild(idx));
  3285. return;
  3286. }
  3287. case childdataset_dataset:
  3288. {
  3289. IHqlExpression * dataset = expr->queryChild(0);
  3290. analyseExpr(dataset);
  3291. nested = setDataset(dataset, dataset);
  3292. first = 1;
  3293. }
  3294. break;
  3295. case childdataset_datasetleft:
  3296. {
  3297. IHqlExpression * dataset = expr->queryChild(0);
  3298. analyseExpr(dataset);
  3299. nested = setDatasetLeft(dataset, dataset, querySelSeq(expr));
  3300. first = 1;
  3301. }
  3302. break;
  3303. case childdataset_left:
  3304. {
  3305. IHqlExpression * left = expr->queryChild(0);
  3306. analyseExpr(left);
  3307. nested = setLeft(left, querySelSeq(expr));
  3308. first = 1;
  3309. }
  3310. break;
  3311. case childdataset_leftright:
  3312. {
  3313. IHqlExpression * left = expr->queryChild(0);
  3314. IHqlExpression * right = expr->queryChild(1);
  3315. IHqlExpression * selSeq = querySelSeq(expr);
  3316. analyseExpr(left);
  3317. if (expr->getOperator() == no_normalize) // right can be dependent on left
  3318. {
  3319. bool nested = setLeft(left, selSeq);
  3320. pushScope();
  3321. analyseExpr(right);
  3322. popScope();
  3323. clearDataset(nested);
  3324. }
  3325. else
  3326. analyseExpr(right);
  3327. nested = setLeftRight(left, right, selSeq);
  3328. first = 2;
  3329. }
  3330. break;
  3331. case childdataset_top_left_right:
  3332. {
  3333. IHqlExpression * left = expr->queryChild(0);
  3334. analyseExpr(left);
  3335. nested = setTopLeftRight(left, left, querySelSeq(expr));
  3336. first = 1;
  3337. }
  3338. break;
  3339. case childdataset_same_left_right:
  3340. case childdataset_nway_left_right:
  3341. {
  3342. IHqlExpression * left = expr->queryChild(0);
  3343. analyseExpr(left);
  3344. nested = setLeftRight(left, left, querySelSeq(expr));
  3345. first = 1;
  3346. if (op == no_selfjoin)
  3347. first = 2;
  3348. }
  3349. break;
  3350. case childdataset_evaluate:
  3351. //done above...
  3352. default:
  3353. UNIMPLEMENTED;
  3354. }
  3355. for (idx = first; idx < numChildren; idx++)
  3356. analyseExpr(expr->queryChild(idx));
  3357. clearDataset(nested);
  3358. break;
  3359. }
  3360. }
  3361. }
  3362. IHqlExpression * ScopedTransformer::createTransformed(IHqlExpression * expr)
  3363. {
  3364. HqlExprArray children;
  3365. node_operator op = expr->getOperator();
  3366. unsigned numChildren = expr->numChildren();
  3367. children.ensure(numChildren);
  3368. unsigned idx;
  3369. switch (op)
  3370. {
  3371. case no_constant:
  3372. return LINK(expr);
  3373. case no_sizeof:
  3374. case no_offsetof:
  3375. case no_nameof:
  3376. // if (!expr->queryChild(0)->isDataset())
  3377. return NewHqlTransformer::createTransformed(expr);
  3378. throwUnexpected();
  3379. case NO_AGGREGATE:
  3380. case no_joined:
  3381. case no_buildindex:
  3382. case no_apply:
  3383. case no_distribution:
  3384. case no_distributer:
  3385. case no_within:
  3386. case no_notwithin:
  3387. case no_output:
  3388. case no_createset:
  3389. case no_soapaction_ds:
  3390. case no_newsoapaction_ds:
  3391. case no_returnresult:
  3392. case no_setgraphresult:
  3393. case no_setgraphloopresult:
  3394. case no_extractresult:
  3395. case no_createdictionary:
  3396. {
  3397. IHqlExpression * dataset = expr->queryChild(0);
  3398. pushScope();
  3399. IHqlExpression * transformedDs = transform(dataset);
  3400. children.append(*transformedDs);
  3401. bool nested = setDataset(dataset, transformedDs);
  3402. for (idx = 1; idx < numChildren; idx++)
  3403. children.append(*transform(expr->queryChild(idx)));
  3404. clearDataset(nested);
  3405. popScope();
  3406. break;
  3407. }
  3408. case no_projectrow:
  3409. {
  3410. //ugly - see comment above
  3411. IHqlExpression * dataset = expr->queryChild(0);
  3412. pushScope();
  3413. IHqlExpression * transformedDs = transform(dataset);
  3414. children.append(*transformedDs);
  3415. bool nested = setLeft(dataset, querySelSeq(expr));
  3416. for (idx = 1; idx < numChildren; idx++)
  3417. children.append(*transform(expr->queryChild(idx)));
  3418. clearDataset(nested);
  3419. popScope();
  3420. break;
  3421. }
  3422. case no_keydiff:
  3423. case no_rowdiff:
  3424. {
  3425. pushScope();
  3426. children.append(*transform(expr->queryChild(0)));
  3427. children.append(*transform(expr->queryChild(1)));
  3428. for (idx = 2; idx < numChildren; idx++)
  3429. children.append(*transform(expr->queryChild(idx)));
  3430. popScope();
  3431. break;
  3432. }
  3433. case no_setresult:
  3434. case no_blob2id:
  3435. {
  3436. IHqlExpression * value = expr->queryChild(0);
  3437. unsigned first = 0;
  3438. if (value->isDataset())
  3439. {
  3440. pushScope();
  3441. children.append(*transform(value));
  3442. popScope();
  3443. first++;
  3444. }
  3445. for (idx=first; idx < numChildren; idx++)
  3446. children.append(*transform(expr->queryChild(idx)));
  3447. break;
  3448. }
  3449. case no_selectnth:
  3450. case no_keypatch:
  3451. {
  3452. pushScope();
  3453. children.append(*transform(expr->queryChild(0)));
  3454. popScope();
  3455. for (idx = 1; idx < numChildren; idx++)
  3456. children.append(*transform(expr->queryChild(idx)));
  3457. break;
  3458. }
  3459. case no_evaluate:
  3460. {
  3461. IHqlExpression * scope = expr->queryChild(0);
  3462. IHqlExpression * transformedScope = transform(scope);
  3463. children.append(*transformedScope);
  3464. pushEvaluateScope(scope, transformedScope);
  3465. children.append(*transform(expr->queryChild(1)));
  3466. popEvaluateScope();
  3467. break;
  3468. }
  3469. case no_assign:
  3470. {
  3471. IHqlExpression * left = expr->queryChild(0);
  3472. IHqlExpression * right = expr->queryChild(1);
  3473. children.append(*LINK(left));
  3474. if (left->isDataset() || left->isDatarow())
  3475. {
  3476. pushScope();
  3477. children.append(*transform(right));
  3478. popScope();
  3479. }
  3480. else
  3481. {
  3482. children.append(*transform(right));
  3483. }
  3484. break;
  3485. }
  3486. case no_lt:
  3487. case no_le:
  3488. case no_gt:
  3489. case no_ge:
  3490. case no_ne:
  3491. case no_eq:
  3492. case no_order:
  3493. {
  3494. IHqlExpression * left = expr->queryChild(0);
  3495. IHqlExpression * right = expr->queryChild(1);
  3496. if (left->isDataset() || left->isDatarow())
  3497. {
  3498. pushScope();
  3499. children.append(*transform(left));
  3500. children.append(*transform(right));
  3501. popScope();
  3502. }
  3503. else
  3504. {
  3505. children.append(*transform(left));
  3506. children.append(*transform(right));
  3507. }
  3508. break;
  3509. }
  3510. case no_keyed:
  3511. case no_loopbody:
  3512. {
  3513. pushScope();
  3514. ForEachChild(idx, expr)
  3515. children.append(*transform(expr->queryChild(idx)));
  3516. popScope();
  3517. break;
  3518. }
  3519. case no_mapto:
  3520. case no_compound:
  3521. {
  3522. if (innerScope && innerScope->isEmpty())
  3523. {
  3524. suspendScope();
  3525. children.append(*transform(expr->queryChild(0)));
  3526. restoreScope();
  3527. }
  3528. else
  3529. children.append(*transform(expr->queryChild(0)));
  3530. children.append(*transform(expr->queryChild(1)));
  3531. break;
  3532. }
  3533. case no_table:
  3534. {
  3535. suspendScope();
  3536. bool restored=false;
  3537. bool nested = false;
  3538. ForEachChild(idx, expr)
  3539. {
  3540. IHqlExpression * cur = expr->queryChild(idx);
  3541. if (idx == 3 && cur->isDataset())
  3542. {
  3543. restored = true;
  3544. restoreScope();
  3545. IHqlExpression * transformed = transform(cur);
  3546. nested = setDataset(cur, transformed);
  3547. children.append(*transformed);
  3548. }
  3549. else
  3550. children.append(*transform(cur));
  3551. }
  3552. if (restored)
  3553. clearDataset(nested);
  3554. else
  3555. restoreScope();
  3556. break;
  3557. }
  3558. case no_select:
  3559. {
  3560. IHqlExpression * dataset = expr->queryChild(0);
  3561. if (expr->hasAttribute(newAtom))
  3562. {
  3563. pushScope();
  3564. IHqlExpression * transformedDs = transform(dataset);
  3565. children.append(*transformedDs);
  3566. bool nested = setDataset(dataset, transformedDs);
  3567. for (idx = 1; idx < numChildren; idx++)
  3568. children.append(*transform(expr->queryChild(idx)));
  3569. clearDataset(nested);
  3570. popScope();
  3571. if (transformedDs->getOperator() == no_activetable)
  3572. {
  3573. children.replace(*LINK(transformedDs->queryChild(0)), 0);
  3574. removeAttribute(children, newAtom);
  3575. }
  3576. }
  3577. else
  3578. return NewHqlTransformer::createTransformed(expr);
  3579. break;
  3580. }
  3581. case no_globalscope:
  3582. if (expr->hasAttribute(optAtom))
  3583. return NewHqlTransformer::createTransformed(expr);
  3584. //fall through
  3585. case no_colon:
  3586. case no_cluster:
  3587. {
  3588. // By definition no_colon is evaluated globally, so no tables are in scope for its children
  3589. ScopeSuspendInfo info;
  3590. suspendAllScopes(info);
  3591. if (expr->isDataset())
  3592. pushScope();
  3593. children.append(*transform(expr->queryChild(0)));
  3594. if (expr->isDataset())
  3595. popScope();
  3596. for (idx = 1; idx < numChildren; idx++)
  3597. children.append(*transform(expr->queryChild(idx)));
  3598. restoreScopes(info);
  3599. break;
  3600. }
  3601. case no_keyindex:
  3602. case no_newkeyindex:
  3603. {
  3604. IHqlExpression * dataset = expr->queryChild(0);
  3605. IHqlExpression * transformedDs = transform(dataset);
  3606. children.append(*transformedDs);
  3607. bool nested = setDataset(dataset, transformedDs);
  3608. unsigned max = expr->numChildren();
  3609. for (unsigned idx=1; idx < max; idx++)
  3610. children.append(*transform(expr->queryChild(idx)));
  3611. clearDataset(nested);
  3612. break;
  3613. }
  3614. case no_activerow:
  3615. {
  3616. IHqlExpression * dataset = expr->queryChild(0);
  3617. IHqlExpression * transformedDs = transformSelector(dataset);
  3618. children.append(*transformedDs);
  3619. break;
  3620. }
  3621. case no_call:
  3622. case no_externalcall:
  3623. case no_attr_expr:
  3624. case no_rowvalue:
  3625. case no_setmeta:
  3626. case no_typetransfer:
  3627. case no_subgraph:
  3628. case no_libraryscopeinstance:
  3629. {
  3630. if (expr->isDataset())
  3631. suspendScope();
  3632. unsigned max = expr->numChildren();
  3633. for (unsigned idx=0; idx < max; idx++)
  3634. {
  3635. IHqlExpression * cur = expr->queryChild(idx);
  3636. if (cur->isDataset())
  3637. pushScope();
  3638. children.append(*transform(cur));
  3639. if (cur->isDataset())
  3640. popScope();
  3641. }
  3642. if (expr->isDataset())
  3643. restoreScope();
  3644. break;
  3645. }
  3646. default:
  3647. {
  3648. unsigned first = (unsigned) -1;
  3649. bool nested = false;
  3650. switch (getChildDatasetType(expr))
  3651. {
  3652. case childdataset_none:
  3653. case childdataset_many_noscope:
  3654. case childdataset_map:
  3655. case childdataset_dataset_noscope:
  3656. {
  3657. return NewHqlTransformer::createTransformed(expr);
  3658. }
  3659. case childdataset_many:
  3660. {
  3661. first = getNumChildTables(expr);
  3662. IHqlExpression * dataset = expr->queryChild(0);
  3663. IHqlExpression * transformedDs = transform(dataset);
  3664. children.append(*transformedDs);
  3665. for (idx = 1; idx < first; idx++)
  3666. children.append(*transform(expr->queryChild(idx)));
  3667. nested = setDataset(dataset, transformedDs);
  3668. break;
  3669. }
  3670. case childdataset_if:
  3671. case childdataset_case:
  3672. {
  3673. assertex(innerScope && innerScope->isEmpty());
  3674. suspendScope();
  3675. children.append(*transform(expr->queryChild(0)));
  3676. restoreScope();
  3677. for (idx = 1; idx < numChildren; idx++)
  3678. children.append(*transform(expr->queryChild(idx)));
  3679. return expr->clone(children);
  3680. }
  3681. case childdataset_dataset:
  3682. {
  3683. IHqlExpression * dataset = expr->queryChild(0);
  3684. IHqlExpression * transformedDs = transform(dataset);
  3685. children.append(*transformedDs);
  3686. nested = setDataset(dataset, transformedDs);
  3687. first = 1;
  3688. }
  3689. break;
  3690. case childdataset_datasetleft:
  3691. {
  3692. IHqlExpression * dataset = expr->queryChild(0);
  3693. IHqlExpression * transformedDs = transform(dataset);
  3694. children.append(*transformedDs);
  3695. nested = setDatasetLeft(dataset, transformedDs, querySelSeq(expr));
  3696. first = 1;
  3697. }
  3698. break;
  3699. case childdataset_left:
  3700. {
  3701. IHqlExpression * left = expr->queryChild(0);
  3702. children.append(*transform(left));
  3703. nested = setLeft(left, querySelSeq(expr));
  3704. first = 1;
  3705. }
  3706. break;
  3707. case childdataset_leftright:
  3708. {
  3709. IHqlExpression * left = expr->queryChild(0);
  3710. IHqlExpression * right = expr->queryChild(1);
  3711. children.append(*transform(left));
  3712. children.append(*transform(right));
  3713. nested = setLeftRight(left, right, querySelSeq(expr));
  3714. first = 2;
  3715. }
  3716. break;
  3717. case childdataset_top_left_right:
  3718. {
  3719. IHqlExpression * left = expr->queryChild(0);
  3720. IHqlExpression * transformedLeft = transform(left);
  3721. children.append(*transformedLeft);
  3722. nested = setTopLeftRight(left, transformedLeft, querySelSeq(expr));
  3723. first = 1;
  3724. }
  3725. break;
  3726. case childdataset_same_left_right:
  3727. case childdataset_nway_left_right:
  3728. {
  3729. IHqlExpression * left = expr->queryChild(0);
  3730. children.append(*transform(left));
  3731. if (op == no_selfjoin)
  3732. children.append(*transform(expr->queryChild(1)));
  3733. nested = setLeftRight(left, left, querySelSeq(expr));
  3734. first = children.ordinality();
  3735. }
  3736. break;
  3737. case childdataset_evaluate:
  3738. //done above...
  3739. default:
  3740. UNIMPLEMENTED;
  3741. }
  3742. for (idx = first; idx < numChildren; idx++)
  3743. children.append(*transform(expr->queryChild(idx)));
  3744. clearDataset(nested);
  3745. break;
  3746. }
  3747. }
  3748. return cloneOrLink(expr, children);
  3749. }
  3750. IHqlExpression * ScopedTransformer::getEvaluateScope(IHqlExpression * scope)
  3751. {
  3752. switch (scope->getOperator())
  3753. {
  3754. case no_left:
  3755. return innerScope->left.getLink();
  3756. case no_right:
  3757. return innerScope->right.getLink();
  3758. default:
  3759. //MORE: We need to remove the LEFT/RIGHT from the scope (if present), and then apply the
  3760. //remaining selections to the result.
  3761. //Something like...
  3762. //OwnedHqlExpr scope1 = replaceSelector(scope, queryPseudoTable(no_left), innerScope->left);
  3763. //OwnedHqlExpr scope2 = replaceSelector(scope, queryPseudoTable(no_right), innerScope->right);
  3764. return LINK(scope);
  3765. }
  3766. }
  3767. void ScopedTransformer::pushScope()
  3768. {
  3769. innerScope = new ScopeInfo;
  3770. scopeStack.append(*innerScope);
  3771. }
  3772. void ScopedTransformer::pushEvaluateScope(IHqlExpression * dataset, IHqlExpression * transformed)
  3773. {
  3774. innerScope = new ScopeInfo;
  3775. scopeStack.append(*innerScope);
  3776. innerScope->setDataset(dataset->queryNormalizedSelector(true), transformed);
  3777. //MORE: Need to correctly translate the dataset.... Not sure what we want to do really.
  3778. // innerScope->evaluateScope.setown(getEvaluateScope(dataset));
  3779. }
  3780. void ScopedTransformer::popScope()
  3781. {
  3782. scopeStack.pop();
  3783. if (scopeStack.ordinality())
  3784. innerScope = &scopeStack.tos();
  3785. else
  3786. innerScope = NULL;
  3787. }
  3788. void ScopedTransformer::popEvaluateScope()
  3789. {
  3790. popScope();
  3791. }
  3792. void ScopedTransformer::clearDataset(bool nested)
  3793. {
  3794. assertex(innerScope->dataset || innerScope->left);
  3795. innerScope->clear();
  3796. }
  3797. bool ScopedTransformer::isDatasetRelatedToScope(IHqlExpression * search)
  3798. {
  3799. if (search->getOperator() == no_selectnth)
  3800. search = search->queryChild(0);
  3801. if (search->queryDataset())
  3802. {
  3803. ForEachItemInRev(idx, scopeStack)
  3804. {
  3805. ScopeInfo & cur = scopeStack.item(idx);
  3806. if (cur.dataset)
  3807. {
  3808. if (isChildRelationOf(search, cur.dataset))
  3809. return true;
  3810. }
  3811. #if 1
  3812. //Removed for the moment, because I think this only needs to work for hole tables
  3813. if (cur.left)
  3814. {
  3815. OwnedHqlExpr left = createSelector(no_left, cur.left, cur.seq);
  3816. if (isChildRelationOf(search, left))
  3817. return true;
  3818. }
  3819. #endif
  3820. }
  3821. }
  3822. else if (search->getOperator() == no_select)
  3823. {
  3824. //field in a nested record, test the selector
  3825. return isDatasetRelatedToScope(search->queryChild(0));
  3826. }
  3827. switch (search->getOperator())
  3828. {
  3829. case no_left:
  3830. case no_right:
  3831. case no_matchattr:
  3832. return true;
  3833. case no_if:
  3834. return isDatasetRelatedToScope(search->queryChild(1)) || isDatasetRelatedToScope(search->queryChild(2));
  3835. }
  3836. return false;
  3837. }
  3838. bool ScopedTransformer::checkInScope(IHqlExpression * selector, bool allowCreate)
  3839. {
  3840. switch (selector->getOperator())
  3841. {
  3842. case no_left:
  3843. case no_right:
  3844. case no_self:
  3845. case no_selfref:
  3846. case no_activetable:
  3847. case no_matchattr:
  3848. return true;
  3849. case no_field:
  3850. return true;
  3851. // assume the expression couldn't have been parsed without this being true.....
  3852. //otherwise we need to search up the list checking if a scope exists that defines left/right.
  3853. case no_selectnth:
  3854. //Indexing any dataset is almost certainly ok - except for child dataset of out of scope dataset
  3855. //don't bother checking.
  3856. return allowCreate;
  3857. case no_select:
  3858. if (selector->isDataset())
  3859. break;
  3860. return checkInScope(selector->queryChild(0), allowCreate);
  3861. case no_globalscope:
  3862. if (selector->hasAttribute(optAtom))
  3863. break;
  3864. //fall through
  3865. case no_colon:
  3866. case no_cluster:
  3867. // By definition no_colon is evaluated globally, so it can always be accessed
  3868. if (allowCreate && selector->isDatarow())
  3869. return true;
  3870. break;
  3871. }
  3872. if (scopeStack.ordinality() == 0)
  3873. return false;
  3874. IHqlExpression * normalized = selector->queryNormalizedSelector(false);
  3875. ForEachItemInRev(idx, scopeStack)
  3876. {
  3877. ScopeInfo & cur = scopeStack.item(idx);
  3878. if (cur.dataset && cur.dataset->queryNormalizedSelector(false) == normalized)
  3879. return true;
  3880. if (isInImplictScope(cur.dataset, normalized))
  3881. return true;
  3882. }
  3883. return false;
  3884. }
  3885. bool ScopedTransformer::isDatasetActive(IHqlExpression * selector)
  3886. {
  3887. return checkInScope(selector, false);
  3888. }
  3889. bool ScopedTransformer::isDatasetARow(IHqlExpression * selector)
  3890. {
  3891. return checkInScope(selector, true);
  3892. }
  3893. bool ScopedTransformer::isTopDataset(IHqlExpression * selector)
  3894. {
  3895. if (scopeStack.ordinality())
  3896. {
  3897. ScopeInfo & top = scopeStack.tos();
  3898. if (top.dataset && top.dataset->queryNormalizedSelector(false) == selector->queryNormalizedSelector(false))
  3899. return true;
  3900. switch (selector->getOperator())
  3901. {
  3902. case no_left:
  3903. return (top.left != NULL);
  3904. case no_right:
  3905. return (top.right != NULL);
  3906. case no_select:
  3907. if (selector->isDataset())
  3908. return false;
  3909. return isTopDataset(selector->queryChild(0));
  3910. }
  3911. }
  3912. return false;
  3913. }
  3914. IHqlExpression * ScopedTransformer::getScopeState()
  3915. {
  3916. HqlExprArray attrs;
  3917. ForEachItemIn(idx, scopeStack)
  3918. {
  3919. ScopeInfo & cur = scopeStack.item(idx);
  3920. if (cur.dataset)
  3921. attrs.append(*LINK(cur.dataset));
  3922. else if (cur.left)
  3923. attrs.append(*createAttribute(leftAtom, LINK(cur.left), LINK(cur.right)));
  3924. else
  3925. {}/*No need to include this*/
  3926. }
  3927. unsigned num = attrs.ordinality();
  3928. if (num == 0)
  3929. return LINK(emptyScopeMarker);
  3930. if (num == 1)
  3931. return &attrs.popGet();
  3932. return createAttribute(scopeAtom, attrs);
  3933. }
  3934. void ScopedTransformer::suspendAllScopes(ScopeSuspendInfo & info)
  3935. {
  3936. ForEachItemIn(i1, scopeStack)
  3937. info.scope.append(scopeStack.item(i1));
  3938. ForEachItemIn(i2, savedStack)
  3939. info.saved.append(savedStack.item(i2));
  3940. scopeStack.kill(true);
  3941. savedStack.kill(true);
  3942. innerScope = NULL;
  3943. }
  3944. void ScopedTransformer::suspendScope()
  3945. {
  3946. assertex(innerScope->isEmpty());
  3947. savedStack.append(*LINK(innerScope));
  3948. popScope();
  3949. }
  3950. void ScopedTransformer::restoreScope()
  3951. {
  3952. innerScope = &savedStack.popGet();
  3953. scopeStack.append(*innerScope);
  3954. }
  3955. void ScopedTransformer::restoreScopes(ScopeSuspendInfo & info)
  3956. {
  3957. ForEachItemIn(i1, info.scope)
  3958. scopeStack.append(info.scope.item(i1));
  3959. ForEachItemIn(i2, info.saved)
  3960. savedStack.append(info.saved.item(i2));
  3961. info.scope.kill(true);
  3962. info.saved.kill(true);
  3963. if (scopeStack.ordinality())
  3964. innerScope = &scopeStack.tos();
  3965. }
  3966. unsigned ScopedTransformer::tableNesting()
  3967. {
  3968. unsigned numTables = scopeStack.ordinality();
  3969. if (isNewDataset())
  3970. numTables--;
  3971. return numTables;
  3972. }
  3973. bool ScopedTransformer::insideActivity()
  3974. {
  3975. return (scopeStack.ordinality() != 0) || (savedStack.ordinality() != 0);
  3976. }
  3977. IHqlExpression * ScopedTransformer::doTransformRootExpr(IHqlExpression * expr)
  3978. {
  3979. IHqlExpression * ret;
  3980. if (expr->isDataset())
  3981. {
  3982. pushScope();
  3983. ret = NewHqlTransformer::doTransformRootExpr(expr);
  3984. popScope();
  3985. }
  3986. else
  3987. ret = NewHqlTransformer::doTransformRootExpr(expr);
  3988. assertex(scopeStack.ordinality() == 0);
  3989. return ret;
  3990. }
  3991. void ScopedTransformer::throwScopeError()
  3992. {
  3993. throwError(HQLERR_DatasetNotExpected);
  3994. }
  3995. //---------------------------------------------------------------------------
  3996. ScopedDependentTransformer::ScopedDependentTransformer(HqlTransformerInfo & _info) : ScopedTransformer(_info)
  3997. {
  3998. cachedLeft.setown(createValue(no_left));
  3999. cachedRight.setown(createValue(no_right));
  4000. }
  4001. bool ScopedDependentTransformer::setDataset(IHqlExpression * ds, IHqlExpression * transformedDs)
  4002. {
  4003. ScopedTransformer::setDataset(ds, transformedDs);
  4004. pushChildContext(ds, transformedDs);
  4005. return true;
  4006. }
  4007. bool ScopedDependentTransformer::setDatasetLeft(IHqlExpression * ds, IHqlExpression * transformedDs, IHqlExpression * seq)
  4008. {
  4009. ScopedTransformer::setDatasetLeft(ds, transformedDs, seq);
  4010. pushChildContext(ds, transformedDs);
  4011. return true;
  4012. }
  4013. bool ScopedDependentTransformer::setLeft(IHqlExpression * _left, IHqlExpression * seq)
  4014. {
  4015. ScopedTransformer::setLeft(_left, seq);
  4016. return false;
  4017. }
  4018. bool ScopedDependentTransformer::setLeftRight(IHqlExpression * _left, IHqlExpression * _right, IHqlExpression * seq)
  4019. {
  4020. ScopedTransformer::setLeftRight(_left, _right, seq);
  4021. return false;
  4022. }
  4023. bool ScopedDependentTransformer::setTopLeftRight(IHqlExpression * ds, IHqlExpression * transformedDs, IHqlExpression * seq)
  4024. {
  4025. ScopedTransformer::setTopLeftRight(ds, transformedDs, seq);
  4026. pushChildContext(ds, transformedDs);
  4027. return true;
  4028. }
  4029. void ScopedDependentTransformer::pushEvaluateScope(IHqlExpression * scope, IHqlExpression * transformedScope)
  4030. {
  4031. ScopedTransformer::pushEvaluateScope(scope, transformedScope);
  4032. pushChildContext(scope->queryNormalizedSelector(true), transformedScope->queryNormalizedSelector(true));
  4033. }
  4034. void ScopedDependentTransformer::popEvaluateScope()
  4035. {
  4036. ScopedTransformer::popEvaluateScope();
  4037. popChildContext();
  4038. }
  4039. void ScopedDependentTransformer::clearDataset(bool nested)
  4040. {
  4041. if (nested)
  4042. popChildContext();
  4043. ScopedTransformer::clearDataset(nested);
  4044. }
  4045. ANewTransformInfo * ScopedDependentTransformer::createTransformInfo(IHqlExpression * expr)
  4046. {
  4047. return CREATE_NEWTRANSFORMINFO(MergingTransformInfo, expr);
  4048. }
  4049. void ScopedDependentTransformer::pushChildContext(IHqlExpression * expr, IHqlExpression * transformed)
  4050. {
  4051. //NB: For this transformer it is the tables that are in scope that matter
  4052. IHqlExpression * scope = expr->queryNormalizedSelector(false);
  4053. //NB: Do no call createComma because that calls createDataset which unwinds a comma list!
  4054. if (childScope)
  4055. childScope.setown(createValue(no_comma,LINK(scope), childScope.getClear()));
  4056. else
  4057. childScope.set(scope);
  4058. //Need map the selectors for all the datasets that are in scope - not just the current one. If the same
  4059. //one occurs twice, the more recent will take precedence.
  4060. ForEachItemIn(idx, scopeStack)
  4061. {
  4062. ScopeInfo & cur = scopeStack.item(idx);
  4063. IHqlExpression * dataset = cur.dataset;
  4064. if (dataset)
  4065. initializeActiveSelector(dataset, cur.transformedDataset);
  4066. }
  4067. }
  4068. void ScopedDependentTransformer::popChildContext()
  4069. {
  4070. if (childScope->getOperator() == no_comma)
  4071. childScope.set(childScope->queryChild(1));
  4072. else
  4073. childScope.clear();
  4074. }
  4075. IHqlExpression * ScopedDependentTransformer::queryAlreadyTransformed(IHqlExpression * expr)
  4076. {
  4077. AMergingTransformInfo * extra = queryExtra(expr);
  4078. return extra->queryAlreadyTransformed(childScope);
  4079. }
  4080. void ScopedDependentTransformer::setTransformed(IHqlExpression * expr, IHqlExpression * transformed)
  4081. {
  4082. AMergingTransformInfo * extra = queryExtra(expr);
  4083. extra->setTransformed(childScope, transformed);
  4084. }
  4085. IHqlExpression * ScopedDependentTransformer::queryAlreadyTransformedSelector(IHqlExpression * expr)
  4086. {
  4087. AMergingTransformInfo * extra = queryExtra(expr->queryNormalizedSelector());
  4088. return extra->queryAlreadyTransformedSelector(childScope);
  4089. }
  4090. void ScopedDependentTransformer::setTransformedSelector(IHqlExpression * expr, IHqlExpression * transformed)
  4091. {
  4092. assertex(expr == expr->queryNormalizedSelector());
  4093. assertex(transformed == transformed->queryNormalizedSelector());
  4094. AMergingTransformInfo * extra = queryExtra(expr->queryNormalizedSelector());
  4095. extra->setTransformedSelector(childScope, transformed);
  4096. }
  4097. void ScopedDependentTransformer::suspendAllScopes(ScopeSuspendInfo & info)
  4098. {
  4099. ScopedTransformer::suspendAllScopes(info);
  4100. info.savedI.append(childScope.getClear());
  4101. }
  4102. void ScopedDependentTransformer::restoreScopes(ScopeSuspendInfo & info)
  4103. {
  4104. childScope.setown(info.savedI.popGet());
  4105. ScopedTransformer::restoreScopes(info);
  4106. }
  4107. //---------------------------------------------------------------------------
  4108. static HqlTransformerInfo splitterVerifierInfo("SplitterVerifier");
  4109. SplitterVerifier::SplitterVerifier() : NewHqlTransformer(splitterVerifierInfo)
  4110. {
  4111. }
  4112. void SplitterVerifier::analyseExpr(IHqlExpression * expr)
  4113. {
  4114. if (expr->getOperator() == no_split)
  4115. {
  4116. SplitterVerifierInfo * extra = queryExtra(expr->queryBody());
  4117. if (extra->useCount++)
  4118. {
  4119. #ifdef _DEBUG
  4120. IHqlExpression * id = expr->queryAttribute(_uid_Atom);
  4121. unsigned idValue = (id ? (unsigned)getIntValue(id->queryChild(0)) : 0);
  4122. #endif
  4123. unsigned splitSize = (unsigned)getIntValue(expr->queryChild(1), 0);
  4124. if (extra->useCount > splitSize)
  4125. throwUnexpected();
  4126. return;
  4127. }
  4128. }
  4129. NewHqlTransformer::analyseExpr(expr);
  4130. }
  4131. void verifySplitConsistency(IHqlExpression * expr)
  4132. {
  4133. SplitterVerifier checker;
  4134. checker.analyse(expr, 0);
  4135. }
  4136. //---------------------------------------------------------------------------
  4137. static HqlTransformerInfo globalToParameterTransformerInfo("GlobalToParameterTransformer");
  4138. class GlobalToParameterTransformer : public QuickHqlTransformer
  4139. {
  4140. public:
  4141. GlobalToParameterTransformer(HqlExprArray & _parameters, HqlExprArray & _defaults)
  4142. : QuickHqlTransformer(globalToParameterTransformerInfo, NULL), parameters(_parameters), defaults(_defaults)
  4143. {}
  4144. virtual IHqlExpression * createTransformedBody(IHqlExpression * expr);
  4145. protected:
  4146. HqlExprArray & parameters;
  4147. HqlExprArray & defaults;
  4148. };
  4149. IHqlExpression * GlobalToParameterTransformer::createTransformedBody(IHqlExpression * expr)
  4150. {
  4151. if (expr->getOperator() != no_colon)
  4152. return QuickHqlTransformer::createTransformedBody(expr);
  4153. StringBuffer paramName;
  4154. paramName.append("_implicit_hidden_").append(parameters.ordinality());
  4155. HqlExprArray attrs;
  4156. attrs.append(*createAttribute(_hidden_Atom));
  4157. IHqlExpression * param = createParameter(createIdAtom(paramName.str()), parameters.ordinality(), expr->getType(), attrs);
  4158. parameters.append(*param);
  4159. defaults.append(*LINK(expr));
  4160. return LINK(param);
  4161. }
  4162. IHqlExpression * convertWorkflowToImplicitParmeters(HqlExprArray & parameters, HqlExprArray & defaults, IHqlExpression * expr)
  4163. {
  4164. GlobalToParameterTransformer transformer(parameters, defaults);
  4165. return transformer.transform(expr);
  4166. }
  4167. //---------------------------------------------------------------------------
  4168. static HqlTransformerInfo createRowSelectorExpanderInfo("CreateRowSelectorExpander");
  4169. class CreateRowSelectorExpander : public NewHqlTransformer
  4170. {
  4171. public:
  4172. CreateRowSelectorExpander() : NewHqlTransformer(createRowSelectorExpanderInfo) {}
  4173. virtual IHqlExpression * createTransformed(IHqlExpression * expr)
  4174. {
  4175. OwnedHqlExpr transformed = NewHqlTransformer::createTransformed(expr);
  4176. if ((transformed->getOperator() == no_select) && transformed->hasAttribute(newAtom))
  4177. {
  4178. IHqlExpression * child = transformed->queryChild(0);
  4179. node_operator childOp = child->getOperator();
  4180. if (childOp == no_createrow)
  4181. {
  4182. OwnedHqlExpr match = getExtractSelect(child->queryChild(0), transformed->queryChild(1), false);
  4183. if (match)
  4184. {
  4185. IHqlExpression * cur = queryUncastExpr(match);
  4186. switch (cur->getOperator())
  4187. {
  4188. case no_constant:
  4189. case no_select:
  4190. return match.getClear();
  4191. }
  4192. }
  4193. }
  4194. }
  4195. return transformed.getClear();
  4196. }
  4197. };
  4198. IHqlExpression * expandCreateRowSelectors(IHqlExpression * expr)
  4199. {
  4200. CreateRowSelectorExpander expander;
  4201. return expander.createTransformed(expr);
  4202. }
  4203. //---------------------------------------------------------------------------
  4204. /*
  4205. Notes:
  4206. The following things are nasty when transforming graphs:
  4207. conditional:
  4208. should multiple conditional items be commoned up, or kept conditional. There is no correct answer, but generally
  4209. if there are any unconditional uses, then they should be commoned up, otherwise they should remain separate.
  4210. sequential:
  4211. nothing within the sequential should be moved before another item. This messes up the conditional handling - since
  4212. we can't move an unconditional evaluation before a conditional sequential one.
  4213. Perfectly we would do the following:
  4214. For each expression:
  4215. For each sequential (and null sequential) section it is used from - maintained in order
  4216. Is it used conditionally/unconditionally
  4217. When transforming, would need to be current sequential branch dependent
  4218. If already transformed unconditionally within a previous branch with the same or lower conditionallity then reuse
  4219. If used unconditionally in this branch hoist within branchand register
  4220. else if conditional create a comma expression locally.
  4221. Could possibly implement if no_sequential contained no_sequentialitem()
  4222. no_sequential_item pushes a new mutex that inherits the previous values
  4223. pops previous values when leaving
  4224. - still causes problems for unconditional uses after conditional.
  4225. In general too complicated to try and solve in a single pass....
  4226. Try two passes.....
  4227. 1. Treat sequential as a new scope and don't common up between items.
  4228. 2.
  4229. */
  4230. #ifdef OPTIMIZE_TRANSFORM_ALLOCATOR
  4231. ANewHqlTransformer::ANewHqlTransformer()
  4232. {
  4233. prevSize = beginTransformerAllocator();
  4234. }
  4235. ANewHqlTransformer::~ANewHqlTransformer()
  4236. {
  4237. endTransformerAllocator(prevSize);
  4238. }
  4239. size32_t beginTransformerAllocator()
  4240. {
  4241. transformerDepth++;
  4242. return transformerHeap->allocated();
  4243. }
  4244. void endTransformerAllocator(size32_t prevSize)
  4245. {
  4246. transformerDepth--;
  4247. //More: Some way to specify minimum memory left unfreed??
  4248. transformerHeap->setSize(prevSize);
  4249. }
  4250. void * transformerAlloc(size32_t size)
  4251. {
  4252. return transformerHeap->alloc(size);
  4253. }
  4254. #endif
  4255. //------------------------------------------------------------------------------------------------
  4256. /*
  4257. Some notes on selector ambiguity.
  4258. a) Whatever work is done, it is going to be impossible to completely get rid of ambiguious selectors.
  4259. It may be possible with no_left/no_right, depending on the implementation, but not with dataset selectors.
  4260. E.g, x(f1 in set(x(f2), f3))
  4261. inside the evaluation of f3, the code generator needs to correctly ensure that
  4262. i) the inner iterator on x(f2) is used when evaluating f3.
  4263. ii) f3 is never hoisted from the inner loop to the outer.
  4264. =>
  4265. i) ALL selector replacement needs to take dataset nesting into account (even non no_left/no_right)
  4266. ii) Need to never evaluate an expression (e.g., alias) in the parent if it will change the meaning.
  4267. => Need to tag inherited rows, and don't evaluate in parent if they clash with required rows.
  4268. => Need to be very careful in any hoisting code (resource/cse etc.)
  4269. b) LEFT and RIGHTT really should be unique to the point they are used.
  4270. => We need to associate some kind of uid with each project. Considered the following options:
  4271. i) create a uid each time an expression that defines LEFT/RIGHT is created. But mangle it with the parameters to ensure really unique.
  4272. ii) create a uid based on some function of the input datasets.
  4273. iii) create a uid based on some function of the normalized selectors for the input datasets.
  4274. (i) Creates a large number of complex expressions, and removes quite a lot of accidental commoning up which occurs.
  4275. (ii) should be ok, but still signficantly increases the number of unique expressions
  4276. (iii) and improvement on (ii), but doesn't fare much better.
  4277. */