12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include "hqlthql.hpp"
- #include <limits.h>
- #include "jmisc.hpp"
- #include "jlog.hpp"
- #include "hqltrans.ipp"
- #include "hqlutil.hpp"
- #include "hqlmeta.hpp"
- #include "workunit.hpp"
- #include "hqlerrors.hpp"
- //The following constants can be uncommented to increase the level of detail which is added to the processed graphs
- //E.g. generated when -fl used in hqltest
- //#define SHOWADDRSYM
- //#define SHOWBRACKETS
- //#define SHOWADDR
- //#define SHOWTYPES
- //#define SHOWFLAGS
- //#define SHOWCONTEXTDETAIL
- //#define SHOWFLAGSVALUE
- //#define SHOW_TABLES
- //#define SHOW_TABLES_EXISTANCE
- //#define SHOWCRC
- //#define SHOW_ANNOTATIONS
- //#define SHOW_NORMALIZED
- //#define SHOW_EXPAND_LEFTRIGHT
- //#define SHOW_DSRECORD
- //#define SHOW_DISTRIBUTION
- //#define SHOW_ORDER
- //#define SHOW_GROUPING
- //#define SHOW_GROUPING_DETAIL
- //#define SHOW_MODULE_STATUS
- //#define SHOW_FUNC_DEFINTION
- //#define SHOW_SYMBOL_LOCATION
- #define MAX_GRAPHTEXT_LEN 80 // Truncate anything more than 80 characters
- bool endsWithDotDotDot(const StringBuffer & s)
- {
- if (s.length() < 3)
- return false;
- return (memcmp(s.str() + s.length() -3, "...", 3) == 0);
- }
- typedef CopyReferenceArrayOf<HqlExprArray> HqlExprArrayArray;
- class HqltHql
- {
- public:
- HqltHql(bool recurse, bool _xgmmlGraphText);
- ~HqltHql();
- void toECL(IHqlExpression *expr, StringBuffer &s, bool paren, bool inType, unsigned recordIndex=0, bool isNamedSymbol=false);
- StringBuffer & gatherDefinitions(StringBuffer & out);
- StringBuffer & gatherServices(StringBuffer & out) { return out.append(m_services); }
- void setExpandProcessed(bool value) { expandProcessed = value; }
- void setExpandNamed(bool value) { expandNamed = value; }
- void setIgnoreModuleNames(bool value) { ignoreModuleNames = value; }
- void setIgnoreVirtualAttrs(bool value) { ignoreVirtualAttrs = value; }
- void setLowerCaseIds(bool value) { lowerCaseIds = value; }
- void setMinimalSelectors(bool value) { minimalSelectors = value; }
- void setMaxRecurseDepth(int depth) { maxDatasetDepth = depth; }
- void setTryToRegenerate(bool value) { tryToRegenerate = value; }
- StringBuffer &doAlias(IHqlExpression * expr, StringBuffer &name, bool inType);
- private:
- void childrenToECL(IHqlExpression *expr, StringBuffer &s, bool inType, bool needComma, unsigned first);
- void defaultToECL(IHqlExpression *expr, StringBuffer &s, bool inType);
- void defaultChildrenToECL(IHqlExpression *expr, StringBuffer &s, bool inType);
- void appendSortOrder(StringBuffer & s, const char * prefix, IHqlExpression * order);
- void createPseudoSymbol(StringBuffer & s, const char * prefix, IHqlExpression * expr);
- void expandTransformValues(StringBuffer & s, IHqlExpression * expr, bool & first);
- StringBuffer &getTypeString(ITypeInfo * i, StringBuffer &s);
- StringBuffer &getFieldTypeString(IHqlExpression * e, StringBuffer &s);
- const char *getEclOpString(node_operator op);
- void defineCallTarget(IHqlExpression * expr, StringBuffer & name);
- bool isFunctionDefined(IHqlExpression * expr);
- IHqlExpression * querySymbolDefined(IHqlExpression * expr);
- bool isSymbolDefined(IHqlExpression * expr) { return querySymbolDefined(expr) != NULL; }
- bool isAlienTypeDefined(ITypeInfo * type);
- IHqlExpression * queryAlienDefinition(ITypeInfo * type);
- void addExport(StringBuffer &s);
- void clearVisited();
- StringBuffer &callEclFunction(StringBuffer &s, IHqlExpression * expr, bool inType);
- bool isSelect(IHqlExpression * expr);
- StringBuffer &lookupSymbolName(IHqlExpression * expr, StringBuffer &s);
- StringBuffer &makeUniqueName(IHqlExpression * expr, StringBuffer &s);
- void addVisited(IHqlExpression * expr);
- HqlExprArray * findVisitedArray();
- void clearAllVisitedArrays();
- bool isServiceDefined(IHqlExpression * expr);
- bool isExportDefined(IHqlExpression * expr);
- void doFunctionDefinition(StringBuffer & newdef, IHqlExpression * funcdef, const char * name, bool inType);
- void sortlistToEcl(IHqlExpression *expr, StringBuffer &s, bool addCurleys, bool inType);
- bool matchesActiveDataset(IHqlExpression * expr);
- void pushScope(IHqlExpression * expr);
- void popScope();
- void mapDatasetRecord(IHqlExpression * expr);
- void popMapping();
- bool queryAddDotDotDot(StringBuffer & s, unsigned startLength);
- IHqlExpression * queryMapped(IHqlExpression * expr);
- IHqlExpression * queryChild(IHqlExpression * e, unsigned i);
- StringBuffer & appendId(StringBuffer & s, IIdAtom * name);
- StringBuffer & queryNewline(StringBuffer &s);
- bool isExported(IHqlExpression * expr)
- {
- return ::isExported(expr) && !tryToRegenerate;
- }
- bool isShared(IHqlExpression * expr)
- {
- return ::isShared(expr) && !tryToRegenerate;
- }
- bool isPublicSymbol(IHqlExpression * expr)
- {
- return ::isPublicSymbol(expr) && !tryToRegenerate;
- }
- bool isInternalAttribute(IHqlExpression * e)
- {
- if (e->isAttribute())
- {
- IAtom * name= e->queryName();
- if ((name == sequenceAtom) || isInternalAttributeName(name))
- return true;
- if ((name == updateAtom) && e->hasAttribute(alwaysAtom))
- return true;
- if (tryToRegenerate)
- {
- if (name == jobTempAtom || name == loopFirstAtom)
- return true;
- }
- }
- return false;
- }
- private:
- bool m_recurse;
- bool ignoreModuleNames;
- bool insideNewTransform;
- int maxDatasetDepth;
- int curDatasetDepth;
- StringBuffer m_definitions;
- StringBuffer m_services;
- IArray m_visitedAlienTypes;
- bool m_isTop;
- int m_export_level;
- unsigned indent;
- bool xgmmlGraphText;
- bool expandNamed;
- bool expandProcessed;
- bool ignoreVirtualAttrs;
- bool lowerCaseIds;
- bool minimalSelectors;
- bool tryToRegenerate;
- StringBufferArray m_exports;
- StringBufferArray m_service_names;
- StringBufferArray m_export_names;
- HqlExprArrayArray m_visited_array;
- PointerArray scope;
- HqlExprArray mapped;
- IPointerArray mapSaved;
- unsigned clashCounter;
- };
- HqltHql::HqltHql(bool recurse, bool _xgmmlGraphText) :
- m_recurse(recurse),
- maxDatasetDepth(_xgmmlGraphText ? 1 : INT_MAX),
- m_isTop(true),
- m_export_level(0)
- {
- lockTransformMutex();
- indent = 1;
- xgmmlGraphText = _xgmmlGraphText;
- curDatasetDepth = 0;
- ignoreModuleNames = false;
- expandNamed = true;
- expandProcessed = false;
- insideNewTransform = false;
- ignoreVirtualAttrs = false;
- minimalSelectors = false;
- lowerCaseIds = false;
- tryToRegenerate = false;
- clashCounter = 0;
- }
- HqltHql::~HqltHql()
- {
- clearAllVisitedArrays();
- unlockTransformMutex();
- }
- StringBuffer & HqltHql::appendId(StringBuffer & s, IIdAtom * id)
- {
- if (lowerCaseIds)
- return s.append(str(lower(id)));
- else
- return s.append(str(id));
- }
- StringBuffer &HqltHql::makeUniqueName(IHqlExpression * expr, StringBuffer &s)
- {
- IIdAtom * moduleName = expr->queryFullContainerId();
- if (moduleName && !ignoreModuleNames)
- {
- if (isPublicSymbol(expr))
- {
- if (xgmmlGraphText)
- appendId(s, moduleName).append(".");
- else
- {
- const char * moduleNameText = str(lower(moduleName));
- for (;;)
- {
- const char * dot = strchr(moduleNameText, '.');
- if (!dot)
- {
- s.append(moduleNameText);
- break;
- }
- s.append(dot-moduleNameText, moduleNameText).append("__");
- moduleNameText = dot+1;
- }
- s.append("__");
- }
- }
- }
- appendId(s, expr->queryId());
- #ifdef SHOWADDRSYM
- if (expandProcessed)
- s.appendf("[%p:%p]",expr, expr->queryBody());
- #endif
- return s;
- }
- bool HqltHql::isSelect(IHqlExpression * expr)
- {
- return expr->getOperator() == no_select;
- }
- void HqltHql::mapDatasetRecord(IHqlExpression * expr)
- {
- IHqlExpression * record = expr->queryRecord()->queryBody();
- mapped.append(*LINK(expr));
- IInterface * mapping = LINK(record->queryTransformExtra());
- mapSaved.append(mapping);
- if (!mapping && expr->queryName())
- record->setTransformExtra(expr);
- }
- void HqltHql::popMapping()
- {
- OwnedHqlExpr expr = &mapped.popGet();
- IHqlExpression * record = expr->queryRecord()->queryBody();
- if (record->queryTransformExtra() == expr)
- record->setTransformExtra(mapSaved.tos());
- mapSaved.pop();
- }
- IHqlExpression * HqltHql::queryMapped(IHqlExpression * expr)
- {
- for (;;)
- {
- IHqlExpression * extra = (IHqlExpression *)expr->queryTransformExtra();
- if (!extra || extra->isAttribute() || extra == expr)
- return expr;
- if (expr->queryName() == lower(unnamedId))
- return expr;
- expr = extra;
- }
- }
- void HqltHql::addExport(StringBuffer &s)
- {
- // Need a map of StringBuffers indexed by m_export_level
- for(int idx = m_exports.ordinality(); idx <= m_export_level; idx++)
- {
- m_exports.append(*new StringBufferItem);
- }
- m_exports.item(m_export_level).append(s);
- }
- StringBuffer & HqltHql::gatherDefinitions(StringBuffer & out)
- {
- out.append(m_definitions);
- for(int idx = (m_exports.length() - 1); idx >=0; idx--)
- out.append(m_exports.item(idx));
- return out;
- }
- void HqltHql::addVisited(IHqlExpression * expr)
- {
- findVisitedArray()->append(*LINK(expr));
- }
- HqlExprArray * HqltHql::findVisitedArray()
- {
- for(int idx = m_visited_array.ordinality(); idx <= m_export_level; idx++)
- m_visited_array.append(*(new HqlExprArray));
- return &(m_visited_array.item(m_export_level));
- }
- void HqltHql::clearVisited()
- {
- HqlExprArray * visited = findVisitedArray();
- ForEachItemInRev(idx, *visited)
- {
- IHqlExpression * expr = &(visited->item(idx));
- if (!isPublicSymbol(expr))
- {
- visited->remove(idx);
- }
- }
- }
- void HqltHql::clearAllVisitedArrays()
- {
- // Empty the array of visited IHqlExpression Arrays
- for(unsigned jdx = 0; jdx < m_visited_array.length(); jdx++)
- {
- delete &(m_visited_array.item(jdx));
- }
- m_visited_array.kill();
- }
- bool HqltHql::isServiceDefined(IHqlExpression * expr)
- {
- StringBuffer name;
- makeUniqueName(expr, name);
- for(unsigned jdx = 0; jdx < m_service_names.length(); jdx++)
- {
- if(!stricmp(m_service_names.item(jdx).str(), name.str()))
- return true;
- }
- return false;
- }
- bool HqltHql::isExportDefined(IHqlExpression * expr)
- {
- StringBuffer name;
- makeUniqueName(expr, name);
- for(unsigned jdx = 0; jdx < m_export_names.length(); jdx++)
- {
- if(!stricmp(m_export_names.item(jdx).str(), name.str()))
- return true;
- }
- return false;
- }
- bool HqltHql::isFunctionDefined(IHqlExpression * expr)
- {
- // THIS FUNCTION IS EXPORTED !!! CHECK THE OTHER EXPORTS TOO
- if(isExportDefined(expr))
- return true;
- return findVisitedArray()->contains(*expr);
- }
- StringBuffer &HqltHql::lookupSymbolName(IHqlExpression * expr, StringBuffer &s)
- {
- IHqlExpression * extra = (IHqlExpression *)expr->queryTransformExtra();
- if (extra)
- {
- if ((extra != expr) && !extra->isAttribute())
- return lookupSymbolName(extra, s);
- return appendId(s, extra->queryId());
- }
- makeUniqueName(expr, s);
- return s;
- }
- IHqlExpression * HqltHql::querySymbolDefined(IHqlExpression * expr)
- {
- StringBuffer xxx;
- lookupSymbolName(expr, xxx);
- HqlExprArray * visited = findVisitedArray();
- for (unsigned i = 0; i < visited->ordinality(); i++)
- {
- IHqlExpression * item = &(visited->item(i));
- IHqlExpression * extra = static_cast<IHqlExpression *>(item->queryTransformExtra());
- if(extra->queryName() && xxx.length())
- {
- if(!stricmp(str(extra->queryName()), xxx.str()))
- return item;
- }
- }
- return NULL;
- }
- IHqlExpression * HqltHql::queryAlienDefinition(ITypeInfo * type)
- {
- IHqlExpression * expr = queryExpression(queryUnqualifiedType(type));
- return expr->queryFunctionDefinition(); // Not really queryFunctionDefinition - original definition of the alien type
- }
- bool HqltHql::isAlienTypeDefined(ITypeInfo * type)
- {
- IHqlExpression * expr = queryAlienDefinition(type);
- if (m_visitedAlienTypes.find(*expr) != NotFound)
- return true;
- m_visitedAlienTypes.append(*LINK(expr));
- return false;
- }
- IHqlExpression * HqltHql::queryChild(IHqlExpression * expr, unsigned i)
- {
- IHqlExpression * child = expr->queryChild(i);
- if (!expandProcessed && isInternalAttribute(child))
- return NULL;
- return child;
- }
- StringBuffer &HqltHql::callEclFunction(StringBuffer &s, IHqlExpression * expr, bool inType)
- {
- assertex(expr->isNamedSymbol());
- IHqlExpression * funcdef = expr->queryFunctionDefinition();
- switch (funcdef->getOperator())
- {
- case no_funcdef:
- case no_internalselect:
- case no_delayedselect:
- break;
- default:
- throw makeStringExceptionV(ERR_INTERNALEXCEPTION, "Internal: Unexpected function definition %s", getOpString(funcdef->getOperator()));
- }
- IHqlExpression * formals = queryFunctionParameters(funcdef);
- s.append('(');
- unsigned numParameters = formals->numChildren();
- bool first = true;
- for (unsigned idx = 0; idx < numParameters; idx++)
- {
- if (expandProcessed || !formals->queryChild(idx)->hasAttribute(_hidden_Atom))
- {
- if (first)
- first = false;
- else
- s.append(", ");
- if(funcdef->isNamedSymbol())
- {
- IHqlExpression * param = expr->queryAnnotationParameter(idx);
- if(param)
- toECL(param, s, false, inType);
- }
- }
- }
- s.append(')');
- return s;
- }
- void HqltHql::popScope()
- {
- scope.pop();
- }
- void HqltHql::pushScope(IHqlExpression * expr)
- {
- if (expr)
- {
- expr = expr->queryNormalizedSelector();
- if (expr->getOperator() == no_selectnth)
- expr = expr->queryChild(0)->queryNormalizedSelector();
- }
- scope.append(expr);
- }
- bool HqltHql::matchesActiveDataset(IHqlExpression * expr)
- {
- if (!expr || (scope.ordinality() == 0))
- return false;
- return expr->queryNormalizedSelector() == scope.tos();
- }
- bool isEclAlias(IHqlExpression * expr)
- {
- IHqlExpression * symbol = queryNamedSymbol(expr);
- if (!symbol)
- return false;
- //don't add an alias around the definition of an external call. Maybe the tree shouldn't include the named symbol in the first place
- if (expr->getOperator() != no_externalcall)
- return true;
- IHqlExpression * funcdef = expr->queryFunctionDefinition();
- if (!funcdef) // attr := call();
- return true;
- return (funcdef->queryChild(0)->getOperator() != no_external);
- }
- static bool needParen(int precedence, IHqlExpression * child)
- {
- if (!child)
- return false;
- if (isEclAlias(child))
- return false;
- return (child->getPrecedence() < precedence) && (child->numChildren() > 1);
- }
- static bool needParen(IHqlExpression * expr, IHqlExpression * child)
- {
- return needParen(expr->getPrecedence(), child);
- }
- StringBuffer & HqltHql::queryNewline(StringBuffer &s)
- {
- const unsigned maxLineLength = 1000;
- unsigned len = s.length();
- if (len < maxLineLength)
- return s;
- const char * text = s.str();
- for (unsigned i = 0; i < maxLineLength; i++)
- if (text[--len] == '\n')
- return s;
- return s.newline();
- }
- void HqltHql::childrenToECL(IHqlExpression *expr, StringBuffer &s, bool inType, bool needComma, unsigned first)
- {
- unsigned kids = expr->numChildren();
- for (unsigned idx = first; idx < kids; idx++)
- {
- IHqlExpression * child = queryChild(expr, idx);
- if (child && (expandProcessed || !isInternalAttribute(expr)))
- {
- if (needComma) queryNewline(s.append(", "));
- needComma = true;
- toECL(child, s, false, inType);
- if (expandProcessed && child->isAction())
- s.newline();
- }
- }
- }
- void splitPayload(SharedHqlExpr & keyed, SharedHqlExpr & payload, IHqlExpression * expr, unsigned payloadFields)
- {
- unsigned numFields = 0;
- ForEachChild(i, expr)
- if (!expr->queryChild(i)->isAttribute())
- numFields++;
- HqlExprArray keyedArgs, payloadArgs;
- unsigned cnt = 0;
- ForEachChild(j, expr)
- {
- IHqlExpression * field = expr->queryChild(j);
- if (!field->isAttribute())
- {
- if (cnt++ < numFields - payloadFields)
- keyedArgs.append(*LINK(field));
- else
- payloadArgs.append(*LINK(field));
- }
- }
- keyed.setown(expr->clone(keyedArgs));
- payload.setown(expr->clone(payloadArgs));
- }
- bool HqltHql::queryAddDotDotDot(StringBuffer & s, unsigned startLength)
- {
- if (xgmmlGraphText && (s.length() - startLength) > MAX_GRAPHTEXT_LEN)
- {
- s.append("...");
- return true;
- }
- return false;
- }
- void HqltHql::expandTransformValues(StringBuffer & s, IHqlExpression * expr, bool & first)
- {
- switch (expr->getOperator())
- {
- case no_assign:
- if (first)
- first = false;
- else
- s.append(",");
- toECL(expr->queryChild(1), s, false, false, 0, false);
- break;
- case no_transform:
- case no_assignall:
- ForEachChild(i, expr)
- expandTransformValues(s, expr->queryChild(i), first);
- break;
- }
- }
- void HqltHql::appendSortOrder(StringBuffer & s, const char * prefix, IHqlExpression * order)
- {
- if (order)
- {
- s.append(prefix).append("[");
- toECL(order, s, false, false, 0, false);
- s.append("]");
- }
- }
- void HqltHql::createPseudoSymbol(StringBuffer & s, const char * prefix, IHqlExpression * expr)
- {
- StringBuffer name;
- bool alreadyDefined = findVisitedArray()->contains(*expr);
- if (!alreadyDefined)
- addVisited(expr);
- name.append(prefix).append(findVisitedArray()->find(*expr));
- if (!alreadyDefined)
- {
- expr->setTransformExtra(expr);
- bool wasInsideNewTransform = insideNewTransform;
- insideNewTransform = false;
-
- StringBuffer temp;
- scope.append(NULL);
- temp.append(name);
- #ifdef SHOW_NORMALIZED
- if (expandProcessed && expr->isDataset())
- temp.appendf(" [N%p]", expr->queryNormalizedSelector());
- #endif
- temp.append(" := ");
- toECL(expr, temp, false, false, 0, true);
- temp.append(";").newline();
- addExport(temp);
- scope.pop();
- insideNewTransform = wasInsideNewTransform;
- }
- s.append(name);
- }
- void HqltHql::toECL(IHqlExpression *expr, StringBuffer &s, bool paren, bool inType, unsigned recordIndex, bool isNamedSymbol)
- {
- if (expandProcessed)
- {
- #ifdef SHOWBRACKETS
- paren = true;
- #endif
- #ifdef SHOWCRC
- s.appendf("[%p]", getExpressionCRC(expr));
- #endif
- #ifdef SHOWADDR
- s.appendf("[%p]", expr);
- #endif
- #ifdef SHOWTYPES
- if (expr->queryType())
- expr->queryType()->getECLType(s.append("[T")).append("]");
- #endif
- #ifdef SHOWFLAGS
- s.append("[");
- #ifdef SHOWFLAGSVALUE
- s.appendf("%p/", expr->getInfoFlags());
- #endif
- if (!expr->isFullyBound())
- s.append("*U");
- if (expr->isPure())
- s.append('P');
- if (expr->isConstant())
- s.append('C');
- if (containsActiveDataset(expr))
- s.append('D');
- if (containsAnyDataset(expr))
- s.append('A');
- if (containsInternalSelect(expr))
- s.append('V');
- if (expr->getInfoFlags() & HEFaction)
- s.append('N');
- if (containsWorkflow(expr))
- s.append('W');
- if (containsSelf(expr))
- s.append('S');
- if (isContextDependent(expr))
- {
- s.append('X');
- #ifdef SHOWCONTEXTDETAIL
- s.append('[');
- unsigned flags = expr->getInfoFlags();
- if (flags & HEFnoduplicate) s.append('V');
- if (flags & HEFgraphDependent) s.append('G');
- if (flags & HEFcontainsSkip) s.append('S');
- if (flags & HEFcontainsCounter) s.append('C');
- if (flags & HEFtransformDependent) s.append('D');
- if (flags & HEFtranslated) s.append('R');
- if (flags & HEFonFailDependent) s.append('F');
- if (flags & HEFcontextDependentException) s.append('E');
- if (flags & HEFthrowscalar) s.append('T');
- if (flags & HEFthrowds) s.append('M');
- s.append(']');
- #endif
- }
- if (containsImplicitNormalize(expr))
- s.append('.');
- if (containsAssertKeyed(expr))
- s.append('K');
- if (containsAliasLocally(expr))
- s.append('L');
- if (containsCall(expr, false))
- s.append('c');
- if (isNamedSymbol)
- {
- if (expr->isDataset())
- {
- IHqlExpression * group = queryGrouping(expr);
- if (group)
- getExprECL(group, s.append("G(")).append(")");
- IHqlExpression * distrib = queryDistribution(expr);
- if (distrib) getExprECL(distrib, s.append("D(")).append(")");
- appendSortOrder(s, "GO", queryGlobalSortOrder(expr));
- appendSortOrder(s, "LO", queryLocalUngroupedSortOrder(expr));
- appendSortOrder(s, "RO", queryGroupSortOrder(expr));
- }
- }
- s.append("]");
- #endif
- #if defined(SHOW_TABLES) || defined(SHOW_TABLES_EXISTANCE)
- if (expr->isAction() || expr->isDataset() || expr->getOperator() == no_assign)
- {
- if (expr->getOperator() != no_rows)
- {
- HqlExprCopyArray inScope;
- expr->gatherTablesUsed(inScope);
- #ifdef SHOW_TABLES_EXISTANCE
- if (inScope.ordinality())
- s.append("[[!]]");
- #endif
- #ifdef SHOW_TABLES
- if (inScope.ordinality())
- {
- s.append("[[");
- ForEachItemIn(i, inScope)
- {
- if (i) s.append(",");
- toECL(&inScope.item(i), s, false, false, 0, false);
- }
- s.append("]]");
- }
- #endif
- }
- }
- else if (!expr->isIndependentOfScope())
- {
- s.append("[[!]]");
- }
- #endif
- #ifdef SHOW_DSRECORD
- if (expr->isDataset() || expr->isTransform())
- {
- s.append("R[");
- toECL(expr->queryRecord(), s, false, false, 0, false);
- s.append("]R");
- }
- #endif
- #ifdef SHOW_DISTRIBUTION
- if (expr->isDataset())
- {
- IHqlExpression * distribution = queryDistribution(expr);
- if (distribution)
- {
- s.append("dist[");
- toECL(distribution, s, false, false, 0, false);
- s.append("]");
- }
- }
- #endif
- #ifdef SHOW_ORDER
- if (expr->isDataset())
- {
- ITypeInfo * type = expr->queryType();
- appendSortOrder(s, "gorder", queryGlobalSortOrder(type));
- appendSortOrder(s, "lorder", queryLocalUngroupedSortOrder(type));
- appendSortOrder(s, "grorder", queryGroupSortOrder(type));
- }
- #endif
- #ifdef SHOW_GROUPING
- if (expr->isDataset())
- {
- IHqlExpression * grouping = queryGrouping(expr);
- if (grouping)
- {
- s.append("gr[");
- #ifdef SHOW_GROUPING_DETAIL
- toECL(grouping, s, false, false, 0, false);
- #endif
- s.append("]");
- }
- }
- #endif
- }
- // bool isTop = m_isTop;
- if(m_isTop)
- m_isTop = false;
- node_operator no = expr->getOperator();
- int precedence;
- bool lparen, rparen;
- IHqlExpression * child0 = expr->queryChild(0);
- IHqlExpression * child1 = expr->queryChild(1);
- unsigned savedDatasetDepth = curDatasetDepth;
- if(paren)
- s.append('(');
- for (;;)
- {
- annotate_kind kind = expr->getAnnotationKind();
- if ((kind == annotate_none) || (kind == annotate_symbol))
- break;
- #ifdef SHOW_ANNOTATIONS
- if (expandProcessed)
- {
- switch (kind)
- {
- case annotate_meta:
- s.append("#M[");
- for (unsigned i= 0; expr->queryAnnotationParameter(i); i++)
- {
- if (i) s.append(",");
- toECL(expr->queryAnnotationParameter(i), s, false, false);
- }
- s.append("]#");
- break;
- case annotate_warning:
- s.append("#W#");
- break;
- case annotate_javadoc:
- s.append("#J#");
- break;
- case annotate_location:
- s.append("#L#");
- break;
- }
- }
- #endif
- expr = expr->queryBody(true);
- }
- if (isEclAlias(expr))
- {
- StringBuffer name;
- if(/*isTop || */ m_recurse)
- {
- doAlias(expr, name, inType);
- s.append(name.str());
- }
- else
- lookupSymbolName(expr, s);
- if(!inType && expr->queryFunctionDefinition() && !expandProcessed)
- {
- callEclFunction(s, expr, inType);
- }
- }
- else if (!expandNamed && !expr->isAttribute() && expr->queryId() && lower(expr->queryId()) != lower(unnamedId) )
- {
- appendId(s, expr->queryId());
- }
- else
- {
- if (expr->isDataset() || expr->isDictionary())
- {
- if (!isNamedSymbol && (expandProcessed || tryToRegenerate) && no != no_field && no != no_rows && !isTargetSelector(expr))
- {
- if (!expr->queryTransformExtra())
- {
- bool wasInsideNewTransform = insideNewTransform;
- insideNewTransform = false;
-
- StringBuffer temp;
- scope.append(NULL);
- if (expr->isDataset())
- temp.appendf("dataset%012" I64F "x ", (__uint64)(memsize_t)expr);
- else
- temp.appendf("dictionary%012" I64F "x ", (__uint64)(memsize_t)expr);
- #ifdef SHOW_NORMALIZED
- if (expandProcessed)
- temp.appendf("[N%p] ", expr->queryNormalizedSelector());
- #endif
- temp.append(":= ");
- toECL(expr, temp, false, false, 0, true);
- temp.append(";").newline();
- addExport(temp);
- scope.pop();
- insideNewTransform = wasInsideNewTransform;
- expr->setTransformExtra(expr);
- }
- if (expr->isDataset())
- s.appendf("dataset%012" I64F "x", (__uint64)(memsize_t)expr);
- else
- s.appendf("dictionary%012" I64F "x", (__uint64)(memsize_t)expr);
- if (paren)
- s.append(')');
- return;
- }
- switch (no)
- {
- case no_addfiles: // looks silly otherwise...
- case no_select:
- case no_field:
- case no_compound_selectnew:
- break;
- case no_compound_diskread:
- case no_compound_indexread:
- case no_compound_disknormalize:
- case no_compound_diskaggregate:
- case no_compound_diskcount:
- case no_compound_diskgroupaggregate:
- case no_compound_indexnormalize:
- case no_compound_indexaggregate:
- case no_compound_indexcount:
- case no_compound_indexgroupaggregate:
- case no_compound_childread:
- case no_compound_childnormalize:
- case no_compound_childaggregate:
- case no_compound_childcount:
- case no_compound_childgroupaggregate:
- case no_compound_inline:
- curDatasetDepth = -1000;
- break;
- default:
- if (curDatasetDepth >= maxDatasetDepth)
- {
- s.append("...");
- if (paren)
- s.append(')');
- return;
- }
- curDatasetDepth++;
- break;
- }
- }
- else if (expandProcessed && no == no_alias)
- {
- if (!isNamedSymbol)
- {
- if (!expr->queryTransformExtra())
- {
- bool wasInsideNewTransform = insideNewTransform;
- insideNewTransform = false;
- StringBuffer temp;
- scope.append(NULL);
- temp.appendf("alias%012" I64F "x ", (__uint64)(memsize_t)expr);
- temp.append(":= ");
- toECL(expr, temp, false, false, 0, true);
- temp.append(";").newline();
- addExport(temp);
- scope.pop();
- insideNewTransform = wasInsideNewTransform;
- expr->setTransformExtra(expr);
- }
- s.appendf("alias%012" I64F "x", (__uint64)(memsize_t)expr);
- if (paren)
- s.append(')');
- return;
- }
- }
- if (expandProcessed && !isNamedSymbol && no == no_record)
- {
- if (!expr->queryTransformExtra())
- {
- StringBuffer temp;
- scope.append(NULL);
- temp.appendf("record%012" I64F "x := ", (__uint64)(memsize_t)expr);
- toECL(expr, temp, false, false, 0, true);
- temp.append(";").newline();
- addExport(temp);
- scope.pop();
- expr->setTransformExtra(expr);
- }
- s.appendf("record%012" I64F "x", (__uint64)(memsize_t)expr);
- return;
- }
- unsigned startLength = s.length();
- switch(no)
- {
- case no_none:
- s.append("<NONE>");
- break;
- case no_pat_instance:
- if (!isNamedSymbol && expandProcessed)
- {
- //Stops generated code exploding - not strictly correct...
- if (!expr->queryTransformExtra())
- {
- bool wasInsideNewTransform = insideNewTransform;
- insideNewTransform = false;
-
- StringBuffer temp;
- scope.append(NULL);
- temp.appendf("pattern%012" I64F "x := ", (__uint64)(memsize_t)expr);
- toECL(expr, temp, false, false, 0, true);
- temp.append(";").newline();
- addExport(temp);
- scope.pop();
- insideNewTransform = wasInsideNewTransform;
- expr->setTransformExtra(expr);
- }
- s.appendf("pattern%012" I64F "x", (__uint64)(memsize_t)expr);
- return;
- }
- else if (expandProcessed)
- {
- defaultToECL(expr, s, inType);
- }
- else
- toECL(expr->queryChild(0), s, false, inType);
- break;
- case no_cast:
- {
- s.append('(');
- getTypeString(expr->queryType(), s);
- s.append(") ");
- toECL(child0, s, needParen(expr->getPrecedence(), child0), inType);
- break;
- }
- case no_implicitcast:
- if (expandProcessed)
- {
- s.append("((");
- getTypeString(expr->queryType(), s);
- s.append(")) ");
- }
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- break;
- case no_param:
- {
- if (expandProcessed)
- s.append("no_param(");
- if(inType) // Hack !
- {
- getTypeString(expr->queryType(), s);
- s.append(' ');
- }
- lookupSymbolName(expr, s);
- if (expandProcessed)
- s.append(")");
- break;
- }
- case no_substring:
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- if(child1)
- {
- s.append("[");
- toECL(child1, s, false, inType);
- s.append("]");
- }
- break;
- case no_rangefrom:
- toECL(child0, s, false, inType);
- s.append("..");
- break;
- case no_rangecommon:
- toECL(child0, s, false, inType);
- s.append("..*");
- break;
- case no_range:
- toECL(child0, s, false, inType);
- s.append("..");
- toECL(child1, s, false, inType);
- break;
- case no_rangeto:
- s.append("..");
- toECL(child0, s, false, inType);
- break;
- case NO_AGGREGATEGROUP:
- {
- s.append(getEclOpString(no));
- s.append("(group");
- childrenToECL(expr, s, inType, true, 0);
- s.append(')');
- break;
- }
- case no_sortlist:
- {
- sortlistToEcl(expr, s, false, inType);
- break;
- }
- case no_rowvalue:
- {
- s.append("{");
- childrenToECL(expr, s, inType, false, 0);
- s.append("}");
- break;
- }
- case no_record:
- {
- bool fieldsInline = (recordIndex == 0) && (expr->numChildren() <= 3) && !isNamedSymbol;
- if (fieldsInline)
- s.append('{');
- else
- {
- s.append("RECORD");
- indent++;
- }
- bool hadAttr = false;
- //Slightly weird. no_record inside a record imply inheritance, and have a slightly different syntax.
- //Should probably be expanded when the graph is normalized...
- ForEachChild(i2, expr)
- {
- IHqlExpression *child = queryChild(expr, i2);
- if (child && child->getOperator() == no_record)
- {
- s.append("(");
- if (isEclAlias(child) || !m_recurse)
- toECL(child, s, false, inType, i2+1);
- else
- createPseudoSymbol(s, "record__", child);
- s.append(")");
- hadAttr = true;
- }
- }
-
- ForEachChild(i1, expr)
- {
- IHqlExpression *child = queryChild(expr, i1);
- if (child && child->isAttribute())
- {
- s.append(",");
- toECL(child, s, false, inType, 0);
- hadAttr = true;
- }
- }
- if (!fieldsInline)
- s.newline();
- //First output the attributes...
- //MORE: Add attributes to the record definition
- bool first = true;
- bool firstPayload = true;
- ForEachChild(idx, expr)
- {
- IHqlExpression *child = queryChild(expr, idx);
- if (child && !child->isAttribute() && child->getOperator() != no_record)
- {
- if (queryAddDotDotDot(s, startLength))
- break;
- if (fieldsInline)
- {
- if (!first)
- {
- if (firstPayload && child->hasAttribute(_payload_Atom))
- {
- s.append(" =>");
- firstPayload = false;
- }
- else
- s.append(",");
- }
- s.append(" ");
- }
- else
- {
- if (!first)
- {
- if (firstPayload && child->hasAttribute(_payload_Atom))
- {
- s.remove(s.length()-2,2).append("\n").pad(indent).append("=>\n");
- firstPayload = false;
- }
- }
- s.pad(indent);
- }
- toECL(child, s, false, inType, idx+1);
- if (!fieldsInline)
- s.append(";\n");
- first = false;
- }
- }
- if (fieldsInline)
- s.append(" }");
- else
- s.pad(--indent).append("END");
- break;
- }
- case no_ifblock:
- {
- s.append("IFBLOCK");
- indent++;
- toECL(expr->queryChild(0), s, true, inType);
- s.append("\n");
- IHqlExpression * record = expr->queryChild(1);
- ForEachChild(idx2, record)
- {
- s.pad(indent);
- toECL(record->queryChild(idx2), s, false, inType, indent*100*recordIndex+idx2+1);
- s.append(";\n");
- }
- s.pad(--indent).append("END");
- break;
- }
- case no_assignall:
- {
- IHqlExpression * original = expr->queryAttribute(_original_Atom);
- if (original)
- {
- toECL(original->queryChild(0), s, false, inType);
- s.append(" := ");
- IHqlExpression * rhs = original->queryChild(1);
- if (rhs->getOperator() == no_null)
- s.append("[]");
- else
- toECL(rhs, s, false, inType);
- }
- else if (child0)
- {
- s.append("SELF := ");
- IHqlExpression * rhs = child0->queryChild(1);
- if (rhs->getOperator() == no_select)
- {
- IHqlExpression * lhs = child0->queryChild(0);
- while (lhs->getOperator() == no_select)
- {
- lhs = lhs->queryChild(0);
- rhs = rhs->queryChild(0);
- }
- toECL(rhs, s, false, inType);
- }
- else
- s.append("[]");
- }
- if (expandProcessed)
- {
- s.append("/* ");
- unsigned max = expr->numChildren();
- for (unsigned idx = 0; idx < max; idx++)
- {
- if (idx) s.append("; ");
- toECL(expr->queryChild(idx), s, false, inType);
- }
- s.append(" */");
- }
- break;
- }
- case no_index:
- case no_selectnth:
- case no_selectmap:
- case no_pat_index:
- {
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- s.append('[');
- toECL(child1, s, child1->getPrecedence() < 0, inType);
- s.append(']');
- break;
- }
- case no_bor:
- case no_band:
- case no_bxor:
- case no_div:
- case no_mul:
- case no_modulus:
- case no_concat:
- case no_add:
- case no_addsets:
- case no_assign:
- case no_addfiles:
- case no_sub:
- case no_eq:
- case no_ne:
- case no_lt:
- case no_le:
- case no_gt:
- case no_ge:
- case no_and:
- case no_or:
- case no_pat_or:
- case no_xor:
- case no_mapto:
- case no_order:
- case no_notin:
- case no_in:
- case no_indict:
- case no_colon:
- case no_pat_select:
- case no_lshift:
- case no_rshift:
- {
- // Standard binary infix operators
- precedence = expr->getPrecedence();
- lparen = needParen(precedence, child0);
- if (child0)
- toECL(child0, s, lparen, inType);
- else
- s.append("?NULL?");
- const char * opText = getEclOpString(no);
- if ((no == no_div) && expr->queryType()->isInteger())
- opText = "DIV";
- if (no == no_addfiles)
- {
- if (isOrdered(expr))
- opText = "&";
- if (expr->hasAttribute(pullAtom))
- opText = "&&";
- }
- unsigned num = expr->numChildren();
- for (unsigned i=1; i < num; i++)
- {
- IHqlExpression * child = queryChild(expr, i);
- if (child)
- {
- if ((no == no_addfiles) && child->isAttribute())
- {
- if (child->queryName() == orderedAtom)
- continue;
- }
- if (xgmmlGraphText && endsWithDotDotDot(s))
- break;
- s.append(' ').append(opText).append(' ');
- if (queryAddDotDotDot(s, startLength))
- break;
- toECL(child, s, needParen(precedence, child), inType);
- }
- }
- break;
- }
- case no_subsort:
- {
- s.append(getEclOpString(expr->getOperator()));
- s.append('(');
- if (!xgmmlGraphText)
- {
- toECL(child0, s, false, inType);
- queryNewline(s.append(", "));
- }
- pushScope(child0);
- //MORE: Sortlists should always be generated using the {} syntax - then this could be simplified
- //NOTE: child(1) and child(2) are output in a different order from their representation
- s.append("{");
- toECL(expr->queryChild(2), s, false, inType);
- s.append("}");
- queryNewline(s.append(", "));
- s.append("{");
- toECL(expr->queryChild(1), s, false, inType);
- s.append("}");
- childrenToECL(expr, s, inType, true, 3);
- popScope();
- s.append(')');
- break;
- }
- case no_select:
- {
- if (!expandProcessed &&
- (matchesActiveDataset(child0) ||
- (child0->getOperator() == no_self && insideNewTransform) ||
- (minimalSelectors && !isAlwaysActiveRow(child0)) ||
- (minimalSelectors && child0->getOperator() == no_activetable))
- )
- toECL(child1, s, false, inType);
- else
- {
- if (!expandProcessed)
- {
- OwnedHqlExpr aggregate = convertToSimpleAggregate(expr);
- if (aggregate)
- {
- toECL(aggregate, s, false, inType);
- break;
- }
- }
- {
- lparen = needParen(expr, child0);
- if (expandProcessed && !expr->hasAttribute(newAtom) && child0->queryName())
- s.append("<").append(child0->queryName()).append(">");
- if (xgmmlGraphText && expr->hasAttribute(newAtom))
- s.append("<...>");
- else
- toECL(child0, s, lparen, inType);
- }
- s.append(getEclOpString(no)); // <- note: no padding
- rparen = needParen(expr, child1);
- toECL(child1, s, rparen, inType);
- }
- if (expandProcessed)
- {
- unsigned max = expr->numChildren();
- if (max != 2)
- {
- s.append("(<");
- for (unsigned i=2; i < max; i++)
- {
- if (i != 2) s.append(",");
- toECL(expr->queryChild(i), s, false, inType);
- }
- s.append(">)");
- }
- }
- break;
- }
- case no_notnot:
- case no_not:
- case no_negate:
- case no_within:
- // Standard unary operators
- precedence = expr->getPrecedence();
- rparen = child0->getPrecedence() < precedence;
- s.append(getEclOpString(no));
- toECL(child0, s, rparen, inType);
- break;
- case no_between:
- case no_notbetween:
- // Standard ternary operators
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- s.append(getEclOpString(no));
- toECL(child1, s, child0->getPrecedence() < 0, inType);
- s.append(',');
- toECL(expr->queryChild(2), s, expr->queryChild(2)->getPrecedence() < 0, inType);
- break;
- #ifndef SHOW_EXPAND_LEFTRIGHT
- case no_left:
- case no_right:
- case no_top:
- #endif
- case no_self:
- case no_rows:
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- else
- s.append(getEclOpString(no));
- #ifdef SHOWADDR
- if (expandProcessed)
- s.appendf("{@%p:%p}", expr->queryChild(0), expr->queryChild(1));
- #endif
- break;
- case no_getgraphloopresultset:
- if (xgmmlGraphText)
- s.append("ROWSET");
- else
- defaultToECL(expr, s, inType);
- break;
- case no_sql:
- case no_flat:
- case no_all:
- case no_activetable:
- case no_counter:
- s.append(getEclOpString(no));
- break;
- case no_selfref:
- if (expandProcessed)
- s.append("SELFref");
- else
- s.append(getEclOpString(no));
- break;
- case no_thor:
- {
- unsigned kids = expr->numChildren();
- if(kids)
- {
- if (expandProcessed)
- s.append(getEclOpString(no)).append("(");
- bool first=true;
- for (unsigned idx = 0; idx < kids; idx++)
- {
- IHqlExpression *child = expr->queryChild(idx);
- if (expandProcessed || !child->isAttribute())
- {
- if (!first)
- s.append(", ");
- first=false;
- toECL(child, s, false, inType);
- }
- }
- if (expandProcessed)
- s.append(")");
- }
- else
- {
- s.append(getEclOpString(no));
- }
- break;
- }
- case no_attr:
- case no_attr_expr:
- case no_attr_link:
- {
- if (isInternalAttribute(expr) && !expandProcessed)
- break;
- IAtom * name = expr->queryName();
- s.append(expr->queryName());
- if (name == _workflowPersist_Atom || name == _original_Atom)
- {
- s.append("(...)");
- break;
- }
- if (child0)
- {
- s.append('(');
- childrenToECL(expr, s, false, false, 0);
- s.append(')');
- }
- else if (expr->querySequenceExtra())
- {
- //Not sure any of these should be included
- s.append("(").append(expr->querySequenceExtra()).append(")");
- }
- break;
- }
- case no_constant:
- {
- expr->queryValue()->generateECL(s);
- if (xgmmlGraphText && (s.length() - startLength) > MAX_GRAPHTEXT_LEN)
- {
- bool addQuote = s.charAt(s.length()-1) == '\'';
- s.setLength(startLength+MAX_GRAPHTEXT_LEN);
- s.append("...");
- if (addQuote)
- s.append("'");
- }
- break;
- }
- case no_list:
- case no_datasetlist:
- case no_recordlist:
- case no_transformlist:
- {
- s.append('[');
- for (unsigned idx = 0; idx < expr->numChildren(); idx++)
- {
- IHqlExpression *child = expr->queryChild(idx);
- if (idx)
- s.append(", ");
- queryNewline(s);
- toECL(child, s, child->getPrecedence() < 0, inType);
- }
- s.append(']');
- break;
- }
- case no_call:
- if (expandProcessed)
- {
- s.append("CALL(");
- toECL(expr->queryBody()->queryFunctionDefinition(), s, false, inType);
- defaultChildrenToECL(expr, s, inType);
- s.append(")");
- break;
- }
- //fall through
- case no_externalcall:
- {
- // OK we got us an external call. Let's try and define it.
- StringBuffer name;
- if (m_recurse)
- defineCallTarget(expr, name);
- else if (xgmmlGraphText)
- lookupSymbolName(expr, name);
- else
- {
- lookupSymbolName(expr, name);
- name.append('.');
- lookupSymbolName(expr, name);
- }
- IHqlExpression *funcdef = (no==no_externalcall) ? expr->queryBody()->queryExternalDefinition() : expr->queryBody()->queryFunctionDefinition();
- IHqlExpression *formals = funcdef ? funcdef->queryChild(1) : nullptr;
- s.append(name);
- s.append('(');
- unsigned idx = 0;
- bool first = true;
- while(IHqlExpression *kid = expr->queryChild(idx))
- {
- bool isHidden = !expandProcessed && kid->isAttribute();
- if (formals && !expandProcessed)
- {
- IHqlExpression *formal = formals->queryChild(idx);
- isHidden = formal && formal->hasAttribute(_hidden_Atom);
- }
- if (!isHidden)
- {
- if (first)
- first = false;
- else
- s.append(", ");
- toECL(kid, s, kid->getPrecedence() < 0, inType);
- }
- idx++;
- }
- s.append(')');
- break;
- }
- case no_external:
- {
- unsigned kids = expr->numChildren();
- bool first = true;
- for (unsigned idx = 0; idx < kids; idx++)
- {
- IHqlExpression *kid = expr->queryChild(idx);
- if (kid->queryName() != pluginAtom)
- {
- if(first)
- first = false;
- else
- s.append(", ");
- s.append(kid->queryName());
- if (kid->isAttribute())
- {
- IHqlExpression * value = kid->queryChild(0);
- if (value)
- {
- IValue * val = value->queryValue();
- if (val)
- {
- s.append("='");
- val->getStringValue(s);
- s.append('\'');
- }
- else
- {
- s.append("=");
- toECL(value, s, false, inType);
- }
- }
- }
- }
- }
- break;
- }
- case no_pat_const:
- case no_pat_imptoken:
- toECL(expr->queryChild(0), s, false, inType);
- break;
- case no_pat_pattern:
- s.append("PATTERN(");
- toECL(expr->queryChild(0), s, false, inType);
- s.append(")");
- break;
- case no_pat_checkin:
- toECL(expr->queryChild(0), s, false, inType);
- s.append(" IN ");
- toECL(expr->queryChild(1), s, false, inType);
- break;
- case no_pat_repeat:
- {
- unsigned low = getRepeatMin(expr);
- unsigned high = getRepeatMax(expr);
- if (isStandardRepeat(expr))
- {
- toECL(expr->queryChild(0), s, false, inType);
- if ((low == 0) && (high == 1))
- s.append("?");
- else if ((low == 0) && (high == (unsigned)-1))
- s.append("*");
- else if ((low == 1) && (high == (unsigned)-1))
- s.append("+");
- }
- else
- {
- s.append("REPEAT(");
- toECL(expr->queryChild(0), s, false, inType);
- s.append(",").append(low);
- if (low != high)
- {
- s.append(",");
- if (high == (unsigned)-1)
- s.append("ANY");
- else
- s.append(high);
- }
- if (expr->hasAttribute(minimalAtom))
- s.append(",MINIMAL");
- s.append(")");
- }
- break;
- }
- case no_pat_follow:
- {
- precedence = expr->getPrecedence();
- ForEachChild(idx, expr)
- {
- if (idx) s.append(" ");
- IHqlExpression * child = expr->queryChild(idx);
- toECL(child, s, needParen(precedence, child), inType);
- }
- break;
- }
- case no_field:
- {
- IHqlExpression * kid = expr->queryChild(0);
- if (kid && kid->isAttribute())
- kid = NULL;
- if (recordIndex || inType)
- {
- if (expr->queryName())
- {
- bool addTypeAndName = true;
- if (kid)
- {
- IHqlExpression * field = NULL;
- if (kid->getOperator() == no_field)
- field = kid;
- else if (kid->getOperator() == no_select)
- field = kid->queryChild(1);
- if (field)
- if ((expr->queryType() == field->queryType()) && (expr->queryName() == field->queryName()))
- addTypeAndName = false;
- }
- if (addTypeAndName)
- {
- getFieldTypeString(expr, s);
- s.append(' ');
- lookupSymbolName(expr, s);
- //Add the attributes....
- bool seenAttr = false;
- ForEachChild(kids, expr)
- {
- IHqlExpression *attr = expr->queryChild(kids);
- if (attr->isAttribute())
- {
- IAtom * name = attr->queryName();
- if (name != countAtom && name != sizeofAtom &&
- !(isInternalAttribute(attr) && !expandProcessed))
- {
- if ((name != virtualAtom) || !ignoreVirtualAttrs)
- {
- if (!seenAttr)
- {
- s.append('{');
- seenAttr = true;
- }
- else
- s.append(", ");
- toECL(attr, s, false, inType);
- }
- }
- }
- }
- if (seenAttr)
- s.append('}');
- if (kid)
- {
- s.append(" := ");
- toECL(kid, s, false, inType);
- }
- }
- else
- toECL(kid, s, false, inType);
- }
- else if (kid)
- {
- assertex(expr->queryType() == kid->queryType());
- toECL(kid, s, false, inType);
- }
- else
- {
- getTypeString(expr->queryType(), s);
- s.append(" _unnamed_").append(recordIndex-1);
- }
- }
- else
- {
- if (expr->queryName())
- lookupSymbolName(expr, s);
- else if (kid)
- toECL(kid, s, false, inType);
- else
- s.append("????");
- break;
- }
- break;
- }
- case no_filter:
- {
- StringBuffer tmp;
- unsigned kids = expr->numChildren();
- if (xgmmlGraphText)
- s.append("FILTER");
- else
- toECL(child0, s, child0->getPrecedence() < 0, inType);
-
- pushScope(child0);
- for (unsigned idx = 1; idx < kids; idx++)
- {
- if (idx > 1)
- queryNewline(tmp.append(", "));
- IHqlExpression *child = expr->queryChild(idx);
- toECL(child, tmp, false, inType);
- }
- popScope();
-
- if(tmp.length())
- queryNewline(s.append('(').append(tmp).append(')'));
- break;
- }
- case no_httpcall:
- case no_soapcall:
- case no_soapcall_ds:
- case no_newsoapcall_ds:
- {
- IHqlExpression * resultFormat = queryNewColumnProvider(expr);
- s.append(getEclOpString(no));
- s.append('(');
- bool needComma = false;
- StringBuffer tmp;
- unsigned kids = expr->numChildren();
- if (!xgmmlGraphText)
- {
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- needComma = true;
- }
-
- pushScope(child0);
- for (unsigned idx = 1; idx < kids; idx++)
- {
- if (needComma)
- s.append(", ");
- IHqlExpression *child = expr->queryChild(idx);
- if (expr->isDataset() && (child == resultFormat))
- {
- s.append("DATASET(");
- toECL(child, s, false, inType);
- s.append(")");
- }
- else
- toECL(child, s, false, inType);
- needComma = true;
- }
- popScope();
- s.append(")");
- break;
- }
- case no_inlinetable:
- {
- s.append("DATASET([");
- ForEachChild(i, child0)
- {
- IHqlExpression * cur = child0->queryChild(i);
- if (i)
- s.append(",");
- s.append("{");
- bool first = true;
- expandTransformValues(s, cur, first);
- s.append("}");
- queryNewline(s);
- if (xgmmlGraphText)
- {
- if (child0->numChildren() != 1)
- s.append(",...");
- break;
- }
- }
- s.append("]");
- childrenToECL(expr, s, inType, true, 1);
- s.append(')');
- break;
- }
- case no_temptable:
- {
- s.append("DATASET(");
- ITypeInfo * child0Type = child0->queryType();
- if (child0Type && child0Type->getTypeCode() == type_set)
- {
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- }
- else
- {
- HqlExprArray records;
- child0->unwindList(records, no_recordlist);
- s.append('[');
- for (unsigned idx = 0; idx < records.length(); idx++)
- {
- IHqlExpression * kid = &records.item(idx);
- if(kid && !kid->isAttribute())
- {
- if (kid->getOperator() == no_record)
- {
- s.append('{');
- bool first = true;
- for (unsigned i = 0; i < kid->numChildren(); i++)
- {
- if (kid->queryChild(i)->isAttribute())
- continue;
- if (!first)
- s.append(", ");
- toECL(kid->queryChild(i)->queryChild(0), s, false, inType);
- first = false;
- }
- s.append('}');
- }
- else
- toECL(kid, s, false, inType);
- }
- if (xgmmlGraphText)
- {
- if (records.length() != 1)
- s.append(",...");
- break;
- }
- if (idx < records.length()-1)
- s.append(',');
- }
- s.append(']');
- }
- if (child1)
- {
- toECL(child1, s.append(", "), child1->getPrecedence() < 0, inType);
- }
- if (expandProcessed)
- childrenToECL(expr, s, inType, true, 2);
- s.append(')');
- break;
- }
- case no_temprow:
- {
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- else
- {
- s.append("ROW(");
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- toECL(child1, s.append(", "), child1->getPrecedence() < 0, inType);
- s.append(")");
- }
- break;
- }
- case no_workunit_dataset:
- {
- s.append("DATASET(WORKUNIT(");
- toECL(child1, s, false, inType);
- if (!isInternalAttribute(expr->queryChild(2)) || expandProcessed)
- {
- s.append(", ");
- toECL(expr->queryChild(2), s, false, inType);
- }
- if (expandProcessed)
- childrenToECL(expr, s, false, true, 3);
- s.append("), ");
- toECL(child0, s, false, inType);
- s.append(")");
- break;
- }
- case no_funcdef:
- {
- if (expandProcessed)
- {
- s.append("funcdef");
- defaultChildrenToECL(expr->queryChild(1), s, inType);
- s.append(" := {");
- defaultToECL(expr->queryChild(0), s, inType);
- s.append("}");
- }
- else
- {
- unsigned kids = expr->numChildren();
- for (unsigned idx = 0; idx < kids; idx++)
- {
- if (idx)
- {
- s.append(", ");
- }
- IHqlExpression *child = expr->queryChild(idx);
- toECL(child, s, child->getPrecedence() < 0, inType);
- }
- }
- break;
- }
- case no_buildindex:
- case no_output:
- {
- s.append(getEclOpString(expr->getOperator())).append('(');
- if (child1 && child1->queryName() == sequenceAtom && !expandProcessed)
- child1 = NULL;
- if (xgmmlGraphText)
- {
- if (child1)
- s.append("..., ");
- else
- s.append("...");
- }
- else
- {
- toECL(child0, s, false, inType);
- if (child0->getOperator() == no_selectfields)
- {
- pushScope(child0->queryChild(0));
- IHqlExpression * c1 = child0->queryChild(1);
- if(c1->numChildren())
- {
- s.append(", ");
- if (hasNamedSymbol(c1))
- toECL(c1, s, c1->getPrecedence() < 0, inType);
- else
- {
- s.append('{');
- for (unsigned idx = 0; idx < c1->numChildren(); idx++)
- {
- if (idx)
- s.append(", ");
- IHqlExpression *child = c1->queryChild(idx);
- toECL(child, s, child->getPrecedence() < 0, inType, idx+1);
- }
- s.append('}');
- }
- }
- else if(child1 && !isInternalAttribute(child1))
- {
- s.append(", ");
- }
- popScope();
- }
- else if(child1 && !isInternalAttribute(child1))
- {
- s.append(", ");
- }
- }
- StringBuffer next;
- unsigned kids = expr->numChildren();
- for (unsigned idx=1; idx < kids; idx++)
- {
- IHqlExpression * cur = queryChild(expr, idx);
- if (cur)
- {
- toECL(cur, next.clear(), cur->getPrecedence() < 0, inType);
- if (next.length())
- s.append(", ").append(next);
- }
- }
- s.append(')');
- break;
- }
- case no_null:
- if (expr->isDataset())
- {
- s.append("_EMPTY_(");
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- s.append(')');
- }
- else
- {
- //MORE!
- }
- break;
- case no_typetransfer:
- {
- if (expr->isDatarow())
- {
- s.append(getEclOpString(no));
- s.append('(');
- toECL(child1, s, child0->getPrecedence() < 0, inType);
- s.append(", ");
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- s.append(')');
- }
- else
- {
- s.append(getEclOpString(no));
- s.append('(');
- toECL(child0, s, child0->getPrecedence() < 0, inType);
- s.append(", ");
- getTypeString(expr->queryType(), s);
- s.append(')');
- }
- break;
- }
- case no_embedbody:
- {
- s.append("BEGINC++\n");
- IValue * value = child0->queryValue();
- if (value)
- value->getUTF8Value(s);
- s.append("ENDC++\n");
- break;
- }
- case no_nofold:
- case no_nohoist:
- case no_nocombine:
- case no_selectfields:
- case no_pure:
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- else
- toECL(child0, s, false, inType);
- break;
- case no_clustersize:
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- else
- s.append(getEclOpString(no));
- break;
- case no_map:
- {
- unsigned kids = expr->numChildren();
- s.append(getEclOpString(no));
- s.append('(');
- for (unsigned idx = 0; idx < kids; idx++)
- {
- if (idx)
- {
- s.append(",");
- if (!xgmmlGraphText)
- s.append("\n\t ");
- }
- IHqlExpression *child = expr->queryChild(idx);
- if (xgmmlGraphText && expr->isDataset() && idx != kids-1)
- child = child->queryChild(0);
- toECL(child, s, child->getPrecedence() < 0, inType);
- }
- s.append(')');
- break;
- }
- case no_newtransform:
- {
- if (expandProcessed)
- {
- defaultToECL(expr, s, inType);
- break;
- }
- // assertex(expandProcessed || !insideNewTransform);
- bool wasInsideNewTransform = insideNewTransform;
- insideNewTransform = true;
- s.append("{ ");
- unsigned kids = expr->numChildren();
- for (unsigned idx = 0; idx < kids; idx++)
- {
- if (idx) s.append(", ");
- IHqlExpression *child = expr->queryChild(idx);
- if (!child->isAttribute())
- getTypeString(child->queryChild(0)->queryType(), s);
- toECL(child, s.append(' '), child->getPrecedence() < 0, inType);
- }
- s.append(" }");
- insideNewTransform = wasInsideNewTransform;
- break;
- }
- case no_transform:
- {
- if (isNamedSymbol)
- {
- s.append(getEclOpString(no)).newline();
- unsigned kids = expr->numChildren();
- for (unsigned idx = 0; idx < kids; idx++)
- {
- IHqlExpression *child = expr->queryChild(idx);
- toECL(child, s.append('\t'), child->getPrecedence() < 0, inType);
- s.append(';').newline();
- }
- s.append("\tEND");
- }
- else
- {
- s.append("TRANSFORM(");
- getTypeString(expr->queryType(), s);
- s.append(",");
- if (tryToRegenerate)
- s.newline();
- unsigned kids = expr->numChildren();
- for (unsigned idx = 0; idx < kids; idx++)
- {
- if (queryAddDotDotDot(s, startLength))
- break;
- IHqlExpression *child = expr->queryChild(idx);
- if (tryToRegenerate)
- s.append("\t");
- toECL(child, s, child->getPrecedence() < 0, inType);
- s.append(';');
- if (tryToRegenerate)
- s.newline();
- }
- s.append(")");
- }
- break;
- }
- case no_newaggregate:
- case no_newusertable:
- {
- s.append(getEclOpString(no));
- s.append('(');
- assertex(child0);
- bool addComma = !xgmmlGraphText;
- if (!xgmmlGraphText)
- toECL(child0, s, false, inType);
- pushScope(child0);
- unsigned start = 2;
- if (expandProcessed)
- start = 1;
- else if (isEclAlias(child1))
- {
- if (addComma)
- s.append(", ");
- toECL(child1, s, false, inType);
- addComma = true;
- start = 3;
- }
- childrenToECL(expr, s, inType, addComma, start);
- popScope();
- s.append(')');
- break;
- }
- case no_newkeyindex:
- {
- s.append(getEclOpString(no));
- s.append('(');
- bool addComma = false;
- if (!xgmmlGraphText)
- {
- toECL(child0, s, false, inType);
- addComma = true;
- }
- pushScope(child0);
- unsigned kids = expr->numChildren();
- unsigned payloadFields = numPayloadFields(expr);
- for (unsigned idx = 1; idx < kids; idx++)
- {
- IHqlExpression * child = queryChild(expr, idx);
- if (child && ((idx != 2) || expandProcessed))
- {
- if (addComma) s.append(", ");
- addComma = true;
- //Normally this is called when file position special field has been removed.
- if ((idx == 1) && (payloadFields != 0) && !expandProcessed)
- {
- OwnedHqlExpr keyedRecord;
- OwnedHqlExpr payloadRecord;
- splitPayload(keyedRecord, payloadRecord, child, payloadFields);
- toECL(keyedRecord, s, false, inType);
- toECL(payloadRecord, s.append(", "), false, inType);
- }
- else
- toECL(child, s, false, inType);
- }
- }
- popScope();
- s.append(')');
- break;
- }
- case no_keyindex:
- {
- unsigned payloadFields = numPayloadFields(expr);
- s.append(getEclOpString(no));
- s.append('(');
- bool addComma = false;
- if (!xgmmlGraphText)
- {
- toECL(child0, s, false, inType);
- addComma = true;
- }
- pushScope(child0);
- unsigned kids = expr->numChildren();
- for (unsigned idx = 1; idx < kids; idx++)
- {
- IHqlExpression * child = queryChild(expr, idx);
- if (child)
- {
- if (addComma) s.append(", ");
- addComma = true;
- if ((idx == 1) && (payloadFields != 1) && !expandProcessed)
- {
- OwnedHqlExpr keyedRecord;
- OwnedHqlExpr payloadRecord;
- splitPayload(keyedRecord, payloadRecord, child, payloadFields);
- toECL(keyedRecord, s, false, inType);
- toECL(payloadRecord, s.append(", "), false, inType);
- }
- else
- toECL(child, s, false, inType);
- }
- }
- popScope();
- s.append(')');
- break;
- }
- case no_preservemeta:
- if (xgmmlGraphText)
- {
- curDatasetDepth--;
- toECL(child0, s, false, inType);
- curDatasetDepth++;
- }
- else if (tryToRegenerate)
- defaultToECL(child0, s, inType);
- else
- defaultToECL(expr, s, inType);
- break;
- case no_callsideeffect:
- if (xgmmlGraphText)
- s.append("...");
- else
- defaultToECL(expr, s, inType);
- break;
- case no_hqlproject:
- case no_iterate:
- {
- s.append(getEclOpString(no));
- s.append('(');
- // Left
- if (!xgmmlGraphText)
- toECL(child0, s, false, inType);
- pushScope(NULL);
- // Transform
- if(child1)
- {
- // I need to feed Left to the transform function definition.
- mapDatasetRecord(child0);
- if (!xgmmlGraphText)
- s.append(", ");
- toECL(child1, s, false, inType);
- popMapping();
- }
- childrenToECL(expr, s, inType, true, 2);
- popScope();
- s.append(')');
- break;
- }
- case no_fetch:
- case no_join:
- case no_selfjoin:
- {
- unsigned kids = expr->numChildren();
- s.append(getEclOpString(no));
- s.append('(');
- if (!xgmmlGraphText)
- {
- toECL(child0, s, false, inType);
-
- // Right
- s.append(", ");
- toECL(queryJoinRhs(expr), s, false, inType);
- }
- pushScope(NULL);
- // Condition
- if(kids > 2)
- {
- if (!xgmmlGraphText)
- s.append(", ");
- toECL(expr->queryChild(2), s, false, inType);
- }
- // Transform
- if(kids > 3)
- {
- // I need to feed Left and Right to the transform function definition.
- mapDatasetRecord(child0);
- mapDatasetRecord(queryJoinRhs(expr));
- toECL(expr->queryChild(3), s.append(", "), false, inType);
- popMapping();
- popMapping();
- }
- // Join type
- if(kids > 4)
- {
- for (unsigned i=4; i < kids; i++)
- {
- IHqlExpression * next = queryChild(expr, i);
- if (next)
- toECL(next, s.append(", "), false, inType);
- }
- }
- s.append(')');
- popScope();
- break;
- }
- case no_sizeof:
- {
- IHqlExpression* child = expr->queryChild(0);
- s.append("sizeof(");
- if (child->getOperator()==no_null)
- child->queryType()->getECLType(s);
- else
- toECL(child,s,false,inType);
- if (child1)
- toECL(child1, s.append(", "), false, inType);
- s.append(")");
- break;
- }
- case no_evaluate:
- {
- s.append(getEclOpString(no));
- s.append('(');
- toECL(child0, s, false, inType);
- s.append(", ");
- pushScope(child0);
- toECL(child1, s, false, inType);
- popScope();
- s.append(')');
- break;
- }
- case no_setmeta:
- {
- IAtom * kind = expr->queryChild(0)->queryName();
- if (kind == debugAtom)
- s.append("#OPTION");
- else if (kind == constAtom)
- s.append("#CONSTANT");
- else if (kind == storedAtom)
- s.append("#STORED");
- else if (kind == workunitAtom)
- s.append("#WORKUNIT");
- else if (kind == webserviceAtom)
- s.append("#WEBSERVICE");
- else
- s.append("#META:").append(kind);
- s.append(" (");
- unsigned kids = expr->numChildren();
- for (unsigned idx = 1; idx < kids; idx++)
- {
- if (idx != 1)
- s.append(", ");
- toECL(expr->queryChild(idx), s, false, inType);
- }
- s.append(")");
- break;
- }
- case NO_AGGREGATE:
- {
- // standard function-style operators
- unsigned kids = expr->numChildren();
- s.append(getEclOpString(no));
- if (child0)
- {
- s.append('(');
- toECL(child0, s, false, inType);
- pushScope(child0);
- for (unsigned idx = 1; idx < kids; idx++)
- {
- IHqlExpression * cur = expr->queryChild(idx);
- if (expandProcessed || !cur->isAttribute())
- {
- if (idx != 0)
- s.append(", ");
- toECL(cur, s, false, inType);
- }
- }
- popScope();
- s.append(')');
- }
- break;
- }
- case no_pat_featureactual:
- {
- toECL(child0, s, false, inType);
- s.append("{");
- toECL(child1, s, false, inType);
- s.append("}");
- break;
- }
- case no_comma:
- toECL(child0, s, false, inType);
- s.append(",");
- toECL(child1, s, false, inType);
- break;
- case no_compound:
- if (!expandProcessed)
- {
- toECL(child0, s, false, inType);
- s.append(",");
- if (!xgmmlGraphText)
- s.newline();
- toECL(child1, s, false, inType);
- }
- else
- defaultToECL(expr, s, inType);
- break;
- case no_choosen:
- {
- // standard function-style operators
- unsigned kids = expr->numChildren();
- s.append(getEclOpString(no));
- s.append('(');
- unsigned noCommaArg = 1;
- if (!xgmmlGraphText || !child0->queryDataset())
- {
- toECL(child0, s, false, inType);
- noCommaArg = 0;
- }
- pushScope(child0);
- for (unsigned idx = 1; idx < kids; idx++)
- {
- if (idx != noCommaArg)
- s.append(", ");
- IHqlExpression * cur = expr->queryChild(idx);
- if ((idx == 1) && isChooseNAllLimit(cur))
- s.append("ALL");
- else
- toECL(cur, s, false, inType);
- }
- popScope();
- s.append(')');
- break;
- }
- case no_matchattr:
- {
- unsigned index;
- if (expr->isDatarow())
- index = (unsigned)getIntValue(child1);
- else
- index = (unsigned)getIntValue(child0);
- s.append('$').append(index+1);
- break;
- }
- case no_setresult:
- #if 0
- if (xgmmlGraphText && scope.ordinality() == 0 && child0->getOperator() == no_select)
- {
- pushScope(child0->queryChild(0));
- defaultToECL(expr, s, inType);
- popScope();
- }
- else
- #endif
- defaultToECL(expr, s, inType);
- break;
- case no_getresult:
- {
- IHqlExpression * name = queryAttributeChild(expr, namedAtom, 0);
- switch (getIntValue(queryAttributeChild(expr, sequenceAtom, 0)))
- {
- case ResultSequencePersist:
- s.append("PERSIST(");
- break;
- case ResultSequenceStored:
- s.append("STORED(");
- break;
- case ResultSequenceInternal:
- s.append("INTERNAL(");
- break;
- default:
- s.append("RESULT(");
- if (!name)
- s.append(getIntValue(queryAttributeChild(expr, sequenceAtom, 0)+1));
- break;
- }
- if (name)
- name->toString(s);
- s.append(")");
- break;
- }
- case no_metaactivity:
- if (expr->hasAttribute(pullAtom))
- s.append("PULL");
- else if (expr->hasAttribute(traceAtom))
- s.append("TRACE");
- else
- s.append("no_metaactivity:unknown");
- defaultChildrenToECL(expr, s, inType);
- break;
- case no_getgraphresult:
- case no_setgraphresult:
- if (expandProcessed || tryToRegenerate)
- defaultToECL(expr, s, inType);
- else
- {
- s.append(getOpString(no));
- toECL(expr->queryChild(2), s, true, inType);
- }
- break;
- case no_alias:
- case no_activerow:
- case no_outofline:
- case no_inline:
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- else
- toECL(child0, s, false, inType);
- break;
- case no_loopcounter:
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- else
- s.append(getOpString(no));
- break;
- case no_omitted:
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- break;
- case no_compound_selectnew:
- if (expandProcessed)
- defaultToECL(expr, s, inType);
- else if (child0->getOperator() == no_select)
- toECL(child0->queryChild(1), s, false, inType);
- else
- toECL(child0, s, false, inType);
- break;
- case no_random:
- defaultToECL(expr, s, inType);
- //s.append("()"); not needed since it always has a hidden parameter which causes () to be generated.
- break;
- case no_subgraph:
- {
- if (tryToRegenerate)
- {
- childrenToECL(expr, s, false, false, 0);
- }
- else
- {
- s.append(getEclOpString(expr->getOperator())).append("(");
- ForEachChild(i, expr)
- {
- s.newline().append("\t");
- toECL(expr->queryChild(i), s, false, inType);
- }
- s.append(")");
- break;
- }
- }
- case no_sequence:
- if (expr->queryName())
- s.append(expr->queryName());
- else
- s.append("SEQ");
- s.append("(").append(expr->querySequenceExtra()).append(")");
- break;
- case no_virtualscope:
- case no_concretescope:
- case no_forwardscope:
- {
- IHqlScope * scope = expr->queryScope();
- #ifdef SHOW_MODULE_STATUS
- if (expandProcessed)
- {
- IHqlScope * concrete = scope->queryConcreteScope();
- if (scope == concrete)
- s.append("[concrete]");
- else if (!concrete)
- s.append("[abstract]");
- else
- s.append("[virtual with concrete]");
- }
- #endif
- defaultToECL(expr, s, inType);
- s.newline();
- HqlExprArray syms;
- scope->getSymbols(syms);
- syms.sort(compareSymbolsByName);
- ForEachItemIn(i, syms)
- {
- toECL(&syms.item(i), s.append("\t"), false, false);
- s.append(";").newline();
- }
- s.append("END;").newline();
- break;
- }
- case no_type:
- {
- IHqlScope * scope = expr->queryScope();
- s.append("TYPE").newline();
- HqlExprArray syms;
- scope->getSymbols(syms);
- syms.sort(compareSymbolsByName);
- ForEachItemIn(i, syms)
- {
- toECL(&syms.item(i), s, false, true);
- }
- s.append("END");
- break;
- }
- case no_libraryscopeinstance:
- if (xgmmlGraphText)
- {
- IHqlExpression * module = expr->queryDefinition()->queryChild(0);
- s.append("LIBRARY(");
- toECL(module->queryAttribute(nameAtom)->queryChild(0), s, false, inType);
- s.append(')');
- }
- else
- {
- s.append(getEclOpString(no));
- s.append('(');
- childrenToECL(expr, s, inType, false, 0);
- s.append(')');
- }
- break;
- case no_typedef:
- {
- getTypeString(expr->queryType(), s);
- if (expr->numChildren())
- {
- s.append("{");
- childrenToECL(expr, s, inType, false, 0);
- s.append("}");
- }
- break;
- }
- case no_split:
- case no_compound_diskread:
- if (xgmmlGraphText && isEclAlias(child0))
- {
- curDatasetDepth--;
- toECL(child0, s, false, inType);
- curDatasetDepth++;
- }
- else if (tryToRegenerate)
- toECL(child0, s, false, inType);
- else
- defaultToECL(expr, s, inType);
- break;
- case no_assert_ds:
- if (xgmmlGraphText)
- {
- pushScope(child0);
- childrenToECL(expr, s, inType, false, 1);
- popScope();
- }
- else
- defaultToECL(expr, s, inType);
- break;
- case no_compound_indexread:
- case no_compound_disknormalize:
- case no_compound_diskaggregate:
- case no_compound_diskcount:
- case no_compound_diskgroupaggregate:
- case no_compound_indexnormalize:
- case no_compound_indexaggregate:
- case no_compound_indexcount:
- case no_compound_indexgroupaggregate:
- case no_compound_childread:
- case no_compound_childnormalize:
- case no_compound_childaggregate:
- case no_compound_childcount:
- case no_compound_childgroupaggregate:
- case no_compound_inline:
- if (tryToRegenerate)
- toECL(child0, s, false, inType);
- else
- defaultToECL(expr, s, inType);
- break;
- //case no_table:
- //case no_count:
- //case no_if:
- case no_simplified:
- s.append(getEclOpString(no));
- s.append('(');
- getTypeString(expr->queryType(), s);
- s.append(')');
- break;
- default:
- defaultToECL(expr, s, inType);
- break;
- }
- }
- if (paren)
- s.append(')');
- curDatasetDepth = savedDatasetDepth;
- }
- void HqltHql::defaultToECL(IHqlExpression *expr, StringBuffer &s, bool inType)
- {
- // standard function-style operators
- s.append(getEclOpString(expr->getOperator()));
- defaultChildrenToECL(expr, s, inType);
- }
- void HqltHql::defaultChildrenToECL(IHqlExpression *expr, StringBuffer &s, bool inType)
- {
- // standard function-style operators
- IHqlExpression * child0 = expr->queryChild(0);
- if (child0)
- {
- s.append('(');
- bool needComma = false;
- if (!xgmmlGraphText || (!child0->queryDataset() && !isInternalAttribute(child0)))
- {
- toECL(child0, s, false, inType);
- needComma = true;
- }
- if (child0->queryDataset())
- pushScope(child0);
- childrenToECL(expr, s, inType, needComma, 1);
- if (child0->queryDataset())
- popScope();
- s.append(')');
- }
- }
- void HqltHql::sortlistToEcl(IHqlExpression *expr, StringBuffer &s, bool addCurleys, bool inType)
- {
- unsigned startLength = s.length();
- if (addCurleys)
- s.append("{ ");
- bool needComma = false;
- ForEachChild(idx, expr)
- {
- IHqlExpression * child = queryChild(expr, idx);
- if (child && (expandProcessed || !isInternalAttribute(expr)))
- {
- if (needComma) queryNewline(s.append(", "));
- if (queryAddDotDotDot(s, startLength))
- break;
- needComma = true;
- toECL(child, s, false, inType);
- }
- }
- if (addCurleys)
- s.append(" }");
- }
- StringBuffer &HqltHql::getFieldTypeString(IHqlExpression * e, StringBuffer &s)
- {
- ITypeInfo * type = e->queryType();
- ITypeInfo * cur = type;
- for(;;)
- {
- typemod_t mod = cur->queryModifier();
- if (mod == typemod_none)
- break;
- if (mod == typemod_attr)
- {
- IHqlExpression * attr = (IHqlExpression *)cur->queryModifierExtra();
- if (!isInternalAttribute(attr))
- s.append(attr->queryName()).append(" ");
- }
- cur = cur->queryTypeBase();
- }
- switch (type->getTypeCode())
- {
- case type_groupedtable:
- s.append("GROUPED ");
- type = type->queryChildType();
- //fall through
- case type_table:
- case type_dictionary:
- {
- s.append(type->getTypeCode()==type_dictionary ? "DICTIONARY(" : "DATASET(");
- getTypeString(type->queryChildType()->queryChildType(), s);
- ForEachChild(i, e)
- {
- IHqlExpression * cur = e->queryChild(i);
- if (cur->isAttribute())
- {
- IAtom * name = cur->queryName();
- if (name == countAtom || name == sizeofAtom)
- {
- toECL(cur, s.append(", "), false, false);
- }
- }
- }
- return s.append(")");
- }
- case type_row:
- return getTypeString(type->queryChildType(), s);
- default:
- return getTypeString(type, s);
- }
- }
- StringBuffer &HqltHql::getTypeString(ITypeInfo * i, StringBuffer &s)
- {
- type_t t = i->getTypeCode();
- switch (t)
- {
- case type_transform:
- i = i->queryChildType();
- //fallthrough
- case type_record:
- case type_row:
- {
- ITypeInfo * original = queryModifier(i, typemod_original);
- IHqlExpression * expr;
- StringBuffer name;
- if (original)
- {
- expr = (IHqlExpression *)original->queryModifierExtra();
- toECL(expr, name, false, false);
- }
- else
- {
- i->getECLType(name);
- expr = queryMapped(queryExpression(queryRecordType(i)));
- }
- StringBuffer tmp;
- if(expr->queryName()==lower(unnamedId))
- {
- HqlExprArray * visited = findVisitedArray();
- for (unsigned idx = 0; idx < visited->ordinality(); idx++)
- {
- IHqlExpression * e = &(visited->item(idx));
- IHqlExpression * extra = static_cast<IHqlExpression *>(e->queryTransformExtra());
- if(e->queryChild(1) && extra)
- {
- if(expr->queryType() == e->queryChild(1)->queryType())
- {
- appendId(tmp, e->queryId());
- break;
- }
- }
- }
- if (!tmp.length())
- {
- //unusual - an inline record definition e.g. { string x } myTransform(...) := transform
- toECL(expr, tmp, false, false);
- }
- }
- else if (isPublicSymbol(expr))
- {
- doAlias(expr, name, false);
- }
- else if (!expr->queryTransformExtra())
- {
- if (isSymbolDefined(expr))
- {
- clashCounter++;
- name.append("___").append(clashCounter);
- }
- OwnedHqlExpr extra = createId(createIdAtom(name.str()));
- expr->setTransformExtra(extra); // LINKs !
- addVisited(expr);
- tmp.append(name);
- tmp.append(" := ");
- toECL(expr->queryBody(), tmp, false, false, 0, true);
- tmp.append(";").newline().newline();
- addExport(tmp);
- tmp.clear();
- }
- else
- {
- IHqlExpression * prev = (IHqlExpression *)expr->queryTransformExtra();
- IIdAtom * prevId = prev->queryId();
- appendId(name.clear(), prevId);
- }
- if(tmp.length())
- {
- s.append(tmp);
- }
- else
- {
- s.append(name);
- }
- break;
- }
- case type_alien:
- {
- IHqlExpression * expr = queryExpression(i);
- if (expr)
- {
- toECL(expr, s, false, false);
- return s;
- }
- break;
- }
- // case type_row:
- case type_table:
- // case type_groupedtable:
- break;
- case type_filepos:
- getTypeString(i->queryChildType(), s);
- break;
- default:
- ITypeInfo * original = queryModifier(i, typemod_original);
- IHqlExpression * originalExpr = NULL;
- if (original)
- originalExpr = (IHqlExpression *)original->queryModifierExtra();
- if (originalExpr && (originalExpr->getOperator() == no_typedef))
- toECL(originalExpr, s, false, false);
- else if (t == type_set)
- {
- s.append("set of ");
- i = i->queryChildType();
- if (i)
- getTypeString(i, s);
- else
- s.append("any");
- }
- else
- i->getECLType(s);
- break;
- }
-
- return s;
- }
- const char * HqltHql::getEclOpString(node_operator op)
- {
- switch(op)
- {
- case no_ave:
- case no_avegroup:
- return "AVE";
- case no_concat:
- return "+";
- case no_ne:
- return "!=";
- case no_not:
- return "NOT ";
- case no_or:
- return "OR";
- case no_and:
- return "AND";
- case no_filepos:
- return "FILEPOSITION";
- case no_file_logicalname:
- return "LOGICALFILENAME";
- case no_compound_diskread:
- return "DISKREAD";
- case no_compound_indexread:
- return "INDEXREAD";
- case no_keyedlimit:
- if (expandProcessed)
- return "KEYEDLIMIT";
- return ::getOpString(op);
- default:
- return ::getOpString(op);
- }
- }
- static bool addExplicitType(IHqlExpression * expr)
- {
- ITypeInfo * type = stripFunctionType(expr->queryType());
- if (!type)
- return false;
- switch (type->getTypeCode())
- {
- case type_transform:
- return true;
- case type_dictionary:
- case type_row:
- case type_table:
- case type_groupedtable:
- case type_alien:
- return false;
- }
- return true;
- }
- void HqltHql::doFunctionDefinition(StringBuffer & newdef, IHqlExpression * funcdef, const char * name, bool inType)
- {
- assertex(funcdef->getOperator() == no_funcdef);
- if (addExplicitType(funcdef))
- {
- ITypeInfo * returnType = funcdef->queryType()->queryChildType();
- StringBuffer tmp;
- getTypeString(returnType, tmp);
- if(tmp.length())
- newdef.append(tmp).append(' ');
- }
- newdef.append(name).append('(');
- IHqlExpression * formals = funcdef->queryChild(1);
- IHqlExpression * defaults = funcdef->queryChild(2);
- assertex( !defaults || formals->numChildren() ==defaults->numChildren());
- bool first = true;
- ForEachChild(idx, formals)
- {
- IHqlExpression * curParam = formals->queryChild(idx);
- if (expandProcessed || !curParam->hasAttribute(_hidden_Atom))
- {
- if (first)
- first = false;
- else
- newdef.append(", ");
- toECL(curParam, newdef, false, hasNamedSymbol(curParam) ? inType : true);
- if (defaults)
- {
- IHqlExpression * defexpr = defaults->queryChild(idx);
- if (defexpr->getOperator() != no_omitted)
- {
- newdef.append("=");
- toECL(defexpr, newdef, false, false);
- }
- }
- }
- }
- newdef.append(')');
- toECL(funcdef->queryChild(0), newdef.append(" := "), false, false, 0, true);
- }
- StringBuffer &HqltHql::doAlias(IHqlExpression * expr, StringBuffer &name, bool inType)
- {
- bool wasInsideNewTransform = insideNewTransform;
- insideNewTransform = false;
- // Start fresh
- name.clear();
-
- StringBuffer tmp;
- StringBuffer exports;
- scope.append(NULL);
- bool undefined = isPublicSymbol(expr) ? !expr->queryTransformExtra() : (findVisitedArray()->find(*expr) == NotFound);
- if (undefined || inType)
- {
- IHqlExpression * body = expr->queryBody(true);
- StringBuffer newdef;
- bool nameClash = false;
- IHqlExpression * funcdef = expr->queryFunctionDefinition();
- if (!funcdef && expr->getOperator() == no_funcdef)
- {
- //True when doAlias() is called on members of a alien type or scope
- //This is a complete mess!
- funcdef = expr;
- }
- if(isExported(expr) || isShared(expr))
- {
- if (isExported(expr))
- exports.append("EXPORT ");
- else
- exports.append("SHARED ");
- m_export_level++;
- nameClash = (!expr->queryTransformExtra() && isExportDefined(expr) && !funcdef);
- }
- else
- nameClash = (!expr->queryTransformExtra() && isSymbolDefined(expr) && !funcdef);
- if (nameClash)
- {
- StringBuffer temp;
- makeUniqueName(expr, temp);
- clashCounter++;
- temp.append("___").append(clashCounter);
- OwnedHqlExpr extra = createId(createIdAtom(temp.str()));
- expr->setTransformExtra(extra); // LINKs !
- }
- #ifdef SHOW_SYMBOL_LOCATION
- if (expandProcessed)
- newdef.append(expr->queryFullContainerId()).append("(").append(expr->getStartLine()).append(",").append(expr->getStartColumn()).append("):");
- #endif
- newdef.append(exports);
- lookupSymbolName(expr, name);
- bool wasFunctionDefined = funcdef && isFunctionDefined(funcdef) && !inType;
- //Add the export name before the body is processed to prevent clashing names (e.g., badrecord2.xhql)
- if (exports.length())
- m_export_names.append(*new StringBufferItem(name));
-
- if(funcdef && !expandProcessed)
- {
- if(!wasFunctionDefined || inType)
- {
- if(!expr->queryTransformExtra())
- {
- OwnedHqlExpr extra = createId(createIdAtom(name.str()));
- expr->setTransformExtra(extra);
- addVisited(expr);
- addVisited(funcdef);
- funcdef->setTransformExtra(extra);
- }
- doFunctionDefinition(newdef, funcdef, name.str(), inType);
- }
- else
- {
- // ???? Huh?
- newdef.clear();
- }
- }
- else if(!inType)
- {
- OwnedHqlExpr extra = createId(createIdAtom(name.str()));
- expr->setTransformExtra(extra); // LINKs !
- addVisited(expr);
-
- // Special cases
- node_operator op = body->getOperator();
- switch(op)
- {
- case no_record:
- {
- newdef.append(name.str()).append(" := ");
- toECL(body, newdef, false, false, 0, true);
- break;
- }
- default:
- if (addExplicitType(expr))
- getTypeString(expr->queryType(), tmp.clear());
- if(tmp.length())
- newdef.append(tmp).append(' ');
- newdef.append(name.str());
- bool isNamed = true;
- if (expr->isDataset())
- {
- if (expandProcessed && op != no_field && op != no_rows && !isTargetSelector(expr))
- isNamed = false;
- }
- toECL (body, newdef.append(" := "), false, inType, 0, isNamed);
- break;
- }
- }
- else
- {
- getTypeString(expr->queryType(), tmp.clear());
- if(tmp.length())
- newdef.append(tmp).append(' ');
- newdef.append(name.str());
- toECL (body, newdef.append(" := "), false, false, 0, true);
- }
- #ifdef SHOW_FUNC_DEFINTION
- if (expandProcessed && expr->getOperator() == no_funcdef)
- {
- newdef.append("{");
- defaultToECL(expr->queryChild(0),newdef,inType);
- newdef.append("}");
- }
- #endif
- if(newdef.length())
- {
- newdef.append(';').newline();
- if(inType)
- {
- name.clear().append(' ').append(newdef);
- }
- else
- {
- addExport(tmp.clear().append(newdef).newline());
- if(exports.length())
- {
- if(m_exports.isItem(m_export_level))
- {
- m_definitions.append(m_exports.item(m_export_level));
- m_exports.item(m_export_level).clear();
- clearVisited();
- }
- }
- }
- }
- // If we got here then we must have finished with the current export
- if(exports.length())
- {
- m_export_level--;
- }
- }
- else
- {
- lookupSymbolName(expr, name);
- }
- scope.pop();
- insideNewTransform = wasInsideNewTransform;
- return name;
- }
- void HqltHql::defineCallTarget(IHqlExpression * call, StringBuffer & name)
- {
- // OK we got us an external call. Let's try and define it.
- //This is a mess! (To put it politely)
- IHqlExpression * funcdef;
- if (call->getOperator() == no_externalcall)
- {
- funcdef = call->queryExternalDefinition();
- }
- else
- {
- funcdef = call->queryBody()->queryFunctionDefinition();
- }
- IHqlExpression * prevName = static_cast<IHqlExpression *>(call->queryTransformExtra());
- if (funcdef && !prevName && !isServiceDefined(call))
- {
- makeUniqueName(call, name);
- StringBuffer newdef;
- m_service_names.append(*new StringBufferItem(name));
- OwnedHqlExpr extra = createId(createIdAtom(name.str()));
- call->setTransformExtra(extra);
- addVisited(call);
- if(hasNamedSymbol(call))
- {
- if(isExported(call))
- {
- newdef.append("EXPORT ");
- }
- else if(isShared(call))
- {
- newdef.append("SHARED ");
- }
- }
- else if (!tryToRegenerate)
- newdef.append("EXPORT "); //not really right - the information is lost about whether the service definition is exported or not.
- newdef.append(name).append(" := ").newline();
- if (call->getOperator() == no_externalcall)
- {
- newdef.append("SERVICE").newline();
- getTypeString(call->queryType(), newdef);
- newdef.append(" ");
- lookupSymbolName(call, newdef);
- }
- if (funcdef->isFunctionDefinition())
- {
- newdef.append("(");
- toECL(funcdef->queryChild(1), newdef, false, true);
- newdef.append(") : ");
- IHqlExpression *child = funcdef->queryChild(0);
- toECL ( child, newdef, child->getPrecedence() < 0, false);
- }
- else
- toECL ( funcdef, newdef, false, false);
- newdef.append(';').newline();
- if (call->getOperator() == no_externalcall)
- {
- newdef.append("END;").newline().newline();
- }
- m_services.append(newdef);
- }
- else
- {
- if (prevName)
- appendId(name, prevName->queryId());
- else
- lookupSymbolName(call, name);
- }
- if (call->getOperator() == no_externalcall)
- {
- name.append('.');
- lookupSymbolName(call, name);
- }
- }
- static StringBuffer &toECL(StringBuffer &s, HqltHql & hqlthql, HqlExprArray & queries, bool recurse, bool isNamedSymbol = false)
- {
- int startpos = s.length();
- try
- {
- ForEachItemIn(idx, queries)
- {
- hqlthql.toECL((IHqlExpression *) &queries.item(idx), s, false, false, 0, isNamedSymbol);
- if(s.length() && s.charAt(s.length() - 1) != ';')
- {
- s.append(';').newline();
- }
- }
- if (recurse)
- {
- StringBuffer definitions;
- hqlthql.gatherServices(definitions);
- hqlthql.gatherDefinitions(definitions);
- s.insert(startpos, definitions.str());
- }
- }
- #ifdef _DEBUG
- catch(int*****************){}
- #else
- catch(...)
- {
- IERRLOG("toECL() threw an exception");
- s.setLength(startpos);
- }
- #endif
- return s;
- }
- static StringBuffer &toECLDefinition(StringBuffer &s, HqltHql & hqlthql, HqlExprArray & queries, bool recurse)
- {
- int startpos = s.length();
- try
- {
- ForEachItemIn(idx, queries)
- {
- StringBuffer name;
- hqlthql.doAlias((IHqlExpression *) &queries.item(idx), name, false);
- }
- if (recurse)
- {
- StringBuffer definitions;
- hqlthql.gatherServices(definitions);
- hqlthql.gatherDefinitions(definitions);
- s.insert(startpos, definitions.str());
- }
- }
- #ifdef _DEBUG
- catch(int*****************){}
- #else
- catch(...)
- {
- IERRLOG("toECLDefinition() threw an exception");
- s.setLength(startpos);
- }
- #endif
- return s;
- }
- StringBuffer &toECL(IHqlExpression * expr, StringBuffer &s, bool recurse, bool xgmmlGraphText)
- {
- HqltHql hqlthql(recurse, xgmmlGraphText);
- HqlExprArray queries;
- unwindCommaCompound(queries, expr);
- return toECL(s, hqlthql, queries, recurse);
- }
- StringBuffer ®enerateECL(IHqlExpression * expr, StringBuffer &s)
- {
- HqltHql hqlthql(true, false);
- hqlthql.setIgnoreModuleNames(true);
- hqlthql.setTryToRegenerate(true);
- HqlExprArray queries;
- unwindCommaCompound(queries, expr);
- return toECL(s, hqlthql, queries, true);
- }
- StringBuffer ®enerateDefinition(IHqlExpression * expr, StringBuffer &s)
- {
- if (!isEclAlias(expr))
- throw makeStringExceptionV(ERR_INTERNALEXCEPTION, "Internal: regenerateDefinition requires ECL alias expression");
- HqltHql hqlthql(true, false);
- hqlthql.setIgnoreModuleNames(true);
- HqlExprArray queries;
- unwindCommaCompound(queries, expr);
- return toECLDefinition(s, hqlthql, queries, true);
- }
- StringBuffer &toUserECL(StringBuffer &s, IHqlExpression * expr, bool recurse)
- {
- HqltHql hqlthql(recurse, false);
- hqlthql.setIgnoreModuleNames(true);
- HqlExprArray queries;
- unwindCommaCompound(queries, expr);
- return toECL(s, hqlthql, queries, recurse);
- }
- void splitECL(IHqlExpression * expr, StringBuffer &s, StringBuffer &d)
- {
- #ifndef _DEBUG
- int startpos = s.length();
- #endif
- try
- {
- HqltHql hqlthql(true, false);
- hqlthql.toECL(expr, s, false, false);
- hqlthql.gatherServices(d);
- hqlthql.gatherDefinitions(d);
- }
- #ifdef _DEBUG
- catch(int*****************){}
- #else
- catch(...)
- {
- IERRLOG("toECL() threw an exception");
- s.setLength(startpos);
- }
- #endif
- }
- StringBuffer &expandDotLiteral(StringBuffer &s, const char *f)
- {
- unsigned lines = 0;
- unsigned chars = 0;
- char c;
- while ((c = *f++))
- {
- switch (c)
- {
- case '\t':
- s.append(" ");
- break;
- case '\r':
- break;
- case '\n':
- s.append("\\l"); // Means left justify.
- if (lines++ > 10)
- return s;
- break;
- case '}':
- case '{':
- case '<':
- case '>': // Special chars in dot graphs
- case '\\':
- case '\"':
- case '\'':
- s.append('\\');
- // fall into...
- default:
- if (chars++ > 1000)
- return s;
- s.append(c);
- break;
- }
- }
- return s;
- }
- StringBuffer & doGetExprECL(IHqlExpression * expr, StringBuffer & out, bool minimalSelectors, bool xgmmlGraphText, unsigned _maxDepth)
- {
- const bool recurse = false;
- HqltHql hqlthql(recurse, xgmmlGraphText);
- hqlthql.setExpandNamed(false);
- hqlthql.setIgnoreModuleNames(true);
- hqlthql.setMinimalSelectors(minimalSelectors);
- if (_maxDepth)
- hqlthql.setMaxRecurseDepth(_maxDepth);
- HqlExprArray queries;
- unwindCommaCompound(queries, expr);
- toECL(out, hqlthql, queries, recurse);
- const char * text = out.str();
- unsigned len = out.length();
- while (len)
- {
- char c = text[len-1];
- if ((c != ';') && (c != '\n') &&(c != '\r'))
- break;
- len--;
- }
- out.setLength(len);
- return out;
- }
- StringBuffer & getExprECL(IHqlExpression * expr, StringBuffer & out, bool minimalSelectors, bool xgmmlGraphText)
- {
- return doGetExprECL(expr, out, minimalSelectors, xgmmlGraphText, 0);
- }
- StringBuffer &getRecordECL(IHqlExpression * expr, StringBuffer & out)
- {
- HqltHql hqlthql(true, false);
- hqlthql.setIgnoreVirtualAttrs(true);
- hqlthql.setLowerCaseIds(true);
- HqlExprArray queries;
- unwindCommaCompound(queries, expr);
- return toECL(out, hqlthql, queries, true, false);
- }
- StringBuffer & processedTreeToECL(IHqlExpression * expr, StringBuffer &s)
- {
- HqltHql hqlthql(true, false);
- hqlthql.setExpandProcessed(true);
- HqlExprArray queries;
- unwindCommaCompound(queries, expr);
- return toECL(s, hqlthql, queries, true);
- }
- StringBuffer & getExprIdentifier(StringBuffer & out, IHqlExpression * expr)
- {
- if (expr->queryName())
- return out.append(expr->queryName());
- return doGetExprECL(expr, out, false, false, 1);
- }
- void dbglogUnboundedText(size32_t len, const char * ecl)
- {
- const size32_t chunkSize = 32768;
- while (len > chunkSize)
- {
- const char * next = strchr(ecl+chunkSize, '\n');
- if (!next || !next[1])
- break;
- unsigned size = next-ecl;
- if (ecl[size-1] == '\r')
- size--;
- DBGLOG("%.*s", size, ecl);
- len -= (next+1-ecl);
- ecl = next+1;
- }
- DBGLOG("%s", ecl);
- }
- void dbglogExpr(IHqlExpression * expr)
- {
- if (expr)
- {
- StringBuffer s;
- processedTreeToECL(expr, s);
- dbglogUnboundedText(s.length(), s.str());
- }
- }
|