hqlgram2.cpp 413 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "platform.h"
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "hql.hpp"
  17. #include "jlib.hpp"
  18. #include "jmisc.hpp"
  19. #include "jexcept.hpp"
  20. #include "hqlerrors.hpp"
  21. #include "jfile.hpp"
  22. #include "junicode.hpp"
  23. #include "hqlgram.hpp"
  24. #include "hqlgram.h"
  25. #include "hqlgram.hpp"
  26. #include "hqlfold.hpp"
  27. #include "hqlpmap.hpp"
  28. #include "eclrtl.hpp"
  29. #include "hqlerrors.hpp"
  30. #include "hqlexpr.ipp"
  31. #include "hqlattr.hpp"
  32. #include "hqlmeta.hpp"
  33. #include "hqlerror.hpp"
  34. #include "hqlplugins.hpp"
  35. #include "hqlscope.hpp"
  36. #include "hqlthql.hpp"
  37. #include "hqlpregex.hpp"
  38. #include "hqlutil.hpp"
  39. #include "hqltrans.ipp"
  40. #include "hqlusage.hpp"
  41. #include "hqlvalid.hpp"
  42. #include "hqlrepository.hpp"
  43. #include "hqlir.hpp"
  44. #define ADD_IMPLICIT_FILEPOS_FIELD_TO_INDEX TRUE
  45. #define FAST_FIND_FIELD
  46. //#define USE_WHEN_FOR_SIDEEFFECTS
  47. #define MANYFIELDS_THRESHOLD 2000
  48. #define MAX_SENSIBLE_FIELD_LENGTH 1000000000
  49. #define MAX_POSSIBLE_FIELD_LENGTH (INFINITE_LENGTH-1)
  50. struct TokenMap
  51. {
  52. int lexToken;
  53. int attrToken;
  54. };
  55. static int defaultTokenMap[YY_LAST_TOKEN];
  56. static int attributeToTokenMap[YY_LAST_TOKEN];
  57. static TokenMap * nestedAttributeMap[YY_LAST_TOKEN];
  58. static IHqlExpression * alreadyAssignedNestedTag;
  59. //Called if token is only ever used as an attribute
  60. static void setAttribute(int attrToken)
  61. {
  62. defaultTokenMap[attrToken] = 0;
  63. attributeToTokenMap[attrToken] = attrToken;
  64. }
  65. static void setKeyword(int attrToken)
  66. {
  67. attributeToTokenMap[attrToken] = attrToken;
  68. }
  69. //called if the attribute is clashes with another reserved word
  70. static void setAttribute(int attrToken, int lexToken)
  71. {
  72. attributeToTokenMap[attrToken] = lexToken;
  73. }
  74. static void setAttributes(int lexToken, ...)
  75. {
  76. unsigned numAttrs = 0;
  77. va_list args;
  78. va_start(args, lexToken);
  79. for (;;)
  80. {
  81. int attrToken = va_arg(args, int);
  82. if (!attrToken)
  83. break;
  84. numAttrs++;
  85. }
  86. va_end(args);
  87. assertex(numAttrs);
  88. TokenMap * map = new TokenMap[numAttrs+1];
  89. unsigned curAttr = 0;
  90. va_list args2;
  91. va_start(args2, lexToken);
  92. for (;;)
  93. {
  94. int attrToken = va_arg(args2, int);
  95. if (!attrToken)
  96. break;
  97. int lexToken = attributeToTokenMap[attrToken];
  98. assertex(lexToken);
  99. map[curAttr].lexToken = lexToken;
  100. map[curAttr].attrToken = attrToken;
  101. curAttr++;
  102. }
  103. va_end(args2);
  104. assertex(curAttr == numAttrs);
  105. map[curAttr].lexToken = 0;
  106. map[curAttr].attrToken = 0;
  107. nestedAttributeMap[lexToken] = map;
  108. }
  109. /*
  110. Why dynamically map keywords? There are several different reasons:
  111. a) If an attribute has a different syntax from the non attribute form of the keyword then dynamically mapping the keyword can allow the
  112. grammar to disambiguate between the two.
  113. b) If a keyword is only used as an attribute name then it allows us to only pollute the name space when that attribute would be valid.
  114. c) If attributes have different forms in different places then using different mapped attributes can allow us to use a single shared
  115. production with all the possible attributes.
  116. (a) Is required in a couple of cases at the moment, there may be other situations in the future.
  117. (b) Generally this is implemented by looking ahead in the parser tables. FORMAT_ATTR is an example that is handled this way.
  118. (c) Unlikely to ever come to anything...
  119. */
  120. MODULE_INIT(INIT_PRIORITY_STANDARD)
  121. {
  122. for (unsigned i=0; i < YY_LAST_TOKEN; i++)
  123. defaultTokenMap[i] = i;
  124. setAttribute(FORMAT_ATTR);
  125. setAttribute(MERGE_ATTR, MERGE);
  126. setAttribute(PARTITION_ATTR, PARTITION);
  127. setAttributes(DISTRIBUTE, MERGE_ATTR, PARTITION_ATTR, 0);
  128. setAttributes(HEADING, FORMAT_ATTR, 0);
  129. setAttributes(STORED, FORMAT_ATTR, 0);
  130. alreadyAssignedNestedTag = createAttribute(_alreadyAssignedNestedTag_Atom);
  131. return true;
  132. }
  133. MODULE_EXIT()
  134. {
  135. ::Release(alreadyAssignedNestedTag);
  136. for (unsigned i=0; i < YY_LAST_TOKEN; i++)
  137. delete [] nestedAttributeMap[i];
  138. }
  139. // An experiment in programming style.
  140. template <class T>
  141. class RestoreValueBlock
  142. {
  143. public:
  144. inline RestoreValueBlock(T & _variable) : variable(_variable), oldValue(_variable) {}
  145. inline RestoreValueBlock(T & _variable, const T newValue) : variable(_variable), oldValue(_variable) { _variable = newValue; }
  146. inline ~RestoreValueBlock() { variable = oldValue; }
  147. protected:
  148. T & variable;
  149. const T oldValue;
  150. };
  151. void attribute::annotateExprWithLocation()
  152. {
  153. if ((atr_type==t_expr) && expr && !queryLocation(expr))
  154. expr = createLocationAnnotation(expr, pos);
  155. }
  156. bool attribute::isZero() const
  157. {
  158. IValue * value = queryExpr()->queryValue();
  159. return (value && (value->getIntValue() == 0));
  160. }
  161. void attribute::setPosition(int _line, int _column, int _position, ISourcePath * _sourcePath)
  162. {
  163. pos.set(_line, _column, _position, _sourcePath);
  164. if ((atr_type==t_expr) && expr)
  165. {
  166. if (okToAddLocation(expr) && !queryLocation(expr))
  167. expr = createLocationAnnotation(expr, pos);
  168. }
  169. }
  170. IHqlExpression * ActiveScopeInfo::createDefaults()
  171. {
  172. ForEachItemIn(i, activeDefaults)
  173. {
  174. if (activeDefaults.item(i).getOperator() != no_omitted)
  175. return createValueSafe(no_sortlist, makeSortListType(NULL), activeDefaults);
  176. }
  177. return NULL;
  178. }
  179. IHqlExpression * ActiveScopeInfo::createFormals(bool oldSetFormat)
  180. {
  181. assertex(isParametered);
  182. if (oldSetFormat)
  183. {
  184. ForEachItemIn(i, activeParameters)
  185. {
  186. IHqlExpression & cur = activeParameters.item(i);
  187. assertex(cur.getOperator() == no_param);
  188. ITypeInfo * type = cur.queryType();
  189. if (type->getTypeCode() == type_set)
  190. {
  191. Owned<ITypeInfo> newType = makeAttributeModifier(LINK(type), createAttribute(oldSetFormatAtom));
  192. HqlExprArray args;
  193. unwindChildren(args, &cur);
  194. activeParameters.replace(*createParameter(cur.queryId(), (unsigned)cur.querySequenceExtra(), newType.getClear(), args), i);
  195. }
  196. }
  197. }
  198. return createValueSafe(no_sortlist, makeSortListType(NULL), activeParameters);
  199. }
  200. void ActiveScopeInfo::newPrivateScope()
  201. {
  202. if (localScope)
  203. privateScope.setown(createPrivateScope(localScope));
  204. }
  205. IHqlExpression * ActiveScopeInfo::queryParameter(IIdAtom * id)
  206. {
  207. IAtom * name = lower(id);
  208. ForEachItemIn(idx, activeParameters)
  209. {
  210. IHqlExpression &parm = activeParameters.item(idx);
  211. if (parm.queryName()==name)
  212. return &parm;
  213. }
  214. return NULL;
  215. }
  216. bool HqlGramCtx::hasAnyActiveParameters()
  217. {
  218. ForEachItemIn(i2, defineScopes)
  219. {
  220. if (defineScopes.item(i2).activeParameters.ordinality())
  221. return true;
  222. }
  223. return false;
  224. }
  225. static IError * createErrorVA(WarnErrorCategory category, ErrorSeverity severity, int errNo, const ECLlocation & pos, const char* format, va_list args) __attribute__((format(printf,5,0)));
  226. static IError * createErrorVA(WarnErrorCategory category, ErrorSeverity severity, int errNo, const ECLlocation & pos, const char* format, va_list args)
  227. {
  228. StringBuffer msg;
  229. msg.valist_appendf(format, args);
  230. return createError(category, severity, errNo, msg.str(), str(pos.sourcePath), pos.lineno, pos.column, pos.position);
  231. }
  232. IHqlExpression * HqlGram::createSetRange(attribute & array, attribute & range)
  233. {
  234. switch (range.queryExpr()->getOperator())
  235. {
  236. case no_range :
  237. case no_rangefrom :
  238. case no_rangeto :
  239. case no_rangecommon :
  240. {
  241. OwnedHqlExpr rangeExpr = range.getExpr();
  242. ITypeInfo * elementType = array.queryExpr()->queryType()->queryChildType();
  243. OwnedHqlExpr field = createField(valueId, LINK(elementType), NULL);
  244. OwnedHqlExpr record = createRecord(field);
  245. OwnedHqlExpr dsFromList = createDataset(no_temptable, array.getExpr(), record.getClear());
  246. OwnedHqlExpr dsChooseN;
  247. switch (rangeExpr->getOperator())
  248. {
  249. case no_range :
  250. {
  251. Owned<ITypeInfo> indexType = makeIntType(8, true);
  252. IHqlExpression * from = ensureExprType(rangeExpr->queryChild(0), indexType);
  253. IHqlExpression * to = ensureExprType(rangeExpr->queryChild(1), indexType);
  254. OwnedHqlExpr length = createValue(no_add, LINK(indexType), createValue(no_sub, LINK(indexType), to, from), createConstant(indexType->castFrom(true, (__int64)1)));
  255. dsChooseN.setown(createDataset(no_choosen, dsFromList.getClear(), createComma(length.getClear(), LINK(from))));
  256. break;
  257. }
  258. case no_rangeto :
  259. {
  260. IHqlExpression * length = rangeExpr->queryChild(0);
  261. dsChooseN.setown(createDataset(no_choosen, dsFromList.getClear(), LINK(length)));
  262. break;
  263. }
  264. case no_rangefrom :
  265. case no_rangecommon :
  266. {
  267. IHqlExpression * from = rangeExpr->queryChild(0);
  268. dsChooseN.setown(createDataset(no_choosen, dsFromList.getClear(), createComma(createConstant(CHOOSEN_ALL_LIMIT), LINK(from))));
  269. break;
  270. }
  271. }
  272. return createValue(no_createset, makeSetType(LINK(elementType)), LINK(dsChooseN), createSelectExpr(LINK(dsChooseN), field.getClear()));
  273. }
  274. default :
  275. return createListIndex(array, range, NULL);
  276. }
  277. }
  278. void HqlGram::gatherActiveParameters(HqlExprCopyArray & target)
  279. {
  280. ForEachItemIn(i2, defineScopes)
  281. {
  282. appendArray(target, defineScopes.item(i2).activeParameters);
  283. }
  284. }
  285. /* In parm: scope not linked */
  286. HqlGram::HqlGram(IHqlScope * _globalScope, IHqlScope * _containerScope, IFileContents * _text, HqlLookupContext & _ctx, IXmlScope *xmlScope, bool _hasFieldMap, bool loadImplicit)
  287. : lookupCtx(_ctx)
  288. {
  289. parseConstantText = false;
  290. init(_globalScope, _containerScope);
  291. fieldMapUsed = _hasFieldMap;
  292. if (!lookupCtx.functionCache)
  293. lookupCtx.functionCache = &localFunctionCache;
  294. errorHandler = lookupCtx.errs;
  295. sourcePath.set(_text->querySourcePath());
  296. moduleName = _containerScope->queryId();
  297. forceResult = false;
  298. parsingTemplateAttribute = false;
  299. inSignedModule = false;
  300. lexObject = new HqlLex(this, _text, xmlScope, NULL);
  301. if(lookupCtx.queryRepository() && loadImplicit && legacyImportSemantics)
  302. {
  303. HqlScopeArray scopes;
  304. getImplicitScopes(scopes, lookupCtx.queryRepository(), _containerScope, lookupCtx);
  305. ForEachItemIn(i, scopes)
  306. defaultScopes.append(OLINK(scopes.item(i)));
  307. }
  308. }
  309. HqlGram::HqlGram(HqlGramCtx & parent, IHqlScope * _containerScope, IFileContents * _text, IXmlScope *xmlScope, bool _parseConstantText)
  310. : lookupCtx(parent.lookupCtx)
  311. {
  312. //This is used for parsing a constant expression inside the preprocessor
  313. //And reprocessing FORWARD module definitions.
  314. ForEachItemIn(i2, parent.defineScopes)
  315. defineScopes.append(OLINK(parent.defineScopes.item(i2)));
  316. init(parent.globalScope, _containerScope);
  317. for (unsigned i=0;i<parent.defaultScopes.length();i++)
  318. defaultScopes.append(*LINK(&parent.defaultScopes.item(i)));
  319. sourcePath.set(parent.sourcePath);
  320. inSignedModule = parent.inSignedModule;
  321. errorHandler = lookupCtx.errs;
  322. moduleName = containerScope->queryId();
  323. ForEachItemIn(i3, parent.imports)
  324. parseScope->defineSymbol(LINK(&parent.imports.item(i3)));
  325. //Clone parseScope
  326. lexObject = new HqlLex(this, _text, xmlScope, NULL);
  327. forceResult = true;
  328. parsingTemplateAttribute = false;
  329. parseConstantText = _parseConstantText;
  330. }
  331. void HqlGram::saveContext(HqlGramCtx & ctx, bool cloneScopes)
  332. {
  333. ForEachItemIn(i2, defineScopes)
  334. {
  335. ActiveScopeInfo & cur = defineScopes.item(i2);
  336. if (cloneScopes)
  337. {
  338. //parameters will be cleared as the rest of the file is parsed => need to preserve
  339. ActiveScopeInfo & clone = * new ActiveScopeInfo;
  340. clone.localScope.set(cur.localScope);
  341. clone.privateScope.set(cur.privateScope);
  342. clone.isParametered = cur.isParametered;
  343. appendArray(clone.activeParameters, cur.activeParameters);
  344. appendArray(clone.activeDefaults, cur.activeDefaults);
  345. ctx.defineScopes.append(clone);
  346. }
  347. else
  348. ctx.defineScopes.append(OLINK(cur));
  349. }
  350. ctx.globalScope.set(globalScope);
  351. appendArray(ctx.defaultScopes, defaultScopes);
  352. ctx.sourcePath.set(sourcePath);
  353. parseScope->getSymbols(ctx.imports);
  354. };
  355. IHqlScope * HqlGram::queryGlobalScope()
  356. {
  357. return globalScope;
  358. }
  359. void HqlGram::init(IHqlScope * _globalScope, IHqlScope * _containerScope)
  360. {
  361. minimumScopeIndex = 0;
  362. isQuery = false;
  363. legacyImportSemantics = queryLegacyImportSemantics();
  364. legacyWhenSemantics = queryLegacyWhenSemantics();
  365. current_id = NULL;
  366. lexObject = NULL;
  367. expectedAttribute = NULL;
  368. pendingAttributes = NULL;
  369. expandingMacroPosition = false;
  370. outerScopeAccessDepth = 0;
  371. inType = false;
  372. aborting = lookupCtx.isAborting();
  373. errorHandler = NULL;
  374. moduleName = NULL;
  375. resolveSymbols = true;
  376. lastpos = 0;
  377. inSignedModule = false;
  378. containerScope = _containerScope;
  379. globalScope = _globalScope;
  380. parseScope.setown(createPrivateScope(_containerScope));
  381. transformScope = NULL;
  382. if (globalScope->queryName() && legacyImportSemantics)
  383. parseScope->defineSymbol(globalScope->queryId(), NULL, LINK(queryExpression(globalScope)), false, false, ob_import);
  384. boolType = makeBoolType();
  385. defaultIntegralType = makeIntType(8, true);
  386. uint4Type = makeIntType(4, false);
  387. defaultRealType = makeRealType(DEFAULT_REAL_SIZE);
  388. current_type = NULL;
  389. curTransform = NULL;
  390. insideEvaluate = false;
  391. fieldMapUsed = false;
  392. associateWarnings = true;
  393. errorDisabled = false;
  394. setIdUnknown(false);
  395. m_maxErrorsAllowed = DEFAULT_MAX_ERRORS;
  396. sortDepth = 0;
  397. serviceScope.clear();
  398. if (globalScope->isPlugin())
  399. {
  400. StringBuffer plugin, version;
  401. globalScope->getProp(pluginAtom, plugin);
  402. globalScope->getProp(versionAtom, version);
  403. serviceExtraAttributes.setown(createExprAttribute(pluginAtom, createConstant(plugin.str()), createConstant(version.str())));
  404. }
  405. }
  406. HqlGram::~HqlGram()
  407. {
  408. errorHandler = NULL;
  409. delete lexObject;
  410. boolType->Release();
  411. defaultIntegralType->Release();
  412. uint4Type->Release();
  413. defaultRealType->Release();
  414. cleanCurTransform();
  415. }
  416. int HqlGram::yyLex(attribute * yylval, const short * activeState)
  417. {
  418. if (aborting) return 0;
  419. return lexObject->yyLex(*yylval, resolveSymbols, activeState);
  420. }
  421. void HqlGram::cleanCurTransform()
  422. {
  423. attribute pseudoErrPos;
  424. pseudoErrPos.pos.clear();
  425. loop
  426. {
  427. IHqlExpression * ret = endTransform(pseudoErrPos);
  428. if (!ret)
  429. break;
  430. ret->Release();
  431. }
  432. }
  433. void HqlGram::pushTopScope(IHqlExpression *newScope)
  434. {
  435. newScope->Link();
  436. topScopes.append(*newScope);
  437. wasInEvaluate.append(insideEvaluate);
  438. insideEvaluate = false;
  439. }
  440. void HqlGram::pushLeftRightScope(IHqlExpression * left, IHqlExpression * right)
  441. {
  442. LeftRightScope * newScope = new LeftRightScope;
  443. newScope->left.set(left);
  444. newScope->right.set(right);
  445. newScope->selSeq.setown(createActiveSelectorSequence(left, right));
  446. leftRightScopes.append(*newScope);
  447. }
  448. void HqlGram::pushPendingLeftRightScope(IHqlExpression * left, IHqlExpression * right)
  449. {
  450. LeftRightScope * newScope = new LeftRightScope;
  451. newScope->left.set(left);
  452. newScope->right.set(right);
  453. leftRightScopes.append(*newScope);
  454. }
  455. void HqlGram::setRightScope(IHqlExpression *newScope)
  456. {
  457. LeftRightScope & topScope = leftRightScopes.tos();
  458. topScope.right.set(newScope);
  459. if (!topScope.selSeq)
  460. topScope.selSeq.setown(createActiveSelectorSequence(topScope.left, topScope.right));
  461. }
  462. void HqlGram::beginRowsScope(node_operator side)
  463. {
  464. LeftRightScope & topScope = leftRightScopes.tos();
  465. IHqlExpression * ds = (side == no_left) ? topScope.left : topScope.right;
  466. topScope.rowsScope.setown(createSelector(side, ds, topScope.selSeq));
  467. topScope.rowsId.setown(createUniqueRowsId());
  468. }
  469. /* in: linked */
  470. void HqlGram::pushSelfScope(IHqlExpression *newScope)
  471. {
  472. selfScopes.append(*newScope);
  473. }
  474. void HqlGram::pushSelfScope(ITypeInfo * selfType)
  475. {
  476. IHqlExpression * record = queryExpression(selfType);
  477. pushSelfScope(createSelector(no_self, record, NULL));
  478. }
  479. void HqlGram::popTopScope()
  480. {
  481. if(topScopes.length() > 0)
  482. {
  483. topScopes.pop();
  484. insideEvaluate = wasInEvaluate.popGet();
  485. }
  486. }
  487. IHqlExpression * HqlGram::endRowsScope()
  488. {
  489. if(leftRightScopes.length() > 0)
  490. {
  491. LeftRightScope & tos = leftRightScopes.tos();
  492. tos.rowsScope.clear();
  493. return tos.rowsId.getClear();
  494. }
  495. return createAttribute(_rowsid_Atom, createConstant(0));
  496. }
  497. void HqlGram::popSelfScope()
  498. {
  499. if(selfScopes.length() > 0)
  500. selfScopes.pop();
  501. }
  502. IHqlExpression * HqlGram::getSelectorSequence()
  503. {
  504. if (leftRightScopes.ordinality())
  505. return LINK(leftRightScopes.tos().selSeq);
  506. //Can occur when LEFT is used in an invalid context
  507. return createDummySelectorSequence();
  508. }
  509. IHqlExpression * HqlGram::getSelector(const attribute & errpos, node_operator side)
  510. {
  511. ForEachItemInRev(i, leftRightScopes)
  512. {
  513. LeftRightScope & curScope = leftRightScopes.item(i);
  514. if (curScope.selSeq)
  515. {
  516. IHqlExpression * ds = (side == no_left) ? curScope.left : curScope.right;
  517. if (ds)
  518. return createSelector(side, ds, curScope.selSeq);
  519. }
  520. }
  521. const char * sideText = (side == no_left) ? "LEFT" : "RIGHT";
  522. reportError(ERR_LEFT_ILL_HERE, errpos, "%s not legal here", sideText);
  523. OwnedHqlExpr selSeq = createDummySelectorSequence();
  524. return createSelector(side, queryNullRecord(), selSeq);
  525. }
  526. void HqlGram::pushLocale(IHqlExpression *newLocale)
  527. {
  528. localeStack.append(*newLocale);
  529. }
  530. void HqlGram::popLocale()
  531. {
  532. if(localeStack.length() > 0)
  533. localeStack.pop();
  534. }
  535. IHqlExpression * HqlGram::queryDefaultLocale()
  536. {
  537. if(localeStack.length() == 0)
  538. return NULL;
  539. return &localeStack.tos();
  540. }
  541. void HqlGram::pushRecord(IHqlExpression *newRecord)
  542. {
  543. activeRecords.append(*newRecord);
  544. }
  545. IHqlExpression* HqlGram::popRecord()
  546. {
  547. return &activeRecords.popGet();
  548. }
  549. IHqlExpression* HqlGram::endRecordDef()
  550. {
  551. IHqlExpression * record = popRecord();
  552. record->Link(); // logically link should be in startrecord, but can only link after finished updating
  553. popSelfScope();
  554. return record->closeExpr();
  555. }
  556. void HqlGram::beginFunctionCall(attribute & function)
  557. {
  558. IHqlExpression * funcdef = function.queryExpr();
  559. //Check for strange situation where this isn't really a function (e.g., an alien type)
  560. //but the grammar allows optional parameters - so need a record on the stack
  561. if (!funcdef->isFunction())
  562. funcdef = NULL;
  563. activeFunctionCalls.append(*new FunctionCallInfo(funcdef));
  564. }
  565. void HqlGram::addActual(const attribute & errpos, IHqlExpression * ownedExpr)
  566. {
  567. assertex(ownedExpr);
  568. FunctionCallInfo & call = activeFunctionCalls.tos();
  569. OwnedHqlExpr releaseExpr = ownedExpr;
  570. processParameter(call, NULL, ownedExpr, errpos);
  571. // call.actuals.append(*LINK(ownedExpr));
  572. }
  573. void HqlGram::addNamedActual(const attribute & errpos, IIdAtom * name, IHqlExpression * ownedExpr)
  574. {
  575. assertex(ownedExpr);
  576. FunctionCallInfo & call = activeFunctionCalls.tos();
  577. OwnedHqlExpr releaseExpr = ownedExpr;
  578. processParameter(call, name, ownedExpr, errpos);
  579. // IHqlExpression * named = createValue(no_namedactual, makeVoidType(), createAttribute(name), ownedExpr);
  580. // call.actuals.append(*named);
  581. }
  582. IHqlExpression * HqlGram::endFunctionCall()
  583. {
  584. FunctionCallInfo & call = activeFunctionCalls.tos();
  585. leaveActualTopScope(call);
  586. OwnedHqlExpr ret = call.getFinalActuals();
  587. activeFunctionCalls.pop();
  588. return ret.getClear();
  589. }
  590. IHqlExpression * HqlGram::createUniqueId()
  591. {
  592. HqlExprArray args;
  593. ForEachItemIn(i, defineScopes)
  594. {
  595. ActiveScopeInfo & curScope = defineScopes.item(i);
  596. appendArray(args, curScope.activeParameters);
  597. }
  598. if (args.ordinality())
  599. {
  600. args.add(*::createUniqueId(), 0);
  601. return createExprAttribute(_uid_Atom, args);
  602. }
  603. return ::createUniqueId();
  604. }
  605. IHqlExpression * HqlGram::createActiveSelectorSequence(IHqlExpression * left, IHqlExpression * right)
  606. {
  607. #ifdef USE_SELSEQ_UID
  608. if (left || right)
  609. {
  610. HqlExprArray args;
  611. if (left)
  612. args.append(*LINK(left->queryNormalizedSelector()));
  613. if (right)
  614. args.append(*LINK(right->queryNormalizedSelector()));
  615. return createExprAttribute(_selectorSequence_Atom, args);
  616. }
  617. return ::createUniqueSelectorSequence();
  618. #else
  619. return createSelectorSequence();
  620. #endif
  621. }
  622. IHqlExpression * HqlGram::popLeftRightScope()
  623. {
  624. if (leftRightScopes.ordinality())
  625. {
  626. LinkedHqlExpr selSeq(leftRightScopes.tos().selSeq);
  627. leftRightScopes.pop();
  628. return selSeq.getClear();
  629. }
  630. return createDummySelectorSequence();
  631. }
  632. void HqlGram::beginList()
  633. {
  634. if (curList)
  635. curListStack.append(*curList.getClear());
  636. curList.setown(createOpenValue(no_comma, makeNullType()));
  637. }
  638. void HqlGram::addListElement(IHqlExpression * expr)
  639. {
  640. if (expr)
  641. curList->addOperand(expr);
  642. }
  643. void HqlGram::endList(HqlExprArray & args)
  644. {
  645. OwnedHqlExpr list = curList.getClear()->closeExpr();
  646. if (curListStack.ordinality())
  647. curList.setown(&curListStack.popGet());
  648. unwindChildren(args, list);
  649. }
  650. IHqlExpression * HqlGram::getActiveCounter(attribute & errpos)
  651. {
  652. OwnedHqlExpr tempCounter;
  653. OwnedHqlExpr * ref;
  654. if (counterStack.empty())
  655. {
  656. reportError(ERR_COUNT_ILL_HERE, errpos, "COUNTER not valid in this context");
  657. ref = &tempCounter;
  658. }
  659. else
  660. ref = &counterStack.tos().value;
  661. if (!ref->get())
  662. ref->setown(createCounter());
  663. return LINK(*ref);
  664. }
  665. static StringBuffer& getFldName(IHqlExpression* field, StringBuffer& s)
  666. {
  667. switch (field->getOperator())
  668. {
  669. case no_select:
  670. getFldName(field->queryChild(0), s).append(".");
  671. getFldName(field->queryChild(1), s);
  672. break;
  673. case no_field:
  674. default:
  675. s.append(str(field->queryName()));
  676. break;
  677. case no_self:
  678. case no_left:
  679. case no_right:
  680. case no_top:
  681. case no_activetable:
  682. s.append(getOpString(field->getOperator()));
  683. break;
  684. }
  685. return s;
  686. }
  687. IHqlExpression * HqlGram::translateFieldsToNewScope(IHqlExpression * expr, IHqlSimpleScope * record, const attribute & err)
  688. {
  689. switch (expr->getOperator())
  690. {
  691. case no_field:
  692. return record->lookupSymbol(expr->queryId());
  693. case no_select:
  694. {
  695. OwnedHqlExpr newDs = translateFieldsToNewScope(expr->queryChild(0), record, err);
  696. IHqlExpression * lhsRecord = newDs->queryRecord();
  697. OwnedHqlExpr newField;
  698. IIdAtom * name = expr->queryChild(1)->queryId();
  699. if (lhsRecord)
  700. newField.setown(lhsRecord->querySimpleScope()->lookupSymbol(name));
  701. if (!newField)
  702. newField.setown(record->lookupSymbol(name));
  703. if (!newField)
  704. {
  705. reportError(ERR_FIELD_NOT_FOUND, err, "Could not find field %s", str(name));
  706. return LINK(expr);
  707. }
  708. return createSelectExpr(newDs.getClear(), newField.getClear());
  709. }
  710. }
  711. bool same = true;
  712. HqlExprArray args;
  713. ForEachChild(idx, expr)
  714. {
  715. IHqlExpression * cur = expr->queryChild(idx);
  716. IHqlExpression * updated = translateFieldsToNewScope(cur, record, err);
  717. if (cur != updated)
  718. same = false;
  719. args.append(*updated);
  720. }
  721. if (same)
  722. return LINK(expr);
  723. return expr->clone(args);
  724. }
  725. void HqlGram::checkSensibleId(const attribute & attr, IIdAtom * id)
  726. {
  727. IAtom * name = lower(id);
  728. if (name == skipAtom || name == eventExtraAtom || name == eventNameAtom || name == failCodeAtom ||
  729. name == failMessageAtom || name == countAtom || name == counterAtom ||
  730. name == matchedAtom || name == matchTextAtom || name == matchUnicodeAtom ||
  731. name == matchUtf8Atom || name == matchLengthAtom || name == matchPositionAtom
  732. )
  733. reportError(ERR_DUBIOUS_NAME, attr.pos, "Identifier '%s' clashes with a reserved symbol", str(name));
  734. }
  735. DefineIdSt * HqlGram::createDefineId(int scope, ITypeInfo * ownedType)
  736. {
  737. DefineIdSt* defineid = new DefineIdSt();
  738. defineid->scope = scope;
  739. defineid->setType(ownedType);
  740. defineid->id = current_id;
  741. defineid->setDoc(lexObject->getClearJavadoc());
  742. return defineid;
  743. }
  744. void HqlGram::beginAlienType(const attribute & errpos)
  745. {
  746. if (inType)
  747. reportError(ERR_USRTYPE_NESTEDDECL, errpos, "Cannot nest TYPE declarations");
  748. inType = true;
  749. enterType(errpos, queryParametered());
  750. }
  751. void HqlGram::beginDefineId(IIdAtom * name, ITypeInfo * type)
  752. {
  753. current_id = name;
  754. current_type = type;
  755. }
  756. IHqlExpression * HqlGram::processAlienType(const attribute & errpos)
  757. {
  758. IHqlScope * alienScope = NULL;
  759. ActiveScopeInfo & cur = defineScopes.tos();
  760. if (checkAlienTypeDef(cur.localScope, errpos))
  761. alienScope = LINK(cur.localScope);
  762. leaveType(errpos);
  763. if (alienScope)
  764. return (createAlienType(current_id, closeScope(alienScope)))->closeExpr();
  765. return createConstant(false);
  766. }
  767. IHqlExpression * HqlGram::processCompoundFunction(attribute & resultAttr, bool outOfLine)
  768. {
  769. OwnedHqlExpr resultExpr = resultAttr.getExpr();
  770. OwnedHqlExpr expr = associateSideEffects(resultExpr, resultAttr.pos);
  771. leaveScope(resultAttr);
  772. leaveCompoundObject();
  773. return expr.getClear();
  774. }
  775. IHqlExpression * HqlGram::convertToOutOfLineFunction(const ECLlocation & errpos, IHqlExpression * expr)
  776. {
  777. if (expr->getOperator() != no_outofline)
  778. {
  779. if (queryParametered())
  780. return createWrapper(no_outofline, LINK(expr));
  781. }
  782. return LINK(expr);
  783. }
  784. IHqlExpression * HqlGram::processEmbedBody(const attribute & errpos, IHqlExpression * embedText, IHqlExpression * language, IHqlExpression *attribs)
  785. {
  786. HqlExprArray args;
  787. embedText->unwindList(args, no_comma);
  788. if (language)
  789. {
  790. IHqlScope *pluginScope = language->queryScope();
  791. OwnedHqlExpr getEmbedContextFunc = pluginScope->lookupSymbol(getEmbedContextId, LSFpublic, lookupCtx);
  792. IIdAtom * moduleId = language->queryId();
  793. if (!moduleId)
  794. moduleId = unnamedId;
  795. if (!getEmbedContextFunc)
  796. reportError(ERR_PluginNoScripting, errpos, "Module %s does not export getEmbedContext() function", str(moduleId));
  797. bool isImport = queryAttributeInList(importAtom, attribs) != NULL;
  798. OwnedHqlExpr checkSupport = pluginScope->lookupSymbol(isImport ? supportsImportId : supportsScriptId, LSFpublic, lookupCtx);
  799. if (!matchesBoolean(checkSupport, true))
  800. reportError(ERR_PluginNoScripting, errpos, "Module %s does not support %s", str(moduleId), isImport ? "import" : "script");
  801. OwnedHqlExpr syntaxCheckFunc = pluginScope->lookupSymbol(syntaxCheckId, LSFpublic, lookupCtx);
  802. if (syntaxCheckFunc && !isImport)
  803. {
  804. // MORE - create an expression that calls it, and const fold it, I guess....
  805. }
  806. args.append(*createExprAttribute(languageAtom, getEmbedContextFunc.getClear()));
  807. }
  808. if (!checkAllowed(errpos, "cpp", "Embedded code"))
  809. args.append(*createExprAttribute(_disallowed_Atom));
  810. if (attribs)
  811. attribs->unwindList(args, no_comma);
  812. Linked<ITypeInfo> type = current_type;
  813. if (!type)
  814. type.setown(makeVoidType());
  815. if (type->getTypeCode() == type_record)
  816. type.setown(makeRowType(LINK(type)));
  817. IHqlExpression * record = queryOriginalRecord(type);
  818. OwnedHqlExpr result;
  819. if (record)
  820. {
  821. args.add(*LINK(record),1);
  822. if (hasLinkCountedModifier(type) || language)
  823. {
  824. //MORE: Recursively set link counted on the records. for language != NULL
  825. args.append(*getLinkCountedAttr());
  826. }
  827. //All non C++ dataset embedded functions must return streamed datasets
  828. if (hasStreamedModifier(type) || (language && isDatasetType(type)))
  829. args.append(*getStreamedAttr());
  830. switch (type->getTypeCode())
  831. {
  832. case type_row:
  833. case type_record:
  834. result.setown(createRow(no_embedbody, args));
  835. break;
  836. case type_table:
  837. case type_groupedtable:
  838. result.setown(createDataset(no_embedbody, args));
  839. break;
  840. case type_transform:
  841. result.setown(createValue(no_embedbody, makeTransformType(LINK(record->queryType())), args));
  842. break;
  843. default:
  844. throwUnexpected();
  845. }
  846. }
  847. else
  848. result.setown(createValue(no_embedbody, LINK(type), args));
  849. result.setown(createLocationAnnotation(result.getClear(), errpos.pos));
  850. if (queryParametered())
  851. {
  852. HqlExprArray args;
  853. args.append(*LINK(result));
  854. if (language)
  855. {
  856. args.append(*createAttribute(contextAtom));
  857. if (result->isDatarow())
  858. args.append(*createAttribute(allocatorAtom));
  859. //Slightly ugly... force all parameters to this function to be link counted
  860. HqlExprArray & params = defineScopes.tos().activeParameters;
  861. ForEachItemIn(i, params)
  862. {
  863. IHqlExpression * param = &params.item(i);
  864. if (param->queryRecord() && !hasLinkCountedModifier(param))
  865. {
  866. HqlExprArray args;
  867. unwindChildren(args, param);
  868. Owned<ITypeInfo> newType = setLinkCountedAttr(param->queryType(), true);
  869. OwnedHqlExpr newParam = createParameter(param->queryId(), (unsigned)param->querySequenceExtra(), newType.getClear(), args);
  870. params.replace(*newParam.getClear(), i);
  871. }
  872. }
  873. }
  874. return createWrapper(no_outofline, result->queryType(), args);
  875. }
  876. return result.getClear();
  877. }
  878. IHqlExpression * HqlGram::processUserAggregate(const attribute & mainPos, attribute & dsAttr, attribute & recordAttr, attribute & transformAttr, attribute * mergeAttr,
  879. attribute *itemsAttr, attribute &rowsAttr, attribute &seqAttr)
  880. {
  881. HqlExprArray sortItems;
  882. endList(sortItems);
  883. OwnedHqlExpr dataset = dsAttr.getExpr();
  884. OwnedHqlExpr record = recordAttr.getExpr();
  885. OwnedHqlExpr transform = transformAttr.getExpr();
  886. OwnedHqlExpr merge = mergeAttr ? mergeAttr->getExpr() : NULL;
  887. OwnedHqlExpr rowsid = rowsAttr.getExpr();
  888. OwnedHqlExpr selSeq = seqAttr.getExpr();
  889. //check the record match
  890. OwnedHqlExpr attrs;
  891. OwnedHqlExpr grouping = itemsAttr ? processSortList(*itemsAttr, no_aggregate, dataset, sortItems, NULL, &attrs) : NULL;
  892. if (grouping && (dataset->getOperator() == no_group) && isGrouped(dataset))
  893. reportWarning(CategoryIgnored, WRN_GROUPINGIGNORED, dsAttr.pos, "Grouping of aggregate input will have no effect, was this intended?");
  894. HqlExprArray args;
  895. args.append(*LINK(dataset));
  896. args.append(*LINK(record));
  897. args.append(*LINK(transform));
  898. if (grouping)
  899. args.append(*LINK(grouping));
  900. if (merge)
  901. args.append(*createExprAttribute(mergeTransformAtom, merge.getClear()));
  902. if (attrs)
  903. attrs->unwindList(args, no_comma);
  904. args.append(*LINK(rowsid));
  905. args.append(*LINK(selSeq));
  906. OwnedHqlExpr ret = createDataset(no_aggregate, args);
  907. checkAggregateRecords(ret, record, transformAttr);
  908. return ret.getClear();
  909. }
  910. IHqlExpression * HqlGram::processIndexBuild(attribute & indexAttr, attribute * recordAttr, attribute * payloadAttr, attribute & filenameAttr, attribute & flagsAttr)
  911. {
  912. if (!recordAttr)
  913. warnIfRecordPacked(indexAttr);
  914. transferOptions(filenameAttr, flagsAttr);
  915. normalizeExpression(filenameAttr, type_string, false);
  916. OwnedHqlExpr dataset = indexAttr.getExpr();
  917. checkBuildIndexFilenameFlags(dataset, flagsAttr);
  918. LinkedHqlExpr inputDataset = dataset;
  919. OwnedHqlExpr flags = flagsAttr.getExpr();
  920. if (recordAttr)
  921. {
  922. OwnedHqlExpr record = recordAttr->getExpr();
  923. if (payloadAttr)
  924. {
  925. OwnedHqlExpr payload = payloadAttr->getExpr();
  926. checkIndexRecordType(record, 0, false, *recordAttr);
  927. checkIndexRecordType(payload, payload->numChildren(), false, *payloadAttr);
  928. modifyIndexPayloadRecord(record, payload, flags, indexAttr);
  929. }
  930. else
  931. {
  932. bool hasFileposition = getBoolAttributeInList(flags, filepositionAtom, true);
  933. unsigned numPayloadFields = hasFileposition ? 1 : 0;
  934. checkIndexRecordType(record, numPayloadFields, false, *recordAttr);
  935. }
  936. //Recalculated because it might be updated in modifyIndexPayloadRecord() above
  937. bool hasFileposition = getBoolAttributeInList(flags, filepositionAtom, true);
  938. record.setown(checkBuildIndexRecord(record.getClear(), *recordAttr));
  939. record.setown(checkIndexRecord(record, *recordAttr, flags));
  940. inputDataset.setown(createDatasetF(no_selectfields, LINK(dataset), LINK(record), NULL));
  941. warnIfRecordPacked(inputDataset, *recordAttr);
  942. }
  943. else
  944. {
  945. checkIndexRecordType(dataset->queryRecord(), 1, false, indexAttr);
  946. }
  947. HqlExprArray args;
  948. args.append(*LINK(inputDataset));
  949. args.append(*filenameAttr.getExpr());
  950. if (flags)
  951. flags->unwindList(args, no_comma);
  952. checkDistributer(flagsAttr.pos, args);
  953. return createValue(no_buildindex, makeVoidType(), args);
  954. }
  955. void HqlGram::processError(bool full)
  956. {
  957. releaseScopes();
  958. sortDepth = 0;
  959. if (full)
  960. {
  961. resetParameters();
  962. current_id = NULL;
  963. current_type = NULL;
  964. }
  965. }
  966. void HqlGram::processEnum(attribute & idAttr, IHqlExpression * value)
  967. {
  968. if (value)
  969. lastEnumValue.setown(ensureExprType(value, curEnumType));
  970. else
  971. lastEnumValue.setown(nextEnumValue());
  972. DefineIdSt * id = new DefineIdSt;
  973. id->id = idAttr.getId();
  974. id->scope = EXPORT_FLAG;
  975. doDefineSymbol(id, LINK(lastEnumValue), NULL, idAttr, idAttr.pos.position, idAttr.pos.position, false);
  976. }
  977. bool HqlGram::extractConstantString(StringBuffer & text, attribute & attr)
  978. {
  979. normalizeExpression(attr, type_string, true);
  980. OwnedHqlExpr str = attr.getExpr();
  981. if (!str->queryValue())
  982. {
  983. reportError(999, attr, "Const-foldable string expression expected");
  984. return false;
  985. }
  986. str->queryValue()->getStringValue(text);
  987. return true;
  988. }
  989. void HqlGram::processLoadXML(attribute & a1, attribute * a2)
  990. {
  991. StringBuffer s1, s2;
  992. if (extractConstantString(s1, a1))
  993. {
  994. if (a2)
  995. {
  996. if (extractConstantString(s2, *a2))
  997. lexObject->loadXML(a1, s1.str(), s2.str());
  998. }
  999. else
  1000. lexObject->loadXML(a1, s1.str());
  1001. }
  1002. }
  1003. IHqlExpression * HqlGram::processModuleDefinition(const attribute & errpos)
  1004. {
  1005. Owned<IHqlScope> scope = defineScopes.tos().localScope;
  1006. if (!scope)
  1007. scope.setown(createScope());
  1008. leaveScope(errpos);
  1009. leaveCompoundObject();
  1010. cloneInheritedAttributes(scope, errpos);
  1011. OwnedHqlExpr newScope;
  1012. try
  1013. {
  1014. newScope.setown(closeAndLink(queryExpression(scope)));
  1015. }
  1016. catch (IException * e)
  1017. {
  1018. StringBuffer s;
  1019. reportError(e->errorCode(), errpos, "%s", e->errorMessage(s).str());
  1020. e->Release();
  1021. newScope.setown(createNullScope());
  1022. }
  1023. //Implements projects the module down to the implementation type.
  1024. //It should also check the parameters match when a symbol is defined.
  1025. IHqlExpression * libraryInterface = newScope->queryAttribute(libraryAtom);
  1026. if (libraryInterface)
  1027. newScope.setown(implementInterfaceFromModule(errpos, errpos, newScope, libraryInterface->queryChild(0), libraryInterface));
  1028. return newScope.getClear();
  1029. }
  1030. IHqlExpression * HqlGram::processRowset(attribute & selectorAttr)
  1031. {
  1032. OwnedHqlExpr ds = selectorAttr.getExpr();
  1033. bool hadRows = false;
  1034. OwnedHqlExpr id;
  1035. ForEachItemInRev(i, leftRightScopes)
  1036. {
  1037. LeftRightScope & curScope = leftRightScopes.item(i);
  1038. if (curScope.rowsScope == ds)
  1039. {
  1040. id.set(curScope.rowsId);
  1041. break;
  1042. }
  1043. else if (curScope.rowsScope)
  1044. hadRows = true;
  1045. }
  1046. if (!id)
  1047. {
  1048. if (!hadRows)
  1049. reportError(ERR_LEFT_ILL_HERE, selectorAttr, "ROWSET not legal here");
  1050. else
  1051. reportError(ERR_LEFT_ILL_HERE, selectorAttr, "ROWSET not legal on this dataset");
  1052. OwnedHqlExpr selSeq = createDummySelectorSequence();
  1053. ds.setown(createSelector(no_left, queryNullRecord(), selSeq));
  1054. }
  1055. OwnedHqlExpr rows = createDataset(no_rows, LINK(ds), LINK(id));
  1056. return createValue(no_rowset, makeSetType(rows->getType()), LINK(rows));
  1057. }
  1058. void HqlGram::processServiceFunction(const attribute & idAttr, IIdAtom * name, IHqlExpression * thisAttrs, ITypeInfo * type)
  1059. {
  1060. setParametered(true);
  1061. IHqlExpression *attrs = createComma(LINK(thisAttrs), LINK(defaultServiceAttrs));
  1062. attrs = checkServiceDef(serviceScope,name,attrs,idAttr);
  1063. bool oldSetFormat = queryAttributeInList(oldSetFormatAtom, attrs) != NULL;
  1064. IHqlExpression *call = createExternalReference(name, LINK(type), attrs);
  1065. IHqlExpression * formals = defineScopes.tos().createFormals(oldSetFormat);
  1066. IHqlExpression * defaults = defineScopes.tos().createDefaults();
  1067. IHqlExpression * func = createFunctionDefinition(name, call, formals, defaults, NULL);
  1068. serviceScope->defineSymbol(name, NULL, func, true, false, 0, NULL, idAttr.pos.lineno, idAttr.pos.column, 0, 0, 0);
  1069. resetParameters();
  1070. }
  1071. void HqlGram::processStartTransform(const attribute & errpos)
  1072. {
  1073. Linked<ITypeInfo> transformType = queryCurrentRecordType();
  1074. if (!transformType || !queryRecordType(transformType))
  1075. {
  1076. // bad type: hard to recover
  1077. StringBuffer msg("TRANSFORM must have a record return type: ");
  1078. if (!current_type)
  1079. msg.append("<none> is given");
  1080. else
  1081. getFriendlyTypeStr(current_type, msg).append(" is given");
  1082. reportError(ERR_TRANS_RECORDTYPE, errpos, "%s", msg.str());
  1083. reportError(ERR_PARSER_CANNOTRECOVER,errpos,"Can not recover from previous error(s) - aborting compilation");
  1084. abortParsing();
  1085. transformType.set(queryNullRecord()->queryType());
  1086. }
  1087. if (false)
  1088. {
  1089. ITypeInfo * original = queryModifier(current_type, typemod_original);
  1090. if (original && !queryModifier(transformType, typemod_original))
  1091. {
  1092. IHqlExpression * originalExpr = (IHqlExpression *)original->queryModifierExtra();
  1093. transformType.setown(makeOriginalModifier(transformType.getClear(), LINK(originalExpr)));
  1094. }
  1095. }
  1096. openTransform(transformType);
  1097. }
  1098. void HqlGram::enterEnum(const attribute & errpos, ITypeInfo * type)
  1099. {
  1100. if (!isIntegralType(type))
  1101. {
  1102. StringBuffer s;
  1103. reportError(ERR_TYPEMISMATCH_INT, errpos, "Integer type expected (%s was given)", getFriendlyTypeStr(type, s).str());
  1104. }
  1105. enterScope(true);
  1106. enterCompoundObject();
  1107. curEnumType.set(type);
  1108. lastEnumValue.setown(createConstant(curEnumType->castFrom(true, 0)));
  1109. }
  1110. void HqlGram::setEnumType(const attribute & errpos, ITypeInfo * type)
  1111. {
  1112. if (!isIntegralType(type))
  1113. {
  1114. StringBuffer s;
  1115. reportError(ERR_TYPEMISMATCH_INT, errpos, "Integer type expected (%s was given)", getFriendlyTypeStr(type, s).str());
  1116. }
  1117. curEnumType.set(type);
  1118. lastEnumValue.setown(createConstant(curEnumType->castFrom(true, 0)));
  1119. }
  1120. IHqlExpression * HqlGram::leaveEnum(const attribute & errpos)
  1121. {
  1122. IHqlScope * enumScope = LINK(defineScopes.tos().localScope);
  1123. leaveScope(errpos);
  1124. leaveCompoundObject();
  1125. return createEnumType(curEnumType.getClear(), closeScope(enumScope));
  1126. }
  1127. IHqlExpression * HqlGram::nextEnumValue()
  1128. {
  1129. IValue * value = lastEnumValue->queryValue();
  1130. if (value)
  1131. return createConstant(curEnumType->castFrom(true, value->getIntValue()+1));
  1132. return createValue(no_add, LINK(curEnumType), LINK(lastEnumValue), createConstant(curEnumType->castFrom(true, 1)));
  1133. }
  1134. void HqlGram::enterService(attribute & attrs)
  1135. {
  1136. enterScope(false); // preserve parameters
  1137. serviceScope.setown(createService());
  1138. defaultServiceAttrs.setown(attrs.getExpr());
  1139. }
  1140. IHqlExpression * HqlGram::leaveService(const attribute & errpos)
  1141. {
  1142. defaultServiceAttrs.clear();
  1143. IHqlExpression* svc = QUERYINTERFACE(serviceScope.getClear(), IHqlExpression);
  1144. if (svc)
  1145. svc = svc->closeExpr();
  1146. leaveScope(errpos);
  1147. return svc;
  1148. }
  1149. //-----------------------------------------------------------------------------
  1150. /* this func does not affect linkage */
  1151. /* Assume: field is of the form: (((self.r1).r2...).rn). */
  1152. IHqlExpression * HqlGram::findAssignment(IHqlExpression *field)
  1153. {
  1154. // assertex(field->getOperator() == no_select);
  1155. #ifdef FAST_FIND_FIELD
  1156. IHqlExpression * match = (IHqlExpression *)field->queryTransformExtra();
  1157. if (match && !match->isAttribute())
  1158. return match;
  1159. return NULL;
  1160. #else
  1161. unsigned kids = curTransform->numChildren();
  1162. for (unsigned idx = 0; idx < kids; idx++)
  1163. {
  1164. IHqlExpression *kid = curTransform->queryChild(idx);
  1165. IHqlExpression * ret = doFindAssignment(kid,field);
  1166. if (ret)
  1167. return ret;
  1168. }
  1169. return NULL;
  1170. #endif
  1171. }
  1172. IHqlExpression * HqlGram::doFindAssignment(IHqlExpression* in, IHqlExpression* field)
  1173. {
  1174. switch (in->getOperator())
  1175. {
  1176. case no_assign:
  1177. if (in->queryChild(0) == field)
  1178. return in->queryChild(1);
  1179. return NULL;
  1180. case no_assignall:
  1181. {
  1182. unsigned kids = in->numChildren();
  1183. for (unsigned idx = 0; idx < kids; idx++)
  1184. {
  1185. IHqlExpression *kid = in->queryChild(idx);
  1186. IHqlExpression * ret = doFindAssignment(kid,field);
  1187. if (ret)
  1188. return ret;
  1189. }
  1190. }
  1191. break;
  1192. case no_attr:
  1193. case no_attr_link:
  1194. case no_attr_expr:
  1195. return NULL;
  1196. default:
  1197. assertex(false);
  1198. }
  1199. return NULL;
  1200. }
  1201. /* All in parms will be consumed by this function */
  1202. void HqlGram::addAssignment(attribute & target, attribute &source)
  1203. {
  1204. OwnedHqlExpr targetExpr = target.getExpr();
  1205. OwnedHqlExpr srcExpr = source.getExpr();
  1206. if (!srcExpr) // something bad just happened.
  1207. return;
  1208. node_operator targetOp = targetExpr->getOperator();
  1209. if (targetOp ==no_self) // self := expr;
  1210. {
  1211. ITypeInfo* type = srcExpr->queryType();
  1212. if (!type)
  1213. type = queryCurrentTransformType();
  1214. switch(type->getTypeCode())
  1215. {
  1216. case type_record:
  1217. case type_row:
  1218. addAssignall(targetExpr.getClear(), srcExpr.getClear(), target);
  1219. break;
  1220. default:
  1221. {
  1222. StringBuffer msg("Can not assign non-record type ");
  1223. getFriendlyTypeStr(type, msg).append(" to self");
  1224. reportError(ERR_TRANS_ILLASSIGN2SELF, target, "%s", msg.str());
  1225. }
  1226. }
  1227. }
  1228. else if (targetOp == no_select)
  1229. {
  1230. // self.* := expr; assertex(targetExpr->getOperator()==no_select);
  1231. if (findAssignment(targetExpr))
  1232. {
  1233. StringBuffer s;
  1234. reportError(ERR_VALUEDEFINED, target, "A value for \"%s\" has already been specified", getFldName(targetExpr,s).str());
  1235. }
  1236. else if (targetExpr->queryType()->getTypeCode() == type_row)
  1237. {
  1238. //assertex(srcExpr->getOperator() == no_null);
  1239. addAssignall(targetExpr.getClear(), srcExpr.getClear(), target);
  1240. }
  1241. else
  1242. doAddAssignment(curTransform, targetExpr.getClear(), srcExpr.getClear(), target);
  1243. }
  1244. //else error occurred somewhere else
  1245. }
  1246. void HqlGram::addAssignment(const attribute & errpos, IHqlExpression * targetExpr, IHqlExpression * srcExpr)
  1247. {
  1248. if (!srcExpr) // something bad just happened.
  1249. return;
  1250. node_operator targetOp = targetExpr->getOperator();
  1251. if (targetOp ==no_self) // self := expr;
  1252. {
  1253. ITypeInfo* type = srcExpr->queryType();
  1254. if (!type)
  1255. type = queryCurrentTransformType();
  1256. switch(type->getTypeCode())
  1257. {
  1258. case type_record:
  1259. case type_row:
  1260. addAssignall(LINK(targetExpr), LINK(srcExpr), errpos);
  1261. break;
  1262. default:
  1263. {
  1264. StringBuffer msg("Can not assign non-record type ");
  1265. getFriendlyTypeStr(type, msg).append(" to self");
  1266. reportError(ERR_TRANS_ILLASSIGN2SELF, errpos, "%s", msg.str());
  1267. }
  1268. }
  1269. }
  1270. else if (targetOp == no_select)
  1271. {
  1272. // self.* := expr; assertex(targetExpr->getOperator()==no_select);
  1273. if (findAssignment(targetExpr))
  1274. {
  1275. StringBuffer s;
  1276. reportError(ERR_VALUEDEFINED, errpos, "A value for \"%s\" has already been specified", getFldName(targetExpr,s).str());
  1277. }
  1278. else if (targetExpr->queryType()->getTypeCode() == type_row)
  1279. {
  1280. //assertex(srcExpr->getOperator() == no_null);
  1281. addAssignall(LINK(targetExpr), LINK(srcExpr), errpos);
  1282. }
  1283. else
  1284. doAddAssignment(curTransform, LINK(targetExpr), LINK(srcExpr), errpos);
  1285. }
  1286. //else error occurred somewhere else
  1287. }
  1288. class SelfReferenceReplacer
  1289. {
  1290. public:
  1291. SelfReferenceReplacer(IHqlExpression * transform, IHqlExpression * _self) : self(_self)
  1292. {
  1293. lockTransformMutex();
  1294. expandTransformAssigns(transform);
  1295. }
  1296. ~SelfReferenceReplacer()
  1297. {
  1298. unlockTransformMutex();
  1299. }
  1300. IHqlExpression * replaceExpression(IHqlExpression * expr)
  1301. {
  1302. ok = true;
  1303. return recursiveReplaceExpression(expr);
  1304. }
  1305. inline bool allFieldsReplaced() { return ok; }
  1306. protected:
  1307. IHqlExpression * doRecursiveReplaceExpression(IHqlExpression * expr)
  1308. {
  1309. IHqlExpression * body = expr->queryBody();
  1310. if (expr != body)
  1311. {
  1312. OwnedHqlExpr mapped = recursiveReplaceExpression(body);
  1313. if (mapped == body)
  1314. return LINK(expr);
  1315. return expr->cloneAllAnnotations(mapped);
  1316. }
  1317. if (expr == self)
  1318. ok = false;
  1319. unsigned max = expr->numChildren();
  1320. if (max == 0)
  1321. return LINK(expr);
  1322. switch (expr->getOperator())
  1323. {
  1324. case no_attr:
  1325. case no_attr_expr:
  1326. case no_left:
  1327. case no_right:
  1328. case no_field:
  1329. case no_record:
  1330. return LINK(expr);
  1331. case no_assign:
  1332. {
  1333. //The following optimization would be required if we ever supported recursive records.
  1334. IHqlExpression * lhs = expr->queryChild(0);
  1335. IHqlExpression * rhs = expr->queryChild(1);
  1336. return createAssign(LINK(lhs), recursiveReplaceExpression(rhs));
  1337. }
  1338. }
  1339. bool same = true;
  1340. HqlExprArray args;
  1341. for (unsigned i=0; i< max; i++)
  1342. {
  1343. IHqlExpression * cur = expr->queryChild(i);
  1344. IHqlExpression * tr = recursiveReplaceExpression(cur);
  1345. args.append(*tr);
  1346. if (cur != tr)
  1347. same = false;
  1348. }
  1349. if (same)
  1350. return LINK(expr);
  1351. return expr->clone(args);
  1352. }
  1353. IHqlExpression * recursiveReplaceExpression(IHqlExpression * expr)
  1354. {
  1355. IHqlExpression * mapped = (IHqlExpression *)expr->queryTransformExtra();
  1356. if (mapped)
  1357. return LINK(mapped);
  1358. IHqlExpression * ret = doRecursiveReplaceExpression(expr);
  1359. expr->setTransformExtra(ret);
  1360. return ret;
  1361. }
  1362. void expandTransformAssigns(IHqlExpression * expr)
  1363. {
  1364. ForEachChild(i, expr)
  1365. {
  1366. IHqlExpression * cur = expr->queryChild(i);
  1367. switch (cur->getOperator())
  1368. {
  1369. case no_transform:
  1370. case no_newtransform:
  1371. case no_assignall:
  1372. expandTransformAssigns(cur);
  1373. break;
  1374. case no_assign:
  1375. {
  1376. IHqlExpression * tgt = cur->queryChild(0);
  1377. OwnedHqlExpr castRhs = ensureExprType(cur->queryChild(1), tgt->queryType());
  1378. tgt->setTransformExtraOwned(castRhs.getClear());
  1379. break;
  1380. }
  1381. }
  1382. }
  1383. }
  1384. protected:
  1385. LinkedHqlExpr self;
  1386. bool ok;
  1387. };
  1388. IHqlExpression * HqlGram::replaceSelfReferences(IHqlExpression * transform, IHqlExpression * rhs, IHqlExpression * self, const attribute& errpos)
  1389. {
  1390. //MORE: This could be done more efficiently by replacing all the self references in a single pass
  1391. //would need to tag assigns in the transform, and process incrementally at the end.
  1392. //Seems to be fast enough anyway at the moment.
  1393. SelfReferenceReplacer replacer(transform, self);
  1394. OwnedHqlExpr ret = replacer.replaceExpression(rhs);
  1395. if (!replacer.allFieldsReplaced())
  1396. reportError(ERR_SELF_ILL_HERE, errpos, "Reference to field in SELF that has not yet been defined");
  1397. return ret.getClear();
  1398. }
  1399. /* all in parms: linked */
  1400. void HqlGram::doAddAssignment(IHqlExpression * transform, IHqlExpression * _field, IHqlExpression * _rhs, const attribute& errpos)
  1401. {
  1402. //The arguments really shouldn't be linked
  1403. OwnedHqlExpr field = _field;
  1404. OwnedHqlExpr rhs = _rhs;
  1405. assertex(field->getOperator()==no_select);
  1406. if (containsSkip(rhs) && field->queryChild(0)->getOperator() != no_self)
  1407. reportError(ERR_SKIP_IN_NESTEDCHILD, errpos, "SKIP in an assignment to a field in a nested record is not supported");
  1408. if (containsSelf(rhs))
  1409. {
  1410. OwnedHqlExpr self = getSelf(curTransform);
  1411. rhs.setown(replaceSelfReferences(curTransform, rhs, self, errpos));
  1412. }
  1413. //
  1414. // type checking
  1415. ITypeInfo* fldType = field->queryType();
  1416. Owned<ITypeInfo> rhsType = rhs->getType();
  1417. if (!rhsType) // this happens when rhs is no_null.
  1418. rhsType.set(fldType);
  1419. // handle alien type
  1420. if (rhsType->getTypeCode() == type_alien)
  1421. {
  1422. IHqlAlienTypeInfo * alien = queryAlienType(rhsType);
  1423. rhsType.setown(alien->getLogicalType());
  1424. }
  1425. if (!fldType->assignableFrom(rhsType))
  1426. {
  1427. StringBuffer msg("Can not assign ");
  1428. getFriendlyTypeStr(rhsType,msg).append(" to ");
  1429. getFriendlyTypeStr(fldType,msg).append(" (field ");
  1430. getFldName(field,msg).append(")");
  1431. reportError(ERR_TYPE_INCOMPATIBLE,errpos, "%s", msg.str());
  1432. rhs.setown(createNullExpr(field));
  1433. }
  1434. appendTransformAssign(transform, field, rhs, errpos);
  1435. }
  1436. void HqlGram::appendTransformAssign(IHqlExpression * transform, IHqlExpression * to, IHqlExpression * _from, const attribute& errpos)
  1437. {
  1438. LinkedHqlExpr from = _from;
  1439. if (isNull(from))
  1440. from.setown(createNullExpr(to));
  1441. else if (from->isConstant())
  1442. from.setown(ensureExprType(from, to->queryType()));
  1443. if (to->isDataset() && !recordTypesMatch(from, to))
  1444. {
  1445. //Fields are assignment compatible, but not the same => project down to the target field.
  1446. if (from->queryRecord()) // project against cascading errors
  1447. from.setown(createDefaultProjectDataset(to->queryRecord(), from, errpos));
  1448. }
  1449. IHqlExpression * assign = createAssign(LINK(to), LINK(from));
  1450. if (okToAddLocation(assign))
  1451. assign = createLocationAnnotation(assign, errpos.pos);
  1452. transform->addOperand(assign);
  1453. #ifdef FAST_FIND_FIELD
  1454. to->setTransformExtraOwned(from.getClear());
  1455. IHqlExpression * parent = to->queryChild(0);
  1456. while ((parent->getOperator() == no_select) && !parent->queryTransformExtra())
  1457. {
  1458. parent->setTransformExtra(alreadyAssignedNestedTag);
  1459. parent = parent->queryChild(0);
  1460. }
  1461. #endif
  1462. }
  1463. IHqlExpression * HqlGram::forceEnsureExprType(IHqlExpression * expr, ITypeInfo * type)
  1464. {
  1465. //Ensure the no_outofline remains the top most node. I suspect this casting should occur much earlier
  1466. //or the out of line node should be added much later.
  1467. if (expr->getOperator() == no_outofline)
  1468. {
  1469. HqlExprArray args;
  1470. args.append(*forceEnsureExprType(expr->queryChild(0), type));
  1471. unwindChildren(args, expr, 1);
  1472. return expr->clone(args);
  1473. }
  1474. OwnedHqlExpr ret = ensureExprType(expr, type);
  1475. if (ret->queryType() == type)
  1476. return ret.getClear();
  1477. return createValue(no_implicitcast, LINK(type), LINK(ret));
  1478. }
  1479. //===================== Collective assignment ==================================//
  1480. /* All in parms: linked */
  1481. static bool containsSelect(IHqlExpression * expr, IHqlExpression * ds)
  1482. {
  1483. loop
  1484. {
  1485. if (expr == ds)
  1486. return true;
  1487. if (expr->getOperator() != no_select)
  1488. return false;
  1489. expr = expr->queryChild(0);
  1490. }
  1491. }
  1492. /*
  1493. static bool doHaveAssignedToChildren(IHqlExpression * select, IHqlExpression * record)
  1494. {
  1495. ForEachChild(i, record)
  1496. {
  1497. IHqlExpression * cur = record->queryChild(i);
  1498. switch (cur->getOperator())
  1499. {
  1500. case no_ifblock:
  1501. if (doHaveAssignedToChildren(select, cur->queryChild(1)))
  1502. return true;
  1503. break;
  1504. case no_field:
  1505. {
  1506. OwnedHqlExpr selected = createSelectExpr(LINK(select), LINK(cur));
  1507. if (findAssignment(selected))
  1508. return true;
  1509. IHqlExpression * child = cur->queryRecord();
  1510. if (selected->isDatarow() && doHaveAssignedToChildren(selected, cur->queryRecord()))
  1511. return true;
  1512. break;
  1513. }
  1514. }
  1515. }
  1516. }
  1517. bool newhaveAssignedToChildren(IHqlExpression * select, IHqlExpression * transform)
  1518. {
  1519. return doHaveAssignedToChildren(select, select->queryRecord());
  1520. }
  1521. */
  1522. bool haveAssignedToChildren(IHqlExpression * select, IHqlExpression * transform)
  1523. {
  1524. ForEachChild(i, transform)
  1525. {
  1526. IHqlExpression * assign = transform->queryChild(i);
  1527. switch (assign->getOperator())
  1528. {
  1529. case no_assign:
  1530. if (containsSelect(assign->queryChild(0), select))
  1531. return true;
  1532. break;
  1533. case no_assignall:
  1534. if (haveAssignedToChildren(select, assign))
  1535. return true;
  1536. break;
  1537. IHqlExpression * child0 = assign->queryChild(0);
  1538. //Only need to check the first subfield, or field of originalAttr
  1539. //if (haveAssignedToChildren(select, assign))
  1540. if (child0 && containsSelect(child0->queryChild(0), select))
  1541. return true;
  1542. break;
  1543. }
  1544. }
  1545. return false;
  1546. }
  1547. bool HqlGram::haveAssignedToChildren(IHqlExpression * select)
  1548. {
  1549. #ifdef FAST_FIND_FIELD
  1550. return select->queryTransformExtra() == alreadyAssignedNestedTag;
  1551. #else
  1552. return ::haveAssignedToChildren(select, curTransform);
  1553. #endif
  1554. }
  1555. void HqlGram::addAssignall(IHqlExpression *tgt, IHqlExpression *src, const attribute& errpos)
  1556. {
  1557. assertex(src);
  1558. node_operator tgtOp = tgt->getOperator();
  1559. if ((tgtOp == no_select) && findAssignment(tgt))
  1560. {
  1561. StringBuffer s;
  1562. reportError(ERR_VALUEDEFINED, errpos, "A value for \"%s\" has already been specified", getFldName(tgt,s).str());
  1563. }
  1564. IHqlExpression * srcRecord = src->queryRecord();
  1565. IHqlExpression * tgtRecord = tgt->queryRecord();
  1566. if (srcRecord && tgtRecord && recordTypesMatch(srcRecord, tgtRecord) && (tgtOp != no_self) && !haveAssignedToChildren(tgt))
  1567. {
  1568. doAddAssignment(curTransform, tgt, src, errpos);
  1569. return;
  1570. }
  1571. IHqlExpression *assignall = createOpenValue(no_assignall, NULL);
  1572. //Should always add, but I don't want to cause persists to rebuild...
  1573. unsigned firstAssign = 0;
  1574. if (tgtOp != no_self)
  1575. {
  1576. assignall->addOperand(createAttribute(_original_Atom, LINK(tgt), LINK(src))); //only used for regeneration
  1577. firstAssign++;
  1578. }
  1579. doAddAssignCompoundOwn(assignall, tgt, src, NULL, errpos);
  1580. assignall = assignall->closeExpr();
  1581. if (assignall->numChildren() > firstAssign)
  1582. curTransform->addOperand(assignall);
  1583. else
  1584. assignall->Release();
  1585. }
  1586. IHqlExpression * HqlGram::createDefaultAssignTransform(IHqlExpression * record, IHqlExpression * rowValue, const attribute & errpos)
  1587. {
  1588. Owned<ITypeInfo> type = createRecordType(record);
  1589. beginTransform(type);
  1590. pushSelfScope(type);
  1591. addAssignall(getSelfScope(), LINK(rowValue), errpos);
  1592. return closeTransform(errpos);
  1593. }
  1594. IHqlExpression * HqlGram::createDefaultProjectDataset(IHqlExpression * record, IHqlExpression * src, const attribute & errpos)
  1595. {
  1596. OwnedHqlExpr seq = createActiveSelectorSequence(src, NULL);
  1597. OwnedHqlExpr left = createSelector(no_left, src, seq);
  1598. OwnedHqlExpr transform = createDefaultAssignTransform(record, left, errpos);
  1599. return createDatasetF(no_hqlproject, ::ensureDataset(src), LINK(transform), LINK(seq), NULL);
  1600. }
  1601. void HqlGram::doAddAssignCompound(IHqlExpression * assignall, IHqlExpression * target, IHqlExpression * src, IHqlExpression * record, const attribute& errpos)
  1602. {
  1603. if (!record) record = target->queryRecord();
  1604. if (!record)
  1605. {
  1606. StringBuffer name;
  1607. reportError(ERR_TYPEMISMATCH_RECORD, errpos, "Cannot assign a row to field %s", getFldName(target, name).str());
  1608. return;
  1609. }
  1610. IHqlExpression * srcRecord = src->queryRecord();
  1611. if (!srcRecord)
  1612. {
  1613. if (src->getOperator() == no_null)
  1614. srcRecord = record;
  1615. else
  1616. {
  1617. StringBuffer name;
  1618. reportError(ERR_TYPEMISMATCH_RECORD, errpos, "Cannot assign a field to row %s", getFldName(target, name).str());
  1619. return;
  1620. }
  1621. }
  1622. IHqlSimpleScope *srcScope = srcRecord->querySimpleScope();
  1623. unsigned numChildren = record->numChildren();
  1624. for (unsigned idx = 0; idx < numChildren; idx++)
  1625. {
  1626. IHqlExpression *subfield = record->queryChild(idx);
  1627. switch (subfield->getOperator())
  1628. {
  1629. case no_ifblock:
  1630. doAddAssignCompound(assignall, target, src, subfield->queryChild(1), errpos);
  1631. break;
  1632. case no_record:
  1633. doAddAssignCompound(assignall, target, src, subfield, errpos);
  1634. break;
  1635. case no_field:
  1636. {
  1637. IHqlExpression *match = srcScope->lookupSymbol(subfield->queryId());
  1638. if (!match)
  1639. continue;
  1640. OwnedHqlExpr lhs = createSelectExpr(LINK(target),LINK(subfield));
  1641. OwnedHqlExpr rhs;
  1642. if (src->getOperator() == no_null)
  1643. {
  1644. rhs.set(src);
  1645. match->Release();
  1646. }
  1647. else
  1648. rhs.setown(createSelectExpr(LINK(src),match));
  1649. if (!findAssignment(lhs))
  1650. {
  1651. IHqlExpression * srcRecord = rhs->queryRecord();
  1652. IHqlExpression * tgtRecord = lhs->queryRecord();
  1653. type_t tc = subfield->queryType()->getTypeCode();
  1654. assertex(tc != type_record);
  1655. if (tc == type_row)
  1656. {
  1657. IHqlExpression * tgtRecord = lhs->queryRecord();
  1658. if (tgtRecord && !haveAssignedToChildren(lhs))
  1659. {
  1660. IHqlExpression * srcRecord = rhs->queryRecord();
  1661. if (false && (rhs->getOperator() == no_null) && !srcRecord)
  1662. {
  1663. OwnedHqlExpr nullRow = createRow(no_createrow, createClearTransform(tgtRecord, errpos));
  1664. // OwnedHqlExpr nullRow = createRow(no_null, LINK(tgtRecord));
  1665. doAddAssignment(assignall,LINK(lhs),LINK(nullRow),errpos);
  1666. }
  1667. else if (srcRecord && recordTypesMatch(srcRecord, tgtRecord))
  1668. doAddAssignment(assignall,LINK(lhs),LINK(rhs),errpos);
  1669. else
  1670. doAddAssignCompound(assignall,lhs,rhs,NULL,errpos);
  1671. }
  1672. else
  1673. doAddAssignCompound(assignall,lhs,rhs,NULL,errpos);
  1674. }
  1675. else if (tc == type_table || tc == type_groupedtable)
  1676. {
  1677. if (srcRecord && tgtRecord && !recordTypesMatch(srcRecord, tgtRecord))
  1678. {
  1679. OwnedHqlExpr project = createDefaultProjectDataset(tgtRecord, rhs, errpos);
  1680. if (project)
  1681. rhs.set(project);
  1682. }
  1683. doAddAssignment(assignall,LINK(lhs),LINK(rhs),errpos);
  1684. }
  1685. else
  1686. doAddAssignment(assignall,LINK(lhs),LINK(rhs),errpos);
  1687. }
  1688. }
  1689. }
  1690. }
  1691. }
  1692. void HqlGram::doAddAssignCompoundOwn(IHqlExpression * assignall, IHqlExpression * target, IHqlExpression * src, IHqlExpression * record, const attribute& errpos)
  1693. {
  1694. doAddAssignCompound(assignall, target, src, record, errpos);
  1695. ::Release(target);
  1696. ::Release(src);
  1697. }
  1698. void HqlGram::doAddAssignSelf(IHqlExpression * assignall, IHqlExpression * field, IHqlExpression * src, const attribute& errpos)
  1699. {
  1700. doAddAssignCompoundOwn(assignall, getSelf(curTransform), src, field, errpos);
  1701. }
  1702. IHqlExpression * HqlGram::createRowAssignTransform(const attribute & srcAttr, const attribute & tgtAttr, const attribute & seqAttr)
  1703. {
  1704. IHqlExpression * src = srcAttr.queryExpr();
  1705. IHqlExpression * res_rec = tgtAttr.queryExpr();
  1706. // create transform
  1707. beginTransform(res_rec->queryRecordType());
  1708. // self := left;
  1709. IHqlExpression *assignall = createOpenValue(no_assignall, NULL);
  1710. doAddAssignSelf(assignall, res_rec->queryRecord(), createSelector(no_left, src, seqAttr.queryExpr()), tgtAttr);
  1711. curTransform->addOperand(assignall->closeExpr());
  1712. // close transform
  1713. checkAllAssigned(res_rec, srcAttr);
  1714. return endTransform(srcAttr);
  1715. }
  1716. IHqlExpression * HqlGram::createClearTransform(IHqlExpression * record, const attribute & errpos)
  1717. {
  1718. OwnedHqlExpr null = createValue(no_null);
  1719. return createDefaultAssignTransform(record, null, errpos);
  1720. }
  1721. ITypeInfo *HqlGram::queryCurrentRecordType()
  1722. {
  1723. return ::queryRecordType(current_type);
  1724. }
  1725. ITypeInfo *HqlGram::queryCurrentTransformType()
  1726. {
  1727. if (curTransform)
  1728. return curTransform->queryRecordType();
  1729. return NULL;
  1730. }
  1731. IHqlExpression *HqlGram::queryCurrentTransformRecord()
  1732. {
  1733. ITypeInfo *t = queryCurrentTransformType();
  1734. if (t)
  1735. return queryExpression(t);
  1736. return NULL;
  1737. }
  1738. /* Linkage: not affected */
  1739. void HqlGram::checkAssignedNormalizeTransform(IHqlExpression * record, const attribute &errpos)
  1740. {
  1741. OwnedHqlExpr self = getSelf(record);
  1742. bool modified = false;
  1743. if (recordContainsNestedRecord(record))
  1744. {
  1745. HqlExprArray assigns;
  1746. doCheckAssignedNormalizeTransform(&assigns, self, self, record, errpos, modified);
  1747. if (modified)
  1748. {
  1749. IHqlExpression * newTransform = createOpenValue(no_transform, curTransform->getType());
  1750. ForEachChild(i, curTransform)
  1751. {
  1752. IHqlExpression * cur = curTransform->queryChild(i);
  1753. switch (cur->getOperator())
  1754. {
  1755. case no_assign:
  1756. case no_assignall:
  1757. break;
  1758. default:
  1759. assigns.append(*LINK(cur));
  1760. break;
  1761. }
  1762. }
  1763. ForEachItemIn(i2, assigns)
  1764. newTransform->addOperand(LINK(&assigns.item(i2)));
  1765. curTransform->closeExpr()->Release();
  1766. curTransform = newTransform;
  1767. }
  1768. }
  1769. else
  1770. doCheckAssignedNormalizeTransform(NULL, self, self, record, errpos, modified);
  1771. }
  1772. static bool isNullDataset(IHqlExpression * expr)
  1773. {
  1774. switch (expr->getOperator())
  1775. {
  1776. case no_null:
  1777. return true;
  1778. case no_temptable:
  1779. {
  1780. IHqlExpression * child = expr->queryChild(0);
  1781. return isNullList(child);
  1782. }
  1783. case no_inlinetable:
  1784. return (expr->queryChild(0)->numChildren() == 0);
  1785. }
  1786. return false;
  1787. }
  1788. void HqlGram::doCheckAssignedNormalizeTransform(HqlExprArray * assigns, IHqlExpression* select, IHqlExpression* targetSelect, IHqlExpression * cur, const attribute& errpos, bool & modified)
  1789. {
  1790. switch (cur->getOperator())
  1791. {
  1792. case no_record:
  1793. {
  1794. ForEachChild(i, cur)
  1795. doCheckAssignedNormalizeTransform(assigns, select, targetSelect, cur->queryChild(i), errpos, modified);
  1796. break;
  1797. }
  1798. case no_ifblock:
  1799. doCheckAssignedNormalizeTransform(assigns, select, targetSelect, cur->queryChild(1), errpos, modified);
  1800. break;
  1801. case no_field:
  1802. {
  1803. OwnedHqlExpr selected = createSelectExpr(LINK(select), LINK(cur));
  1804. OwnedHqlExpr targetSelected = createSelectExpr(LINK(targetSelect), LINK(cur));
  1805. IHqlExpression * match = findAssignment(selected);
  1806. if (match)
  1807. {
  1808. if (assigns)
  1809. assigns->append(*createAssign(LINK(targetSelected), LINK(match)));
  1810. }
  1811. else
  1812. {
  1813. type_t tc = cur->queryType()->getTypeCode();
  1814. assertex(tc != type_record);
  1815. if (tc == type_row)
  1816. {
  1817. IHqlExpression * record = cur->queryRecord();
  1818. OwnedHqlExpr self = getSelf(record);
  1819. if (assigns)
  1820. {
  1821. //create a new nested project.
  1822. HqlExprArray subAssigns;
  1823. doCheckAssignedNormalizeTransform(&subAssigns, selected, self, record, errpos, modified);
  1824. OwnedHqlExpr newTransform = createValue(no_transform, makeTransformType(record->getType()), subAssigns);
  1825. OwnedHqlExpr newValue = createRow(no_createrow, newTransform.getClear());
  1826. assigns->append(*createAssign(LINK(targetSelected), LINK(newValue)));
  1827. modified = true;
  1828. }
  1829. else
  1830. doCheckAssignedNormalizeTransform(NULL, selected, self, record, errpos, modified);
  1831. }
  1832. else
  1833. {
  1834. IHqlExpression * child0 = queryRealChild(cur, 0);
  1835. if (child0 && (child0->isConstant() || isNullDataset(child0)))
  1836. {
  1837. OwnedHqlExpr castChild = ensureExprType(child0, targetSelected->queryType());
  1838. if (assigns)
  1839. assigns->append(*createAssign(LINK(targetSelected), LINK(castChild)));
  1840. else
  1841. appendTransformAssign(curTransform, targetSelected, castChild, errpos);
  1842. modified = true;
  1843. }
  1844. else if (!insideTemplateFunction())
  1845. {
  1846. StringBuffer fldName;
  1847. getFldName(selected,fldName);
  1848. //Not very nice - only ok in some situations....
  1849. if (cur->hasAttribute(virtualAtom))
  1850. {
  1851. reportWarning(CategorySyntax, ERR_TRANS_NOVALUE4FIELD, errpos.pos, "Transform does not supply a value for field \"%s\"", fldName.str());
  1852. OwnedHqlExpr null = createNullExpr(cur);
  1853. if (assigns)
  1854. assigns->append(*createAssign(LINK(targetSelected), LINK(null)));
  1855. else
  1856. appendTransformAssign(curTransform, targetSelected, null, errpos);
  1857. }
  1858. else
  1859. reportError(ERR_TRANS_NOVALUE4FIELD, errpos, "Transform does not supply a value for field \"%s\"", fldName.str());
  1860. }
  1861. }
  1862. }
  1863. break;
  1864. }
  1865. case no_attr:
  1866. case no_attr_link:
  1867. case no_attr_expr:
  1868. break;
  1869. }
  1870. }
  1871. void HqlGram::checkAllAssigned(IHqlExpression * record, const attribute &errpos)
  1872. {
  1873. checkAssignedNormalizeTransform(record, errpos);
  1874. }
  1875. void HqlGram::checkFoldConstant(attribute & attr)
  1876. {
  1877. Owned<IHqlExpression> expr = attr.getExpr();
  1878. attr.setExpr(foldHqlExpression(expr), attr);
  1879. checkConstant(attr);
  1880. }
  1881. IHqlExpression * HqlGram::checkConstant(const attribute & errpos, IHqlExpression * expr)
  1882. {
  1883. if (expr->isConstant() || (expr->getOperator() == no_assertconstant))
  1884. return LINK(expr);
  1885. return createValue(no_assertconstant, expr->getType(), LINK(expr), createLocationAttr(errpos));
  1886. }
  1887. void HqlGram::checkConstant(attribute & attr)
  1888. {
  1889. OwnedHqlExpr value = attr.getExpr();
  1890. attr.setExpr(checkConstant(attr, value));
  1891. }
  1892. void HqlGram::checkInlineDatasetOptions(const attribute & attr)
  1893. {
  1894. IHqlExpression * options = attr.queryExpr();
  1895. unsigned optionCount = 0;
  1896. if (queryAttributeInList(distributedAtom, options))
  1897. optionCount++;
  1898. if (queryAttributeInList(localAtom, options))
  1899. optionCount++;
  1900. if (queryAttributeInList(noLocalAtom, options))
  1901. optionCount++;
  1902. if (optionCount > 1)
  1903. reportError(ERR_DSPARAM_INVALIDOPTCOMB, attr, "The DATASET options DISTRIBUTED, LOCAL, and NOLOCAL cannot be combined.");
  1904. }
  1905. IHqlExpression * HqlGram::checkConcreteModule(const attribute & errpos, IHqlExpression * expr)
  1906. {
  1907. return checkCreateConcreteModule(this, expr, errpos.pos);
  1908. }
  1909. void HqlGram::checkConstantEvent(attribute & attr)
  1910. {
  1911. IHqlExpression * event = attr.queryExpr();
  1912. if (!event->queryChild(0)->isConstant())
  1913. reportError(ERR_EXPECTED_CONST, attr, "Expected a constant event name");
  1914. IHqlExpression * filter = event->queryChild(1);
  1915. if (filter && !filter->isConstant())
  1916. reportError(ERR_EXPECTED_CONST, attr, "Expected a constant event filter");
  1917. }
  1918. void HqlGram::checkUseLocation(const attribute & errpos)
  1919. {
  1920. if (!current_type || current_type->getTypeCode() != type_rule)
  1921. reportError(ERR_USEONLYINRULE, errpos, "USE can only be used inside a rule");
  1922. }
  1923. void HqlGram::openTransform(ITypeInfo * type)
  1924. {
  1925. beginTransform(type);
  1926. pushSelfScope(type);
  1927. enterCompoundObject();
  1928. }
  1929. IHqlExpression *HqlGram::closeTransform(const attribute &errpos)
  1930. {
  1931. // make sure all fields are covered
  1932. IHqlExpression *record = queryOriginalRecord(curTransform->queryType());
  1933. checkAllAssigned(record, errpos);
  1934. popSelfScope();
  1935. IHqlExpression *ret = endTransform(errpos);
  1936. return ret;
  1937. }
  1938. IHqlExpression * HqlGram::transformRecord(IHqlExpression *record, IAtom * targetCharset, IHqlExpression * scope, bool & changed, const attribute & errpos)
  1939. {
  1940. Owned<ICharsetInfo> charset = getCharset(targetCharset);
  1941. IHqlExpression *newrec = createRecord();
  1942. unsigned kids = record->numChildren();
  1943. if (!scope) scope = newrec;
  1944. for (unsigned i = 0; i < kids; i++)
  1945. {
  1946. IHqlExpression *src = record->queryChild(i);
  1947. switch (src->getOperator())
  1948. {
  1949. case no_attr:
  1950. case no_attr_expr:
  1951. case no_attr_link:
  1952. newrec->addOperand(LINK(src));
  1953. break;
  1954. case no_ifblock:
  1955. {
  1956. IHqlExpression * newRecord = transformRecord(src->queryChild(1), targetCharset, scope, changed, errpos);
  1957. IHqlExpression * newCond = translateFieldsToNewScope(src->queryChild(0), scope->querySimpleScope(), errpos);
  1958. newrec->addOperand(createValue(no_ifblock, makeNullType(), newCond, newRecord));
  1959. break;
  1960. }
  1961. case no_record:
  1962. newrec->addOperand(transformRecord(src, targetCharset, scope, changed, errpos));
  1963. break;
  1964. case no_field:
  1965. {
  1966. Linked<ITypeInfo> srcType = src->queryType();
  1967. type_t tc = srcType->getTypeCode();
  1968. assertex(tc != type_record);
  1969. if (tc == type_row)
  1970. {
  1971. OwnedHqlExpr newRecord = transformRecord(src->queryRecord(), targetCharset, NULL, changed, errpos);
  1972. srcType.setown(replaceChildType(srcType, newRecord->queryType()));
  1973. }
  1974. else
  1975. {
  1976. if ((tc ==type_string) && (srcType->queryCharset() != charset))
  1977. {
  1978. srcType.setown(makeStringType(srcType->getStringLen(), LINK(charset), NULL));
  1979. changed = true;
  1980. }
  1981. //MORE, should copy some attributes (cardinality) but not others (virtual)
  1982. }
  1983. IHqlExpression *newField = createField(src->queryId(), srcType.getClear(), NULL);
  1984. newrec->addOperand(newField);
  1985. break;
  1986. }
  1987. default:
  1988. UNIMPLEMENTED;
  1989. }
  1990. }
  1991. return newrec->closeExpr();
  1992. }
  1993. IHqlExpression *HqlGram::transformRecord(IHqlExpression *dataset, IAtom * targetCharset, const attribute & errpos)
  1994. {
  1995. bool changed = false;
  1996. IHqlExpression * newRec = transformRecord(dataset->queryRecord(), targetCharset, NULL, changed, errpos);
  1997. if (changed)
  1998. return newRec;
  1999. newRec->Release();
  2000. return NULL;
  2001. }
  2002. ITypeInfo * HqlGram::mapAlienType(IHqlSimpleScope * scope, ITypeInfo * type, const attribute & errpos)
  2003. {
  2004. IHqlExpression * alienExpr = queryExpression(type);
  2005. OwnedHqlExpr mappedAlien = translateFieldsToNewScope(alienExpr, scope, errpos);
  2006. return makeModifier(mappedAlien->getType(), typemod_indirect, LINK(mappedAlien));
  2007. }
  2008. /* In parm e: not linked */
  2009. void HqlGram::addFields(const attribute &errpos, IHqlExpression *e, IHqlExpression * dataset, bool clone)
  2010. {
  2011. if (e->getOperator() != no_record)
  2012. {
  2013. //dataset.childrecord or similar!
  2014. clone = true;
  2015. e = e->queryRecord();
  2016. }
  2017. //If inside an ifblock this may not match activeRecord.tos()..
  2018. if (selfScopes.ordinality() == 0)
  2019. return;
  2020. IHqlSimpleScope * topScope = selfScopes.tos().querySimpleScope();
  2021. assertex(e->getOperator()==no_record);
  2022. ForEachChild(nkid, e)
  2023. {
  2024. IHqlExpression *field = e->queryChild(nkid);
  2025. if (field->isAttribute())
  2026. {
  2027. if (!clone)
  2028. addToActiveRecord(LINK(field));
  2029. continue;
  2030. }
  2031. IIdAtom * id = field->queryId();
  2032. OwnedHqlExpr match = topScope->lookupSymbol(id);
  2033. if (match)
  2034. {
  2035. if (!clone)
  2036. reportWarning(CategorySyntax, ERR_REC_DUPFIELD, errpos.pos, "A field called %s is already defined in this record",str(id));
  2037. continue;
  2038. }
  2039. if (!clone)
  2040. addToActiveRecord(LINK(field));
  2041. else
  2042. {
  2043. //MORE: Fields that are referenced in user defined types need to be resolved to the new cloned field names. No idea how to fix it...
  2044. switch (field->getOperator())
  2045. {
  2046. case no_attr:
  2047. case no_attr_expr:
  2048. case no_attr_link:
  2049. break;
  2050. case no_field:
  2051. {
  2052. IHqlExpression * attrs = extractFieldAttrs(field);
  2053. Owned<ITypeInfo> type = field->getType();
  2054. IIdAtom * fieldId = field->queryId();
  2055. if (type->getTypeCode() == type_alien)
  2056. type.setown(mapAlienType(activeRecords.tos().querySimpleScope(), type, errpos));
  2057. if (dataset)
  2058. {
  2059. OwnedHqlExpr value = createSelectExpr(LINK(dataset), LINK(field));
  2060. OwnedHqlExpr match = activeRecords.tos().querySimpleScope()->lookupSymbol(fieldId);
  2061. //Ignore identical fields that are already present, so ds can be used to mean all fields not already added.
  2062. bool ignore = false;
  2063. if (match)
  2064. {
  2065. IHqlExpression * matchValue = match->queryChild(0);
  2066. if (matchValue && matchValue->queryNormalizedSelector() == value->queryNormalizedSelector())
  2067. ignore = true;
  2068. }
  2069. if (!ignore)
  2070. addField(errpos, fieldId, type.getClear(), createSelectExpr(LINK(dataset), LINK(field)), attrs);
  2071. }
  2072. else
  2073. //We either cope with fields being able to be shared between records in folder etc.,
  2074. //or we have to create a new field at this point...
  2075. //addToActiveRecord(LINK(field));
  2076. addField(errpos, fieldId, type.getClear(), LINK(queryRealChild(field, 0)), attrs);
  2077. break;
  2078. }
  2079. case no_ifblock:
  2080. {
  2081. beginIfBlock();
  2082. addFields(errpos, field->queryChild(1), dataset, clone);
  2083. IHqlExpression * record = endIfBlock();
  2084. //The condition in the if block needs translating to the new fields....
  2085. IHqlExpression * cond = translateFieldsToNewScope(field->queryChild(0), activeRecords.tos().querySimpleScope(), errpos);
  2086. IHqlExpression * expr = createValue(no_ifblock, makeNullType(), cond, record);
  2087. activeRecords.tos().addOperand(expr);
  2088. break;
  2089. }
  2090. case no_record:
  2091. addFields(errpos, field, dataset, clone);
  2092. break;
  2093. }
  2094. }
  2095. }
  2096. }
  2097. void HqlGram::addToActiveRecord(IHqlExpression * newField)
  2098. {
  2099. IHqlExpression & topRecord = activeRecords.tos();
  2100. topRecord.addOperand(newField);
  2101. //This is horrible, but if a field is within an ifblock we need to immediately add it to the parent record's scope table,
  2102. //rather than waiting for the ifblock to be added, otherwise the field can't be found in scope.
  2103. //it means fields from ifblocks are inserted twice into the symbol table - and we still need to expose this internal function
  2104. OwnedHqlExpr self = getSelfScope();
  2105. assertex(self);
  2106. CHqlRecord *currentRecord = QUERYINTERFACE(self->queryRecord(), CHqlRecord);
  2107. //Protect against adding fields to closed records (can only occur after errors).
  2108. if (currentRecord && (currentRecord != &topRecord) && !currentRecord->isExprClosed())
  2109. currentRecord->insertSymbols(newField);
  2110. }
  2111. IIdAtom * HqlGram::createUnnamedFieldId(const char * prefix)
  2112. {
  2113. StringBuffer s;
  2114. s.append(prefix).append(activeRecords.tos().numChildren()+1);
  2115. return createIdAtom(s.str());
  2116. }
  2117. IIdAtom * HqlGram::createUnnamedFieldId()
  2118. {
  2119. return createUnnamedFieldId("_unnamed_");
  2120. }
  2121. /* In parms: type, value: linked */
  2122. void HqlGram::addField(const attribute &errpos, IIdAtom * name, ITypeInfo *_type, IHqlExpression * _value, IHqlExpression *attrs)
  2123. {
  2124. Owned<ITypeInfo> fieldType = _type;
  2125. OwnedHqlExpr value = _value;
  2126. Linked<ITypeInfo> expectedType = fieldType;
  2127. if (expectedType->getTypeCode() == type_alien)
  2128. {
  2129. IHqlAlienTypeInfo * alien = queryAlienType(fieldType);
  2130. expectedType.setown(alien->getLogicalType());
  2131. }
  2132. if (value && !isSameBasicType(value->queryType(), expectedType))
  2133. {
  2134. ITypeInfo * valueType = value->queryType();
  2135. // MORE - is this implicit or explicit?
  2136. if (!expectedType->assignableFrom(valueType->queryPromotedType()))
  2137. canNotAssignTypeWarn(fieldType,valueType,errpos);
  2138. if (expectedType->getTypeCode() != type_row)
  2139. {
  2140. value.setown(ensureExprType(value, expectedType));
  2141. }
  2142. }
  2143. IHqlExpression * defaultAttr = queryAttributeInList(defaultAtom, attrs);
  2144. if (defaultAttr)
  2145. {
  2146. IHqlExpression * defaultValue = defaultAttr->queryChild(0);
  2147. if (defaultValue)
  2148. {
  2149. ITypeInfo * defvalueType = defaultValue->queryType();
  2150. if (defvalueType != expectedType)
  2151. {
  2152. if (!expectedType->assignableFrom(defvalueType->queryPromotedType()))
  2153. canNotAssignTypeError(fieldType,defvalueType,errpos);
  2154. IValue * constValue = defaultValue->queryValue();
  2155. if (constValue && (constValue->rangeCompare(expectedType) > 0))
  2156. reportWarning(CategorySyntax, ERR_TYPE_INCOMPATIBLE, errpos.pos, "%s", "Default value too large");
  2157. if (expectedType->getTypeCode() != type_row)
  2158. {
  2159. HqlExprArray allAttrs;
  2160. attrs->unwindList(allAttrs, no_comma);
  2161. IHqlExpression * newValue = ensureExprType(defaultValue, expectedType);
  2162. allAttrs.zap(*defaultAttr);
  2163. allAttrs.append(*createExprAttribute(defaultAtom, newValue));
  2164. attrs->Release();
  2165. attrs = createComma(allAttrs);
  2166. }
  2167. }
  2168. }
  2169. }
  2170. switch (fieldType->getTypeCode())
  2171. {
  2172. case type_any:
  2173. if (!queryTemplateContext())
  2174. {
  2175. reportUnsupportedFieldType(fieldType, errpos);
  2176. fieldType.set(defaultIntegralType);
  2177. }
  2178. break;
  2179. case type_decimal:
  2180. if (fieldType->getSize() == UNKNOWN_LENGTH)
  2181. {
  2182. reportWarning(CategorySyntax, ERR_BAD_FIELD_TYPE, errpos.pos, "Fields of unknown length decimal not currently supported");
  2183. fieldType.setown(makeDecimalType(MAX_DECIMAL_DIGITS, MAX_DECIMAL_PRECISION, fieldType->isSigned()));
  2184. }
  2185. break;
  2186. }
  2187. if (queryAttributeInList(virtualAtom, attrs) && !fieldType->isScalar())
  2188. reportError(ERR_BAD_FIELD_ATTR, errpos, "Virtual can only be specified on a scalar field");
  2189. if (!name)
  2190. name = createUnnamedFieldId();
  2191. checkFieldnameValid(errpos, name);
  2192. if(isUnicodeType(fieldType) && (*str(fieldType->queryLocale()) == 0))
  2193. {
  2194. StringBuffer locale;
  2195. IAtom * localeAtom = createLowerCaseAtom(queryDefaultLocale()->queryValue()->getStringValue(locale));
  2196. switch (fieldType->getTypeCode())
  2197. {
  2198. case type_varunicode:
  2199. fieldType.setown(makeVarUnicodeType(fieldType->getStringLen(), localeAtom));
  2200. break;
  2201. case type_unicode:
  2202. fieldType.setown(makeUnicodeType(fieldType->getStringLen(), localeAtom));
  2203. break;
  2204. case type_utf8:
  2205. fieldType.setown(makeUtf8Type(fieldType->getStringLen(), localeAtom));
  2206. break;
  2207. default:
  2208. throwUnexpectedType(fieldType);
  2209. }
  2210. }
  2211. size32_t fieldSize = fieldType->getSize();
  2212. if (fieldSize != UNKNOWN_LENGTH)
  2213. {
  2214. if (fieldSize > MAX_SENSIBLE_FIELD_LENGTH)
  2215. reportWarning(CategoryEfficiency, SeverityError, ERR_BAD_FIELD_SIZE, errpos.pos, "Field %s is larger than max sensible size", str(name));
  2216. else if (fieldSize > MAX_POSSIBLE_FIELD_LENGTH)
  2217. reportError(ERR_BAD_FIELD_SIZE, errpos.pos, "Field %s is too large", str(name));
  2218. }
  2219. OwnedHqlExpr newField = createField(name, fieldType.getClear(), value.getClear(), attrs);
  2220. OwnedHqlExpr annotated = createLocationAnnotation(LINK(newField), errpos.pos);
  2221. addToActiveRecord(LINK(newField));
  2222. }
  2223. void HqlGram::addDatasetField(const attribute &errpos, IIdAtom * name, ITypeInfo * fieldType, IHqlExpression *value, IHqlExpression * attrs)
  2224. {
  2225. if (!name)
  2226. name = createUnnamedFieldId();
  2227. checkFieldnameValid(errpos, name);
  2228. if (fieldType)
  2229. {
  2230. IHqlExpression * childAttrs = queryAttribute(fieldType, _childAttr_Atom);
  2231. if (childAttrs)
  2232. attrs = createComma(LINK(childAttrs->queryChild(0)), attrs);
  2233. }
  2234. Owned<ITypeInfo> dsType = LINK(fieldType);
  2235. if (value)
  2236. {
  2237. ITypeInfo * valueType = value->queryType();
  2238. if (!dsType || queryRecord(dsType)->numChildren() == 0)
  2239. {
  2240. ITypeInfo * recordType = queryRecordType(valueType);
  2241. dsType.setown(makeTableType(makeRowType(LINK(recordType))));
  2242. }
  2243. else if (!dsType->assignableFrom(valueType))
  2244. {
  2245. canNotAssignTypeError(dsType,valueType,errpos);
  2246. value->Release();
  2247. value = NULL;
  2248. }
  2249. }
  2250. else
  2251. {
  2252. assertex(dsType && queryRecord(dsType));
  2253. checkRecordIsValid(errpos, queryRecord(dsType));
  2254. }
  2255. if (queryAttributeInList(virtualAtom, attrs))
  2256. reportError(ERR_BAD_FIELD_ATTR, errpos, "Virtual can only be specified on a scalar field");
  2257. if (!attrs)
  2258. attrs = extractAttrsFromExpr(value);
  2259. //An explicitly link counted dataset type should ensure the field is linkcounted
  2260. if (isLinkedRowset(dsType) && !queryAttributeInList(_linkCounted_Atom, attrs))
  2261. attrs = createComma(attrs, getLinkCountedAttr());
  2262. IHqlExpression *newField = createField(name, LINK(dsType), value, attrs);
  2263. addToActiveRecord(newField);
  2264. }
  2265. void HqlGram::addDictionaryField(const attribute &errpos, IIdAtom * name, ITypeInfo * type, IHqlExpression *value, IHqlExpression * attrs)
  2266. {
  2267. if (!name)
  2268. name = createUnnamedFieldId();
  2269. checkFieldnameValid(errpos, name);
  2270. Owned<ITypeInfo> dictType = LINK(type);
  2271. if (value)
  2272. {
  2273. ITypeInfo * valueType = value->queryType();
  2274. if (queryRecord(dictType)->numChildren() == 0)
  2275. dictType.set(value->queryType());
  2276. else if (!dictType->assignableFrom(valueType))
  2277. {
  2278. canNotAssignTypeError(dictType,valueType,errpos);
  2279. value->Release();
  2280. value = NULL;
  2281. }
  2282. }
  2283. if (queryAttributeInList(virtualAtom, attrs))
  2284. reportError(ERR_BAD_FIELD_ATTR, errpos, "Virtual can only be specified on a scalar field");
  2285. if (!attrs)
  2286. attrs = extractAttrsFromExpr(value);
  2287. if (isLinkedRowset(dictType) && !queryAttributeInList(_linkCounted_Atom, attrs))
  2288. attrs = createComma(attrs, getLinkCountedAttr());
  2289. IHqlExpression *newField = createField(name, dictType.getClear(), value, attrs);
  2290. addToActiveRecord(newField);
  2291. }
  2292. void HqlGram::addFieldFromValue(const attribute &errpos, attribute & valueAttr)
  2293. {
  2294. normalizeExpression(valueAttr);
  2295. IHqlExpression *value = valueAttr.getExpr();
  2296. IIdAtom * name = createFieldNameFromExpr(value);
  2297. IHqlExpression * attrs = extractAttrsFromExpr(value);
  2298. if (value->isDataset())
  2299. addDatasetField(errpos, name, NULL, value, attrs);
  2300. else
  2301. addField(errpos, name, value->getType(), value, attrs);
  2302. }
  2303. void HqlGram::addIfBlockToActive(const attribute &errpos, IHqlExpression * ifblock)
  2304. {
  2305. activeRecords.tos().addOperand(LINK(ifblock));
  2306. }
  2307. void HqlGram::beginIfBlock()
  2308. {
  2309. IHqlExpression * record = createRecord();
  2310. activeIfBlocks.append(*record); // stop a leak if crashed whilst processing
  2311. pushRecord(record);
  2312. }
  2313. IHqlExpression * HqlGram::endIfBlock()
  2314. {
  2315. activeIfBlocks.pop(true);
  2316. return popRecord()->closeExpr();
  2317. }
  2318. void HqlGram::checkFieldnameValid(const attribute &errpos, IIdAtom * name)
  2319. {
  2320. OwnedHqlExpr self = getSelfScope();
  2321. if (!self)
  2322. throwUnexpected();
  2323. IHqlSimpleScope *recordScope = self->querySimpleScope();
  2324. OwnedHqlExpr t(recordScope->lookupSymbol(name));
  2325. if (t.get())
  2326. reportError(ERR_REC_DUPFIELD, errpos, "A field called %s is already defined in this record",str(name));
  2327. }
  2328. /* Linkage: not affected */
  2329. void HqlGram::checkCosort(IHqlExpression * sortlist, IHqlExpression * joined, const attribute & ea)
  2330. {
  2331. IHqlExpression * partition = joined->queryChild(0);
  2332. IHqlExpression * othersortlist = partition->queryChild(1);
  2333. unsigned numCpts = sortlist->numChildren();
  2334. //should this be > instead of !=
  2335. if (sortlist->numChildren() != othersortlist->numChildren())
  2336. {
  2337. reportError(ERR_JOINED_DIFFNOFIELDS, ea, "JOINED data set has different number of sort fields: %d vs %d", sortlist->numChildren(), othersortlist->numChildren());
  2338. }
  2339. else
  2340. {
  2341. unsigned idx;
  2342. for (idx = 0; idx < numCpts; ++idx)
  2343. {
  2344. IHqlExpression * cur = sortlist->queryChild(idx);
  2345. IHqlExpression * other = othersortlist->queryChild(idx);
  2346. if (cur->queryType() != other->queryType())
  2347. {
  2348. StringBuffer x, y;
  2349. reportError(ERR_JOINED_DIFFTYPE, ea, "Component of JOINED has different type in sort field %d: %s vs %s",
  2350. idx+1, getFriendlyTypeStr(cur, x).str(), getFriendlyTypeStr(other, y).str());
  2351. }
  2352. }
  2353. }
  2354. }
  2355. void HqlGram::enterType(const attribute &errpos, bool isParametered)
  2356. {
  2357. enterScope(true);
  2358. enterCompoundObject();
  2359. }
  2360. void HqlGram::enterCompoundObject()
  2361. {
  2362. savedIds.append(current_id);
  2363. savedLastpos.append(lastpos);
  2364. }
  2365. void HqlGram::leaveCompoundObject()
  2366. {
  2367. current_id = (IIdAtom *)savedIds.popGet();
  2368. lastpos = savedLastpos.popGet();
  2369. }
  2370. void HqlGram::leaveType(const YYSTYPE & errpos)
  2371. {
  2372. leaveCompoundObject();
  2373. leaveScope(errpos);
  2374. inType = false;
  2375. }
  2376. void HqlGram::appendToActiveScope(IHqlExpression * arg)
  2377. {
  2378. IHqlScope * scope = defineScopes.tos().localScope;
  2379. if (scope)
  2380. queryExpression(scope)->addOperand(LINK(arg));
  2381. }
  2382. void HqlGram::enterScope(IHqlScope * scope, bool allowExternal)
  2383. {
  2384. ActiveScopeInfo & next = * new ActiveScopeInfo;
  2385. if (allowExternal)
  2386. {
  2387. next.localScope.set(scope);
  2388. next.privateScope.setown(createPrivateScope(scope));
  2389. }
  2390. else
  2391. next.privateScope.set(scope);
  2392. next.firstSideEffect = parseResults.ordinality();
  2393. defineScopes.append(next);
  2394. }
  2395. void HqlGram::enterScope(bool allowExternal)
  2396. {
  2397. ActiveScopeInfo & next = * new ActiveScopeInfo;
  2398. if (allowExternal)
  2399. next.localScope.setown(createScope());
  2400. next.privateScope.setown(createPrivateScope());
  2401. next.firstSideEffect = parseResults.ordinality();
  2402. defineScopes.append(next);
  2403. }
  2404. void HqlGram::enterVirtualScope()
  2405. {
  2406. //This isn't perfect, but it is the best I can do.
  2407. StringBuffer fullName;
  2408. fullName.append(globalScope->queryFullName());
  2409. ForEachItemIn(i, savedIds)
  2410. {
  2411. IIdAtom * id = (IIdAtom *)savedIds.item(i);
  2412. if (id)
  2413. {
  2414. if (fullName.length())
  2415. fullName.append(".");
  2416. fullName.append(str(id));
  2417. }
  2418. }
  2419. if (current_id)
  2420. {
  2421. if (fullName.length())
  2422. fullName.append(".");
  2423. fullName.append(str(current_id));
  2424. }
  2425. ActiveScopeInfo & next = * new ActiveScopeInfo;
  2426. next.localScope.setown(createVirtualScope(current_id, fullName));
  2427. next.privateScope.setown(createPrivateScope());
  2428. next.firstSideEffect = parseResults.ordinality();
  2429. defineScopes.append(next);
  2430. }
  2431. bool HqlGram::insideNestedScope() const
  2432. {
  2433. return defineScopes.ordinality() > minimumScopeIndex;
  2434. }
  2435. bool HqlGram::sideEffectsPending() const
  2436. {
  2437. unsigned first = defineScopes.tos().firstSideEffect;
  2438. return (parseResults.ordinality() != first);
  2439. }
  2440. void HqlGram::clearSideEffects()
  2441. {
  2442. unsigned first = defineScopes.tos().firstSideEffect;
  2443. parseResults.popn(parseResults.ordinality() - first);
  2444. }
  2445. void HqlGram::leaveScope(const YYSTYPE & errpos)
  2446. {
  2447. if (sideEffectsPending())
  2448. {
  2449. clearSideEffects();
  2450. reportError(ERR_RESULT_IGNORED, errpos, "Action side effect is not associated with a definition");
  2451. }
  2452. if (defineScopes.ordinality() > minimumScopeIndex)
  2453. defineScopes.pop();
  2454. }
  2455. IHqlScope * HqlGram::closeLeaveScope(const YYSTYPE & errpos)
  2456. {
  2457. IHqlScope * scope = defineScopes.tos().localScope;
  2458. if (!scope)
  2459. scope = defineScopes.tos().privateScope;
  2460. LINK(scope);
  2461. leaveScope(errpos);
  2462. return closeScope(scope);
  2463. }
  2464. IHqlExpression * HqlGram::leaveLamdaExpression(attribute & exprattr)
  2465. {
  2466. OwnedHqlExpr resultExpr = exprattr.getExpr();
  2467. OwnedHqlExpr expr = associateSideEffects(resultExpr, exprattr.pos);
  2468. if (queryParametered())
  2469. {
  2470. ActiveScopeInfo & activeScope = defineScopes.tos();
  2471. OwnedHqlExpr formals = activeScope.createFormals(false);
  2472. OwnedHqlExpr defaults = activeScope.createDefaults();
  2473. expr.setown(createFunctionDefinition(atId, expr.getClear(), formals.getClear(), defaults.getClear(), NULL));
  2474. }
  2475. leaveScope(exprattr);
  2476. leaveCompoundObject();
  2477. return expr.getClear();
  2478. }
  2479. //---------------------------------------------------------------------------------------------------------------------
  2480. #ifdef _DEBUG
  2481. #define PSEUDO_UNIMPLEMENTED
  2482. //#define PSEUDO_UNIMPLEMENTED UNIMPLEMENTED
  2483. #else
  2484. #define PSEUDO_UNIMPLEMENTED
  2485. #endif
  2486. class PseudoPatternScope : public CHqlScope
  2487. {
  2488. public:
  2489. PseudoPatternScope(IHqlExpression * _patternList);
  2490. IMPLEMENT_IINTERFACE_USING(CHqlScope)
  2491. virtual void defineSymbol(IIdAtom * name, IIdAtom * moduleName, IHqlExpression *value, bool isExported, bool isShared, unsigned flags, IFileContents *fc, int bodystart, int lineno, int column) { ::Release(value); PSEUDO_UNIMPLEMENTED; }
  2492. virtual void defineSymbol(IIdAtom * name, IIdAtom * moduleName, IHqlExpression *value, bool isExported, bool isShared, unsigned flags) { ::Release(value); PSEUDO_UNIMPLEMENTED; }
  2493. virtual void defineSymbol(IHqlExpression * value) { PSEUDO_UNIMPLEMENTED; ::Release(value); }
  2494. virtual IHqlExpression *lookupSymbol(IIdAtom * name, unsigned lookupFlags, HqlLookupContext & ctx);
  2495. virtual void removeSymbol(IIdAtom * name) { PSEUDO_UNIMPLEMENTED; }
  2496. virtual void getSymbols(HqlExprArray& exprs) const { PSEUDO_UNIMPLEMENTED; }
  2497. virtual IAtom * queryName() const { PSEUDO_UNIMPLEMENTED; return NULL; }
  2498. virtual const char * queryFullName() const { PSEUDO_UNIMPLEMENTED; return NULL; }
  2499. virtual ISourcePath * querySourcePath() const { PSEUDO_UNIMPLEMENTED; return NULL; }
  2500. virtual bool hasBaseClass(IHqlExpression * searchBase) { return false; }
  2501. virtual bool allBasesFullyBound() const { return true; }
  2502. virtual void ensureSymbolsDefined(HqlLookupContext & ctx) { }
  2503. virtual bool isImplicit() const { return false; }
  2504. virtual bool isPlugin() const { return false; }
  2505. virtual int getPropInt(IIdAtom *, int dft) const { PSEUDO_UNIMPLEMENTED; return dft; }
  2506. virtual bool getProp(IIdAtom *, StringBuffer &) const { PSEUDO_UNIMPLEMENTED; return false; }
  2507. virtual IHqlScope * clone(HqlExprArray & children, HqlExprArray & symbols) { throwUnexpected(); }
  2508. virtual IHqlScope * queryConcreteScope() { return this; }
  2509. virtual IHqlScope * queryResolvedScope(HqlLookupContext * context) { return this; }
  2510. protected:
  2511. IHqlExpression * patternList; // NB: Not linked.
  2512. };
  2513. void HqlGram::enterPatternScope(IHqlExpression * pattern)
  2514. {
  2515. Owned<IHqlScope> scope = new PseudoPatternScope(pattern);
  2516. enterScope(scope, false);
  2517. }
  2518. void HqlGram::leavePatternScope(const YYSTYPE & errpos)
  2519. {
  2520. leaveScope(errpos);
  2521. }
  2522. //---------------------------------------------------------------------------------------------------------------------
  2523. void HqlGram::releaseScopes()
  2524. {
  2525. while(topScopes.length()>0)
  2526. popTopScope();
  2527. leftRightScopes.kill();
  2528. while (selfScopes.length() > 0)
  2529. {
  2530. //Ensure that we do not remove any scopes that are still active - otherwise they will be released too early
  2531. OwnedHqlExpr self = getSelfScope();
  2532. if (activeRecords.contains(*self))
  2533. break;
  2534. popSelfScope();
  2535. }
  2536. modScope.clear();
  2537. outerScopeAccessDepth = 0;
  2538. dotScope.clear();
  2539. }
  2540. void HqlGram::processForwardModuleDefinition(const attribute & errpos)
  2541. {
  2542. //called when FORWARD is the token just returned from yyLex(), this consumes up until the last END
  2543. ActiveScopeInfo & activeScope = defineScopes.tos();
  2544. IHqlScope * scope = activeScope.localScope;
  2545. if (!scope)
  2546. return;
  2547. IHqlExpression * scopeExpr = queryExpression(scope);
  2548. if (scopeExpr->hasAttribute(_virtualSeq_Atom))
  2549. {
  2550. reportError(ERR_NO_FORWARD_VIRTUAL, errpos, "Cannot use FORWARD in combination with a VIRTUAL module ");
  2551. return;
  2552. }
  2553. HqlGramCtx * parentCtx = new HqlGramCtx(lookupCtx, inSignedModule);
  2554. saveContext(*parentCtx, true);
  2555. Owned<IHqlScope> newScope = createForwardScope(queryGlobalScope(), parentCtx, lookupCtx.queryParseContext());
  2556. IHqlExpression * newScopeExpr = queryExpression(newScope);
  2557. ForEachChild(i, scopeExpr)
  2558. newScopeExpr->addOperand(LINK(scopeExpr->queryChild(i)));
  2559. unsigned endNesting = 0;
  2560. unsigned braNesting = 0;
  2561. IIdAtom * prevId = NULL;
  2562. IIdAtom * sharedSymbolName = NULL;
  2563. int sharedSymbolKind = 0;
  2564. ECLlocation start;
  2565. lexObject->getPosition(start);
  2566. int prev = 0;
  2567. YYSTYPE nextToken;
  2568. loop
  2569. {
  2570. int next = lexObject->yyLex(nextToken, false, NULL);
  2571. switch (next)
  2572. {
  2573. case ASSIGN:
  2574. if ((sharedSymbolKind != 0) && !sharedSymbolName && prevId && (endNesting == 0))
  2575. {
  2576. sharedSymbolName = prevId;
  2577. }
  2578. break;
  2579. case UNKNOWN_ID:
  2580. {
  2581. IIdAtom * id = nextToken.getId();
  2582. IAtom * name = lower(id);
  2583. if ((braNesting == 0) && (endNesting == 0)) // last identifier seen, but don't include parameters, or record members
  2584. prevId = id;
  2585. if (name == ruleAtom)
  2586. next = RULE;
  2587. else if (name == wholeAtom)
  2588. next = WHOLE;
  2589. else if (name == typeAtom)
  2590. {
  2591. // ":= TYPE" Beginning of a user type definition
  2592. if (prev == ASSIGN)
  2593. {
  2594. prevId = NULL;
  2595. endNesting++;
  2596. }
  2597. }
  2598. break;
  2599. }
  2600. case SHARED:
  2601. case EXPORT:
  2602. if (endNesting == 0)
  2603. {
  2604. braNesting = 0; // in case something else has confused us.
  2605. sharedSymbolKind = next;
  2606. }
  2607. break;
  2608. case '(':
  2609. //Functional version of IF, and inline version of transform doesn't have END
  2610. if ((prev == IF) || (prev == TRANSFORM))
  2611. endNesting--;
  2612. braNesting++;
  2613. break;
  2614. case ')':
  2615. braNesting--;
  2616. break;
  2617. case ';':
  2618. if (sharedSymbolName && braNesting == 0 && endNesting == 0)
  2619. {
  2620. ECLlocation end;
  2621. lexObject->getPosition(end);
  2622. checkNotAlreadyDefined(sharedSymbolName, newScope, errpos);
  2623. unsigned symbolFlags = 0;
  2624. IIdAtom * moduleName = NULL;
  2625. Owned<IFileContents> contents = createFileContentsSubset(lexObject->queryFileContents(), start.position, end.position - start.position);
  2626. addForwardDefinition(newScope, sharedSymbolName, moduleName, contents,
  2627. symbolFlags, (sharedSymbolKind == EXPORT), start.lineno, start.column);
  2628. //Looks like the end of the shared symbol => define it
  2629. start.set(end);
  2630. sharedSymbolKind = 0;
  2631. prevId = NULL;
  2632. sharedSymbolName = NULL;
  2633. }
  2634. break;
  2635. case RECORD:
  2636. //Don't increment nesting when [WHOLE] RECORD used to indicate which fields to dedup by
  2637. if ((prev != ',') && (prev != WHOLE) && (prev != VIRTUAL))
  2638. endNesting++;
  2639. break;
  2640. case IF:
  2641. //increment nesting, but probably decrement it straight away when we see the '('
  2642. endNesting++;
  2643. break;
  2644. //MORE: These are now hard reserved....
  2645. case FUNCTION:
  2646. case IFBLOCK:
  2647. case INTERFACE:
  2648. case MODULE:
  2649. case SERVICE:
  2650. case TRANSFORM:
  2651. endNesting++;
  2652. break;
  2653. case END:
  2654. if (endNesting == 0)
  2655. {
  2656. lexObject->pushText("END");
  2657. closeScope(activeScope.localScope.getClear())->Release();
  2658. activeScope.localScope.setown(newScope.getClear());
  2659. return;
  2660. }
  2661. endNesting--;
  2662. break;
  2663. case EOF:
  2664. case 0:
  2665. reportError(ERR_EXPECTED, errpos, "Missing END in FORWARD module definition");
  2666. abortParsing();
  2667. return;
  2668. case COMPLEX_MACRO:
  2669. case MACRO:
  2670. case SIMPLE_TYPE:
  2671. case CPPBODY:
  2672. case STRING_CONST:
  2673. case REAL_CONST:
  2674. case UNICODE_CONST:
  2675. case DATA_CONST:
  2676. break;
  2677. }
  2678. nextToken.release();
  2679. prev = next;
  2680. }
  2681. }
  2682. IHqlExpression *HqlGram::queryTopScope()
  2683. {
  2684. IHqlExpression *top = NULL;
  2685. if (topScopes.length())
  2686. {
  2687. top = (IHqlExpression *) &topScopes.item(topScopes.length()-1);
  2688. }
  2689. return top;
  2690. }
  2691. IHqlExpression *HqlGram::getTopScope()
  2692. {
  2693. if (!topScopes.length())
  2694. return NULL;
  2695. IHqlExpression * ret = (IHqlExpression *) &topScopes.item(topScopes.length()-1);
  2696. ret->Link();
  2697. return ret;
  2698. }
  2699. IHqlExpression *HqlGram::getSelfScope()
  2700. {
  2701. if (!selfScopes.length())
  2702. return NULL;
  2703. IHqlExpression * ret = &selfScopes.tos();
  2704. ret->Link();
  2705. return ret;
  2706. }
  2707. IHqlExpression *HqlGram::queryLeftScope()
  2708. {
  2709. ForEachItemInRev(i, leftRightScopes)
  2710. {
  2711. LeftRightScope & curScope = leftRightScopes.item(i);
  2712. if (curScope.left)
  2713. return curScope.left;
  2714. }
  2715. return NULL;
  2716. }
  2717. IHqlExpression *HqlGram::queryRightScope()
  2718. {
  2719. ForEachItemInRev(i, leftRightScopes)
  2720. {
  2721. LeftRightScope & curScope = leftRightScopes.item(i);
  2722. if (curScope.right)
  2723. return curScope.right;
  2724. }
  2725. return NULL;
  2726. }
  2727. IHqlExpression *HqlGram::resolveRows(const attribute & errpos, IHqlExpression * ds)
  2728. {
  2729. bool hadRows = false;
  2730. ForEachItemInRev(i, leftRightScopes)
  2731. {
  2732. LeftRightScope & curScope = leftRightScopes.item(i);
  2733. if (curScope.rowsScope == ds)
  2734. {
  2735. IHqlExpression * id = LINK(curScope.rowsId);
  2736. return createDataset(no_rows, LINK(ds), id);
  2737. }
  2738. else if (curScope.rowsScope)
  2739. hadRows = true;
  2740. }
  2741. if (!hadRows)
  2742. reportError(ERR_LEFT_ILL_HERE, errpos, "ROWS not legal here");
  2743. else
  2744. reportError(ERR_LEFT_ILL_HERE, errpos, "ROWS not legal on this dataset");
  2745. return createDataset(no_null, LINK(ds->queryRecord()));
  2746. }
  2747. IHqlExpression * HqlGram::getSelfDotExpr(const attribute & errpos)
  2748. {
  2749. OwnedHqlExpr self = getSelfScope();
  2750. setDotScope(self);
  2751. if (!self)
  2752. reportError(ERR_SELF_ILL_HERE, errpos, "SELF not legal here");
  2753. if (curTransform && dotScope && recordTypesMatch(dotScope, curTransform))
  2754. {
  2755. return getSelf(curTransform);
  2756. }
  2757. return LINK(querySelfReference());
  2758. }
  2759. bool HqlGram::checkValidBaseModule(const attribute & attr, SharedHqlExpr & expr)
  2760. {
  2761. node_operator op = expr->getOperator();
  2762. if ((op == no_virtualscope) || (op == no_libraryscopeinstance) || (op == no_param))
  2763. return true;
  2764. if (op == no_forwardscope)
  2765. {
  2766. IHqlScope * scope = expr->queryScope();
  2767. IHqlScope * resolved = scope->queryResolvedScope(&lookupCtx);
  2768. expr.set(queryExpression(resolved));
  2769. return true;
  2770. }
  2771. return true;
  2772. }
  2773. bool extractSymbolParameters(HqlExprArray & parameters, IHqlExpression * symbol)
  2774. {
  2775. if (symbol->isFunction())
  2776. {
  2777. unwindChildren(parameters, queryFunctionParameters(symbol));
  2778. return true;
  2779. }
  2780. return false;
  2781. }
  2782. //Given a previous symbol definition and a new value, create a attribute with the same structure
  2783. IHqlExpression * HqlGram::createSymbolFromValue(IHqlExpression * primaryExpr, IHqlExpression * value)
  2784. {
  2785. return primaryExpr->cloneAllAnnotations(value);
  2786. }
  2787. IHqlExpression * HqlGram::implementInterfaceFromModule(const attribute & modpos, const attribute & ipos, IHqlExpression * implementModule, IHqlExpression * _projectInterface, IHqlExpression * flags)
  2788. {
  2789. //MORE: What about multiple base interfaces? Shouldn't really be needed, but would probably be easy enough to implement.
  2790. HqlExprArray selectedFields;
  2791. bool optional = false;
  2792. if (flags)
  2793. {
  2794. flags->unwindList(selectedFields, no_comma);
  2795. IHqlExpression * optionalAttr = queryAttribute(optAtom, selectedFields);
  2796. if (optionalAttr)
  2797. {
  2798. optional = true;
  2799. selectedFields.zap(*optionalAttr);
  2800. }
  2801. }
  2802. IHqlExpression * libraryAttr = queryAttribute(libraryAtom, selectedFields);
  2803. if (libraryAttr)
  2804. selectedFields.zap(*libraryAttr);
  2805. LinkedHqlExpr projectInterface = _projectInterface;
  2806. if (projectInterface->getOperator() == no_funcdef)
  2807. projectInterface.set(projectInterface->queryChild(0));
  2808. OwnedHqlExpr concreteModule = checkCreateConcreteModule(lookupCtx.errs, implementModule, modpos.pos);
  2809. IHqlScope * scope = concreteModule->queryScope();
  2810. assertex(scope);
  2811. Owned<IHqlScope> newScope = createVirtualScope();
  2812. IHqlExpression * newScopeExpr = queryExpression(newScope);
  2813. if (!checkValidBaseModule(ipos, projectInterface))
  2814. return projectInterface.getClear();
  2815. newScopeExpr->addOperand(LINK(projectInterface));
  2816. IHqlScope * base = projectInterface->queryScope();
  2817. if (base)
  2818. {
  2819. HqlExprArray syms;
  2820. if (selectedFields.ordinality())
  2821. {
  2822. ForEachItemIn(i, selectedFields)
  2823. {
  2824. IHqlExpression & cur = selectedFields.item(i);
  2825. assertex(cur.getOperator() == no_id);
  2826. IIdAtom * id = cur.queryId();
  2827. OwnedHqlExpr match = base->lookupSymbol(id, LSFpublic, lookupCtx);
  2828. if (match)
  2829. syms.append(*match.getClear());
  2830. else
  2831. reportError(ERR_EXPECTED_ATTRIBUTE, ipos, "Interface does not define %s", str(id));
  2832. }
  2833. }
  2834. else
  2835. base->getSymbols(syms);
  2836. syms.sort(compareSymbolsByName);
  2837. ForEachItemIn(iSym, syms)
  2838. {
  2839. IHqlExpression & baseSym = syms.item(iSym);
  2840. IIdAtom * id = baseSym.queryId();
  2841. OwnedHqlExpr match = scope->lookupSymbol(id, LSFpublic, lookupCtx);
  2842. if (match)
  2843. {
  2844. HqlExprArray parameters;
  2845. bool isParametered = extractSymbolParameters(parameters, &baseSym);
  2846. checkDerivedCompatible(id, newScopeExpr, match, isParametered, parameters, modpos);
  2847. newScope->defineSymbol(LINK(match));
  2848. }
  2849. else if (!optional)
  2850. reportError(ERR_EXPECTED_ATTRIBUTE, modpos, "Module does not define %s", str(id));
  2851. }
  2852. }
  2853. //Keep the library property so can check prototypes match later.
  2854. if (libraryAttr)
  2855. newScopeExpr->addOperand(LINK(libraryAttr));
  2856. cloneInheritedAttributes(newScope, ipos);
  2857. return closeAndLink(newScopeExpr);
  2858. }
  2859. IHqlExpression * HqlGram::implementInterfaceFromModule(attribute & mAttr, attribute & iAttr, IHqlExpression * flags)
  2860. {
  2861. OwnedHqlExpr projectInterface = iAttr.getExpr();
  2862. OwnedHqlExpr implementModule = mAttr.getExpr();
  2863. return implementInterfaceFromModule(mAttr, iAttr, implementModule, projectInterface, flags);
  2864. }
  2865. void HqlGram::setActiveAttrs(int activityToken, const TokenMap * attrs)
  2866. {
  2867. //Nasty special case because valid attribute handling is a side effect of the lexer rather than
  2868. //the grammar reductions.
  2869. //This function is typically called before the '(', or before the first comma of the attributes
  2870. //At that point the next token will have already have been lexed (and saved in lastToken)
  2871. //If is is a close bracket then the valid attribute stack will have already been popped
  2872. //so make sure we don't update otherwise it will mess up the parent's scope.
  2873. if (lexObject->queryLastToken() == ')')
  2874. return;
  2875. int lastToken = lexObject->queryLastToken();
  2876. switch (lastToken)
  2877. {
  2878. case '(':
  2879. case ',':
  2880. {
  2881. unsigned max = validAttributesStack.ordinality();
  2882. if (max)
  2883. validAttributesStack.replace(attrs, max-1);
  2884. break;
  2885. }
  2886. default:
  2887. if (lastToken == activityToken)
  2888. pendingAttributes = attrs;
  2889. }
  2890. }
  2891. void HqlGram::enableAttributes(int activityToken)
  2892. {
  2893. assertex(activityToken >= 0 && activityToken < YY_LAST_TOKEN);
  2894. TokenMap * map = nestedAttributeMap[activityToken];
  2895. // assertex(map);
  2896. if (map)
  2897. setActiveAttrs(activityToken, map);
  2898. }
  2899. int HqlGram::mapToken(int lexToken) const
  2900. {
  2901. if (validAttributesStack.ordinality() != 0)
  2902. {
  2903. const TokenMap * activeMap = static_cast<const TokenMap *>(validAttributesStack.tos());
  2904. if (activeMap)
  2905. {
  2906. for (unsigned i=0;;i++)
  2907. {
  2908. int curLexToken = activeMap[i].lexToken;
  2909. if (curLexToken == 0)
  2910. break;
  2911. if (curLexToken == lexToken)
  2912. return activeMap[i].attrToken;
  2913. }
  2914. }
  2915. }
  2916. return defaultTokenMap[lexToken];
  2917. }
  2918. void HqlGram::onOpenBra()
  2919. {
  2920. //This is called as a side-effect from the lexer, rather than as a production in the
  2921. //grammar since it is simpler, significantly reduces the grammar production tables,
  2922. //and also avoids some potential r/r errors. See also onCloseBra()
  2923. //However that can cause interesting interaction between productions and lexer side effects,
  2924. //see setActiveAttrs for more details.
  2925. validAttributesStack.append(pendingAttributes);
  2926. pendingAttributes = NULL;
  2927. }
  2928. void HqlGram::onCloseBra()
  2929. {
  2930. if (validAttributesStack.ordinality())
  2931. validAttributesStack.pop();
  2932. }
  2933. IHqlExpression *HqlGram::lookupSymbol(IHqlScope * scope, IIdAtom * searchName)
  2934. {
  2935. return scope->lookupSymbol(searchName, LSFpublic, lookupCtx);
  2936. }
  2937. unsigned HqlGram::getExtraLookupFlags(IHqlScope * scope)
  2938. {
  2939. if (scope == containerScope)
  2940. return LSFsharedOK;
  2941. return 0;
  2942. }
  2943. IHqlExpression *HqlGram::lookupSymbol(IIdAtom * searchName, const attribute& errpos)
  2944. {
  2945. #if 0
  2946. if (stricmp(searchName->getAtomNamePtr(), "gh2")==0)
  2947. searchName = searchName;
  2948. #endif
  2949. if (expectedUnknownId)
  2950. return NULL;
  2951. //Check periodically if parsing a referenced identifier has caused the compile to abort.
  2952. if (lookupCtx.isAborting())
  2953. aborting = true;
  2954. try
  2955. {
  2956. // If there is a temporary scope, we only look up in that (and it must exist!).
  2957. if (dotScope)
  2958. {
  2959. IHqlExpression *ret = NULL;
  2960. if (dotScope->getOperator() == no_enum)
  2961. {
  2962. ret = dotScope->queryScope()->lookupSymbol(searchName, LSFrequired, lookupCtx);
  2963. }
  2964. else
  2965. {
  2966. IHqlExpression * dotRecord = dotScope->queryRecord();
  2967. if(!dotRecord)
  2968. return NULL;
  2969. IHqlExpression* map = queryFieldMap(dotScope);
  2970. if (map)
  2971. {
  2972. searchName = fieldMapTo(map, searchName);
  2973. IHqlExpression* ds = dotScope->queryChild(0);
  2974. ret = ds->queryRecord()->querySimpleScope()->lookupSymbol(searchName);
  2975. if (!ret)
  2976. reportError(ERR_OBJ_NOSUCHFIELD, errpos, "Object '%s' does not have a field named '%s'", str(ds->queryName()), str(searchName));
  2977. }
  2978. else
  2979. {
  2980. ret = dotRecord->querySimpleScope()->lookupSymbol(searchName);
  2981. if (!ret)
  2982. {
  2983. StringBuffer s;
  2984. getExprECL(dotScope, s);
  2985. reportError(ERR_OBJ_NOSUCHFIELD, errpos, "Object '%s' does not have a field named '%s'", s.str(), str(searchName));
  2986. }
  2987. }
  2988. }
  2989. // dotScope only works once
  2990. dotScope.clear();
  2991. return ret;
  2992. }
  2993. if (modScope)
  2994. {
  2995. OwnedHqlExpr resolved = modScope->lookupSymbol(searchName, LSFrequired|LSFsharedOK, lookupCtx);
  2996. if (!resolved)
  2997. {
  2998. if (modScope->queryName())
  2999. reportError(ERR_OBJ_NOSUCHFIELD, errpos, "Object '%s' does not have a member named '%s'", str(modScope->queryName()), str(searchName));
  3000. else
  3001. reportError(ERR_OBJ_NOSUCHFIELD, errpos, "Object does not have a member named '%s'", str(searchName));
  3002. }
  3003. else if ((modScope != containerScope) && !isExported(resolved))
  3004. reportError(HQLERR_CannotAccessShared, errpos, "Cannot access SHARED symbol '%s' in another module", str(searchName));
  3005. return resolved.getClear();
  3006. }
  3007. // Then come implicitly defined fields...
  3008. IHqlExpression *top = queryTopScope();
  3009. if (top)
  3010. {
  3011. if (outerScopeAccessDepth == 0)
  3012. {
  3013. IHqlExpression* ret;
  3014. IHqlExpression* map = queryFieldMap(top);
  3015. if (map)
  3016. {
  3017. searchName = fieldMapTo(map, searchName);
  3018. IHqlExpression* ds = top->queryChild(0);
  3019. ret = ds->queryRecord()->querySimpleScope()->lookupSymbol(searchName);
  3020. }
  3021. else
  3022. ret = top->queryRecord()->querySimpleScope()->lookupSymbol(searchName);
  3023. if (ret)
  3024. {
  3025. if (top->getOperator() != no_record)
  3026. {
  3027. //more: Should probably return createDataset(no_anon, record)
  3028. // or something similar, but need to watch evaluate(dataset[1], datatset.x) and SQL generation.
  3029. if (insideEvaluate)
  3030. return addDatasetSelector(getActiveTableSelector(), ret);
  3031. IHqlExpression * topSelect = top->queryNormalizedSelector(true);
  3032. return addDatasetSelector(LINK(topSelect), ret);
  3033. }
  3034. else
  3035. return addDatasetSelector(getActiveTableSelector(), ret);
  3036. }
  3037. }
  3038. else
  3039. outerScopeAccessDepth--;
  3040. }
  3041. //Slightly strange... The parameters for the current nested object are stored in the previous ActiveScopeInfo record.
  3042. //This means outerScopeDepth is decremented after looking at the parameters. It also means we need to increment by
  3043. //one before we start.
  3044. //It does mean
  3045. //export anotherFunction(integer SomeValue2) := SomeValue2 * ^.SomeValue2; Doesn't quite work as expected, but
  3046. //it serves the user right for choosing a parameter name that clashes. Otherwise you'd generally need one more ^ than you'd expect.
  3047. if (outerScopeAccessDepth)
  3048. outerScopeAccessDepth++;
  3049. //Also note, if we're inside a template function then we need to record all access to symbols that occur at an outer level
  3050. IHqlScope * templateScope = NULL;
  3051. ForEachItemInRev(scopeIdx, defineScopes)
  3052. {
  3053. ActiveScopeInfo & cur = defineScopes.item(scopeIdx);
  3054. if (cur.templateAttrContext)
  3055. templateScope = cur.templateAttrContext;
  3056. if (outerScopeAccessDepth == 0)
  3057. {
  3058. IHqlExpression * match = cur.queryParameter(searchName);
  3059. if (match)
  3060. {
  3061. // PrintLog("Lookup %s got parameter %s", searchName->getAtomNamePtr(), searchName->getAtomNamePtr());
  3062. return LINK(match);
  3063. }
  3064. }
  3065. else
  3066. outerScopeAccessDepth--;
  3067. if (outerScopeAccessDepth == 0)
  3068. {
  3069. IHqlExpression *ret = cur.privateScope->lookupSymbol(searchName, LSFsharedOK, lookupCtx);
  3070. if (ret)
  3071. return recordLookupInTemplateContext(searchName, ret, templateScope);
  3072. if (cur.localScope)
  3073. {
  3074. ret = cur.localScope->lookupSymbol(searchName, LSFsharedOK, lookupCtx);
  3075. if (ret)
  3076. {
  3077. return recordLookupInTemplateContext(searchName, ret, templateScope);
  3078. }
  3079. }
  3080. }
  3081. }
  3082. //Now look up imports
  3083. IHqlExpression *ret = parseScope->lookupSymbol(searchName, LSFsharedOK, lookupCtx);
  3084. if (ret)
  3085. return recordLookupInTemplateContext(searchName, ret, templateScope);
  3086. // finally comes the local scope
  3087. if (legacyImportSemantics && lower(searchName)==globalScope->queryName())
  3088. return LINK(recordLookupInTemplateContext(searchName, queryExpression(globalScope), templateScope));
  3089. ForEachItemIn(idx2, defaultScopes)
  3090. {
  3091. IHqlScope &plugin = defaultScopes.item(idx2);
  3092. IHqlExpression *ret = plugin.lookupSymbol(searchName, LSFpublic|getExtraLookupFlags(&plugin), lookupCtx);
  3093. if (ret)
  3094. {
  3095. recordLookupInTemplateContext(searchName, ret, templateScope);
  3096. return ret;
  3097. }
  3098. }
  3099. return NULL;
  3100. }
  3101. catch(IError* error)
  3102. {
  3103. if(errorHandler && !errorDisabled)
  3104. errorHandler->report(error);
  3105. error->Release();
  3106. // recover: to avoid reload the definition again and again
  3107. return createSymbol(searchName, createConstant(0), ob_private);
  3108. }
  3109. return NULL;
  3110. }
  3111. IHqlExpression * HqlGram::recordLookupInTemplateContext(IIdAtom * name, IHqlExpression * expr, IHqlScope * templateScope)
  3112. {
  3113. if (expr && templateScope)
  3114. templateScope->defineSymbol(name,NULL,expr,true,false,0);
  3115. return expr;
  3116. }
  3117. unsigned HqlGram::checkCompatible(ITypeInfo * t1, ITypeInfo * t2, const attribute &ea, bool complain)
  3118. {
  3119. if (t1 && t2)
  3120. {
  3121. if (t1->assignableFrom(t2))
  3122. return 1;
  3123. if (t2->assignableFrom(t1))
  3124. return 2;
  3125. }
  3126. if (complain)
  3127. {
  3128. StringBuffer msg("Type mismatch - expected ");
  3129. getFriendlyTypeStr(t1,msg).append(" value, given ");
  3130. getFriendlyTypeStr(t2,msg);
  3131. reportError(ERR_EXPECTED, ea, "%s", msg.str());
  3132. }
  3133. return 0;
  3134. }
  3135. ITypeInfo *HqlGram::checkType(attribute &a1, attribute &a2)
  3136. {
  3137. ITypeInfo *t1 = a1.queryExprType();
  3138. ITypeInfo *t2 = a2.queryExprType();
  3139. switch (checkCompatible(t1, t2, a2))
  3140. {
  3141. case 1:
  3142. ::Link(t1);
  3143. return t1;
  3144. case 2:
  3145. ::Link(t2);
  3146. return t2;
  3147. }
  3148. ::Link(t1);
  3149. return t1;
  3150. }
  3151. void HqlGram::checkType(attribute &a1, ITypeInfo *t2)
  3152. {
  3153. checkCompatible(a1.queryExprType(), t2, a1);
  3154. }
  3155. void HqlGram::checkMaxCompatible(IHqlExpression * sortOrder, IHqlExpression * values, attribute & errpos)
  3156. {
  3157. if (sortOrder->numChildren() != values->numChildren())
  3158. {
  3159. reportError(ERR_MAX_MISMATCH, errpos, "MAX() must specify a value for each sort order element");
  3160. return;
  3161. }
  3162. ForEachChild(i, sortOrder)
  3163. {
  3164. if (checkCompatible(sortOrder->queryChild(i)->queryType(), values->queryChild(i)->queryType(), errpos, false) == 0)
  3165. {
  3166. reportError(ERR_MAX_MISMATCH, errpos, "Value for MAX() element %d is not compatible with the sort order", i);
  3167. return;
  3168. }
  3169. }
  3170. }
  3171. void HqlGram::checkSvcAttrNoValue(IHqlExpression* attr, const attribute& errpos)
  3172. {
  3173. if (attr->numChildren()>0)
  3174. reportWarning(CategorySyntax, WRN_SVC_ATTRNEEDNOVALUE, errpos.pos,"Service attribute '%s' requires no value; ignored",str(attr->queryName()));
  3175. }
  3176. void cleanupService(IHqlScope*& serviceScope)
  3177. {
  3178. IHqlExpression* svc = queryExpression(serviceScope);
  3179. if (svc)
  3180. {
  3181. if (!svc->isExprClosed())
  3182. svc = svc->closeExpr();
  3183. svc->Release();
  3184. }
  3185. serviceScope = NULL;
  3186. }
  3187. IHqlExpression* HqlGram::checkServiceDef(IHqlScope* serviceScope,IIdAtom * name, IHqlExpression* attrs, const attribute& errpos)
  3188. {
  3189. // already defined?
  3190. OwnedHqlExpr def = serviceScope->lookupSymbol(name, LSFsharedOK|LSFignoreBase, lookupCtx);
  3191. if (def)
  3192. reportError(ERR_SVC_FUNCDEFINED,errpos, "Function is already defined in service: %s",str(name));
  3193. // gather the attrs
  3194. HqlExprArray attrArray;
  3195. if (attrs)
  3196. attrs->unwindList(attrArray,no_comma);
  3197. bool hasEntrypoint = false;
  3198. bool foldSeen = false;
  3199. bool nofoldSeen = false;
  3200. unsigned count = attrArray.length();
  3201. if (count>0)
  3202. {
  3203. // check attr one by one
  3204. bool bcdApi = false, rtlApi = false, cApi = false;
  3205. for (unsigned i=0; i<count; i++)
  3206. {
  3207. IHqlExpression* attr = &attrArray.item(i);
  3208. IAtom * name = attr->queryName();
  3209. if (attr->queryChild(0) && !attr->queryChild(0)->queryValue())
  3210. reportError(ERR_EXPECTED_CONST, errpos.pos, "Expected a constant argument for service attribute: '%s';", str(name));
  3211. // check duplication
  3212. unsigned j;
  3213. for (j=0; j<i; j++)
  3214. {
  3215. IHqlExpression & cur = attrArray.item(j);
  3216. if (cur.queryName()==name)
  3217. {
  3218. if (&cur != attr)
  3219. reportError(ERR_SVC_ATTRDEFINED, errpos, "Service has duplicate attribute with different value: %s", str(name));
  3220. break;
  3221. }
  3222. }
  3223. if (name == entrypointAtom || name == initfunctionAtom)
  3224. {
  3225. hasEntrypoint = true;
  3226. bool invalid = false;
  3227. StringBuffer buf;
  3228. if (attr->numChildren()==0)
  3229. invalid = true;
  3230. else
  3231. {
  3232. getStringValue(buf, attr->queryChild(0));
  3233. if (!isCIdentifier(buf.str()))
  3234. invalid = true;
  3235. }
  3236. if (invalid)
  3237. {
  3238. if (name == entrypointAtom)
  3239. reportError(ERR_SVC_INVALIDENTRYPOINT, errpos, "Invalid entrypoint '%s': must be valid C identifier", buf.str());
  3240. else
  3241. reportError(ERR_SVC_INVALIDINITFUNC, errpos, "Invalid initFunction '%s': must be valid C identifier", buf.str());
  3242. }
  3243. }
  3244. else if (name == pseudoentrypointAtom)
  3245. {
  3246. HqlExprArray args;
  3247. unwindChildren(args, attr);
  3248. attrs = createComma(attrs, createAttribute(entrypointAtom, args));
  3249. hasEntrypoint = true;
  3250. }
  3251. else if (name == libraryAtom || name == pluginAtom)
  3252. {
  3253. bool invalid = false;
  3254. if (attr->numChildren()==0)
  3255. invalid = true;
  3256. else
  3257. {
  3258. StringBuffer buf;
  3259. getStringValue(buf, attr->queryChild(0));
  3260. // can we do better?
  3261. if (*buf.str() == 0)
  3262. invalid = true;
  3263. }
  3264. if (invalid)
  3265. reportError(ERR_SVC_INVALIDLIBRARY,errpos,"Invalid %s: can not be empty", str(name));
  3266. }
  3267. else if (name == includeAtom)
  3268. {
  3269. bool invalid = false;
  3270. //no parameters on include stops definition being generated - used internally.
  3271. if (attr->numChildren()!=0)
  3272. {
  3273. StringBuffer buf;
  3274. getStringValue(buf, attr->queryChild(0));
  3275. // can we do better?
  3276. if (*buf.str() == 0)
  3277. invalid = true;
  3278. }
  3279. /* should be really an error */
  3280. if (invalid)
  3281. reportWarning(CategorySyntax, ERR_SVC_INVALIDINCLUDE,errpos.pos, "Invalid include: can not be empty");
  3282. }
  3283. else if (name == eclrtlAtom)
  3284. {
  3285. rtlApi = true;
  3286. checkSvcAttrNoValue(attr, errpos);
  3287. }
  3288. else if (name == cAtom)
  3289. {
  3290. cApi = true;
  3291. checkSvcAttrNoValue(attr, errpos);
  3292. }
  3293. else if (name == bcdAtom)
  3294. {
  3295. bcdApi = true;
  3296. checkSvcAttrNoValue(attr, errpos);
  3297. }
  3298. else if (name == pureAtom || name == templateAtom || name == volatileAtom || name == onceAtom || name == actionAtom)
  3299. {
  3300. checkSvcAttrNoValue(attr, errpos);
  3301. }
  3302. else if ((name == gctxmethodAtom) || (name == ctxmethodAtom) || (name == contextAtom) || (name == globalContextAtom) || (name == sysAtom) ||
  3303. (name == methodAtom) || (name == newSetAtom) || (name == omethodAtom) || (name == oldSetFormatAtom) || (name == contextSensitiveAtom))
  3304. {
  3305. checkSvcAttrNoValue(attr, errpos);
  3306. }
  3307. else if ((name == userMatchFunctionAtom) || (name == costAtom) || (name == allocatorAtom) || (name == extendAtom) || (name == passParameterMetaAtom))
  3308. {
  3309. }
  3310. else if (name == holeAtom)
  3311. {
  3312. //backward compatibility
  3313. }
  3314. else if (name == foldAtom)
  3315. foldSeen = true;
  3316. else if (name == nofoldAtom)
  3317. nofoldSeen = true;
  3318. else // unsupported
  3319. reportWarning(CategorySyntax,WRN_SVC_UNSUPPORTED_ATTR, errpos.pos, "Unsupported service attribute: '%s'; ignored", str(name));
  3320. }
  3321. // check attribute conflicts
  3322. int apiAttrs = 0;
  3323. if (rtlApi) apiAttrs++;
  3324. if (cApi) apiAttrs++;
  3325. if (bcdApi) apiAttrs++;
  3326. if (apiAttrs>1)
  3327. reportWarning(CategorySyntax, ERR_SVC_ATTRCONFLICTS, errpos.pos, "Attributes eclrtl, bcd, c are conflict: only 1 can be used at a time");
  3328. }
  3329. if (foldSeen && !nofoldSeen)
  3330. {
  3331. // Check that we are allowed to fold...
  3332. if (!checkAllowed(errpos, "foldextern", "FOLD attribute"))
  3333. attrs = createComma(attrs, createAttribute(_disallowed_Atom));
  3334. }
  3335. if (!hasEntrypoint)
  3336. {
  3337. IHqlExpression *nameAttr = createAttribute(entrypointAtom, createConstant(str(name)));
  3338. attrs = createComma(attrs, nameAttr);
  3339. }
  3340. attrs = createComma(attrs, LINK(serviceExtraAttributes));
  3341. return attrs;
  3342. }
  3343. bool HqlGram::checkAlienTypeDef(IHqlScope* scope, const attribute& errpos)
  3344. {
  3345. bool hasError = false;
  3346. if (!scope)
  3347. return false;
  3348. // load
  3349. OwnedHqlExpr load = scope->lookupSymbol(loadId, LSFpublic, lookupCtx);
  3350. if (!load)
  3351. {
  3352. reportError(ERR_USRTYPE_NOLOAD,errpos,"Load function is not defined for user type");
  3353. hasError = true;
  3354. }
  3355. else
  3356. {
  3357. if (!load->isFunctionDefinition())
  3358. {
  3359. reportError(ERR_USRTYPE_NOTDEFASFUNC, errpos, "Load is not defined as a function for user type");
  3360. hasError = true;
  3361. }
  3362. else if (load->numChildren()!=2)
  3363. {
  3364. reportError(ERR_PARAM_WRONGNUMBER, errpos, "Load must have exactly 1 parameter");
  3365. hasError = true;
  3366. }
  3367. }
  3368. // store
  3369. OwnedHqlExpr store = scope->lookupSymbol(storeId, LSFpublic, lookupCtx);
  3370. if (!store)
  3371. {
  3372. reportError(ERR_USRTYPE_NOSTORE,errpos,"Store function is not defined for alien type");
  3373. hasError = true;
  3374. }
  3375. else
  3376. {
  3377. if (!store->isFunctionDefinition())
  3378. {
  3379. reportError(ERR_USRTYPE_NOTDEFASFUNC, errpos, "Store is not defined as a function for user type");
  3380. hasError = true;
  3381. }
  3382. else if (store->numChildren()!=2)
  3383. {
  3384. reportError(ERR_PARAM_WRONGNUMBER, errpos,"Store must have exactly 1 parameter");
  3385. hasError = true;
  3386. }
  3387. }
  3388. // types
  3389. if (!hasError) /* only do the type check when no error, otherwise, crash may occur */
  3390. {
  3391. IHqlExpression * loadParam = load->queryChild(1)->queryChild(0);
  3392. IHqlExpression * storeParam = store->queryChild(1)->queryChild(0);
  3393. ITypeInfo * storeType = store->queryType()->queryChildType();
  3394. ITypeInfo* logical= load->queryType()->queryChildType();
  3395. ITypeInfo* physical = loadParam->queryType();
  3396. if (logical != storeParam->queryType())
  3397. reportError(ERR_USRTYPE_BADLOGTYPE, errpos, "User type has inconsistent logical types");
  3398. else if (physical != storeType)
  3399. reportError(ERR_USRTYPE_BADPHYTYPE, errpos,"User type has inconsistent physical types");
  3400. else
  3401. {
  3402. // check whether we need a physicalLength()
  3403. bool phylenNeeded = physical->getSize()==UNKNOWN_LENGTH;
  3404. OwnedHqlExpr phyLen = scope->lookupSymbol(physicalLengthId, LSFpublic, lookupCtx);
  3405. // physicalLength
  3406. if (phylenNeeded)
  3407. {
  3408. if (!phyLen)
  3409. reportError(ERR_USRTYPE_NOPHYLEN, errpos, "Need physicalLength since physical type size is unknown");
  3410. else
  3411. {
  3412. if (phyLen->isFunctionDefinition())
  3413. {
  3414. unsigned numArgs = phyLen->queryChild(1)->numChildren();
  3415. if (numArgs == 1)
  3416. {
  3417. IHqlExpression * phylenParam = phyLen->queryChild(1)->queryChild(0);
  3418. if (physical == storeType && phylenParam->queryType() != physical)
  3419. reportError(ERR_USRTYPE_BADPHYLEN, errpos, "physicalLength need to take physical type as parameter");
  3420. }
  3421. else if (numArgs > 1)
  3422. reportError(ERR_PARAM_WRONGNUMBER, errpos, "physicalLength can have at most 1 parameter");
  3423. if (phyLen->queryType()->queryChildType()->getTypeCode() != type_int)
  3424. reportError(ERR_TYPEERR_INT, errpos, "physicalLength needs to return integer");
  3425. }
  3426. else
  3427. {
  3428. // must be defined as an attribute.
  3429. // How to check??
  3430. // MORE: should disallow this:
  3431. // export physicalLength := MACRO 3x ENDMACRO;
  3432. // and
  3433. // export physicalLength(String physical) := MACRO 3x ENDMACRO;
  3434. if (phyLen->isMacro() || !phyLen->queryType() || phyLen->queryType()->getTypeCode()!=type_int)
  3435. reportError(ERR_TYPEERR_INT,errpos, "physicalLength needs to be type integer");
  3436. }
  3437. }
  3438. }
  3439. else
  3440. {
  3441. if (phyLen)
  3442. reportWarning(CategoryIgnored, WRN_USRTYPE_EXTRAPHYLEN,errpos.pos,"physicalLength not needed since the type size is known");
  3443. }
  3444. }
  3445. }
  3446. return !hasError;
  3447. }
  3448. ITypeInfo *HqlGram::checkPromoteType(attribute &a1, attribute &a2)
  3449. {
  3450. checkCompatible(a1.queryExprType(), a2.queryExprType(), a2);
  3451. return promoteToSameType(a1, a2);
  3452. }
  3453. ITypeInfo *HqlGram::checkPromoteIfType(attribute &a1, attribute &a2)
  3454. {
  3455. if (a1.isDataset() || a2.isDataset())
  3456. {
  3457. OwnedHqlExpr right = a2.getExpr();
  3458. a2.setExpr(checkEnsureRecordsMatch(a1.queryExpr(), right, a2.pos, false));
  3459. ensureDataset(a1);
  3460. ensureDataset(a2);
  3461. return NULL;
  3462. }
  3463. if (a1.isDatarow() || a2.isDatarow())
  3464. {
  3465. OwnedHqlExpr right = a2.getExpr();
  3466. a2.setExpr(checkEnsureRecordsMatch(a1.queryExpr(), right, a2.pos, true));
  3467. checkDatarow(a1);
  3468. checkDatarow(a2);
  3469. return NULL;
  3470. }
  3471. if (a1.isDictionary() || a2.isDictionary())
  3472. {
  3473. OwnedHqlExpr right = a2.getExpr();
  3474. a2.setExpr(checkEnsureRecordsMatch(a1.queryExpr(), right, a2.pos, true));
  3475. checkDictionary(a1);
  3476. checkDictionary(a2);
  3477. return NULL;
  3478. }
  3479. checkCompatible(a1.queryExprType(), a2.queryExprType(), a2);
  3480. ITypeInfo *t1 = a1.queryExprType();
  3481. ITypeInfo *t2 = a2.queryExprType();
  3482. Owned<ITypeInfo> type = ::getPromotedECLType(t1, t2);
  3483. if ((isStringType(type) || isUnicodeType(type)) && (t1->getStringLen() != t2->getStringLen()))
  3484. type.setown(getStretchedType(UNKNOWN_LENGTH, type));
  3485. ensureType(a1, type);
  3486. ensureType(a2, type);
  3487. return type.getClear();
  3488. }
  3489. ITypeInfo * HqlGram::checkStringIndex(attribute & strAttr, attribute & idxAttr)
  3490. {
  3491. IHqlExpression * src = strAttr.queryExpr();
  3492. SubStringHelper info(strAttr.queryExpr(), idxAttr.queryExpr());
  3493. unsigned strSize = getBestLengthEstimate(src);
  3494. unsigned startIndex = info.fixedStart;
  3495. unsigned endIndex = info.fixedEnd;
  3496. if (info.knownStart() && (startIndex < 1 || ((strSize != UNKNOWN_LENGTH) && startIndex > strSize)))
  3497. {
  3498. if (startIndex<1)
  3499. reportWarning(CategoryIndex, ERR_SUBSTR_INVALIDRANGE, idxAttr.pos,"Invalid substring range: start index %d must >= 1", startIndex);
  3500. else /* assert: strSize != UNKNOWN_LENGTH */
  3501. reportWarning(CategoryIndex, ERR_SUBSTR_INVALIDRANGE, idxAttr.pos,"Invalid substring range: index %d out of bound: 1..%d", startIndex, strSize);
  3502. }
  3503. else if (info.knownEnd() && (endIndex < 1 || ((strSize != UNKNOWN_LENGTH) && endIndex > strSize)))
  3504. {
  3505. if (endIndex < 1)
  3506. reportWarning(CategoryIndex, ERR_SUBSTR_INVALIDRANGE, idxAttr.pos, "Invalid substring range: end index %d must >= 1", endIndex);
  3507. else
  3508. reportWarning(CategoryIndex, ERR_SUBSTR_INVALIDRANGE, idxAttr.pos, "Invalid substring range: index %d out of bound: 1..%d", endIndex, strSize);
  3509. }
  3510. else if (info.knownStart() && info.knownEnd() && startIndex > endIndex)
  3511. reportWarning(CategoryIndex, ERR_SUBSTR_INVALIDRANGE, idxAttr.pos, "Invalid substring range: start index %d > end index %d", startIndex, endIndex);
  3512. unsigned resultSize = UNKNOWN_LENGTH;
  3513. // if (strSize != UNKNOWN_LENGTH)
  3514. {
  3515. if (info.knownStart() && info.knownEnd() && endIndex >= startIndex)
  3516. resultSize = endIndex - startIndex + 1;
  3517. else if (info.from == info.to)
  3518. resultSize = 1;
  3519. }
  3520. ITypeInfo * subType;
  3521. ITypeInfo *type = src->queryType();
  3522. if (type->getTypeCode() == type_varstring)
  3523. subType = makeStringType(UNKNOWN_LENGTH, NULL, NULL);
  3524. else if (type->getTypeCode() == type_varunicode)
  3525. subType = makeUnicodeType(UNKNOWN_LENGTH, type->queryLocale());
  3526. else
  3527. subType = getStretchedType(resultSize, type);
  3528. return subType;
  3529. }
  3530. void HqlGram::checkAggregateRecords(IHqlExpression * expr, IHqlExpression * record, attribute & errpos)
  3531. {
  3532. if (!recordTypesMatch(expr->queryChild(1), record))
  3533. reportError(ERR_ONFAIL_MISMATCH, errpos, "Type of the transform does not match the aggregate record");
  3534. if (containsIfBlock(record))
  3535. reportError(ERR_NO_IFBLOCKS, errpos, "IFBLOCKS not supported in the aggregate target record");
  3536. IHqlExpression * mergeTransform = queryAttributeChild(expr, mergeTransformAtom, 0);
  3537. if (mergeTransform)
  3538. {
  3539. if (!recordTypesMatch(mergeTransform, expr))
  3540. reportError(ERR_ONFAIL_MISMATCH, errpos, "Type of the MERGE transform does not match the aggregate record");
  3541. }
  3542. }
  3543. void HqlGram::checkOnFailRecord(IHqlExpression * expr, attribute & errpos)
  3544. {
  3545. IHqlExpression * onFail = expr->queryAttribute(onFailAtom);
  3546. if (onFail)
  3547. {
  3548. IHqlExpression * transform = onFail->queryChild(0);
  3549. if (transform->getOperator() != no_skip)
  3550. {
  3551. if (!recordTypesMatch(transform, expr))
  3552. reportError(ERR_ONFAIL_MISMATCH, errpos, "Type of the ONFAIL transform does not match the type of the result");
  3553. }
  3554. }
  3555. }
  3556. void HqlGram::applyDefaultPromotions(attribute &a1, bool extendPrecision)
  3557. {
  3558. ITypeInfo *t1 = a1.queryExprType();
  3559. switch (t1->getTypeCode())
  3560. {
  3561. case type_swapint:
  3562. case type_packedint:
  3563. case type_bitfield:
  3564. ensureType(a1, defaultIntegralType);
  3565. break;
  3566. }
  3567. if (extendPrecision)
  3568. {
  3569. ITypeInfo * type = a1.queryExprType();
  3570. if ((type->getTypeCode() == type_int) && (type->getSize() < 8))
  3571. ensureType(a1, defaultIntegralType);
  3572. }
  3573. }
  3574. void HqlGram::checkSameType(attribute &a1, attribute &a2)
  3575. {
  3576. ITypeInfo *t1 = a1.queryExprType();
  3577. ITypeInfo *t2 = a2.queryExprType();
  3578. if (t1 != t2)
  3579. {
  3580. StringBuffer s1, s2;
  3581. reportError(ERR_TYPE_DIFFER, a2, "Expressions must have the same type: %s vs %s",getFriendlyTypeStr(t1, s1).str(), getFriendlyTypeStr(t2, s2).str());
  3582. }
  3583. }
  3584. void HqlGram::normalizeStoredNameExpression(attribute & a)
  3585. {
  3586. normalizeExpression(a, type_string, true);
  3587. IHqlExpression * name = a.queryExpr();
  3588. if (name && name->queryValue())
  3589. {
  3590. StringBuffer nameText;
  3591. name->queryValue()->getStringValue(nameText);
  3592. if (!isCIdentifier(nameText))
  3593. reportError(ERR_NAME_NOT_VALID_ID, a, "Name '%s' must be a valid identifier.", nameText.str());
  3594. }
  3595. }
  3596. IHqlExpression * HqlGram::addDatasetSelector(IHqlExpression * lhs, IHqlExpression * rhs)
  3597. {
  3598. if (rhs->getOperator() != no_select)
  3599. return createSelectExpr(lhs, rhs);
  3600. IHqlExpression * ret = addDatasetSelector(lhs, LINK(rhs->queryChild(0)));
  3601. ret = createSelectExpr(ret, LINK(rhs->queryChild(1)));
  3602. rhs->Release();
  3603. return ret;
  3604. }
  3605. bool HqlGram::isSingleValuedExpressionList(const attribute & attr)
  3606. {
  3607. IHqlExpression * expr = attr.queryExpr();
  3608. if (expr->getOperator() == no_comma)
  3609. return false;
  3610. if (expr->isList())
  3611. return false;
  3612. return true;
  3613. }
  3614. IHqlExpression * HqlGram::createListFromExprArray(const attribute & errpos, HqlExprArray & args)
  3615. {
  3616. ITypeInfo * retType = promoteToSameType(args, errpos, NULL, true);
  3617. return createValue(no_list, makeSetType(retType), args);
  3618. }
  3619. IHqlExpression * HqlGram::createListFromExpressionList(attribute & attr)
  3620. {
  3621. HqlExprArray args;
  3622. attr.unwindCommaList(args);
  3623. return normalizeExprList(attr, args);
  3624. }
  3625. void HqlGram::normalizeExpression(attribute & exprAttr)
  3626. {
  3627. if (exprAttr.getOperator() == no_sortlist)
  3628. {
  3629. HqlExprArray args;
  3630. unwindChildren(args, exprAttr.queryExpr());
  3631. assertex(args.ordinality());
  3632. exprAttr.release().setExpr(normalizeExprList(exprAttr, args));
  3633. }
  3634. }
  3635. void HqlGram::normalizeExpression(attribute & exprAttr, type_t expectedType, bool isConstant)
  3636. {
  3637. normalizeExpression(exprAttr);
  3638. switch (expectedType)
  3639. {
  3640. case type_boolean:
  3641. checkBoolean(exprAttr);
  3642. break;
  3643. case type_string:
  3644. checkString(exprAttr);
  3645. break;
  3646. case type_int:
  3647. checkInteger(exprAttr);
  3648. break;
  3649. case type_any:
  3650. //No checking
  3651. break;
  3652. case type_numeric:
  3653. checkNumeric(exprAttr);
  3654. break;
  3655. case type_scalar:
  3656. checkScalar(exprAttr);
  3657. break;
  3658. case type_real:
  3659. checkReal(exprAttr);
  3660. break;
  3661. case type_stringorunicode:
  3662. checkStringOrUnicode(exprAttr);
  3663. break;
  3664. case type_set:
  3665. checkList(exprAttr);
  3666. break;
  3667. case type_dictionary:
  3668. checkDictionary(exprAttr);
  3669. break;
  3670. case type_table:
  3671. ensureDataset(exprAttr);
  3672. break;
  3673. case type_data:
  3674. //MORE: Complain if not assign compatible.
  3675. break;
  3676. case type_unicode:
  3677. ensureUnicode(exprAttr);
  3678. break;
  3679. default:
  3680. throwUnexpected();
  3681. }
  3682. if (isConstant)
  3683. checkFoldConstant(exprAttr);
  3684. }
  3685. IHqlExpression * HqlGram::normalizeExprList(const attribute & errpos, const HqlExprArray & values)
  3686. {
  3687. if ((values.ordinality() == 1) && values.item(0).isList())
  3688. return &OLINK(values.item(0));
  3689. HqlExprArray lists;
  3690. HqlExprArray thisList;
  3691. IHqlExpression * emptyList = NULL;
  3692. ForEachItemIn(i, values)
  3693. {
  3694. IHqlExpression & cur = values.item(i);
  3695. if (cur.isList())
  3696. {
  3697. switch (cur.getOperator())
  3698. {
  3699. case no_list:
  3700. unwindChildren(thisList, &cur);
  3701. if (cur.numChildren() == 0)
  3702. emptyList = &cur;
  3703. break;
  3704. case no_null:
  3705. emptyList = &cur;
  3706. break;
  3707. default:
  3708. if (thisList.ordinality())
  3709. {
  3710. lists.append(*createListFromExprArray(errpos, thisList));
  3711. thisList.kill();
  3712. }
  3713. lists.append(OLINK(cur));
  3714. break;
  3715. }
  3716. }
  3717. else
  3718. thisList.append(OLINK(cur));
  3719. }
  3720. if (thisList.ordinality())
  3721. lists.append(*createListFromExprArray(errpos, thisList));
  3722. if (lists.ordinality() == 0)
  3723. {
  3724. if (emptyList)
  3725. return LINK(emptyList);
  3726. return createValue(no_list, makeSetType(NULL));
  3727. }
  3728. Owned<ITypeInfo> combinedType = promoteToSameType(lists, errpos, NULL, true);
  3729. return createUnbalanced(no_addsets, combinedType, lists);
  3730. }
  3731. IHqlExpression * HqlGram::createIndirectSelect(IHqlExpression * lhs, IHqlExpression * rhs, const attribute & errpos)
  3732. {
  3733. OwnedHqlExpr releaseRhs = rhs;
  3734. IHqlExpression * record = lhs->queryRecord();
  3735. assertex(record);
  3736. IHqlExpression * field = rhs;
  3737. while (rhs->getOperator() == no_indirect)
  3738. rhs = rhs->queryChild(0);
  3739. if (rhs->getOperator() == no_select)
  3740. field = rhs->queryChild(1);
  3741. if (!isValidFieldReference(field))
  3742. {
  3743. reportError(ERR_EXPECTED_FIELD, errpos, "Expected a field reference inside <>");
  3744. lhs->Release();
  3745. return createNullExpr(rhs);
  3746. }
  3747. if (record->hasAttribute(abstractAtom) || (field->getOperator() != no_field))
  3748. return ::createSelectExpr(lhs, createValue(no_indirect, field->getType(), LINK(field)));
  3749. OwnedHqlExpr match = record->querySimpleScope()->lookupSymbol(field->queryId());
  3750. if (match)
  3751. {
  3752. if (match == field)
  3753. return createSelect(lhs, LINK(match), errpos);
  3754. OwnedHqlExpr normalizedMatch = getUnadornedRecordOrField(match);
  3755. OwnedHqlExpr normalizedField = getUnadornedRecordOrField(field);
  3756. if (normalizedMatch == normalizedField)
  3757. return createSelect(lhs, LINK(match), errpos);
  3758. }
  3759. if (rhs->getOperator() == no_select)
  3760. {
  3761. IHqlExpression * selector = rhs->queryChild(0);
  3762. if (selector->getOperator() == no_select)
  3763. {
  3764. OwnedHqlExpr selected = createIndirectSelect(lhs, LINK(selector), errpos);
  3765. return createIndirectSelect(selected.getClear(), field, errpos);
  3766. }
  3767. }
  3768. reportError(ERR_DATASET_NOT_CONTAIN_X, errpos, "Dataset doesn't contain a field %s", str(field->queryName()));
  3769. lhs->Release();
  3770. return createNullExpr(rhs);
  3771. }
  3772. IHqlExpression * HqlGram::createSelect(IHqlExpression * lhs, IHqlExpression * rhs, const attribute & errpos)
  3773. {
  3774. if (rhs->getOperator() == no_indirect)
  3775. {
  3776. OwnedHqlExpr releaseRhs = rhs;
  3777. return createIndirectSelect(lhs, LINK(rhs->queryChild(0)), errpos);
  3778. }
  3779. if (rhs->getOperator() != no_field)
  3780. {
  3781. rhs->Release();
  3782. rhs = ::createField(unnamedId, LINK(defaultIntegralType), NULL);
  3783. }
  3784. return ::createSelectExpr(lhs, rhs);
  3785. }
  3786. IHqlExpression * HqlGram::createAveList(const attribute & errpos, IHqlExpression * list)
  3787. {
  3788. ITypeInfo * elemType = queryElementType(errpos, list);
  3789. Owned<ITypeInfo> sumType = getSumAggType(elemType);
  3790. OwnedHqlExpr sum = createValue(no_sumlist, LINK(sumType), LINK(list));
  3791. OwnedHqlExpr count = createValue(no_countlist, LINK(defaultIntegralType), LINK(list));
  3792. return createValue(no_div, LINK(defaultRealType), ensureExprType(sum, defaultRealType), ensureExprType(count, defaultRealType));
  3793. }
  3794. IHqlExpression * HqlGram::createSortExpr(node_operator op, attribute & dsAttr, const attribute & orderAttr, HqlExprArray & args)
  3795. {
  3796. IHqlExpression *input = dsAttr.getExpr();
  3797. OwnedHqlExpr joinedClause;
  3798. OwnedHqlExpr attrs;
  3799. IHqlExpression *sortOrder = processSortList(orderAttr, no_sort, input, args, &joinedClause, &attrs);
  3800. if (!sortOrder)
  3801. {
  3802. reportWarning(CategoryMistake, SeverityError, ERR_SORT_EMPTYLIST, orderAttr.pos, "The list to be sorted on is empty");
  3803. return input;
  3804. }
  3805. bool isLocal = (queryAttributeInList(localAtom, attrs)!=NULL);
  3806. checkDistribution(dsAttr, input, isLocal, false);
  3807. if (joinedClause)
  3808. {
  3809. checkCosort(sortOrder, joinedClause, orderAttr);
  3810. sortOrder = createComma(sortOrder, joinedClause.getClear());
  3811. op = no_cosort;
  3812. }
  3813. sortOrder = createComma(sortOrder, attrs.getClear());
  3814. return createDataset(op, input, sortOrder);
  3815. }
  3816. ITypeInfo * HqlGram::queryElementType(const attribute & errpos, IHqlExpression * list)
  3817. {
  3818. ITypeInfo * elemType = list->queryType()->queryChildType();
  3819. if (elemType)
  3820. return elemType;
  3821. reportError(ERR_CANNOT_DEDUCE_TYPE, errpos, "Can't deduce type of elements in list");
  3822. return defaultIntegralType;
  3823. }
  3824. void HqlGram::setDefaultString(attribute &a)
  3825. {
  3826. a.release();
  3827. a.setExpr(createConstant(""));
  3828. }
  3829. void HqlGram::ensureString(attribute &a)
  3830. {
  3831. ITypeInfo *t1 = a.queryExprType();
  3832. if (t1 && !isSimpleStringType(t1))
  3833. {
  3834. if (!t1->isScalar()) // is this test sufficient
  3835. {
  3836. StringBuffer s;
  3837. reportError(ERR_TYPE_INCOMPATIBLE, a, "Incompatible types: expected String, given %s", getFriendlyTypeStr(t1, s).str());
  3838. setDefaultString(a);
  3839. }
  3840. else if (isStringType(t1))
  3841. {
  3842. t1 = makeStringType(t1->getStringLen(), NULL, NULL);
  3843. a.setExpr(createValue(no_implicitcast, t1, a.getExpr() ));
  3844. }
  3845. else
  3846. {
  3847. t1 = makeStringType(UNKNOWN_LENGTH, NULL, NULL);
  3848. a.setExpr(createValue(no_implicitcast, t1, a.getExpr() ));
  3849. }
  3850. }
  3851. }
  3852. void HqlGram::validateXPath(attribute & a)
  3853. {
  3854. IHqlExpression * expr = a.queryExpr();
  3855. IValue * value = expr->queryValue();
  3856. if (value)
  3857. {
  3858. StringBuffer s, error;
  3859. value->getStringValue(s);
  3860. if (!validateXMLParseXPath(s.str(), &error))
  3861. reportError(ERR_INVALID_XPATH, a, "Invalid XPATH syntax: %s", error.str());
  3862. }
  3863. }
  3864. void HqlGram::ensureTypeCanBeIndexed(attribute &a)
  3865. {
  3866. ITypeInfo *t1 = a.queryExprType();
  3867. if (!t1)
  3868. setDefaultString(a);
  3869. else
  3870. {
  3871. switch (t1->queryPromotedType()->getTypeCode())
  3872. {
  3873. case type_string:
  3874. case type_varstring:
  3875. case type_qstring:
  3876. case type_data:
  3877. case type_unicode:
  3878. case type_varunicode:
  3879. case type_utf8:
  3880. case type_any:
  3881. break;
  3882. default:
  3883. {
  3884. StringBuffer typeName;
  3885. reportWarning(CategorySyntax, ERR_TYPEMISMATCH_STRING, a.pos, "substring applied to value of type %s", getFriendlyTypeStr(t1, typeName).str());
  3886. ensureString(a);
  3887. break;
  3888. }
  3889. }
  3890. }
  3891. }
  3892. void HqlGram::ensureUnicode(attribute &a)
  3893. {
  3894. ITypeInfo *t1 = a.queryExprType();
  3895. if (t1 && !isUnicodeType(t1))
  3896. {
  3897. if (isStringType(t1))
  3898. {
  3899. Owned<ITypeInfo> unicodeType = makeUnicodeType(UNKNOWN_LENGTH, NULL);
  3900. OwnedHqlExpr value = a.getExpr();
  3901. a.setExpr(ensureExprType(value, unicodeType));
  3902. }
  3903. else
  3904. {
  3905. StringBuffer s;
  3906. reportError(ERR_TYPE_INCOMPATIBLE, a, "Incompatible types: expected Unicode, given %s", getFriendlyTypeStr(t1, s).str());
  3907. }
  3908. }
  3909. }
  3910. void HqlGram::ensureData(attribute &a)
  3911. {
  3912. ITypeInfo *t1 = a.queryExprType();
  3913. if (t1 && (t1->getTypeCode() != type_data))
  3914. {
  3915. StringBuffer s;
  3916. reportError(ERR_TYPE_INCOMPATIBLE, a, "Incompatible types: expected Data, given %s", getFriendlyTypeStr(t1, s).str());
  3917. }
  3918. }
  3919. IAtom * HqlGram::ensureCommonLocale(attribute &a, attribute &b)
  3920. {
  3921. ITypeInfo * t1 = a.queryExprType();
  3922. ITypeInfo * t2 = b.queryExprType();
  3923. if(t1 && t2)
  3924. {
  3925. if(haveCommonLocale(t1, t2))
  3926. return getCommonLocale(t1, t2);
  3927. reportError(ERR_LOCALES_INCOMPATIBLE, b, "Incompatible locales in unicode arguments of binary operation");
  3928. }
  3929. return _empty_str_Atom;
  3930. }
  3931. void HqlGram::ensureUnicodeLocale(attribute & a, char const * locale)
  3932. {
  3933. Owned<ITypeInfo> type = a.queryExpr()->getType();
  3934. if(strcmp(locale, str(type->queryLocale())) != 0)
  3935. {
  3936. switch (type->getTypeCode())
  3937. {
  3938. case type_varunicode:
  3939. type.setown(makeVarUnicodeType(type->getStringLen(), createLowerCaseAtom(locale)));
  3940. break;
  3941. case type_unicode:
  3942. type.setown(makeUnicodeType(type->getStringLen(), createLowerCaseAtom(locale)));
  3943. break;
  3944. case type_utf8:
  3945. type.setown(makeUtf8Type(type->getStringLen(), createLowerCaseAtom(locale)));
  3946. break;
  3947. }
  3948. a.setExpr(createValue(no_implicitcast, LINK(type), a.getExpr()));
  3949. }
  3950. }
  3951. void HqlGram::checkPattern(attribute & pattern, bool isCompound)
  3952. {
  3953. type_t ptc = pattern.queryExprType()->getTypeCode();
  3954. if (current_type)
  3955. {
  3956. switch (current_type->getTypeCode())
  3957. {
  3958. case type_pattern:
  3959. if (ptc != type_pattern)
  3960. reportError(ERR_TOKEN_IN_PATTERN, pattern, "Only patterns are valid inside pattern definitions");
  3961. break;
  3962. case type_token:
  3963. if (isCompound && ptc != type_pattern)
  3964. reportError(ERR_TOKEN_IN_TOKEN, pattern, "Combinations of tokens are not valid inside a token definition");
  3965. else if (ptc == type_rule)
  3966. reportError(ERR_TOKEN_IN_TOKEN, pattern, "Rules are not valid inside a token definition");
  3967. break;
  3968. case type_rule:
  3969. if (ptc == type_pattern)
  3970. pattern.setExpr(createValue(no_pat_imptoken, makeTokenType(), pattern.getExpr()));
  3971. break;
  3972. }
  3973. }
  3974. else
  3975. {
  3976. //Must be an separator attribute - allow anything
  3977. }
  3978. }
  3979. IHqlExpression * HqlGram::createPatternOr(HqlExprArray & args, const attribute & errpos)
  3980. {
  3981. if (args.ordinality() == 1)
  3982. return &OLINK(args.item(0));
  3983. Owned<ITypeInfo> type = makePatternType();
  3984. ForEachItemIn(idx, args)
  3985. {
  3986. ITypeInfo * argType = args.item(idx).queryType();
  3987. type_t argtc = argType->getTypeCode();
  3988. if (type->getTypeCode() == type_rule)
  3989. {
  3990. ITypeInfo * rRecord = type->queryChildType();
  3991. ITypeInfo * aRecord = argType->queryChildType();
  3992. if (aRecord != rRecord)
  3993. {
  3994. if (!rRecord || !aRecord || !recordTypesMatch(rRecord, aRecord))
  3995. reportError(ERR_PATTERN_TYPE_MATCH, errpos, "Productions must return the same record");
  3996. }
  3997. }
  3998. if (argtc == type_rule)
  3999. {
  4000. if (idx == 0)
  4001. type.set(argType);
  4002. }
  4003. else if ((argtc == type_token) && (type->getTypeCode() == type_pattern))
  4004. type.set(argType);
  4005. }
  4006. if (type->getTypeCode() != type_pattern)
  4007. {
  4008. ForEachItemIn(idx, args)
  4009. {
  4010. IHqlExpression & cur = args.item(idx);
  4011. ITypeInfo * argType = cur.queryType();
  4012. if (argType->getTypeCode() == type_pattern)
  4013. args.replace(*createValue(no_pat_imptoken, makeTokenType(), LINK(&cur)), idx);
  4014. }
  4015. }
  4016. return createValue(no_pat_or, type.getClear(), args);
  4017. }
  4018. void HqlGram::checkSubPattern(attribute & subpattern)
  4019. {
  4020. if (subpattern.queryExprType()->getTypeCode() == type_rule)
  4021. {
  4022. //MORE: May want to extend this eventually!
  4023. reportError(ERR_PATTEN_SUBPATTERN, subpattern, "Expected a pattern for the check pattern");
  4024. }
  4025. }
  4026. IHqlExpression * HqlGram::createNullPattern()
  4027. {
  4028. ITypeInfo * type = NULL;
  4029. if (current_type && (current_type->getTypeCode() == type_rule))
  4030. type = makeTokenType();
  4031. else
  4032. type = makePatternType();
  4033. return createValue(no_null, type);
  4034. }
  4035. void HqlGram::checkPattern(attribute & pattern, HqlExprArray & values)
  4036. {
  4037. if (current_type)
  4038. {
  4039. type_t currentTC = current_type->getTypeCode();
  4040. if (currentTC == type_rule)
  4041. {
  4042. ForEachItemIn(idx, values)
  4043. {
  4044. IHqlExpression & cur = values.item(idx);
  4045. if (cur.queryType()->getTypeCode() == type_pattern)
  4046. values.replace(*createValue(no_pat_imptoken, makeTokenType(), LINK(&cur)), idx);
  4047. }
  4048. }
  4049. else
  4050. {
  4051. ForEachItemIn(idx, values)
  4052. {
  4053. IHqlExpression & cur = values.item(idx);
  4054. if (cur.queryType()->getTypeCode() != type_pattern)
  4055. {
  4056. if (currentTC == type_pattern)
  4057. reportError(ERR_TOKEN_IN_PATTERN, pattern, "Only patterns are valid inside pattern definitions");
  4058. else
  4059. reportError(ERR_TOKEN_IN_TOKEN, pattern, "Combinations of rules/tokens are not valid inside a token definition");
  4060. }
  4061. }
  4062. }
  4063. }
  4064. }
  4065. void HqlGram::checkProduction(const HqlExprArray & args, const attribute & errpos)
  4066. {
  4067. bool matched = false;
  4068. ForEachItemIn(i, args)
  4069. {
  4070. IHqlExpression & cur = args.item(i);
  4071. IHqlExpression * record = cur.queryRecord();
  4072. if (record)
  4073. {
  4074. if (matched)
  4075. {
  4076. reportError(ERR_AMBIGUOUS_PRODUCTION, errpos, "Cannot create implicit production - more than one pattern with record type");
  4077. return;
  4078. }
  4079. matched = true;
  4080. }
  4081. }
  4082. }
  4083. IHqlExpression * HqlGram::convertPatternToExpression(attribute & text)
  4084. {
  4085. IHqlExpression * expr = text.queryExpr();
  4086. try
  4087. {
  4088. IValue * value = expr->queryValue();
  4089. if (!value)
  4090. return NULL;
  4091. unsigned len = value->queryType()->getStringLen();
  4092. const void * data = value->queryValue();
  4093. switch (expr->queryType()->getTypeCode())
  4094. {
  4095. case type_unicode:
  4096. case type_varunicode:
  4097. return ::convertPatternToExpression(len, (const UChar *)data);
  4098. case type_utf8:
  4099. return ::convertUtf8PatternToExpression(len, (const char *)data);
  4100. default:
  4101. return ::convertPatternToExpression(len, (const char *)data);
  4102. }
  4103. }
  4104. catch (IException * e)
  4105. {
  4106. StringBuffer s;
  4107. e->errorMessage(s);
  4108. reportError(ERR_BAD_PATTERN, text, "%s", s.str());
  4109. e->Release();
  4110. }
  4111. return NULL;
  4112. }
  4113. ITypeInfo * HqlGram::getCompoundRuleType(ITypeInfo * lType, ITypeInfo * rType)
  4114. {
  4115. if ((lType->getTypeCode() == type_pattern) && (lType == rType))
  4116. return LINK(lType);
  4117. //preserve the record for a rule if only one of the arguments has a record type
  4118. if ((lType->getTypeCode() == type_rule) && lType->queryChildType())
  4119. {
  4120. if (!rType->queryChildType())
  4121. return LINK(lType);
  4122. }
  4123. else if ((rType->getTypeCode() == type_rule) && rType->queryChildType())
  4124. {
  4125. return LINK(rType);
  4126. }
  4127. return makeRuleType(NULL);
  4128. }
  4129. ITypeInfo * HqlGram::getCompoundRuleType(IHqlExpression * lhs)
  4130. {
  4131. ITypeInfo * lType = lhs->queryType();
  4132. switch (lType->getTypeCode())
  4133. {
  4134. case type_pattern:
  4135. case type_rule: //NB: preserve the record, if specified
  4136. return LINK(lType);
  4137. }
  4138. return makeRuleType(NULL);
  4139. }
  4140. IHqlExpression * HqlGram::getFeatureParams()
  4141. {
  4142. implicitFeatureNames.kill();
  4143. implicitFeatureValues.kill();
  4144. return curFeatureParams.getClear();
  4145. }
  4146. IHqlExpression * HqlGram::deduceGuardFeature(IHqlExpression * value, attribute & errpos)
  4147. {
  4148. if (implicitFeatureNames.ordinality() == 0)
  4149. expandImplicitFeatures();
  4150. IHqlExpression * match = NULL;
  4151. switch (value->getOperator())
  4152. {
  4153. case no_constant:
  4154. {
  4155. ITypeInfo * searchType;
  4156. if (isStringType(value->queryType()))
  4157. searchType = makeStringType(UNKNOWN_LENGTH, NULL, NULL);
  4158. else
  4159. searchType = makeIntType(DEFAULT_INT_SIZE, true);
  4160. OwnedHqlExpr search = createValue(no_null, makeFeatureType(), createValue(no_featuretype, searchType));
  4161. match = findFeature(search);
  4162. break;
  4163. }
  4164. case no_pat_or:
  4165. {
  4166. HqlExprArray args;
  4167. value->unwindList(args, no_pat_or);
  4168. match = findFeature(&args.item(0));
  4169. break;
  4170. }
  4171. default:
  4172. match = findFeature(value);
  4173. break;
  4174. }
  4175. if (match)
  4176. return LINK(match);
  4177. reportError(ERR_BADGUARD, errpos, "Could not deduce the feature being guarded");
  4178. return createValue(no_null, makeFeatureType());
  4179. }
  4180. void HqlGram::expandImplicitFeatures(IHqlExpression * feature, IHqlExpression * value)
  4181. {
  4182. assertex(value->getOperator() == no_pat_featuredef);
  4183. implicitFeatureNames.append(*feature); // not linked
  4184. implicitFeatureValues.append(*value); // not linked
  4185. value = value->queryChild(0);
  4186. switch (value->getOperator())
  4187. {
  4188. case no_null:
  4189. break;
  4190. case no_pat_featuredef:
  4191. expandImplicitFeatures(feature, value);
  4192. break;
  4193. case no_pat_or:
  4194. {
  4195. HqlExprArray args;
  4196. value->unwindList(args, no_pat_or);
  4197. ForEachItemIn(idx, args)
  4198. expandImplicitFeatures(feature, &args.item(idx));
  4199. break;
  4200. }
  4201. default:
  4202. UNIMPLEMENTED;
  4203. }
  4204. }
  4205. IHqlExpression * HqlGram::findFeature(IHqlExpression * value)
  4206. {
  4207. unsigned match = implicitFeatureValues.find(*value);
  4208. if (match == NotFound)
  4209. return NULL;
  4210. return &implicitFeatureNames.item(match);
  4211. }
  4212. void HqlGram::expandImplicitFeatures()
  4213. {
  4214. HqlExprArray features;
  4215. if (curFeatureParams)
  4216. {
  4217. curFeatureParams->unwindList(features, no_comma);
  4218. ForEachItemIn(idx, features)
  4219. {
  4220. IHqlExpression & cur = features.item(idx);
  4221. expandImplicitFeatures(&cur, &cur);
  4222. }
  4223. }
  4224. }
  4225. void HqlGram::setFeatureParamsOwn(IHqlExpression * expr)
  4226. {
  4227. curFeatureParams.setown(expr);
  4228. }
  4229. static IHqlExpression * translateExprToPattern(IHqlExpression * expr, bool insideRule);
  4230. static IHqlExpression * doTranslateExprToPattern(IHqlExpression * expr, bool insideRule)
  4231. {
  4232. switch (expr->getOperator())
  4233. {
  4234. case no_constant:
  4235. switch (expr->queryType()->getTypeCode())
  4236. {
  4237. case type_string:
  4238. case type_unicode:
  4239. case type_utf8:
  4240. return createValue(no_pat_const, makePatternType(), LINK(expr));
  4241. }
  4242. break;
  4243. case no_list:
  4244. {
  4245. HqlExprArray args;
  4246. ForEachChild(idx, expr)
  4247. {
  4248. IHqlExpression * next = translateExprToPattern(expr->queryChild(idx), insideRule);
  4249. if (!next)
  4250. return NULL;
  4251. args.append(*next);
  4252. }
  4253. return createValue(no_pat_or, insideRule ? makeRuleType(NULL) : makePatternType(), args);
  4254. }
  4255. }
  4256. return NULL;
  4257. }
  4258. static IHqlExpression * translateExprToPattern(IHqlExpression * expr, bool insideRule)
  4259. {
  4260. IHqlExpression * pattern = doTranslateExprToPattern(expr, insideRule);
  4261. if (pattern && insideRule && pattern->queryType()->getTypeCode() == type_pattern)
  4262. pattern = createValue(no_pat_imptoken, makeTokenType(), pattern);
  4263. return pattern;
  4264. }
  4265. IHqlExpression * HqlGram::processExprInPattern(attribute & attr)
  4266. {
  4267. OwnedHqlExpr expr = attr.getExpr();
  4268. OwnedHqlExpr folded = foldHqlExpression(expr);
  4269. bool insideRule = current_type && (current_type->getTypeCode() == type_rule);;
  4270. OwnedHqlExpr translated = translateExprToPattern(folded, insideRule);
  4271. if (!translated)
  4272. {
  4273. reportError(ERR_EXPR_IN_PATTERN, attr, "This expression cannot be included in a pattern");
  4274. translated.setown(createValue(no_pat_anychar, makePatternType()));
  4275. }
  4276. return translated.getClear();
  4277. }
  4278. void HqlGram::ensureBoolean(attribute &a)
  4279. {
  4280. ensureType(a, boolType);
  4281. }
  4282. void HqlGram::ensureType(attribute &a, ITypeInfo * type)
  4283. {
  4284. IHqlExpression *expr = a.queryExpr();
  4285. ITypeInfo * exprType = expr->queryType();
  4286. if (!isSameBasicType(exprType, type))
  4287. {
  4288. if (!type->queryPromotedType()->assignableFrom(exprType->queryPromotedType()))
  4289. {
  4290. StringBuffer msg("Incompatible types: expected ");
  4291. getFriendlyTypeStr(type, msg).append(", given ");
  4292. getFriendlyTypeStr(expr->queryType(),msg);
  4293. reportError(ERR_TYPE_INCOMPATIBLE, a, "%s", msg.str());
  4294. }
  4295. expr = a.getExpr();
  4296. a.setExpr(ensureExprType(expr, type));
  4297. expr->Release();
  4298. }
  4299. }
  4300. ITypeInfo *HqlGram::promoteToSameType(attribute &a1, attribute &a2)
  4301. {
  4302. ITypeInfo *t1 = a1.queryExprType();
  4303. ITypeInfo *t2 = a2.queryExprType();
  4304. ITypeInfo * type = ::getPromotedECLType(t1, t2);
  4305. ensureType(a1, type);
  4306. ensureType(a2, type);
  4307. return type;
  4308. }
  4309. ITypeInfo *HqlGram::promoteToSameCompareType(attribute &a1, attribute &a2)
  4310. {
  4311. ITypeInfo *t1 = a1.queryExprType();
  4312. ITypeInfo *t2 = a2.queryExprType();
  4313. ITypeInfo * type = ::getPromotedECLCompareType(t1, t2);
  4314. ensureType(a1, type);
  4315. ensureType(a2, type);
  4316. return type;
  4317. }
  4318. IHqlExpression * HqlGram::createArithmeticOp(node_operator op, attribute &a1, attribute &a2)
  4319. {
  4320. normalizeExpression(a1, type_numeric, false);
  4321. normalizeExpression(a2, type_numeric, false);
  4322. switch (op)
  4323. {
  4324. case no_add:
  4325. case no_sub:
  4326. case no_mul:
  4327. case no_div:
  4328. applyDefaultPromotions(a1, true);
  4329. applyDefaultPromotions(a2, (op != no_div));
  4330. break;
  4331. }
  4332. ITypeInfo *t1 = a1.queryExprType();
  4333. ITypeInfo *t2 = a2.queryExprType();
  4334. Owned<ITypeInfo> type;
  4335. switch (op)
  4336. {
  4337. case no_add:
  4338. case no_sub:
  4339. type.setown(getPromotedAddSubType(t1, t2));
  4340. break;
  4341. case no_mul:
  4342. case no_div:
  4343. type.setown(getPromotedMulDivType(t1, t2));
  4344. break;
  4345. }
  4346. if (!type)
  4347. type.setown(getPromotedType(t1, t2));
  4348. if (!isDecimalType(type))
  4349. {
  4350. ensureType(a1, type);
  4351. ensureType(a2, type);
  4352. }
  4353. return createValue(op, type.getClear(), a1.getExpr(), a2.getExpr());
  4354. }
  4355. void HqlGram::promoteToSameCompareType(attribute &a1, attribute &a2, node_operator op)
  4356. {
  4357. if ((a1.queryExpr()->getOperator() == no_constant) && (a2.queryExpr()->getOperator() != no_constant) && (op != no_between))
  4358. {
  4359. promoteToSameCompareType(a2, a1, getReverseOp(op));
  4360. return;
  4361. }
  4362. ITypeInfo * t1 = a1.queryExprType();
  4363. IHqlExpression * e2 = a2.queryExpr();
  4364. //Check for comparisons that are always true/false....
  4365. IValue * value = e2->queryValue();
  4366. if (value)
  4367. {
  4368. bool alwaysFalse = false;
  4369. bool alwaysTrue = false;
  4370. int rc = value->rangeCompare(t1);
  4371. if (rc != 0)
  4372. {
  4373. switch (op)
  4374. {
  4375. case no_eq:
  4376. alwaysFalse = true;
  4377. break;
  4378. case no_ne:
  4379. alwaysTrue = true;
  4380. break;
  4381. case no_le:
  4382. case no_lt:
  4383. if (rc > 0)
  4384. alwaysTrue = true;
  4385. else
  4386. alwaysFalse = true;
  4387. break;
  4388. case no_gt:
  4389. case no_ge:
  4390. if (rc < 0) // value underflows => test field will always be less than
  4391. alwaysTrue = true;
  4392. else
  4393. alwaysFalse = true;
  4394. break;
  4395. case no_between:
  4396. //Don't do anything
  4397. break;
  4398. }
  4399. }
  4400. else
  4401. {
  4402. //This is worth doing for between as well.
  4403. //Integer comparisons are done as int64 unless we are careful. This ensures that
  4404. //comparisons against constants are done at non-constant width if appropriate.
  4405. ITypeInfo * t2 = e2->queryType();
  4406. type_t ttc1 = t1->getTypeCode();
  4407. if (((ttc1==type_int) && t2->isInteger()) || (ttc1==type_decimal))
  4408. {
  4409. OwnedIValue castValue = value->castTo(t1);
  4410. if (castValue)
  4411. {
  4412. OwnedITypeInfo promoted = ::getPromotedECLType(t1, t2);
  4413. OwnedIValue promotedCastValue = castValue->castTo(promoted);
  4414. OwnedIValue promotedValue = value->castTo(promoted);
  4415. if (promotedCastValue->compare(promotedValue) == 0)
  4416. {
  4417. //Value is represented in t1 type so do comparison as type t1.
  4418. a2.release();
  4419. a2.setExpr(createConstant(LINK(castValue)));
  4420. }
  4421. }
  4422. }
  4423. #if 0
  4424. //Check if comparison value can be represented in the other type - if not, then it's not going to compare equal
  4425. OwnedIValue uncastValue(value->castTo(t1));
  4426. if (!uncastValue)
  4427. {
  4428. if (op == no_eq)
  4429. alwaysFalse = true;
  4430. else if (op == no_ne)
  4431. alwaysTrue = true;
  4432. }
  4433. #endif
  4434. }
  4435. if (alwaysTrue)
  4436. reportWarning(CategoryFolding, WRN_COND_ALWAYS_TRUE, a2.pos, "Condition is always true");
  4437. if (alwaysFalse)
  4438. reportWarning(CategoryFolding, WRN_COND_ALWAYS_FALSE, a2.pos, "Condition is always false");
  4439. }
  4440. #if 0
  4441. //The following improves the generated code, but causes a few problems at the moment
  4442. if (op != no_between && !e2->isConstant())
  4443. {
  4444. switch (t1->getTypeCode())
  4445. {
  4446. case type_string:
  4447. case type_unicode:
  4448. case type_utf8:
  4449. {
  4450. Owned<ITypeInfo> otherType = getStretchedType(t1->getStringLen(), e2->queryType());
  4451. if (t1 == otherType)
  4452. return;
  4453. }
  4454. break;
  4455. }
  4456. }
  4457. #endif
  4458. // ::Release(promoteToSameCompareType(a1, a2));
  4459. ::Release(promoteToSameType(a1, a2));
  4460. }
  4461. void HqlGram::warnIfFoldsToConstant(IHqlExpression * expr, const attribute & errpos)
  4462. {
  4463. if (expr && !expr->queryValue())
  4464. {
  4465. OwnedHqlExpr folded = foldExprIfConstant(expr);
  4466. if (folded->queryValue())
  4467. {
  4468. if (folded->queryValue()->getBoolValue())
  4469. reportWarning(CategoryFolding, WRN_COND_ALWAYS_TRUE, errpos.pos, "Condition is always true");
  4470. else
  4471. reportWarning(CategoryFolding, WRN_COND_ALWAYS_FALSE, errpos.pos, "Condition is always false");
  4472. }
  4473. }
  4474. }
  4475. void HqlGram::warnIfRecordPacked(IHqlExpression * expr, const attribute & errpos)
  4476. {
  4477. IHqlExpression * record = expr->queryRecord();
  4478. if (record && record->hasAttribute(packedAtom))
  4479. reportWarning(CategoryFuture, WRN_PACKED_MAY_CHANGE, errpos.pos, "Packed record used for external input or output, packed formats may change");
  4480. }
  4481. void HqlGram::promoteToSameCompareType(attribute &a1, attribute &a2, attribute &a3)
  4482. {
  4483. promoteToSameCompareType(a1, a2, no_between);
  4484. promoteToSameCompareType(a1, a3, no_between);
  4485. promoteToSameCompareType(a1, a2, no_between);
  4486. }
  4487. ITypeInfo * HqlGram::getPromotedECLType(HqlExprArray & exprs, ITypeInfo * _promoted, bool allowVariableLength)
  4488. {
  4489. unsigned start = 0;
  4490. Linked<ITypeInfo> promoted = _promoted;
  4491. if (!promoted)
  4492. promoted.set(exprs.item(start++).queryType());
  4493. Linked<ITypeInfo> initial = promoted;
  4494. unsigned max = exprs.ordinality();
  4495. unsigned idx;
  4496. bool allSame = true;
  4497. for (idx = start; idx < max; idx++)
  4498. {
  4499. ITypeInfo * curType = exprs.item(idx).queryType();
  4500. promoted.setown(::getPromotedECLType(promoted, curType));
  4501. if (promoted != curType)
  4502. allSame = false;
  4503. }
  4504. if (allowVariableLength)
  4505. {
  4506. //Really, maps/cases that return different length strings should have variable length string returns, but
  4507. //that would cause differences in HOLe. I suspect we should enable this and report errors in hole if the lengths
  4508. //mismatch, rather than hobbling the code generator.
  4509. if ((promoted != initial) || !allSame)
  4510. {
  4511. switch (promoted->getTypeCode())
  4512. {
  4513. case type_string:
  4514. case type_varstring:
  4515. case type_qstring:
  4516. case type_unicode:
  4517. case type_varunicode:
  4518. case type_utf8:
  4519. promoted.setown(getStretchedType(UNKNOWN_LENGTH, promoted));
  4520. break;
  4521. }
  4522. }
  4523. }
  4524. return promoted.getClear();
  4525. }
  4526. ITypeInfo *HqlGram::promoteToSameType(HqlExprArray & exprs, const attribute &ea, ITypeInfo * otherType, bool allowVariableLength)
  4527. {
  4528. if (exprs.ordinality() == 0)
  4529. return LINK(otherType);
  4530. ITypeInfo * promoted = getPromotedECLType(exprs, otherType, allowVariableLength);
  4531. ForEachItemIn(idx, exprs)
  4532. {
  4533. IHqlExpression & cur = exprs.item(idx);
  4534. checkCompatible(cur.queryType(), promoted, ea);
  4535. IHqlExpression * cast = ensureExprType(&cur, promoted);
  4536. exprs.replace(*cast, idx);
  4537. }
  4538. return promoted;
  4539. }
  4540. ITypeInfo *HqlGram::promoteMapToSameType(HqlExprArray & exprs, attribute &eElse)
  4541. {
  4542. bool differentLengthStringsVariableLengthRatherThanLongest = false;
  4543. ITypeInfo * promoted = getPromotedECLType(exprs, eElse.queryExprType(), differentLengthStringsVariableLengthRatherThanLongest);
  4544. ForEachItemIn(idx, exprs)
  4545. {
  4546. IHqlExpression & cur = exprs.item(idx);
  4547. checkCompatible(cur.queryType(), promoted, eElse);
  4548. IHqlExpression * cast = ensureExprType(cur.queryChild(1), promoted);
  4549. IHqlExpression * cond = cur.queryChild(0);
  4550. IHqlExpression * map = createValue(no_mapto, LINK(promoted), LINK(cond), cast);
  4551. exprs.replace(*map, idx);
  4552. }
  4553. checkType(eElse, promoted);
  4554. ensureType(eElse, promoted);
  4555. return promoted;
  4556. }
  4557. void HqlGram::promoteToSameListType(attribute & leftAttr, attribute & rightAttr)
  4558. {
  4559. ITypeInfo * leftType = leftAttr.queryExprType();
  4560. ITypeInfo * rightType = rightAttr.queryExprType();
  4561. if (leftType != rightType)
  4562. {
  4563. IHqlExpression * left= leftAttr.getExpr();
  4564. IHqlExpression * right = rightAttr.getExpr();
  4565. if ((left->getOperator() == no_list) && (left->numChildren() == 0))
  4566. {
  4567. left->Release();
  4568. left = createValue(no_list, LINK(rightType));
  4569. }
  4570. else if ((right->getOperator() == no_list) && (right->numChildren() == 0))
  4571. {
  4572. right->Release();
  4573. right = createValue(no_list, LINK(leftType));
  4574. }
  4575. else
  4576. {
  4577. assertex(leftType->getTypeCode() == type_set && rightType->getTypeCode() == type_set);
  4578. ITypeInfo * promoted = ::getPromotedECLType(leftType, rightType);
  4579. IHqlExpression * newLeft = ensureExprType(left, promoted);
  4580. left->Release();
  4581. left = newLeft;
  4582. IHqlExpression * newRight = ensureExprType(right, promoted);
  4583. right->Release();
  4584. right = newRight;
  4585. promoted->Release();
  4586. }
  4587. leftAttr.setExpr(left);
  4588. rightAttr.setExpr(right);
  4589. }
  4590. }
  4591. ITypeInfo * HqlGram::promoteSetToSameType(HqlExprArray & exprs, attribute &errpos)
  4592. {
  4593. Owned<ITypeInfo> promoted = exprs.item(0).getType();
  4594. unsigned max = exprs.ordinality();
  4595. for (unsigned idx1 = 1; idx1 < max; idx1++)
  4596. {
  4597. ITypeInfo * type = exprs.item(idx1).queryType();
  4598. if (isStringType(promoted) && isStringType(type))
  4599. {
  4600. if (promoted->getStringLen() != type->getStringLen())
  4601. {
  4602. promoted.setown(::getPromotedECLType(promoted, type));
  4603. promoted.setown(getStretchedType(UNKNOWN_LENGTH, promoted));
  4604. }
  4605. }
  4606. promoted.setown(::getPromotedECLType(promoted, type));
  4607. }
  4608. ForEachItemIn(idx, exprs)
  4609. {
  4610. IHqlExpression & cur = exprs.item(idx);
  4611. checkCompatible(cur.queryType(), promoted, errpos);
  4612. IHqlExpression * cast = ensureExprType(&cur, promoted);
  4613. exprs.replace(*cast, idx);
  4614. }
  4615. return promoted.getClear();
  4616. }
  4617. IHqlExpression *HqlGram::createINExpression(node_operator op, IHqlExpression *expr, IHqlExpression *set, attribute &errpos)
  4618. {
  4619. ITypeInfo * exprType = expr->queryType();
  4620. ITypeInfo * elementType = set->queryType()->queryChildType();
  4621. if (elementType)
  4622. checkCompatible(exprType, elementType, errpos);
  4623. OwnedHqlExpr normalized = normalizeListCasts(set);
  4624. if (normalized->getOperator()==no_list)
  4625. {
  4626. HqlExprArray args;
  4627. unwindChildren(args, normalized);
  4628. bool differentLengthStringsVariableLengthRatherThanLongest = false;
  4629. Owned<ITypeInfo> retType = promoteToSameType(args, errpos, exprType, differentLengthStringsVariableLengthRatherThanLongest);
  4630. if (retType != elementType)
  4631. normalized.setown(createValue(no_list, makeSetType(LINK(retType)), args));
  4632. }
  4633. elementType = normalized->queryType()->queryChildType();
  4634. if (elementType)
  4635. {
  4636. Owned<ITypeInfo> promotedType = ::getPromotedECLType(exprType, elementType);
  4637. if (!isSameBasicType(exprType, promotedType))
  4638. expr = createValue(no_implicitcast, LINK(promotedType), expr);
  4639. }
  4640. set->Release();
  4641. return createBoolExpr(op, expr, normalized.getClear());
  4642. }
  4643. void HqlGram::checkCaseForDuplicates(HqlExprArray & exprs, attribute &err)
  4644. {
  4645. TransformMutexBlock lock;
  4646. unsigned max = exprs.ordinality();
  4647. for (unsigned idx1 = 0; idx1 < max; idx1++)
  4648. {
  4649. IHqlExpression * e1 = exprs.item(idx1).queryChild(0)->queryBody();
  4650. if (e1->queryTransformExtra())
  4651. {
  4652. StringBuffer s;
  4653. s.append("Duplicate case entry: ");
  4654. toECL(e1, s, false);
  4655. reportWarning(CategoryIgnored, WRN_DUPLICATECASE, err.pos, "%s", s.str());
  4656. }
  4657. else
  4658. e1->setTransformExtraUnlinked(e1);
  4659. }
  4660. }
  4661. /* Linkage: not affected */
  4662. ITypeInfo *HqlGram::promoteCaseToSameType(attribute &eTest, HqlExprArray & exprs, attribute &eElse)
  4663. {
  4664. Owned<ITypeInfo> promotedTest = eTest.queryExpr()->getType();
  4665. Owned<ITypeInfo> promotedResult = eElse.queryExpr()->getType();
  4666. ForEachItemIn(idx, exprs)
  4667. {
  4668. IHqlExpression & cur = exprs.item(idx);
  4669. promotedTest.setown(::getPromotedECLType(promotedTest, cur.queryChild(0)->queryType()));
  4670. promotedResult.setown(::getPromotedECLType(promotedResult, cur.queryChild(1)->queryType()));
  4671. }
  4672. ForEachItemIn(idx2, exprs)
  4673. {
  4674. IHqlExpression & cur = exprs.item(idx2);
  4675. IHqlExpression * cond = cur.queryChild(0);
  4676. IHqlExpression * cast = cur.queryChild(1);
  4677. checkCompatible(cond->queryType(), promotedTest, eTest);
  4678. checkCompatible(cast->queryType(), promotedResult, eTest);
  4679. cond = ensureExprType(cond, promotedTest);
  4680. cast = ensureExprType(cast, promotedResult);
  4681. IHqlExpression * map = createValue(no_mapto, LINK(promotedResult), cond, cast);
  4682. exprs.replace(*map, idx2);
  4683. }
  4684. checkType(eTest, promotedTest);
  4685. ensureType(eTest, promotedTest);
  4686. checkType(eElse, promotedResult);
  4687. ensureType(eElse, promotedResult);
  4688. return promotedResult.getClear();
  4689. }
  4690. void HqlGram::checkReal(attribute &a1)
  4691. {
  4692. ITypeInfo *t1 = a1.queryExprType();
  4693. // MORE - do we need to put in a cast for the integer case?
  4694. if (t1 && t1->getTypeCode() != type_real && t1->getTypeCode() != type_int)
  4695. {
  4696. Owned<ITypeInfo> realType = makeRealType(DEFAULT_REAL_SIZE);
  4697. if (t1->getTypeCode() == type_decimal)
  4698. {
  4699. reportWarning(CategoryCast, ERR_TYPEMISMATCH_REAL, a1.pos, "Decimal implicitly converted to a real");
  4700. }
  4701. else
  4702. {
  4703. StringBuffer msg("Type mismatch - Real value expected (");
  4704. getFriendlyTypeStr(t1,msg).append(" was given)");
  4705. reportError(ERR_TYPEMISMATCH_REAL, a1, "%s", msg.str());
  4706. }
  4707. OwnedHqlExpr value = a1.getExpr();
  4708. a1.setExpr(ensureExprType(value, realType));
  4709. }
  4710. }
  4711. void HqlGram::checkInteger(attribute &a1)
  4712. {
  4713. ITypeInfo *t1 = a1.queryExprType();
  4714. if (!t1 || !isIntegralType(t1))
  4715. {
  4716. if (t1 && isNumericType(t1))
  4717. {
  4718. OwnedHqlExpr value = a1.getExpr();
  4719. a1.setExpr(ensureExprType(value, defaultIntegralType));
  4720. }
  4721. else
  4722. {
  4723. StringBuffer s;
  4724. reportError(ERR_TYPEMISMATCH_INT, a1, "Type mismatch - Integer value expected (%s was given)", t1 ? getFriendlyTypeStr(t1, s).str() : "?");
  4725. a1.release().setExpr(createConstant(I64C(0)));
  4726. }
  4727. }
  4728. }
  4729. void HqlGram::checkPositive(attribute &a1)
  4730. {
  4731. IValue * value = a1.queryExpr()->queryValue();
  4732. if (value && value->queryType()->isSigned())
  4733. {
  4734. //MORE: Recode to allow decimal and other types
  4735. Owned<IValue> zero = value->queryType()->castFrom(0, (const char *)NULL);
  4736. if (value->compare(zero) < 0)
  4737. reportWarning(CategoryIndex, SeverityError, ERR_TYPEMISMATCH_INT, a1.pos, "Type mismatch - the value must be positive");
  4738. }
  4739. }
  4740. bool HqlGram::checkString(attribute &a1)
  4741. {
  4742. ITypeInfo *t1 = a1.queryExprType();
  4743. if (t1)
  4744. {
  4745. t1 = t1->queryPromotedType();
  4746. if (!isSimpleStringType(t1))
  4747. {
  4748. if (isStringType(t1))
  4749. {
  4750. ensureString(a1);
  4751. }
  4752. else
  4753. {
  4754. StringBuffer msg("Type mismatch - String value expected (");
  4755. getFriendlyTypeStr(t1, msg).append(" was given)");
  4756. reportError(ERR_TYPEMISMATCH_STRING, a1, "%s", msg.str());
  4757. return false;
  4758. }
  4759. }
  4760. }
  4761. return true;
  4762. }
  4763. bool HqlGram::checkStringOrUnicode(attribute & exprAttr)
  4764. {
  4765. ITypeInfo * type = exprAttr.queryExprType()->queryPromotedType();
  4766. switch (type->getTypeCode())
  4767. {
  4768. case type_string:
  4769. case type_varstring:
  4770. case type_data:
  4771. case type_qstring:
  4772. case type_unicode:
  4773. case type_varunicode:
  4774. case type_utf8:
  4775. return true;
  4776. }
  4777. StringBuffer msg("Type mismatch - String or unicode value expected (");
  4778. getFriendlyTypeStr(type, msg).append(" was given)");
  4779. reportError(ERR_TYPEMISMATCH_STRING, exprAttr, "%s", msg.str());
  4780. return false;
  4781. }
  4782. void HqlGram::checkIntegerOrString(attribute & a1)
  4783. {
  4784. ITypeInfo *t1 = a1.queryExprType();
  4785. if (t1 && !isIntegralType(t1) && !isStringType(t1))
  4786. {
  4787. StringBuffer msg("Type mismatch - Integer or string value expected (");
  4788. getFriendlyTypeStr(t1, msg).append(" was given)");
  4789. reportError(ERR_TYPEMISMATCH_INTSTRING, a1, "%s", msg.str());
  4790. }
  4791. }
  4792. void HqlGram::checkNumeric(attribute &a1)
  4793. {
  4794. ITypeInfo *t1 = a1.queryExprType();
  4795. if (!t1 || (!isNumericType(t1) && !isAnyType(t1)))
  4796. {
  4797. StringBuffer msg("Type mismatch - numeric expression expected");
  4798. if (t1)
  4799. {
  4800. msg.append("(");
  4801. getFriendlyTypeStr(t1, msg).append(" was given)");
  4802. }
  4803. reportError(ERR_EXPECTED_NUMERIC, a1, "%s", msg.str());
  4804. a1.release().setExpr(getSizetConstant(0));
  4805. }
  4806. }
  4807. ITypeInfo *HqlGram::checkNumericGetType(attribute &a1)
  4808. {
  4809. ITypeInfo *t1 = a1.queryExpr()->getType();
  4810. if (!t1)
  4811. {
  4812. reportError(ERR_TYPEMISMATCH_INTREAL, a1, "Type mismatch - unknown type! Integer or real value expected");
  4813. t1 = makeIntType(DEFAULT_INT_SIZE, true);
  4814. }
  4815. if (!isNumericType(t1))
  4816. {
  4817. StringBuffer msg("Type mismatch - Integer or real value expected (");
  4818. getFriendlyTypeStr(t1, msg).append(" was given)");
  4819. reportError(ERR_TYPEMISMATCH_INTREAL, a1, "%s", msg.str());
  4820. t1->Release();
  4821. t1 = makeIntType(DEFAULT_INT_SIZE, true);
  4822. }
  4823. return t1;
  4824. }
  4825. IHqlExpression * HqlGram::createDatasetFromList(attribute & listAttr, attribute & recordAttr)
  4826. {
  4827. OwnedHqlExpr list = listAttr.getExpr();
  4828. OwnedHqlExpr record = recordAttr.getExpr();
  4829. if (list->getOperator() == no_comma)
  4830. {
  4831. reportErrorUnexpectedX(listAttr, dynamicAtom);
  4832. list.set(list->queryChild(0)); // should really complain about dynamic
  4833. }
  4834. if ((list->getOperator() == no_list) && (list->numChildren() == 0))
  4835. {
  4836. OwnedHqlExpr list = createValue(no_null);
  4837. OwnedHqlExpr table = createDataset(no_temptable, LINK(list), record.getClear());
  4838. return convertTempTableToInlineTable(*errorHandler, listAttr.pos, table);
  4839. }
  4840. IHqlExpression * listRecord = list->queryRecord();
  4841. if (listRecord)
  4842. {
  4843. if (list->getOperator() != no_list)
  4844. {
  4845. reportError(ERR_EXPECTED, listAttr, "Expected a list of rows");
  4846. return createDataset(no_null, LINK(record));
  4847. }
  4848. HqlExprArray args;
  4849. unwindChildren(args, list);
  4850. if (args.item(0).queryRecord() != record->queryRecord())
  4851. reportError(ERR_TYPEMISMATCH_RECORD, recordAttr, "Datarow must match the record definition, try using ROW()");
  4852. OwnedHqlExpr combined;
  4853. ForEachItemIn(i, args)
  4854. {
  4855. OwnedHqlExpr ds = ::ensureDataset(&args.item(i));
  4856. if (combined)
  4857. combined.setown(createDataset(no_addfiles, LINK(combined), LINK(ds)));
  4858. else
  4859. combined.set(ds);
  4860. }
  4861. return combined.getClear();
  4862. }
  4863. ITypeInfo * listType = list->queryType();
  4864. assertex(listType);
  4865. ITypeInfo * childType = listType->queryChildType();
  4866. IHqlExpression * field = queryOnlyField(record);
  4867. if (!field)
  4868. reportError(ERR_EXPECT_SINGLE_FIELD, recordAttr, "Expected a single field in the dataset parameter");
  4869. else if (childType && !field->queryType()->assignableFrom(childType))
  4870. reportError(ERR_RECORD_NOT_MATCH_SET, recordAttr, "The field in the record does not match the type of the set elements");
  4871. OwnedHqlExpr table = createDataset(no_temptable, LINK(list), record.getClear());
  4872. return convertTempTableToInlineTable(*errorHandler, listAttr.pos, table);
  4873. }
  4874. ITypeInfo *HqlGram::checkPromoteNumeric(attribute &a1, bool extendPrecision)
  4875. {
  4876. applyDefaultPromotions(a1, extendPrecision);
  4877. return checkNumericGetType(a1);
  4878. }
  4879. bool HqlGram::expandWholeAndExcept(IHqlExpression * dataset, const attribute & errpos, HqlExprArray & parms)
  4880. {
  4881. HqlExprArray results;
  4882. //Process record first because it needs to be added before the EXCEPT.
  4883. bool expandPending = false;
  4884. bool hadExcept = false;
  4885. bool hadField = false;
  4886. ForEachItemIn(idx1, parms)
  4887. {
  4888. IHqlExpression &e = parms.item(idx1);
  4889. if (e.isAttribute())
  4890. {
  4891. if (e.queryName() == recordAtom)
  4892. {
  4893. expandPending = true;
  4894. }
  4895. else if (e.queryName() == exceptAtom)
  4896. {
  4897. if (!hadField)
  4898. expandPending = true;
  4899. hadExcept = true;
  4900. break;
  4901. }
  4902. }
  4903. else
  4904. {
  4905. if (e.queryType())
  4906. hadField = true;
  4907. results.append(OLINK(e));
  4908. }
  4909. }
  4910. if (!expandPending && !hadExcept)
  4911. return false;
  4912. if (expandPending)
  4913. {
  4914. if (dataset)
  4915. expandRecord(results, dataset->queryNormalizedSelector(), dataset->queryRecord());
  4916. else
  4917. reportError(ERR_NO_WHOLE_RECORD, errpos, "WHOLE RECORD is not valid here");
  4918. }
  4919. hadExcept = false;
  4920. ForEachItemIn(idx2, parms)
  4921. {
  4922. IHqlExpression &e = parms.item(idx2);
  4923. OwnedHqlExpr except;
  4924. if (e.isAttribute())
  4925. {
  4926. IAtom * attr = e.queryName();
  4927. if (attr == exceptAtom)
  4928. {
  4929. hadExcept = true;
  4930. except.set(e.queryChild(0));
  4931. }
  4932. else if (attr != recordAtom)
  4933. results.append(OLINK(e));
  4934. }
  4935. else
  4936. {
  4937. if (hadExcept)
  4938. {
  4939. if (e.queryType())
  4940. except.set(&e);
  4941. else
  4942. results.append(OLINK(e));
  4943. }
  4944. }
  4945. if (except)
  4946. {
  4947. IHqlExpression * search = except->queryNormalizedSelector();
  4948. unsigned match = results.find(*search);
  4949. if (match != NotFound)
  4950. results.remove(match);
  4951. else
  4952. {
  4953. StringBuffer s;
  4954. toECL(search, s, false);
  4955. reportError(ERR_EXCEPT_NOT_FOUND, errpos, "EXCEPT: %s not found in the incoming record", s.str());
  4956. }
  4957. }
  4958. }
  4959. parms.swapWith(results);
  4960. return true;
  4961. }
  4962. void HqlGram::expandWholeAndExcept(IHqlExpression * dataset, attribute & a)
  4963. {
  4964. OwnedHqlExpr list = a.getExpr();
  4965. HqlExprArray parms;
  4966. if (list)
  4967. list->unwindList(parms, no_comma);
  4968. if (!expandWholeAndExcept(dataset, a, parms))
  4969. {
  4970. a.setExpr(list.getClear());
  4971. return;
  4972. }
  4973. a.setExpr(createComma(parms));
  4974. }
  4975. void HqlGram::expandSortedAsList(HqlExprArray & args)
  4976. {
  4977. LinkedHqlExpr sorted = queryAttribute(sortedAtom, args);
  4978. if (!sorted)
  4979. return;
  4980. args.zap(*sorted);
  4981. unwindChildren(args, sorted);
  4982. }
  4983. IHqlExpression * HqlGram::createAssert(attribute & condAttr, attribute * msgAttr, attribute & flagsAttr)
  4984. {
  4985. if (queryAttributeInList(constAtom, flagsAttr.queryExpr()))
  4986. {
  4987. checkConstant(condAttr);
  4988. if (msgAttr)
  4989. checkConstant(*msgAttr);
  4990. }
  4991. OwnedHqlExpr cond = condAttr.getExpr();
  4992. HqlExprArray args;
  4993. args.append(*LINK(cond));
  4994. if (msgAttr)
  4995. {
  4996. normalizeExpression(*msgAttr, type_string, false);
  4997. args.append(*msgAttr->getExpr());
  4998. }
  4999. else
  5000. {
  5001. args.append(*createDefaultAssertMessage(cond));
  5002. args.append(*createAttribute(_default_Atom));
  5003. }
  5004. flagsAttr.unwindCommaList(args);
  5005. args.append(*condAttr.pos.createLocationAttr());
  5006. return createValue(no_assert, makeVoidType(), args);
  5007. }
  5008. IHqlExpression * HqlGram::processSortList(const attribute & errpos, node_operator op, IHqlExpression * dataset, HqlExprArray & items, OwnedHqlExpr * joinedClause, OwnedHqlExpr * attributes)
  5009. {
  5010. expandWholeAndExcept(dataset, errpos, items);
  5011. if (items.ordinality() == 0)
  5012. {
  5013. if (op == no_list)
  5014. return createValue(no_sortlist, makeSortListType(NULL));
  5015. return NULL;
  5016. }
  5017. bool expandRows = false;
  5018. switch (op)
  5019. {
  5020. case no_hash:
  5021. expandRows = true;
  5022. break;
  5023. }
  5024. ForEachItemInRev(idx, items)
  5025. {
  5026. IHqlExpression &e = items.item(idx);
  5027. node_operator eop = e.getOperator();
  5028. if (e.isAttribute())
  5029. {
  5030. IAtom * attr = e.queryName();
  5031. bool ok = false;
  5032. if (attributes)
  5033. {
  5034. if (attr == hintAtom) ok = true;
  5035. switch (op)
  5036. {
  5037. case no_aggregate:
  5038. if (attr == keyedAtom) ok = true;
  5039. if (attr == localAtom) ok = true;
  5040. if (attr == fewAtom) ok = true;
  5041. if (attr == manyAtom) ok = true;
  5042. if (attr == sortedAtom) ok = true;
  5043. if (attr == unsortedAtom) ok = true;
  5044. if (attr == skewAtom) ok = true;
  5045. if (attr == thresholdAtom) ok = true;
  5046. break;
  5047. case no_usertable:
  5048. if (attr == keyedAtom) ok = true;
  5049. if (attr == prefetchAtom) ok = true;
  5050. if (attr == mergeAtom) ok = true;
  5051. if (attr == groupedAtom) ok = true;
  5052. //fall through
  5053. case no_group:
  5054. if (attr == allAtom) ok = true;
  5055. if (attr == localAtom) ok = true;
  5056. if (attr == fewAtom) ok = true;
  5057. if (attr == manyAtom) ok = true;
  5058. if (attr == sortedAtom) ok = true;
  5059. if (attr == unsortedAtom) ok = true;
  5060. if (attr == skewAtom) ok = true;
  5061. if (attr == thresholdAtom) ok = true;
  5062. break;
  5063. case no_topn:
  5064. if (attr == bestAtom) ok = true;
  5065. //fall through
  5066. case no_sort:
  5067. if (attr == localAtom) ok = true;
  5068. if (attr == skewAtom) ok = true;
  5069. if (attr == thresholdAtom) ok = true;
  5070. if (attr == manyAtom) ok = true;
  5071. if (attr == fewAtom) ok = true;
  5072. if (attr == assertAtom) ok = true;
  5073. if (attr == stableAtom) ok = true;
  5074. if (attr == unstableAtom) ok = true;
  5075. if (attr == parallelAtom) ok = true;
  5076. break;
  5077. case no_nwaymerge:
  5078. if (attr == localAtom) ok = true;
  5079. if (attr == dedupAtom) ok = true;
  5080. break;
  5081. case no_mergejoin:
  5082. if (attr == dedupAtom) ok = true;
  5083. if (attr == assertAtom) ok = true;
  5084. //fall through
  5085. case no_nwayjoin:
  5086. if (attr == localAtom) ok = true;
  5087. if (attr == mofnAtom) ok = true;
  5088. if (attr == leftonlyAtom) ok = true;
  5089. if (attr == leftouterAtom) ok = true;
  5090. if (attr == assertAtom) ok = true;
  5091. if (attr == skewAtom) ok = true;
  5092. if (attr == internalFlagsAtom) ok = true;
  5093. //if (attr == sortedAtom) ok = true; - already converted
  5094. break;
  5095. }
  5096. }
  5097. if (!ok)
  5098. {
  5099. StringBuffer msg;
  5100. msg.append(attr).append(" is not valid here");
  5101. reportError(ERR_ILL_HERE, errpos, "%s", msg.str());
  5102. }
  5103. else
  5104. attributes->setown(createComma(LINK(&e), attributes->getClear()));
  5105. items.remove(idx);
  5106. }
  5107. else if (eop == no_joined)
  5108. {
  5109. if ((op != no_sort && op != no_topn) || !joinedClause)
  5110. reportError(ERR_JOINED_ILL_HERE, errpos, "JOINED is not valid here");
  5111. else if (*joinedClause)
  5112. {
  5113. reportError(ERR_JOINED_TOOMANY, errpos, "Too many joined clauses: only 1 can be used");
  5114. }
  5115. else
  5116. joinedClause->set(&e);
  5117. items.remove(idx);
  5118. }
  5119. else if (eop == no_constant)
  5120. {
  5121. if ((op != no_hash) && (op != no_hash32) && (op != no_hash64) && (op != no_crc) && (op != no_hashmd5) && (op != no_list))
  5122. reportWarning(CategoryUnusual, ERR_CONSTANT_DAFT, errpos.pos, "Constant group/sort clauses make no sense");
  5123. }
  5124. else if (!containsAnyDataset(&e))
  5125. {
  5126. if ((op != no_hash) && (op != no_hash32) && (op != no_hash64) && (op != no_crc) && (op != no_hashmd5) && (op != no_list))
  5127. reportWarning(CategoryUnusual, WRN_SORT_INVARIANT, errpos.pos, "Sort/Group element is not related to the dataset");
  5128. }
  5129. else if (e.isDatarow() && expandRows)
  5130. {
  5131. //Expanding the row selectors at this point generates better code if the hash is done inside a compound read activity
  5132. LinkedHqlExpr row = &e;
  5133. RecordSelectIterator iter(e.queryRecord(), row);
  5134. items.remove(idx);
  5135. unsigned i=0;
  5136. ForEach(iter)
  5137. {
  5138. items.add(*iter.get(), idx+i);
  5139. i++;
  5140. }
  5141. }
  5142. }
  5143. if (items.ordinality())
  5144. return createSortList(items);
  5145. if (op == no_list)
  5146. return createValue(no_sortlist, makeSortListType(NULL), items);
  5147. return NULL;
  5148. }
  5149. IHqlExpression * HqlGram::createDistributeCond(IHqlExpression * leftDs, IHqlExpression * rightDs, const attribute & err, const attribute & seqAttr)
  5150. {
  5151. IHqlSimpleScope * leftScope = leftDs->queryRecord()->querySimpleScope();
  5152. IHqlExpression * rightRecord = rightDs->queryRecord();
  5153. OwnedHqlExpr left = createSelector(no_left, leftDs, seqAttr.queryExpr());
  5154. OwnedHqlExpr right = createSelector(no_right, rightDs, seqAttr.queryExpr());
  5155. IHqlExpression * cond = NULL;
  5156. unsigned numFields = rightRecord->numChildren()-numPayloadFields(rightDs);
  5157. for (unsigned i =0; i < numFields; i++)
  5158. {
  5159. IHqlExpression * rightField = rightRecord->queryChild(i);
  5160. if (rightField->getOperator() == no_field)
  5161. {
  5162. IHqlExpression * leftField = leftScope->lookupSymbol(rightField->queryId());
  5163. if (!leftField)
  5164. {
  5165. reportError(ERR_FIELD_NOT_FOUND, err, "Could not find a field %s in the dataset", str(rightField->queryName()));
  5166. leftField = LINK(rightField);
  5167. }
  5168. IHqlExpression * test = createBoolExpr(no_eq, createSelectExpr(LINK(left), leftField), createSelectExpr(LINK(right), LINK(rightField)));
  5169. cond = extendConditionOwn(no_and, cond, test);
  5170. }
  5171. }
  5172. return cond;
  5173. }
  5174. IHqlExpression * HqlGram::createLoopCondition(IHqlExpression * leftDs, IHqlExpression * arg1, IHqlExpression * arg2, IHqlExpression * seq, IHqlExpression * rowsid)
  5175. {
  5176. IHqlExpression * count = NULL;
  5177. IHqlExpression * filter = NULL;
  5178. IHqlExpression * loopCond = NULL;
  5179. if (arg1->queryType() == boolType)
  5180. {
  5181. if (arg2)
  5182. {
  5183. filter = arg1;
  5184. loopCond = arg2;
  5185. }
  5186. else
  5187. {
  5188. //if refers to fields in LEFT then must be a row filter
  5189. OwnedHqlExpr left = createSelector(no_left, leftDs, seq);
  5190. OwnedHqlExpr rows = createDataset(no_rows, LINK(left), LINK(rowsid));
  5191. if (containsExpression(arg1, rows) || !containsSelector(arg1, left))
  5192. loopCond = arg1;
  5193. else
  5194. filter = arg1;
  5195. }
  5196. }
  5197. else
  5198. {
  5199. count = arg1;
  5200. if (arg2)
  5201. filter = arg2;
  5202. }
  5203. if (!count) count = createAttribute(_omitted_Atom);
  5204. if (!filter) filter = createAttribute(_omitted_Atom);
  5205. if (!loopCond) loopCond= createAttribute(_omitted_Atom);
  5206. return createComma(count, filter, loopCond);
  5207. }
  5208. void HqlGram::reportError(int errNo, const attribute& a, const char* format, ...)
  5209. {
  5210. va_list args;
  5211. va_start(args, format);
  5212. reportErrorVa(errNo, a.pos, format, args);
  5213. va_end(args);
  5214. }
  5215. void HqlGram::reportError(int errNo, const ECLlocation & pos, const char* format, ...)
  5216. {
  5217. va_list args;
  5218. va_start(args, format);
  5219. reportErrorVa(errNo, pos, format, args);
  5220. va_end(args);
  5221. }
  5222. void HqlGram::reportErrorUnexpectedX(const attribute& errpos, IAtom * unexpected)
  5223. {
  5224. reportError(ERR_UNEXPECTED_ATTRX, errpos, "Unexpected attribute %s", str(unexpected));
  5225. }
  5226. void HqlGram::doReportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int pos)
  5227. {
  5228. Owned<IError> error = createError(category, queryDefaultSeverity(category), warnNo, msg, filename, lineno, column, pos);
  5229. report(error);
  5230. }
  5231. void HqlGram::reportMacroExpansionPosition(IError * warning, HqlLex * lexer)
  5232. {
  5233. if (expandingMacroPosition)
  5234. return;
  5235. HqlLex * macro = lexer->getMacroLex();
  5236. if (!macro)
  5237. return;
  5238. reportMacroExpansionPosition(warning, macro);
  5239. StringBuffer s;
  5240. s.appendf("While expanding macro %s", macro->getMacroName());
  5241. expandingMacroPosition = true;
  5242. unsigned code = warning->errorCode();
  5243. if (warning->getSeverity() == SeverityFatal)
  5244. errorHandler->reportError(code, s.str(), str(lexer->querySourcePath()), lexer->get_yyLineNo(), lexer->get_yyColumn(), 0);
  5245. else
  5246. doReportWarning(warning->getCategory(), code, s.str(), str(lexer->querySourcePath()), lexer->get_yyLineNo(), lexer->get_yyColumn(), 0);
  5247. expandingMacroPosition = false;
  5248. }
  5249. void HqlGram::reportErrorVa(int errNo, const ECLlocation & pos, const char* format, va_list args)
  5250. {
  5251. Owned<IError> error = createErrorVA(CategoryError, SeverityFatal, errNo, pos, format, args);
  5252. report(error);
  5253. }
  5254. void HqlGram::reportError(int errNo, const char *msg, int lineno, int column, int position)
  5255. {
  5256. if (errorHandler && !errorDisabled)
  5257. {
  5258. Owned<IError> error = createError(errNo, msg, str(lexObject->queryActualSourcePath()), lineno, column, position);
  5259. report(error);
  5260. }
  5261. }
  5262. void HqlGram::reportWarning(WarnErrorCategory category, int warnNo, const ECLlocation & pos, const char* format, ...)
  5263. {
  5264. if (errorHandler && !errorDisabled)
  5265. {
  5266. va_list args;
  5267. va_start(args, format);
  5268. Owned<IError> error = createErrorVA(category, queryDefaultSeverity(category), warnNo, pos, format, args);
  5269. va_end(args);
  5270. report(error);
  5271. }
  5272. }
  5273. void HqlGram::reportWarning(WarnErrorCategory category, ErrorSeverity severity, int warnNo, const ECLlocation & pos, const char* format, ...)
  5274. {
  5275. if (errorHandler && !errorDisabled)
  5276. {
  5277. StringBuffer msg;
  5278. va_list args;
  5279. va_start(args, format);
  5280. Owned<IError> error = createErrorVA(category, severity, warnNo, pos, format, args);
  5281. va_end(args);
  5282. report(error);
  5283. }
  5284. }
  5285. void HqlGram::reportWarningVa(WarnErrorCategory category, int warnNo, const attribute& a, const char* format, va_list args)
  5286. {
  5287. const ECLlocation & pos = a.pos;
  5288. if (errorHandler && !errorDisabled)
  5289. {
  5290. Owned<IError> error = createErrorVA(category, queryDefaultSeverity(category), warnNo, pos, format, args);
  5291. report(error);
  5292. }
  5293. }
  5294. void HqlGram::reportWarning(WarnErrorCategory category, int warnNo, const char *msg, int lineno, int column)
  5295. {
  5296. if (errorHandler && !errorDisabled)
  5297. doReportWarning(category, warnNo, msg, querySourcePathText(), lineno, column, 0);
  5298. }
  5299. //interface IErrorReceiver
  5300. void HqlGram::reportError(int errNo, const char *msg, const char *filename, int lineno, int column, int position)
  5301. {
  5302. Owned<IError> err = createError(errNo,msg,filename,lineno,column,position);
  5303. report(err);
  5304. }
  5305. IError * HqlGram::mapError(IError * error)
  5306. {
  5307. return errorHandler->mapError(error);
  5308. }
  5309. void HqlGram::exportMappings(IWorkUnit * wu) const
  5310. {
  5311. return errorHandler->exportMappings(wu);
  5312. }
  5313. void HqlGram::report(IError* error)
  5314. {
  5315. if (errorHandler && !errorDisabled)
  5316. {
  5317. //Severity of warnings are not mapped here. Fatal errors are reported directly. Others are delayed
  5318. //(and may possibly be disabled by local onWarnings etc.)
  5319. bool isFatalError = (error->getSeverity() == SeverityFatal);
  5320. if (!isFatalError)
  5321. {
  5322. if (associateWarnings)
  5323. pendingWarnings.append(*LINK(error));
  5324. else
  5325. {
  5326. Owned<IError> mappedError = mapError(error);
  5327. errorHandler->report(mappedError);
  5328. }
  5329. }
  5330. else
  5331. {
  5332. errorHandler->report(error);
  5333. if (getMaxErrorsAllowed()>0 && errorHandler->errCount() >= getMaxErrorsAllowed())
  5334. {
  5335. errorHandler->reportError(ERR_ERROR_TOOMANY,"Too many errors; parsing aborted",error->getFilename(),error->getLine(),error->getColumn(),error->getPosition());
  5336. abortParsing();
  5337. }
  5338. }
  5339. reportMacroExpansionPosition(error, lexObject);
  5340. }
  5341. }
  5342. void HqlGram::reportWarning(WarnErrorCategory category, int warnNo, const char *msg, const char *filename, int lineno, int column, int pos)
  5343. {
  5344. if (errorHandler && !errorDisabled)
  5345. doReportWarning(category, warnNo, msg, filename, lineno, column, pos);
  5346. }
  5347. size32_t HqlGram::errCount()
  5348. {
  5349. return errorHandler ? errorHandler->errCount() : 0;
  5350. }
  5351. size32_t HqlGram::warnCount()
  5352. {
  5353. return errorHandler ? errorHandler->warnCount() : 0;
  5354. }
  5355. IHqlExpression * HqlGram::createLocationAttr(const attribute & a)
  5356. {
  5357. return a.pos.createLocationAttr();
  5358. }
  5359. void HqlGram::addResult(IHqlExpression *_query, const attribute& errpos)
  5360. {
  5361. if (!_query)
  5362. return;
  5363. OwnedHqlExpr query = createLocationAnnotation(_query, errpos.pos);
  5364. if (query->getOperator() == no_loadxml)
  5365. return;
  5366. parseResults.append(*query.getClear());
  5367. }
  5368. void HqlGram::checkFormals(IIdAtom * name, HqlExprArray& parms, HqlExprArray& defaults, attribute& object)
  5369. {
  5370. node_operator op = object.queryExpr()->getOperator();
  5371. bool isMacro = (op == no_macro);
  5372. for (unsigned idx = 0; idx < parms.length(); idx++) // Can NOT use ForEachItemIn.
  5373. {
  5374. IHqlExpression* parm = (IHqlExpression*)&parms.item(idx);
  5375. if (isMacro && !parm->hasAttribute(noTypeAtom))
  5376. reportError(ERR_MACRO_NOPARAMTYPE, object, "Type is not allowed for macro: parameter %d of %s", idx+1, str(name));
  5377. //
  5378. // check default value
  5379. if (isMacro)
  5380. {
  5381. IHqlExpression* def = &defaults.item(idx);
  5382. if ((def->getOperator() != no_omitted) && !def->isConstant())
  5383. {
  5384. if (def->queryType()->getTypeCode() != type_string)
  5385. reportError(ERR_MACRO_CONSTDEFPARAM, object, "Default parameter to macro must be constant string: parameter %d of %s",idx+1,str(name));
  5386. }
  5387. }
  5388. }
  5389. }
  5390. void HqlGram::addParameter(const attribute & errpos, IIdAtom * name, ITypeInfo* type, IHqlExpression* defValue)
  5391. {
  5392. checkSensibleId(errpos, name);
  5393. HqlExprArray attrs;
  5394. endList(attrs);
  5395. if (hasAttribute(fieldsAtom, attrs))
  5396. {
  5397. type = makeSortListType(type);
  5398. if (!defValue && hasAttribute(optAtom, attrs))
  5399. defValue = createValue(no_sortlist, LINK(type));
  5400. }
  5401. addActiveParameterOwn(errpos, createParameter(name, nextParameterIndex(), type, attrs), defValue);
  5402. }
  5403. void HqlGram::addFunctionParameter(const attribute & errpos, IIdAtom * name, ITypeInfo* type, IHqlExpression* defValue)
  5404. {
  5405. checkSensibleId(errpos, name);
  5406. ActiveScopeInfo & activeScope = defineScopes.tos();
  5407. OwnedHqlExpr formals = activeScope.createFormals(false);
  5408. OwnedHqlExpr defaults = activeScope.createDefaults();
  5409. //MORE default values for these parameters are currently lost...
  5410. leaveScope(errpos); // Restores previous active parameters
  5411. HqlExprArray attrs;
  5412. endList(attrs);
  5413. Owned<ITypeInfo> funcType = makeFunctionType(type, LINK(formals), defaults.getClear(), NULL);
  5414. addActiveParameterOwn(errpos, createParameter(name, nextParameterIndex(), LINK(funcType), attrs), defValue);
  5415. }
  5416. void HqlGram::addFunctionProtoParameter(const attribute & errpos, IIdAtom * name, IHqlExpression * donor, IHqlExpression* defValue)
  5417. {
  5418. checkSensibleId(errpos, name);
  5419. assertex(donor->isFunction());
  5420. HqlExprArray attrs;
  5421. endList(attrs);
  5422. addActiveParameterOwn(errpos, createParameter(name, nextParameterIndex(), donor->getType(), attrs), defValue);
  5423. donor->Release();
  5424. }
  5425. IHqlScope * HqlGram::queryTemplateContext()
  5426. {
  5427. ForEachItemIn(i, defineScopes)
  5428. {
  5429. IHqlScope * scope = defineScopes.item(i).templateAttrContext;
  5430. if (scope)
  5431. return scope;
  5432. }
  5433. return NULL;
  5434. }
  5435. IHqlExpression *HqlGram::bindParameters(const attribute & errpos, IHqlExpression * function, HqlExprArray & actuals)
  5436. {
  5437. assertex(function->isFunction());
  5438. // something bad happened
  5439. if (checkParameters(function, actuals, errpos))
  5440. {
  5441. try
  5442. {
  5443. const bool expandCallsWhenBound = lookupCtx.queryExpandCallsWhenBound();
  5444. if (function->getOperator() != no_funcdef)
  5445. return createBoundFunction(this, function, actuals, lookupCtx.functionCache, expandCallsWhenBound);
  5446. IHqlExpression * body = function->queryChild(0);
  5447. if (body->getOperator() == no_template_context)
  5448. {
  5449. if (requireLateBind(function, actuals))
  5450. {
  5451. IHqlExpression * ret = NULL;
  5452. if (!expandCallsWhenBound)
  5453. {
  5454. HqlExprArray args;
  5455. args.append(*LINK(body));
  5456. unwindChildren(args, function, 1);
  5457. OwnedHqlExpr newFunction = createFunctionDefinition(function->queryId(), args);
  5458. OwnedHqlExpr boundExpr = createBoundFunction(this, newFunction, actuals, lookupCtx.functionCache, expandCallsWhenBound);
  5459. // get rid of the wrapper
  5460. //assertex(boundExpr->getOperator()==no_template_context);
  5461. ret = LINK(boundExpr);//->queryChild(0));
  5462. }
  5463. else
  5464. {
  5465. OwnedHqlExpr boundExpr = createBoundFunction(this, function, actuals, lookupCtx.functionCache, expandCallsWhenBound);
  5466. // get rid of the wrapper
  5467. assertex(boundExpr->getOperator()==no_template_context);
  5468. ret = LINK(boundExpr->queryChild(0));
  5469. }
  5470. IHqlExpression * formals = function->queryChild(1);
  5471. // bind fields
  5472. ForEachItemIn(idx, actuals)
  5473. {
  5474. IHqlExpression *formal = formals->queryChild(idx);
  5475. if (isAbstractDataset(formal))
  5476. {
  5477. IHqlExpression *actual = &actuals.item(idx);
  5478. ret = bindDatasetParameter(ret, formal, actual, errpos);
  5479. }
  5480. }
  5481. return ret;
  5482. }
  5483. else
  5484. return bindTemplateFunctionParameters(function, actuals, errpos);
  5485. }
  5486. else
  5487. {
  5488. bool expandCall = insideTemplateFunction() ? false : expandCallsWhenBound;
  5489. // do the actual binding
  5490. return createBoundFunction(this, function, actuals, lookupCtx.functionCache, expandCall);
  5491. }
  5492. }
  5493. catch (IException * e)
  5494. {
  5495. if (e->errorCode() == ERR_ABORT_PARSING)
  5496. throw;
  5497. StringBuffer msg;
  5498. e->errorMessage(msg);
  5499. reportError(e->errorCode(), errpos, "%s", msg.str());
  5500. e->Release();
  5501. }
  5502. }
  5503. //Stop parameter mismatches causing failures/seh later because a dataset is expected to be returned.
  5504. if (function->isDataset())
  5505. {
  5506. IHqlExpression * record = function->queryRecord();
  5507. if (!record)
  5508. record = queryNullRecord();
  5509. return createDataset(no_null, LINK(record));
  5510. }
  5511. return createNullExpr(stripFunctionType(function->queryType()));
  5512. }
  5513. IHqlExpression *HqlGram::bindParameters(const attribute & errpos, IHqlExpression * func, IHqlExpression *parms)
  5514. {
  5515. HqlExprArray actuals;
  5516. if (parms)
  5517. parms->unwindList(actuals, no_comma);
  5518. return bindParameters(errpos, func, actuals);
  5519. }
  5520. IHqlExpression *HqlGram::bindParameters(attribute &a, IHqlExpression *parms)
  5521. {
  5522. HqlExprArray actuals;
  5523. if (parms)
  5524. {
  5525. parms->unwindList(actuals, no_comma);
  5526. parms->Release();
  5527. }
  5528. OwnedHqlExpr origFunc = a.getExpr();
  5529. return bindParameters(a, origFunc, actuals);
  5530. }
  5531. bool areFunctionsCompatible(IHqlExpression * arg1, IHqlExpression * arg2)
  5532. {
  5533. ITypeInfo * type1 = arg1->queryType();
  5534. ITypeInfo * type2 = arg2->queryType();
  5535. if (!arg1->isFunction())
  5536. {
  5537. if (!arg2->isFunction())
  5538. return (type1 == type2);
  5539. return false;
  5540. }
  5541. if (!arg2->isFunction())
  5542. return false;
  5543. ITypeInfo * returnType1 = type1->queryChildType();
  5544. ITypeInfo * returnType2 = type2->queryChildType();
  5545. if (arg1->isDataset())
  5546. {
  5547. if (!returnType1->assignableFrom(returnType2->queryPromotedType()))
  5548. return false;
  5549. }
  5550. else if (returnType1 != returnType2)
  5551. return false;
  5552. IHqlExpression * formals1 = queryFunctionParameters(type1);
  5553. IHqlExpression * formals2 = queryFunctionParameters(type2);
  5554. unsigned max = formals1->numChildren();
  5555. if (max != formals2->numChildren())
  5556. return false;
  5557. for (unsigned i=0; i < max; i++)
  5558. {
  5559. if (!areFunctionsCompatible(formals1->queryChild(i), formals2->queryChild(i)))
  5560. return false;
  5561. }
  5562. return true;
  5563. }
  5564. FunctionCallInfo::FunctionCallInfo(IHqlExpression * _funcdef)
  5565. : funcdef(_funcdef)
  5566. {
  5567. hadNamed = false;
  5568. hasActiveTopDataset = false;
  5569. numFormals = 0;
  5570. if (funcdef)
  5571. {
  5572. IHqlExpression * formals = queryFunctionParameters(funcdef);
  5573. numFormals = formals->numChildren();
  5574. //Don't allow implicit hidden parameters to be specified
  5575. while (numFormals && formals->queryChild(numFormals-1)->hasAttribute(_hidden_Atom))
  5576. numFormals--;
  5577. }
  5578. }
  5579. IHqlExpression * FunctionCallInfo::getFinalActuals()
  5580. {
  5581. assertex(!hasActiveTopDataset);
  5582. flushPendingComponents();
  5583. if (actuals.ordinality() == 1)
  5584. {
  5585. if (actuals.item(0).getOperator() == no_omitted)
  5586. actuals.pop();
  5587. }
  5588. return createComma(actuals);
  5589. }
  5590. void FunctionCallInfo::flushPendingComponents()
  5591. {
  5592. if (pendingComponents.ordinality() != 0)
  5593. {
  5594. IHqlExpression * formals = queryFunctionParameters(funcdef);
  5595. IHqlExpression * formal = formals->queryChild(actuals.ordinality());
  5596. assertex(formal && formal->hasAttribute(fieldsAtom));
  5597. actuals.append(*createValue(no_sortlist, formal->getType(), pendingComponents));
  5598. pendingComponents.kill();
  5599. }
  5600. }
  5601. void FunctionCallInfo::fillWithOmitted(unsigned next)
  5602. {
  5603. while (actuals.ordinality() < next)
  5604. actuals.append(*createOmittedValue());
  5605. }
  5606. /**
  5607. * This handles parameter type checking and defvalue.
  5608. *
  5609. * Return: true: binding is needed
  5610. * false: binding is not needed (either not a func, or FATAL error happened).
  5611. */
  5612. IHqlExpression * HqlGram::checkParameter(const attribute * errpos, IHqlExpression * actual, IHqlExpression * formal, bool isDefault, IHqlExpression * funcdef)
  5613. {
  5614. if (actual->getOperator() == no_omitted)
  5615. return LINK(actual);
  5616. ITypeInfo * actualType = actual->queryType();
  5617. IIdAtom * formalName = formal->queryId();
  5618. if (actualType==NULL ||
  5619. ((actualType->getTypeCode() == type_void) && !actual->isFunction()))
  5620. {
  5621. if (errpos)
  5622. reportError(ERR_PARAM_NOTYPEORVOID, *errpos, "Non-typed or void type expression can not used: parameter %s", str(formalName));
  5623. return NULL;
  5624. }
  5625. ITypeInfo * formalType = formal->queryType();
  5626. if (formal->isFunction() || actual->isFunction())
  5627. {
  5628. if (formal->isFunction() && actual->isFunction())
  5629. {
  5630. if (!areFunctionsCompatible(formal, actual))
  5631. {
  5632. if (errpos)
  5633. {
  5634. if (isGrouped(formal) != isGrouped(actual))
  5635. reportError(ERR_PARAM_TYPEMISMATCH, *errpos, "Grouping for functional parameter %s does not match", str(formalName));
  5636. else
  5637. reportError(ERR_PARAM_TYPEMISMATCH, *errpos, "Types for functional parameter %s does not match exactly", str(formalName));
  5638. }
  5639. return NULL;
  5640. }
  5641. return LINK(actual);
  5642. }
  5643. if (formal->isFunction())
  5644. {
  5645. if (errpos)
  5646. reportError(ERR_PARAM_TYPEMISMATCH, *errpos, "Parameter %s requires an unbound functional argument", str(formalName));
  5647. return NULL;
  5648. }
  5649. if (errpos)
  5650. reportError(ERR_PARAM_TYPEMISMATCH, *errpos, "Cannot pass a functional definition to parameter %s", str(formalName));
  5651. return NULL;
  5652. }
  5653. type_t actualTC = actualType->getTypeCode();
  5654. type_t formalTC = formalType->getTypeCode();
  5655. LinkedHqlExpr ret = actual;
  5656. switch (formalTC)
  5657. {
  5658. case type_rule:
  5659. case type_token:
  5660. if (actualTC == type_pattern)
  5661. ret.setown(createValue(no_pat_imptoken, makeTokenType(), LINK(actual)));
  5662. else if ((actualTC != type_rule) && (actualTC != type_token))
  5663. {
  5664. if (errpos)
  5665. reportError(ERR_PARAM_TYPEMISMATCH, *errpos, "Expression passed to pattern parameter");
  5666. return NULL;
  5667. }
  5668. break;
  5669. case type_pattern:
  5670. if (actualTC != type_pattern)
  5671. {
  5672. if (errpos)
  5673. reportError(ERR_TOKEN_IN_PATTERN, *errpos, "Only patterns can be passed to pattern parameters");
  5674. return NULL;
  5675. }
  5676. break;
  5677. case type_table:
  5678. case type_groupedtable:
  5679. {
  5680. if (actual->isDatarow() && errpos)
  5681. reportError(ERR_EXPECTED_DATASET, *errpos, "Expected a dataset instead of a row");
  5682. IHqlExpression * record = formal->queryRecord();
  5683. if (record->numChildren() == 0)
  5684. break;
  5685. // fallthrough
  5686. }
  5687. default:
  5688. if (formalTC == type_row)
  5689. formalType = formalType->queryChildType();
  5690. if (!formalType->assignableFrom(actualType->queryPromotedType()))
  5691. {
  5692. if (errpos)
  5693. {
  5694. StringBuffer s,tp1,tp2;
  5695. if (isDefault)
  5696. {
  5697. s.appendf("Default for parameter %s type mismatch - expected %s, given %s",str(formalName),
  5698. getFriendlyTypeStr(formal,tp1).str(),
  5699. getFriendlyTypeStr(actual,tp2).str());
  5700. }
  5701. else
  5702. {
  5703. s.appendf("Parameter %s type mismatch - expected %s, given %s",str(formalName),
  5704. getFriendlyTypeStr(formal,tp1).str(),
  5705. getFriendlyTypeStr(actual,tp2).str());
  5706. }
  5707. reportError(ERR_PARAM_TYPEMISMATCH, *errpos, "%s", s.str());
  5708. }
  5709. return NULL;
  5710. }
  5711. break;
  5712. }
  5713. // if (formal->hasAttribute(constAtom) && funcdef && !isExternalFunction(funcdef))
  5714. if (errpos && formal->hasAttribute(assertConstAtom))
  5715. ret.setown(checkConstant(*errpos, ret));
  5716. if (formal->hasAttribute(fieldAtom))
  5717. {
  5718. if (!isValidFieldReference(actual))
  5719. {
  5720. if (errpos)
  5721. reportError(ERR_EXPECTED_FIELD, *errpos, "Expected a field reference to be passed to parameter %s", str(formalName));
  5722. return NULL;
  5723. }
  5724. if (ret->getOperator() != no_indirect)
  5725. ret.setown(createValue(no_indirect, ret->getType(), LINK(ret)));
  5726. }
  5727. else
  5728. {
  5729. if (isFieldSelectedFromRecord(ret))
  5730. {
  5731. if (errpos)
  5732. reportError(ERR_EXPECTED, *errpos, "Expression expected for parameter %s. Fields from records can only be passed to field references", str(formalName));
  5733. return NULL;
  5734. }
  5735. }
  5736. if (formal->hasAttribute(fieldsAtom))
  5737. {
  5738. if (!isValidFieldReference(actual) && actualTC != type_sortlist)
  5739. {
  5740. if (errpos)
  5741. reportError(ERR_EXPECTED_FIELD, *errpos, "Expected a field reference to be passed to parameter %s", str(formalName));
  5742. return NULL;
  5743. }
  5744. }
  5745. return ret.getClear();
  5746. }
  5747. static unsigned findParameterByName(IHqlExpression * formals, IIdAtom * searchId)
  5748. {
  5749. IAtom * searchName = lower(searchId);
  5750. ForEachChild(i, formals)
  5751. {
  5752. if (formals->queryChild(i)->queryName() == searchName)
  5753. return i;
  5754. }
  5755. return (unsigned)-1;
  5756. }
  5757. void HqlGram::checkActualTopScope(FunctionCallInfo & call, IHqlExpression * formal, IHqlExpression * actual)
  5758. {
  5759. if (isAbstractDataset(formal))
  5760. {
  5761. leaveActualTopScope(call);
  5762. if (!isOmitted(actual))
  5763. {
  5764. pushTopScope(actual);
  5765. call.hasActiveTopDataset = true;
  5766. }
  5767. }
  5768. }
  5769. void HqlGram::leaveActualTopScope(FunctionCallInfo & call)
  5770. {
  5771. if (call.hasActiveTopDataset)
  5772. {
  5773. popTopScope();
  5774. call.hasActiveTopDataset = false;
  5775. }
  5776. }
  5777. bool HqlGram::processParameter(FunctionCallInfo & call, IIdAtom * name, IHqlExpression * actualValue, const attribute& errpos)
  5778. {
  5779. IHqlExpression * func = call.funcdef;
  5780. if (!func)
  5781. {
  5782. reportError(ERR_TYPE_NOPARAMNEEDED, errpos, "Type does not require parameters");
  5783. return false;
  5784. }
  5785. IIdAtom * funcName = func->queryId();
  5786. IHqlExpression * formals = queryFunctionParameters(func);
  5787. unsigned targetActual = call.actuals.ordinality();
  5788. LinkedHqlExpr actual = actualValue;
  5789. if (name)
  5790. {
  5791. call.flushPendingComponents();
  5792. targetActual = findParameterByName(formals, name);
  5793. if (targetActual == (unsigned)-1)
  5794. {
  5795. reportError(ERR_NAMED_PARAM_NOT_FOUND, errpos, "Could not find a parameter named %s", str(name));
  5796. return false;
  5797. }
  5798. if (call.actuals.isItem(targetActual) && call.actuals.item(targetActual).getOperator() != no_omitted)
  5799. {
  5800. reportError(ERR_NAMED_ALREADY_HAS_VALUE, errpos, "Parameter %s already has a value supplied", str(name));
  5801. return false;
  5802. }
  5803. call.hadNamed = true;
  5804. }
  5805. else
  5806. {
  5807. if (call.hadNamed)
  5808. {
  5809. reportError(ERR_NON_NAMED_AFTER_NAMED, errpos, "Named parameters cannot be followed by unnamed parameters");
  5810. return false;
  5811. }
  5812. //opt parameters are skipped if the value passed is not compatible with the formal
  5813. while (targetActual < call.numFormals)
  5814. {
  5815. IHqlExpression * formal = formals->queryChild(targetActual);
  5816. if (!formal->hasAttribute(optAtom))
  5817. {
  5818. //Non opt <?> may skip this argument if we have already had one that is compatible
  5819. if (!formal->hasAttribute(fieldsAtom))
  5820. break;
  5821. if (call.pendingComponents.ordinality() == 0)
  5822. break;
  5823. }
  5824. //Just check - don't report any errors.
  5825. OwnedHqlExpr checked = checkParameter(NULL, actual, formal, false, func);
  5826. if (checked)
  5827. break;
  5828. targetActual++;
  5829. call.flushPendingComponents();
  5830. }
  5831. }
  5832. if (targetActual >= call.numFormals)
  5833. {
  5834. if (isOmitted(actual))
  5835. return true;
  5836. reportError(ERR_PARAM_TOOMANY, errpos, "Too many parameters passed to function %s (expected %d)", str(funcName), call.numFormals);
  5837. return false;
  5838. }
  5839. IHqlExpression * formal = formals->queryChild(targetActual);
  5840. OwnedHqlExpr checked = checkParameter(&errpos, actual, formal, false, func);
  5841. if (!checked)
  5842. return false;
  5843. call.fillWithOmitted(targetActual);
  5844. //Process <??>. Append to a pending list as many actual parameters as we can that are compatible, and later create a no_sortlist in its place.
  5845. if (!name && formal->hasAttribute(fieldsAtom) && (checked->queryType()->getTypeCode() != type_sortlist))
  5846. {
  5847. call.pendingComponents.append(*LINK(checked));
  5848. return true;
  5849. }
  5850. if (call.actuals.isItem(targetActual))
  5851. call.actuals.replace(*LINK(checked), targetActual);
  5852. else
  5853. call.actuals.append(*LINK(checked));
  5854. if (!name)
  5855. checkActualTopScope(call, formal, checked);
  5856. return true;
  5857. }
  5858. bool HqlGram::checkParameters(IHqlExpression* func, HqlExprArray& actuals, const attribute& errpos)
  5859. {
  5860. IIdAtom * funcName = func->queryId();
  5861. if (!func->isFunction())
  5862. {
  5863. if (actuals.length())
  5864. reportError(ERR_TYPE_NOPARAMNEEDED, errpos, "Type does not require parameters: %s", str(funcName));
  5865. return false;
  5866. }
  5867. IHqlExpression * formals = queryFunctionParameters(func);
  5868. IHqlExpression * defaults = queryFunctionDefaults(func);
  5869. ForEachChild(idx, formals)
  5870. {
  5871. IHqlExpression *formal = formals->queryChild(idx);
  5872. if (!actuals.isItem(idx))
  5873. actuals.append(*createOmittedValue());
  5874. IHqlExpression *actual = &actuals.item(idx);
  5875. if (actual->getOperator()==no_omitted)
  5876. {
  5877. IHqlExpression * defvalue = queryDefaultValue(defaults, idx);
  5878. if (!defvalue)
  5879. {
  5880. IIdAtom * formalName = formal->queryId();
  5881. reportError(ERR_PARAM_NODEFVALUE, errpos, "Omitted parameter %s has no default value", str(formalName));
  5882. return false;
  5883. }
  5884. // actuals.replace(*LINK(defvalue), idx);
  5885. }
  5886. }
  5887. return true;
  5888. }
  5889. void HqlGram::addActiveParameterOwn(const attribute & errpos, IHqlExpression * param, IHqlExpression * defaultValue)
  5890. {
  5891. ActiveScopeInfo & activeScope = defineScopes.tos();
  5892. activeScope.activeParameters.append(*param);
  5893. activeScope.activeDefaults.append(*ensureNormalizedDefaultValue(defaultValue));
  5894. if (defaultValue && !param->hasAttribute(noTypeAtom))
  5895. {
  5896. OwnedHqlExpr newActual = checkParameter(&errpos, defaultValue, param, true, NULL);
  5897. }
  5898. }
  5899. IHqlExpression * HqlGram::checkBuildIndexRecord(IHqlExpression *record, attribute & errpos)
  5900. {
  5901. bool allConstant;
  5902. IHqlExpression * newRecord = checkOutputRecord(record, errpos, allConstant, true);
  5903. record->Release();
  5904. return newRecord;
  5905. // MORE - check that there is a file position, no constants, that kind of thing
  5906. // MORE - check all fields are big_endian?
  5907. }
  5908. void HqlGram::checkBuildIndexFilenameFlags(IHqlExpression * dataset, attribute & flags)
  5909. {
  5910. }
  5911. IHqlExpression * HqlGram::createBuildFileFromTable(IHqlExpression * table, const HqlExprArray & buildOptions, IHqlExpression * filename, attribute & errpos)
  5912. {
  5913. IHqlExpression * originAttr = table->queryAttribute(_origin_Atom);
  5914. IHqlExpression * ds = originAttr->queryChild(0);
  5915. IHqlExpression * mode = table->queryChild(2);
  5916. if (!filename) filename = table->queryChild(0);
  5917. HqlExprArray args;
  5918. args.append(*LINK(ds));
  5919. args.append(*LINK(filename));
  5920. switch (mode->getOperator())
  5921. {
  5922. case no_csv:
  5923. args.append(*createAttribute(csvAtom, LINK(mode->queryChild(0))));
  5924. break;
  5925. case no_xml:
  5926. args.append(*createAttribute(xmlAtom, LINK(mode->queryChild(0))));
  5927. break;
  5928. }
  5929. ForEachItemIn(i, buildOptions)
  5930. {
  5931. IHqlExpression & cur = buildOptions.item(i);
  5932. IAtom * name = cur.queryName();
  5933. if ((name == overwriteAtom) ||(name == backupAtom) || (name == namedAtom) || (name == updateAtom) || (name == expireAtom))
  5934. args.append(OLINK(cur));
  5935. else if (name == persistAtom)
  5936. args.append(*createAttribute(persistAtom, LINK(ds))); // preserve so changes in representation don't affect crc.
  5937. }
  5938. return createValue(no_output, makeVoidType(), args);
  5939. }
  5940. IHqlExpression * queryRootIndex(IHqlExpression * index)
  5941. {
  5942. loop
  5943. {
  5944. node_operator op = index->getOperator();
  5945. if (op == no_compound)
  5946. index = index->queryChild(1);
  5947. else if (op == no_executewhen)
  5948. index = index->queryChild(0);
  5949. else
  5950. return index;
  5951. }
  5952. }
  5953. IHqlExpression * HqlGram::createBuildIndexFromIndex(attribute & indexAttr, attribute & flagsAttr, attribute & errpos)
  5954. {
  5955. warnIfRecordPacked(indexAttr);
  5956. OwnedHqlExpr index = indexAttr.getExpr();
  5957. index.set(queryRootIndex(index));
  5958. HqlExprArray buildOptions;
  5959. flagsAttr.unwindCommaList(buildOptions);
  5960. LinkedHqlExpr filename;
  5961. LinkedHqlExpr sourceDataset;
  5962. ForEachItemInRev(iOption, buildOptions)
  5963. {
  5964. IHqlExpression & cur = buildOptions.item(iOption);
  5965. if (cur.isDataset())
  5966. {
  5967. if (sourceDataset)
  5968. reportError(ERR_DUPLICATE_SOURCE,errpos,"Source dataset cannot be specified more than once");
  5969. sourceDataset.set(&cur);
  5970. buildOptions.remove(iOption);
  5971. }
  5972. else if (!cur.isAttribute())
  5973. {
  5974. if (cur.getOperator() != no_distributer)
  5975. {
  5976. if (filename)
  5977. reportError(ERR_DUPLICATE_FILENAME,errpos,"Index filename cannot be specified more than once");
  5978. filename.set(&cur);
  5979. buildOptions.remove(iOption);
  5980. }
  5981. }
  5982. }
  5983. if (!isKey(index))
  5984. {
  5985. if (index->getOperator() == no_table && index->hasAttribute(_origin_Atom))
  5986. return createBuildFileFromTable(index, buildOptions, filename, errpos);
  5987. reportError(ERR_EXPECTED_INDEX,indexAttr,"Expected an index as the first parameter");
  5988. return createDataset(no_null, LINK(queryNullRecord()));
  5989. }
  5990. LinkedHqlExpr dataset = index->queryChild(0);
  5991. IHqlExpression *record = index->queryChild(1);
  5992. OwnedHqlExpr transform;
  5993. if (index->getOperator() == no_keyindex)
  5994. {
  5995. if (!filename)
  5996. filename.set(index->queryChild(2));
  5997. }
  5998. else
  5999. {
  6000. transform.set(index->queryChild(2));
  6001. if (!filename)
  6002. filename.set(index->queryChild(3));
  6003. }
  6004. if (sourceDataset)
  6005. transform.setown(createDefaultAssignTransform(record, sourceDataset->queryNormalizedSelector(), indexAttr));
  6006. //need to tag record scope in this case so it generates no_activetable as top selector
  6007. OwnedHqlExpr distribution;
  6008. if (!sourceDataset)
  6009. {
  6010. bool allConstant = true;
  6011. bool someMissing = false;
  6012. ForEachChild(idx, record)
  6013. {
  6014. IHqlExpression * field = record->queryChild(idx);
  6015. if (field->isAttribute())
  6016. continue;
  6017. IHqlExpression * value = field->queryChild(0);
  6018. if (!value)
  6019. someMissing = true;
  6020. else if (!value->isAttribute() && !value->isConstant())
  6021. allConstant = false;
  6022. }
  6023. if (someMissing)
  6024. reportError(ERR_KEYEDINDEXINVALID,indexAttr,"The index record contains fields with no mappings - cannot build an index on it");
  6025. else if (allConstant)
  6026. reportError(ERR_KEYEDINDEXINVALID,indexAttr,"The index record has no mappings from the dataset - cannot build an index on it");
  6027. }
  6028. IHqlExpression * select;
  6029. if (sourceDataset)
  6030. select = createDatasetF(no_newusertable, LINK(sourceDataset), LINK(record), LINK(transform), NULL); //createUniqueId(), NULL);
  6031. else if (transform)
  6032. select = createDatasetF(no_newusertable, LINK(dataset), LINK(record), LINK(transform), NULL); //createUniqueId(), NULL);
  6033. else
  6034. {
  6035. IHqlExpression * newRecord = checkBuildIndexRecord(LINK(record), errpos);
  6036. select = createDatasetF(no_selectfields, LINK(dataset), newRecord, NULL); //createUniqueId(), NULL);
  6037. }
  6038. HqlExprArray args;
  6039. args.append(*select);
  6040. args.append(*LINK(filename));
  6041. ForEachItemIn(i, buildOptions)
  6042. {
  6043. IHqlExpression & cur = buildOptions.item(i);
  6044. IAtom * name = cur.queryName();
  6045. if (name == distributedAtom)
  6046. distribution.setown(&cur);
  6047. else if (name == persistAtom)
  6048. args.append(*createAttribute(persistAtom, LINK(index))); // preserve so changes in representation don't affect crc.
  6049. else
  6050. args.append(OLINK(cur));
  6051. }
  6052. //Clone flags from the index that are required.
  6053. ForEachChild(iflag, index)
  6054. {
  6055. IHqlExpression * cur = index->queryChild(iflag);
  6056. if (cur->isAttribute())
  6057. {
  6058. IAtom * name = cur->queryName();
  6059. if ((name == sort_AllAtom) || (name == sort_KeyedAtom) || (name == fixedAtom) || (name == compressedAtom) || (name == dedupAtom))
  6060. args.append(*LINK(cur));
  6061. else if (name == distributedAtom)
  6062. {
  6063. args.append(*createAttribute(noRootAtom));
  6064. if (cur->queryChild(0))
  6065. distribution.setown(replaceSelector(cur, queryActiveTableSelector(), select));
  6066. args.append(*createLocalAttribute());
  6067. }
  6068. else if (name == maxLengthAtom)
  6069. {
  6070. if (!queryAttribute(name, args))
  6071. args.append(*LINK(cur));
  6072. }
  6073. }
  6074. }
  6075. IHqlExpression * payload = index->queryAttribute(_payload_Atom);
  6076. if (payload)
  6077. args.append(*LINK(payload));
  6078. IHqlExpression * fileposition = index->queryAttribute(filepositionAtom);
  6079. if (fileposition)
  6080. args.append(*LINK(fileposition));
  6081. if (distribution)
  6082. args.append(*distribution.getClear());
  6083. checkDistributer(flagsAttr.pos, args);
  6084. return createValue(no_buildindex, makeVoidType(), args);
  6085. }
  6086. bool HqlGram::doCheckValidFieldValue(const attribute &errpos, IHqlExpression *value, IHqlExpression * field)
  6087. {
  6088. if (value->queryTransformExtra())
  6089. return true;
  6090. value->setTransformExtraUnlinked(value);
  6091. switch (value->getOperator())
  6092. {
  6093. case NO_AGGREGATE:
  6094. return true;
  6095. case no_select:
  6096. {
  6097. do
  6098. {
  6099. value = value->queryChild(0);
  6100. } while (value->getOperator() == no_select);
  6101. if (value->getOperator() == no_selfref)
  6102. {
  6103. reportError(ERR_BAD_FIELD_ATTR, errpos, "SELF cannot be used to provide a value for field '%s'", str(field->queryName()));
  6104. return false;
  6105. }
  6106. return true;
  6107. }
  6108. }
  6109. ITypeInfo * type = value->queryType();
  6110. if (!type || !type->isScalar())
  6111. return true;
  6112. ForEachChild(i, value)
  6113. {
  6114. if (!doCheckValidFieldValue(errpos, value->queryChild(i), field))
  6115. return false;
  6116. }
  6117. return true;
  6118. }
  6119. bool HqlGram::checkValidFieldValue(const attribute &errpos, IHqlExpression *value, IHqlExpression *field)
  6120. {
  6121. TransformMutexBlock lock;
  6122. return doCheckValidFieldValue(errpos, value, field);
  6123. }
  6124. IHqlExpression * HqlGram::checkOutputRecord(IHqlExpression *record, const attribute & errpos, bool & allConstant, bool outerLevel)
  6125. {
  6126. assertex(record->getOperator()==no_record||record->getOperator()==no_null);
  6127. HqlExprArray children;
  6128. unsigned numkids = record->numChildren();
  6129. for (unsigned i = 0; i < numkids; i++)
  6130. {
  6131. IHqlExpression *field = record->queryChild(i);
  6132. switch(field->getOperator())
  6133. {
  6134. case no_ifblock:
  6135. {
  6136. HqlExprArray args;
  6137. args.append(*LINK(field->queryChild(0)));
  6138. args.append(*checkOutputRecord(field->queryChild(1), errpos, allConstant, outerLevel));
  6139. children.append(*cloneOrLink(field, args));
  6140. break;
  6141. }
  6142. case no_record:
  6143. children.append(*checkOutputRecord(field, errpos, allConstant, outerLevel));
  6144. break;
  6145. case no_field:
  6146. {
  6147. LinkedHqlExpr newField = field;
  6148. IHqlExpression * child0 = field->queryChild(0);
  6149. if (child0 && !child0->isAttribute())
  6150. {
  6151. checkValidFieldValue(errpos, child0, field);
  6152. if (!child0->isConstant())
  6153. allConstant = false;
  6154. }
  6155. else if (field->isDatarow())
  6156. {
  6157. IHqlExpression * oldRecord = field->queryRecord();
  6158. OwnedHqlExpr newRecord = checkOutputRecord(oldRecord, errpos, allConstant, outerLevel);
  6159. if (newRecord != oldRecord)
  6160. {
  6161. HqlExprArray args;
  6162. unwindChildren(args, field);
  6163. newField.setown(createField(field->queryId(), newRecord->getType(), args));
  6164. }
  6165. }
  6166. else
  6167. {
  6168. IIdAtom * name = field->queryId();
  6169. reportError(ERR_REC_FIELDNODEFVALUE, errpos, REC_FLD_ERR_STR, name ? str(name) : "?");
  6170. allConstant = false; // no point reporting this as well.
  6171. HqlExprArray args;
  6172. args.append(*createNullExpr(field));
  6173. newField.setown(field->clone(args));
  6174. }
  6175. children.append(*newField.getClear());
  6176. break;
  6177. }
  6178. case no_attr:
  6179. case no_attr_expr:
  6180. case no_attr_link:
  6181. children.append(*LINK(field));
  6182. break;
  6183. default:
  6184. PrintLogExprTree(field, "This is not a field! :");
  6185. assertex(field->getOperator()==no_field);
  6186. break;
  6187. }
  6188. }
  6189. return cloneOrLink(record, children);
  6190. }
  6191. //Add the CRC of the original expression to as an argument to the update attribute so it gets preserved throughout the transformations.
  6192. void HqlGram::processUpdateAttr(attribute & attr)
  6193. {
  6194. OwnedHqlExpr expr = attr.getExpr();
  6195. HqlExprArray args;
  6196. unwindChildren(args, expr);
  6197. if (expr->queryAttribute(updateAtom))
  6198. {
  6199. removeAttribute(args, updateAtom);
  6200. args.append(*createAttribute(updateAtom, createConstant((__int64)getExpressionCRC(expr))));
  6201. }
  6202. else
  6203. args.append(*createAttribute(updateAtom, createConstant((__int64)getExpressionCRC(expr)), createAttribute(alwaysAtom)));
  6204. expr.setown(expr->clone(args));
  6205. attr.setExpr(expr.getClear());
  6206. }
  6207. void HqlGram::checkOutputRecord(attribute & errpos, bool outerLevel)
  6208. {
  6209. OwnedHqlExpr record = errpos.getExpr();
  6210. bool allConstant = true;
  6211. errpos.setExpr(checkOutputRecord(record, errpos, allConstant, outerLevel));
  6212. if (allConstant && (record->getOperator() != no_null) && (record->numChildren() != 0))
  6213. reportWarning(CategoryUnusual, WRN_OUTPUT_ALL_CONSTANT,errpos.pos,"All values for OUTPUT are constant - is this the intention?");
  6214. }
  6215. void HqlGram::checkSoapRecord(attribute & errpos)
  6216. {
  6217. IHqlExpression * record = errpos.queryExpr();
  6218. bool allConstant = true;
  6219. OwnedHqlExpr mapped = checkOutputRecord(record, errpos, allConstant, true);
  6220. }
  6221. IHqlExpression * HqlGram::checkIndexRecord(IHqlExpression * record, const attribute & errpos, OwnedHqlExpr & indexAttrs)
  6222. {
  6223. unsigned numFields = record->numChildren();
  6224. if (numFields && getBoolAttributeInList(indexAttrs, filepositionAtom, true))
  6225. {
  6226. // if not, implies some error (already reported)
  6227. if (numFields == 1)
  6228. {
  6229. indexAttrs.setown(createComma(indexAttrs.getClear(), createExprAttribute(filepositionAtom, createConstant(false))));
  6230. }
  6231. else
  6232. {
  6233. IHqlExpression * lastField = record->queryChild(numFields-1);
  6234. ITypeInfo * fileposType = lastField->queryType();
  6235. if (!isIntegralType(fileposType))
  6236. indexAttrs.setown(createComma(indexAttrs.getClear(), createExprAttribute(filepositionAtom, createConstant(false))));
  6237. }
  6238. }
  6239. return LINK(record);
  6240. }
  6241. void HqlGram::reportUnsupportedFieldType(ITypeInfo * type, const attribute & errpos)
  6242. {
  6243. StringBuffer s;
  6244. getFriendlyTypeStr(type, s);
  6245. reportError(ERR_INDEX_BADTYPE, errpos, "Fields of type %s are not currently supported", s.str());
  6246. }
  6247. void HqlGram::reportInvalidIndexFieldType(IHqlExpression * expr, bool isKeyed, const attribute & errpos)
  6248. {
  6249. const char * id = str(expr->queryId());
  6250. StringBuffer s;
  6251. getFriendlyTypeStr(expr, s);
  6252. if (isKeyed)
  6253. reportError(ERR_INDEX_BADTYPE, errpos, "INDEX does not currently support keyed field (%s) of type '%s'", id, s.str());
  6254. else
  6255. reportError(ERR_INDEX_BADTYPE, errpos, "INDEX does not currently support field (%s) of type '%s'", id, s.str());
  6256. }
  6257. void HqlGram::checkIndexFieldType(IHqlExpression * expr, bool isPayload, bool insideNestedRecord, const attribute & errpos)
  6258. {
  6259. bool variableOk = isPayload;
  6260. switch (expr->getOperator())
  6261. {
  6262. case no_field:
  6263. {
  6264. ITypeInfo * type = expr->queryType();
  6265. IIdAtom * id = expr->queryId();
  6266. type_t tc = type->getTypeCode();
  6267. switch (tc)
  6268. {
  6269. case type_real:
  6270. if (!isPayload)
  6271. reportInvalidIndexFieldType(expr, true, errpos);
  6272. break;
  6273. case type_decimal:
  6274. if (!isPayload && type->isSigned())
  6275. reportInvalidIndexFieldType(expr, true, errpos);
  6276. break;
  6277. case type_bitfield:
  6278. case type_any:
  6279. reportInvalidIndexFieldType(expr, false, errpos);
  6280. break;
  6281. case type_record:
  6282. throwUnexpected();
  6283. case type_row:
  6284. {
  6285. IHqlExpression * record = expr->queryRecord();
  6286. unsigned numPayload = isPayload ? record->numChildren() : 0;
  6287. checkIndexRecordType(record, numPayload, true, errpos);
  6288. break;
  6289. }
  6290. case type_dictionary:
  6291. case type_table:
  6292. case type_groupedtable:
  6293. case type_packedint:
  6294. case type_set:
  6295. case type_varstring:
  6296. case type_varunicode:
  6297. if (!isPayload)
  6298. reportInvalidIndexFieldType(expr, true, errpos);
  6299. break;
  6300. case type_int:
  6301. case type_swapint:
  6302. if (!isPayload && insideNestedRecord)
  6303. {
  6304. if (type->isSigned() ||
  6305. ((tc == type_littleendianint) && (type->getSize() != 1)))
  6306. reportError(ERR_INDEX_BADTYPE, errpos.pos, "Signed or little-endian field %s is not supported inside a keyed record field ", str(id));
  6307. }
  6308. break;
  6309. default:
  6310. if (!type->isScalar())
  6311. reportInvalidIndexFieldType(expr, false, errpos);
  6312. else if ((type->getSize() == UNKNOWN_LENGTH) && !variableOk)
  6313. {
  6314. reportError(ERR_INDEX_BADTYPE, errpos, "Variable size fields (%s) are not supported inside indexes", str(id));
  6315. break;
  6316. }
  6317. }
  6318. break;
  6319. }
  6320. case no_ifblock:
  6321. {
  6322. if (!isPayload)
  6323. reportError(ERR_INDEX_BADTYPE, errpos, "IFBLOCKS not supported inside indexes");
  6324. IHqlExpression * record = expr->queryChild(1);
  6325. unsigned numPayload = isPayload ? record->numChildren() : 0;
  6326. checkIndexRecordType(record, numPayload, insideNestedRecord, errpos);
  6327. break;
  6328. }
  6329. case no_record:
  6330. {
  6331. unsigned numPayload = isPayload ? expr->numChildren() : 0;
  6332. checkIndexRecordType(expr, numPayload, insideNestedRecord, errpos);
  6333. break;
  6334. }
  6335. }
  6336. }
  6337. void HqlGram::checkIndexRecordType(IHqlExpression * record, unsigned numPayloadFields, bool insideNestedRecord, const attribute & errpos)
  6338. {
  6339. unsigned max = record->numChildren();
  6340. for (unsigned i=0;i < max; i++)
  6341. checkIndexFieldType(record->queryChild(i), i >= max-numPayloadFields, insideNestedRecord, errpos);
  6342. }
  6343. void HqlGram::checkIndexRecordTypes(IHqlExpression * index, const attribute & errpos)
  6344. {
  6345. IHqlExpression * record = index->queryChild(1);
  6346. checkIndexRecordType(record, numPayloadFields(index), false, errpos);
  6347. IHqlExpression * ds = index->queryChild(0)->queryNormalizedSelector();
  6348. IHqlExpression * filename = index->queryChild(2);
  6349. if (filename->usesSelector(ds))
  6350. {
  6351. if (filename->getOperator() == no_select)
  6352. reportError(ERR_INDEX_DEPEND_DATASET, errpos, "INDEX Filename cannot be dependent on the input dataset. Field '%s' used from the index.",
  6353. str(filename->queryChild(1)->queryId()));
  6354. else
  6355. reportError(ERR_INDEX_DEPEND_DATASET, errpos, "INDEX filename cannot be dependent on the input dataset.");
  6356. }
  6357. }
  6358. IHqlExpression * HqlGram::createRecordFromDataset(IHqlExpression * ds)
  6359. {
  6360. IHqlExpression * record = ds->queryRecord();
  6361. HqlExprArray fields;
  6362. ForEachChild(idx, record)
  6363. {
  6364. IHqlExpression * field = record->queryChild(idx);
  6365. if (field->isAttribute())
  6366. fields.append(*LINK(field));
  6367. else
  6368. {
  6369. //MORE: This should clone all attributes - not just extractFieldAttrs(), but if so it would also need to map the
  6370. //fields referenced in COUNT(SELF.x) as well.
  6371. fields.append(*createField(field->queryId(), field->getType(), createSelectExpr(LINK(ds), LINK(field)), extractFieldAttrs(field)));
  6372. }
  6373. }
  6374. return createRecord(fields);
  6375. }
  6376. IHqlExpression * HqlGram::cleanIndexRecord(IHqlExpression * record)
  6377. {
  6378. HqlExprArray fields;
  6379. bool same = true;
  6380. ForEachChild(idx, record)
  6381. {
  6382. IHqlExpression * field = record->queryChild(idx);
  6383. if (field->getOperator() == no_field && hasUninheritedAttribute(field))
  6384. {
  6385. IHqlExpression * value = queryRealChild(field, 0);
  6386. fields.append(*createField(field->queryId(), field->getType(), LINK(value), extractFieldAttrs(field)));
  6387. same = false;
  6388. }
  6389. else
  6390. fields.append(*LINK(field));
  6391. }
  6392. if (same)
  6393. return LINK(record);
  6394. return createRecord(fields);
  6395. }
  6396. interface IRecordFieldCompare
  6397. {
  6398. virtual bool include(IHqlExpression * field) = 0;
  6399. };
  6400. class RecordFieldDifference : implements IRecordFieldCompare
  6401. {
  6402. public:
  6403. RecordFieldDifference(IHqlExpression * record, HqlGram & _gram, const attribute & _errpos) : gram(_gram), errpos(_errpos)
  6404. {
  6405. scope = record->querySimpleScope();
  6406. }
  6407. virtual bool include(IHqlExpression * field)
  6408. {
  6409. IIdAtom * id = field->queryId();
  6410. OwnedHqlExpr match = scope->lookupSymbol(id);
  6411. if (!match)
  6412. return true;
  6413. if (field->queryType() != match->queryType())
  6414. gram.reportError(ERR_TYPEMISMATCH_RECORD, errpos, "Field %s has different type in records", str(id));
  6415. return false;
  6416. }
  6417. protected:
  6418. HqlGram & gram;
  6419. const attribute & errpos;
  6420. IHqlSimpleScope * scope;
  6421. };
  6422. class RecordFieldExcept : implements IRecordFieldCompare
  6423. {
  6424. public:
  6425. RecordFieldExcept(IHqlExpression * list, HqlGram & _gram, const attribute & _errpos) : gram(_gram), errpos(_errpos)
  6426. {
  6427. expand(list);
  6428. }
  6429. void checkAllUsed()
  6430. {
  6431. ForEachItemIn(i, names)
  6432. {
  6433. if (!matchedName.item(i))
  6434. gram.reportError(ERR_OBJ_NOSUCHFIELD, errpos, "Record doesn't contain a field called %s", str(&names.item(i)));
  6435. }
  6436. }
  6437. void expand(IHqlExpression * list)
  6438. {
  6439. while (list->getOperator() == no_comma)
  6440. {
  6441. expand(list->queryChild(0));
  6442. list = list->queryChild(1);
  6443. }
  6444. names.append(*list->queryName());
  6445. matchedName.append(false);
  6446. }
  6447. virtual bool include(IHqlExpression * field)
  6448. {
  6449. unsigned match = names.find(*field->queryName());
  6450. if (match == NotFound)
  6451. return true;
  6452. matchedName.replace(true, match);
  6453. return false;
  6454. }
  6455. protected:
  6456. HqlGram & gram;
  6457. const attribute & errpos;
  6458. AtomArray names;
  6459. BoolArray matchedName;
  6460. };
  6461. class RecordFieldIntersect : implements IRecordFieldCompare
  6462. {
  6463. public:
  6464. RecordFieldIntersect(IHqlExpression * record, HqlGram & _gram, const attribute & _errpos) : gram(_gram), errpos(_errpos)
  6465. {
  6466. scope = record->querySimpleScope();
  6467. }
  6468. virtual bool include(IHqlExpression * field)
  6469. {
  6470. IIdAtom * id = field->queryId();
  6471. OwnedHqlExpr match = scope->lookupSymbol(id);
  6472. if (match)
  6473. {
  6474. if (field->queryType() != match->queryType())
  6475. gram.reportError(ERR_TYPEMISMATCH_RECORD, errpos, "Field %s has different type in records", str(id));
  6476. return true;
  6477. }
  6478. return false;
  6479. }
  6480. protected:
  6481. HqlGram & gram;
  6482. const attribute & errpos;
  6483. IHqlSimpleScope * scope;
  6484. };
  6485. static bool ifblockFieldsIncluded(IHqlExpression * expr, IRecordFieldCompare & other)
  6486. {
  6487. if (expr->getOperator() == no_select)
  6488. {
  6489. IHqlExpression * ds = expr->queryChild(0);
  6490. while (ds->getOperator() == no_select)
  6491. {
  6492. expr = ds;
  6493. ds = expr->queryChild(0);
  6494. }
  6495. return other.include(expr->queryChild(1));
  6496. }
  6497. ForEachChild(i, expr)
  6498. if (!ifblockFieldsIncluded(expr->queryChild(i), other))
  6499. return false;
  6500. return true;
  6501. }
  6502. static IHqlExpression * createRecordExcept(IHqlExpression * left, IRecordFieldCompare & other)
  6503. {
  6504. HqlExprArray fields;
  6505. ForEachChild(i, left)
  6506. {
  6507. IHqlExpression * cur = left->queryChild(i);
  6508. switch (cur->getOperator())
  6509. {
  6510. case no_field:
  6511. if (other.include(cur))
  6512. fields.append(*LINK(cur));
  6513. break;
  6514. case no_record:
  6515. {
  6516. OwnedHqlExpr newRecord = createRecordExcept(cur, other);
  6517. if (newRecord->numChildren() != 0)
  6518. fields.append(*newRecord.getClear());
  6519. break;
  6520. }
  6521. case no_ifblock:
  6522. {
  6523. IHqlExpression * cond = cur->queryChild(0);
  6524. if (ifblockFieldsIncluded(cond, other))
  6525. {
  6526. IHqlExpression * record = cur->queryChild(1);
  6527. OwnedHqlExpr newRecord = createRecordExcept(record, other);
  6528. if (newRecord->numChildren() != 0)
  6529. {
  6530. if (newRecord == record)
  6531. fields.append(*LINK(cur));
  6532. else
  6533. fields.append(*createValue(no_ifblock, makeNullType(), LINK(cond), newRecord.getClear()));
  6534. }
  6535. }
  6536. break;
  6537. }
  6538. default:
  6539. fields.append(*LINK(cur));
  6540. break;
  6541. }
  6542. }
  6543. return cloneOrLink(left, fields);
  6544. }
  6545. IHqlExpression * HqlGram::createRecordIntersection(IHqlExpression * left, IHqlExpression * right, const attribute & errpos)
  6546. {
  6547. RecordFieldIntersect compare(right, *this, errpos);
  6548. return ::createRecordExcept(left, compare);
  6549. }
  6550. static void unwindExtraFields(HqlExprArray & fields, IHqlExpression * expr)
  6551. {
  6552. ForEachChild(i, expr)
  6553. {
  6554. IHqlExpression * cur = expr->queryChild(i);
  6555. switch (cur->getOperator())
  6556. {
  6557. case no_attr:
  6558. case no_attr_link:
  6559. case no_attr_expr:
  6560. if (!queryAttribute(cur->queryName(), fields))
  6561. fields.append(*LINK(cur));
  6562. break;
  6563. case no_record:
  6564. unwindExtraFields(fields, cur);
  6565. break;
  6566. default:
  6567. fields.append(*LINK(cur));
  6568. }
  6569. }
  6570. }
  6571. IHqlExpression * HqlGram::createRecordUnion(IHqlExpression * left, IHqlExpression * right, const attribute & errpos)
  6572. {
  6573. RecordFieldDifference compare(left, *this, errpos);
  6574. OwnedHqlExpr extra = ::createRecordExcept(right, compare);
  6575. HqlExprArray args;
  6576. unwindChildren(args, left);
  6577. unwindExtraFields(args, extra);
  6578. return cloneOrLink(left, args);
  6579. }
  6580. IHqlExpression * HqlGram::createRecordDifference(IHqlExpression * left, IHqlExpression * right, const attribute & errpos)
  6581. {
  6582. RecordFieldDifference compare(right, *this, errpos);
  6583. return ::createRecordExcept(left, compare);
  6584. }
  6585. IHqlExpression * HqlGram::createRecordExcept(IHqlExpression * left, IHqlExpression * right, const attribute & errpos)
  6586. {
  6587. RecordFieldExcept compare(right, *this, errpos);
  6588. OwnedHqlExpr ret = ::createRecordExcept(left, compare);
  6589. compare.checkAllUsed();
  6590. return ret.getClear();
  6591. }
  6592. IHqlExpression * HqlGram::createIndexFromRecord(IHqlExpression * record, IHqlExpression * attrs, const attribute & errpos)
  6593. {
  6594. IHqlExpression * ds = createDataset(no_null, LINK(record), NULL);
  6595. OwnedHqlExpr newAttrs = LINK(attrs);
  6596. OwnedHqlExpr finalRecord = checkIndexRecord(record, errpos, newAttrs);
  6597. finalRecord.setown(cleanIndexRecord(finalRecord));
  6598. OwnedHqlExpr transform = createClearTransform(finalRecord, errpos);
  6599. return createDataset(no_newkeyindex, ds, createComma(LINK(finalRecord), transform.getClear(), newAttrs.getClear()));
  6600. }
  6601. void HqlGram::inheritRecordMaxLength(IHqlExpression * dataset, SharedHqlExpr & record)
  6602. {
  6603. IHqlExpression * maxLength = queryRecordAttribute(dataset->queryRecord(), maxLengthAtom);
  6604. if (maxLength && !queryRecordAttribute(record, maxLengthAtom))
  6605. {
  6606. HqlExprArray fields;
  6607. unwindChildren(fields, record);
  6608. fields.add(*LINK(maxLength), 0);
  6609. record.setown(record->clone(fields));
  6610. }
  6611. }
  6612. static HqlTransformerInfo groupExpressionCheckerInfo("GroupExpressionChecker");
  6613. class GroupExpressionChecker : public QuickHqlTransformer
  6614. {
  6615. public:
  6616. GroupExpressionChecker(const HqlExprArray & _groups)
  6617. : QuickHqlTransformer(groupExpressionCheckerInfo, NULL)
  6618. {
  6619. ok = true;
  6620. ForEachItemIn(i, _groups)
  6621. groups.append(*_groups.item(i).queryBody());
  6622. }
  6623. virtual void doAnalyseBody(IHqlExpression * expr)
  6624. {
  6625. if (!ok)
  6626. return;
  6627. if (expr->isAggregate() || expr->isConstant())
  6628. return;
  6629. if (groups.contains(*expr))
  6630. return;
  6631. // No dice - check kids
  6632. switch (expr->getOperator())
  6633. {
  6634. case no_select:
  6635. ok = false;
  6636. return;
  6637. }
  6638. QuickHqlTransformer::doAnalyseBody(expr);
  6639. }
  6640. bool isOk() const { return ok; }
  6641. protected:
  6642. HqlExprCopyArray groups;
  6643. bool ok;
  6644. };
  6645. bool checkGroupExpression(HqlExprArray &groups, IHqlExpression *field)
  6646. {
  6647. GroupExpressionChecker checker(groups);
  6648. checker.analyse(field);
  6649. return checker.isOk();
  6650. }
  6651. static HqlTransformerInfo quickSelectNormalizerInfo("QuickSelectNormalizer");
  6652. class HQL_API QuickSelectNormalizer : public QuickHqlTransformer
  6653. {
  6654. public:
  6655. QuickSelectNormalizer() : QuickHqlTransformer(quickSelectNormalizerInfo, NULL)
  6656. {
  6657. }
  6658. virtual IHqlExpression * createTransformed(IHqlExpression * expr)
  6659. {
  6660. switch (expr->getOperator())
  6661. {
  6662. case no_constant:
  6663. case no_colon:
  6664. case no_cluster:
  6665. return LINK(expr);
  6666. case no_globalscope:
  6667. if (!expr->hasAttribute(optAtom))
  6668. return LINK(expr);
  6669. break;
  6670. case NO_AGGREGATE:
  6671. //These aren't strictly correct, but will only go wrong if the same
  6672. //obscure expression is written out twice differently.
  6673. //you really should be projecting or using the same attribute
  6674. return LINK(expr);
  6675. case no_select:
  6676. return LINK(expr->queryNormalizedSelector());
  6677. }
  6678. return QuickHqlTransformer::createTransformed(expr);
  6679. }
  6680. };
  6681. static IHqlExpression * normalizeSelects(IHqlExpression * expr)
  6682. {
  6683. QuickSelectNormalizer transformer;
  6684. return transformer.transform(expr);
  6685. }
  6686. void HqlGram::checkGrouping(const attribute& errpos, HqlExprArray & parms, IHqlExpression* record, IHqlExpression* groups)
  6687. {
  6688. unsigned reckids = record->numChildren();
  6689. for (unsigned i = 0; i < reckids; i++)
  6690. {
  6691. IHqlExpression *field = record->queryChild(i);
  6692. switch(field->getOperator())
  6693. {
  6694. case no_record:
  6695. checkGrouping(errpos, parms, field, groups);
  6696. break;
  6697. case no_ifblock:
  6698. reportError(ERR_GROUP_BADSELECT, errpos, "IFBLOCKs are not supported inside grouped aggregates");
  6699. break;
  6700. case no_field:
  6701. {
  6702. IHqlExpression * rawValue = field->queryChild(0);
  6703. if (rawValue)
  6704. {
  6705. OwnedHqlExpr value = normalizeSelects(rawValue);
  6706. bool ok = checkGroupExpression(parms, value);
  6707. if (!ok)
  6708. {
  6709. IIdAtom * id = NULL;
  6710. switch(field->getOperator())
  6711. {
  6712. case no_select:
  6713. id = field->queryChild(1)->queryId();
  6714. break;
  6715. case no_field:
  6716. id = field->queryId();
  6717. break;
  6718. default:
  6719. id = field->queryId();
  6720. break;
  6721. }
  6722. StringBuffer msg("Field ");
  6723. if (id)
  6724. msg.append("'").append(str(id)).append("' ");
  6725. msg.append("in TABLE does not appear to be properly defined by grouping conditions");
  6726. reportWarning(CategoryUnexpected, ERR_GROUP_BADSELECT,errpos.pos, "%s", msg.str());
  6727. }
  6728. }
  6729. else if (field->isDatarow())
  6730. {
  6731. checkGrouping(errpos, parms, field->queryRecord(), groups);
  6732. }
  6733. else
  6734. throwUnexpected();
  6735. }
  6736. break;
  6737. case no_attr:
  6738. case no_attr_expr:
  6739. case no_attr_link:
  6740. break;
  6741. default:
  6742. assertex(false);
  6743. }
  6744. }
  6745. }
  6746. // MORE: how about child dataset?
  6747. void HqlGram::checkGrouping(const attribute & errpos, IHqlExpression * dataset, IHqlExpression* record, IHqlExpression* groups)
  6748. {
  6749. if (!groups) return;
  6750. assertex(record->getOperator()==no_record);
  6751. //match should be by structure!!
  6752. HqlExprArray parms1;
  6753. HqlExprArray parms;
  6754. groups->unwindList(parms1, no_sortlist);
  6755. //The expressions need normalizing because the selectors need to be normalized before checking for matches.
  6756. //The problem is that before the tree is tagged replaceSelector() doesn't work. So have to use
  6757. //an approximation instead.
  6758. ForEachItemIn(idx, parms1)
  6759. {
  6760. IHqlExpression * cur = &parms1.item(idx);
  6761. if (cur->getOperator() == no_field)
  6762. reportError(ERR_GROUP_BADSELECT, errpos, "cannot use field of result record as a grouping parameter");
  6763. else
  6764. {
  6765. IHqlExpression * mapped = normalizeSelects(cur);
  6766. parms.append(*mapped);
  6767. }
  6768. }
  6769. checkGrouping(errpos, parms, record, groups);
  6770. }
  6771. void HqlGram::checkConditionalAggregates(IIdAtom * name, IHqlExpression * value, const attribute & errpos)
  6772. {
  6773. if (!value->isGroupAggregateFunction())
  6774. return;
  6775. IHqlExpression * cond;
  6776. switch (value->getOperator())
  6777. {
  6778. case no_sumgroup:
  6779. case no_maxgroup:
  6780. case no_mingroup:
  6781. case no_avegroup:
  6782. case no_vargroup:
  6783. cond = queryRealChild(value, 1);
  6784. break;
  6785. case no_existsgroup:
  6786. case no_countgroup:
  6787. cond = queryRealChild(value, 0);
  6788. break;
  6789. case no_covargroup:
  6790. case no_corrgroup:
  6791. cond = queryRealChild(value, 1);
  6792. break;
  6793. default:
  6794. {
  6795. ForEachChild(i, value)
  6796. checkConditionalAggregates(name, value->queryChild(i), errpos);
  6797. return;
  6798. }
  6799. }
  6800. if (cond)
  6801. reportError(ERR_AGG_FIELD_AFTER_VAR, errpos, "Field %s: Conditional aggregates cannot follow a variable length field", name ? str(name) : "");
  6802. }
  6803. void HqlGram::checkProjectedFields(IHqlExpression * e, attribute & errpos)
  6804. {
  6805. if (!isAggregateDataset(e))
  6806. return;
  6807. IHqlExpression * record = e->queryRecord();
  6808. bool hadVariableAggregate = false;
  6809. bool isVariableOffset = false;
  6810. ForEachChild(idx, record)
  6811. {
  6812. IHqlExpression * field = record->queryChild(idx);
  6813. if (field->getOperator() == no_field)
  6814. {
  6815. IHqlExpression * value = field->queryChild(0);
  6816. if (value)
  6817. {
  6818. IIdAtom * id = field->queryId();
  6819. bool isVariableSize = (value->queryType()->getSize() == UNKNOWN_LENGTH);
  6820. if (value->getOperator() == no_implicitcast)
  6821. value = value->queryChild(0);
  6822. if (isVariableSize)
  6823. {
  6824. if (hadVariableAggregate)
  6825. reportError(ERR_AGG_FIELD_AFTER_VAR, errpos, "Field %s: Fields cannot follow a variable length aggregate in the record", id ? str(id) : "");
  6826. if (value->isGroupAggregateFunction())
  6827. hadVariableAggregate = true;
  6828. }
  6829. if (isVariableOffset)
  6830. checkConditionalAggregates(id, value, errpos);
  6831. if (isVariableSize)
  6832. isVariableOffset = true;
  6833. }
  6834. }
  6835. }
  6836. }
  6837. void HqlGram::validateParseTerminate(IHqlExpression * expr, attribute & errpos)
  6838. {
  6839. switch (expr->getOperator())
  6840. {
  6841. case no_list:
  6842. {
  6843. ForEachChild(idx, expr)
  6844. validateParseTerminate(expr->queryChild(idx), errpos);
  6845. break;
  6846. }
  6847. case no_constant:
  6848. {
  6849. ITypeInfo * type = expr->queryType();
  6850. const void * value = expr->queryValue()->queryValue();
  6851. switch (type->getTypeCode())
  6852. {
  6853. case type_data:
  6854. case type_string:
  6855. case type_unicode:
  6856. if (type->getStringLen() != 1)
  6857. reportError(ERR_EXPECTED_CHARLIST, errpos, "Expected a list of single character strings");
  6858. break;
  6859. case type_utf8:
  6860. if (type->getStringLen() != 1)
  6861. reportError(ERR_EXPECTED_CHARLIST, errpos, "Expected a list of single character strings");
  6862. else if (rtlUtf8Size(1, value) != 1)
  6863. reportError(ERR_EXPECTED_CHARLIST, errpos, "Expected a list of single byte character strings");
  6864. break;
  6865. default:
  6866. reportError(ERR_EXPECTED_CHARLIST, errpos, "Expected a list of single character strings");
  6867. break;
  6868. }
  6869. break;
  6870. }
  6871. default:
  6872. reportError(ERR_EXPECTED_CHARLIST, errpos, "Expected a list of single character strings");
  6873. break;
  6874. }
  6875. }
  6876. bool HqlGram::isExplicitlyDistributed(IHqlExpression *e)
  6877. {
  6878. if (e->getOperator()==no_distribute || e->getOperator()==no_keyeddistribute)
  6879. return true;
  6880. return false;
  6881. }
  6882. static bool isFromFile(IHqlExpression * expr)
  6883. {
  6884. loop
  6885. {
  6886. switch (expr->getOperator())
  6887. {
  6888. case no_table:
  6889. return true;
  6890. case no_usertable:
  6891. if (isAggregateDataset(expr))
  6892. return false;
  6893. //fallthrough...
  6894. case no_filter:
  6895. case no_hqlproject:
  6896. expr = expr->queryChild(0);
  6897. break;
  6898. default:
  6899. return false;
  6900. }
  6901. }
  6902. }
  6903. static const char * getName(IHqlExpression * e)
  6904. {
  6905. if (e->queryName())
  6906. return str(e->queryName());
  6907. return "";
  6908. }
  6909. void HqlGram::checkDistribution(attribute &errpos, IHqlExpression *input, bool localSpecified, bool ignoreGrouping)
  6910. {
  6911. bool inputIsGrouped = isGrouped(input);
  6912. if (localSpecified)
  6913. {
  6914. if (inputIsGrouped && !ignoreGrouping)
  6915. reportError(WRN_LOCALIGNORED,errpos,"LOCAL specified on a grouped dataset %s - ungroup first", getName(input));
  6916. }
  6917. else
  6918. {
  6919. if (isExplicitlyDistributed(input))
  6920. {
  6921. if (!inputIsGrouped || ignoreGrouping)
  6922. {
  6923. const char * name = getName(input);
  6924. reportWarning(CategoryEfficiency, WRN_LOCALONEXPLICITDIST,errpos.pos,"Input %s is explicitly DISTRIBUTEd but LOCAL not specified", name);
  6925. }
  6926. }
  6927. }
  6928. }
  6929. void HqlGram::checkDistribution(attribute &errpos, IHqlExpression * newExpr, bool ignoreGrouping)
  6930. {
  6931. checkDistribution(errpos, newExpr->queryChild(0), newExpr->hasAttribute(localAtom), ignoreGrouping);
  6932. }
  6933. bool HqlGram::isDiskFile(IHqlExpression * expr)
  6934. {
  6935. switch (expr->getOperator())
  6936. {
  6937. case no_table:
  6938. return true;
  6939. case no_cluster:
  6940. return !expr->hasAttribute(fewAtom);
  6941. case no_colon:
  6942. {
  6943. ForEachChild(i, expr)
  6944. {
  6945. if (i && isSaved(expr->queryChild(i)))
  6946. return true;
  6947. }
  6948. break;
  6949. }
  6950. case no_keyed:
  6951. return isDiskFile(expr->queryChild(0));
  6952. }
  6953. return false;
  6954. }
  6955. bool HqlGram::isFilteredDiskFile(IHqlExpression * expr)
  6956. {
  6957. loop
  6958. {
  6959. switch (expr->getOperator())
  6960. {
  6961. case no_filter:
  6962. expr = expr->queryChild(0);
  6963. break;
  6964. default:
  6965. return isDiskFile(expr);
  6966. }
  6967. }
  6968. }
  6969. void HqlGram::checkJoinFlags(const attribute &err, IHqlExpression * join)
  6970. {
  6971. bool lonly = join->hasAttribute(leftonlyAtom);
  6972. bool ronly = join->hasAttribute(rightonlyAtom);
  6973. bool fonly = join->hasAttribute(fullonlyAtom);
  6974. bool lo = join->hasAttribute(leftouterAtom) || lonly;
  6975. bool ro = join->hasAttribute(rightouterAtom) || ronly;
  6976. bool fo = join->hasAttribute(fullouterAtom) || fonly;
  6977. bool keep = join->hasAttribute(keepAtom);
  6978. bool isLookup = join->hasAttribute(lookupAtom);
  6979. bool isSmart = join->hasAttribute(smartAtom);
  6980. bool isAll = join->hasAttribute(allAtom);
  6981. bool isStreamed = join->hasAttribute(streamedAtom);
  6982. IHqlExpression * rowLimit = join->queryAttribute(rowLimitAtom);
  6983. IHqlExpression * keyed = join->queryAttribute(keyedAtom);
  6984. if (keyed)
  6985. {
  6986. if (isAll || isLookup || isSmart || isStreamed)
  6987. reportError(ERR_KEYEDINDEXINVALID, err, "LOOKUP/ALL/SMART/STREAMED is not compatible with KEYED");
  6988. }
  6989. else if (isLookup)
  6990. {
  6991. //The following should be, and will become, an error. However too many legacy queries have it, so make a warning for now.
  6992. if (isAll)
  6993. reportWarning(CategorySyntax, ERR_KEYEDINDEXINVALID, err.pos, "ALL is not compatible with LOOKUP");
  6994. if (isSmart)
  6995. reportError(ERR_KEYEDINDEXINVALID, err.pos, "SMART is not compatible with LOOKUP");
  6996. if (isStreamed)
  6997. reportError(ERR_KEYEDINDEXINVALID, err.pos, "STREAMED is not compatible with LOOKUP");
  6998. }
  6999. else if (isSmart)
  7000. {
  7001. if (isAll)
  7002. reportError(ERR_KEYEDINDEXINVALID, err, "ALL is not compatible with KEYED");
  7003. if (isStreamed)
  7004. reportError(ERR_KEYEDINDEXINVALID, err.pos, "STREAMED is not compatible with SMART");
  7005. }
  7006. else if (isAll)
  7007. {
  7008. if (isStreamed)
  7009. reportError(ERR_KEYEDINDEXINVALID, err.pos, "STREAMED is not compatible with ALL");
  7010. }
  7011. if (keyed)
  7012. {
  7013. IHqlExpression * index = keyed->queryChild(0);
  7014. if (index)
  7015. {
  7016. if (isKey(index))
  7017. {
  7018. IHqlExpression * rhs = join->queryChild(1);
  7019. IHqlExpression * indexDataset = index->queryChild(0)->queryNormalizedSelector();
  7020. if (indexDataset != rhs->queryNormalizedSelector())
  7021. reportWarning(CategoryUnusual, ERR_KEYEDNOTMATCHDATASET,err.pos,"Parameter to KEYED is not an index on the RIGHT dataset");
  7022. else if (!isFilteredDiskFile(rhs))
  7023. reportError(ERR_KEYEDNOTMATCHDATASET,err,"RIGHT side of a full keyed join must be a disk file");
  7024. else
  7025. {
  7026. if (indexDataset->getOperator() == no_table)
  7027. {
  7028. switch (indexDataset->queryChild(2)->getOperator())
  7029. {
  7030. case no_csv:
  7031. case no_xml:
  7032. reportError(ERR_KEYEDNOTMATCHDATASET,err,"RIGHT side of a full keyed join must be a THOR disk file (CSV/XML) not currently supported");
  7033. break;
  7034. }
  7035. }
  7036. }
  7037. IHqlExpression * indexRecord = index->queryRecord();
  7038. bool hadMapping = false;
  7039. if (indexRecord)
  7040. {
  7041. unsigned max = indexRecord->numChildren()-numPayloadFields(index);
  7042. for (unsigned i = 0; i < max; i++)
  7043. {
  7044. IHqlExpression * cur = indexRecord->queryChild(i);
  7045. if (!cur->isAttribute() && queryRealChild(cur, 0))
  7046. hadMapping = true;
  7047. }
  7048. }
  7049. if (!hadMapping)
  7050. reportError(ERR_KEYEDINDEXINVALID, err, "Record of KEYED index does not contain references to the dataset");
  7051. }
  7052. }
  7053. }
  7054. if (isLookup || isSmart)
  7055. {
  7056. bool isMany = join->hasAttribute(manyAtom) || isSmart;
  7057. const char * joinText = isSmart ? "Smart" : "Lookup";
  7058. if (ro || fo)
  7059. reportError(ERR_BADKIND_LOOKUPJOIN, err, "%s joins only support INNER, LEFT OUTER, and LEFT ONLY joins", joinText);
  7060. if (join->hasAttribute(partitionRightAtom))
  7061. reportError(ERR_BADKIND_LOOKUPJOIN, err, "%s joins do not support PARTITION RIGHT", joinText);
  7062. if (keep && !isMany)
  7063. reportError(ERR_BADKIND_LOOKUPJOIN, err, "%s joins do not support KEEP", joinText);
  7064. if (join->hasAttribute(atmostAtom) && !isMany)
  7065. reportError(ERR_BADKIND_LOOKUPJOIN, err, "Non-Many %s joins do not support ATMOST", joinText);
  7066. if (rowLimit && !isMany)
  7067. reportError(ERR_BADKIND_LOOKUPJOIN, err, "%s joins do not support LIMIT (they can only match 1 entry)", joinText);
  7068. if (isKey(join->queryChild(1)))
  7069. reportWarning(CategoryEfficiency, ERR_BADKIND_LOOKUPJOIN, err.pos, "%s specified on an unfiltered keyed join - was this intended?", joinText);
  7070. }
  7071. else if (isKeyedJoin(join))
  7072. {
  7073. if (ro || fo)
  7074. reportError(ERR_INVALIDKEYEDJOIN, err, "Keyed joins only support LEFT OUTER/ONLY");
  7075. if (join->hasAttribute(partitionRightAtom))
  7076. reportError(ERR_INVALIDKEYEDJOIN, err, "Keyed joins do not support PARTITION RIGHT");
  7077. }
  7078. if (join->hasAttribute(allAtom))
  7079. {
  7080. if (join->hasAttribute(partitionRightAtom))
  7081. reportError(ERR_INVALIDALLJOIN, err, "JOIN(,ALL) does not support PARTITION RIGHT");
  7082. if (ro || fo)
  7083. reportError(ERR_INVALIDALLJOIN, err, "JOIN(ALL) only supports INNER, LEFT OUTER, and LEFT ONLY joins");
  7084. if (join->hasAttribute(atmostAtom))
  7085. reportError(ERR_INVALIDALLJOIN, err, "JOIN(ALL) does not support ATMOST");
  7086. if (rowLimit)
  7087. reportError(ERR_INVALIDALLJOIN, err, "JOIN(ALL) does not support LIMIT");
  7088. }
  7089. if (join->hasAttribute(atmostAtom))
  7090. {
  7091. if (fo || ro)
  7092. reportError(ERR_BAD_JOINFLAG, err, "ATMOST cannot be used with FULL or RIGHT ONLY/OUTER");
  7093. if (rowLimit)// && getIntValue(rowLimit->queryChild(0), 1) != 0)
  7094. reportError(ERR_BAD_JOINFLAG, err, "LIMIT and ATMOST can't be used in combination");
  7095. }
  7096. if (keep)
  7097. {
  7098. if (lonly || ro || fo)
  7099. reportError(ERR_BAD_JOINFLAG, err, "KEEP can only be used with INNER, LEFT OUTER");
  7100. }
  7101. if (lonly || ronly || fonly)
  7102. {
  7103. if (rowLimit)
  7104. reportError(ERR_BAD_JOINFLAG, err, "LIMIT cannot be used in combination ONLY");
  7105. if (join->hasAttribute(onFailAtom))
  7106. reportError(ERR_BAD_JOINFLAG, err, "ONFAIL cannot be used in combination ONLY");
  7107. }
  7108. IHqlExpression * rhs = join->queryChild(1);
  7109. if (!isKeyedJoin(join) && (rhs->getOperator() == no_filter) && (rhs != join->queryChild(0)))
  7110. {
  7111. IHqlExpression * cur = rhs;
  7112. while (cur->getOperator() == no_filter)
  7113. cur = cur->queryChild(0);
  7114. if (isKey(cur))
  7115. reportWarning(CategoryEfficiency, ERR_BAD_JOINFLAG, err.pos, "Filtered RIGHT prevents a keyed join being used. Consider including the filter in the join condition.");
  7116. }
  7117. IHqlExpression * group = join->queryAttribute(groupAtom);
  7118. if (group)
  7119. {
  7120. //Check that each of the fields mentioned in the group are projected into the output.
  7121. OwnedHqlExpr left = createSelector(no_left, join->queryChild(0), querySelSeq(join));
  7122. OwnedHqlExpr right = createSelector(no_right, join->queryChild(1), querySelSeq(join));
  7123. NewProjectMapper2 mapper;
  7124. mapper.setMapping(join->queryChild(3));
  7125. IHqlExpression * sortlist = group->queryChild(0);
  7126. ForEachChild(i, sortlist)
  7127. {
  7128. IHqlExpression * cur = sortlist->queryChild(i);
  7129. if (cur->usesSelector(right))
  7130. {
  7131. StringBuffer s;
  7132. getExprECL(cur, s);
  7133. reportError(ERR_BAD_JOINGROUP_FIELD, err, "GROUP expression '%s' cannot include fields from RIGHT", s.str());
  7134. }
  7135. else
  7136. {
  7137. bool matchedAll = true;
  7138. OwnedHqlExpr mapped = mapper.collapseFields(cur, left, queryActiveTableSelector(), left, &matchedAll);
  7139. if (!matchedAll)
  7140. {
  7141. StringBuffer s;
  7142. getExprECL(cur, s);
  7143. reportError(ERR_BAD_JOINGROUP_FIELD, err, "GROUP expression '%s' is not included in the JOIN output", s.str());
  7144. }
  7145. }
  7146. }
  7147. }
  7148. }
  7149. void HqlGram::checkLoopFlags(const attribute &err, IHqlExpression * loopExpr)
  7150. {
  7151. if (loopExpr->hasAttribute(parallelAtom))
  7152. {
  7153. unsigned base = (loopExpr->getOperator() == no_loop ? 1 : 2);
  7154. if (!queryRealChild(loopExpr, base))
  7155. reportWarning(CategorySyntax, WRN_BAD_LOOPFLAG, err.pos, "PARALLEL is currently only supported with a defined number of iterations");
  7156. if (queryRealChild(loopExpr, base+2))
  7157. reportWarning(CategorySyntax, WRN_BAD_LOOPFLAG, err.pos, "PARALLEL is not supported with dataset loop termination condition");
  7158. }
  7159. }
  7160. bool HqlGram::checkTransformTypeMatch(const attribute & errpos, IHqlExpression * ds, IHqlExpression * transform)
  7161. {
  7162. if (!recordTypesMatch(ds, transform))
  7163. {
  7164. reportError(ERR_TRANSFORM_TYPE_MISMATCH,errpos,"Type returned from transform must match the source dataset type");
  7165. return false;
  7166. }
  7167. return true;
  7168. }
  7169. void HqlGram::ensureTransformTypeMatch(attribute & tattr, IHqlExpression * ds)
  7170. {
  7171. if (!checkTransformTypeMatch(tattr, ds, tattr.queryExpr()))
  7172. {
  7173. tattr.release();
  7174. tattr.setExpr(createClearTransform(ds->queryRecord(), tattr));
  7175. }
  7176. }
  7177. void HqlGram::ensureDatasetTypeMatch(attribute & tattr, IHqlExpression * ds)
  7178. {
  7179. if (!recordTypesMatch(ds, tattr.queryExpr()))
  7180. {
  7181. reportError(ERR_TRANSFORM_TYPE_MISMATCH,tattr,"Output dataset must match the source dataset type");
  7182. tattr.release();
  7183. tattr.setExpr(createDataset(no_null, LINK(ds->queryRecord())));
  7184. }
  7185. }
  7186. void HqlGram::ensureDataset(attribute & attr)
  7187. {
  7188. if (attr.queryExpr()->isDatarow())
  7189. {
  7190. IHqlExpression * ds = createDatasetFromRow(attr.getExpr());
  7191. attr.setExpr(ds);
  7192. }
  7193. checkDataset(attr);
  7194. }
  7195. void HqlGram::expandPayload(HqlExprArray & fields, IHqlExpression * payload, IHqlSimpleScope * scope, ITypeInfo * & lastFieldType, const attribute & errpos)
  7196. {
  7197. ForEachChild(i2, payload)
  7198. {
  7199. IHqlExpression * cur = payload->queryChild(i2);
  7200. switch (cur->getOperator())
  7201. {
  7202. case no_record:
  7203. expandPayload(fields, cur, scope, lastFieldType, errpos);
  7204. break;
  7205. case no_ifblock:
  7206. lastFieldType = NULL;
  7207. fields.append(*LINK(cur));
  7208. break;
  7209. case no_field:
  7210. {
  7211. OwnedHqlExpr match = scope->lookupSymbol(cur->queryId());
  7212. if (match)
  7213. {
  7214. //Ignore any fields that are completely duplicated in the payload to allow
  7215. //INDEX(ds, { ds.x, ds.y }, {ds} ) to mean add everything else as payload.
  7216. IHqlExpression * matchValue = match->queryChild(0);
  7217. IHqlExpression * curValue = cur->queryChild(0);
  7218. if (matchValue)
  7219. matchValue = queryStripCasts(matchValue->queryNormalizedSelector());
  7220. if (curValue)
  7221. curValue = queryStripCasts(curValue->queryNormalizedSelector());
  7222. if (matchValue != curValue)
  7223. reportError(ERR_REC_DUPFIELD, errpos, "Field %s is already defined in the key portion", str(cur->queryName()));
  7224. }
  7225. else
  7226. {
  7227. lastFieldType = cur->queryType();
  7228. fields.append(*LINK(cur));
  7229. }
  7230. break;
  7231. }
  7232. }
  7233. }
  7234. }
  7235. void HqlGram::mergeDictionaryPayload(OwnedHqlExpr & record, IHqlExpression * payload, const attribute & errpos)
  7236. {
  7237. checkRecordIsValid(errpos, record.get());
  7238. IHqlSimpleScope * scope = record->querySimpleScope();
  7239. // Move all the attributes to the front of the record
  7240. HqlExprArray fields;
  7241. ForEachChild(i3, record)
  7242. {
  7243. IHqlExpression * cur = record->queryChild(i3);
  7244. if (cur->isAttribute())
  7245. fields.append(*LINK(cur));
  7246. }
  7247. ForEachChild(i1, record)
  7248. {
  7249. IHqlExpression * cur = record->queryChild(i1);
  7250. if (!cur->isAttribute())
  7251. fields.append(*LINK(cur));
  7252. }
  7253. unsigned payloadCount = 0;
  7254. ITypeInfo * lastFieldType = NULL;
  7255. if (payload)
  7256. {
  7257. unsigned oldFields = fields.ordinality();
  7258. expandPayload(fields, payload, scope, lastFieldType, errpos);
  7259. payloadCount = fields.ordinality() - oldFields;
  7260. }
  7261. fields.add(*createAttribute(_payload_Atom, createConstant((__int64) payloadCount)), 0);
  7262. record.setown(createRecord(fields));
  7263. }
  7264. void HqlGram::modifyIndexPayloadRecord(SharedHqlExpr & record, SharedHqlExpr & payload, SharedHqlExpr & extra, const attribute & errpos)
  7265. {
  7266. checkRecordIsValid(errpos, record.get());
  7267. IHqlSimpleScope * scope = record->querySimpleScope();
  7268. // Move all the attributes to the front of the record
  7269. HqlExprArray fields;
  7270. ForEachChild(i3, record)
  7271. {
  7272. IHqlExpression * cur = record->queryChild(i3);
  7273. if (cur->isAttribute())
  7274. fields.append(*LINK(cur));
  7275. }
  7276. ForEachChild(i1, record)
  7277. {
  7278. IHqlExpression * cur = record->queryChild(i1);
  7279. if (!cur->isAttribute())
  7280. fields.append(*LINK(cur));
  7281. }
  7282. unsigned payloadCount = 0;
  7283. ITypeInfo * lastFieldType = NULL;
  7284. if (payload)
  7285. {
  7286. unsigned oldFields = fields.ordinality();
  7287. expandPayload(fields, payload, scope, lastFieldType, errpos);
  7288. payloadCount = fields.ordinality() - oldFields;
  7289. }
  7290. //This needs to be here until filepositions are no longer special cased.
  7291. if ((!lastFieldType || !lastFieldType->isInteger()) && getBoolAttributeInList(extra, filepositionAtom, true))
  7292. {
  7293. if (ADD_IMPLICIT_FILEPOS_FIELD_TO_INDEX)
  7294. {
  7295. IHqlSimpleScope * payloadScope = payload ? payload->querySimpleScope() : NULL;
  7296. IIdAtom * implicitFieldName;
  7297. for (unsigned suffix =1;;suffix++)
  7298. {
  7299. StringBuffer name;
  7300. name.append("__internal_fpos");
  7301. if (suffix > 1)
  7302. name.append(suffix);
  7303. name.append("__");
  7304. implicitFieldName = createIdAtom(name);
  7305. OwnedHqlExpr resolved = scope->lookupSymbol(implicitFieldName);
  7306. if (!resolved && payloadScope)
  7307. resolved.setown(payloadScope->lookupSymbol(implicitFieldName));
  7308. if (!resolved)
  7309. break;
  7310. }
  7311. ITypeInfo * fileposType = makeIntType(8, false);
  7312. fields.append(*createField(implicitFieldName, fileposType, createConstant(I64C(0)), createAttribute(_implicitFpos_Atom)));
  7313. payloadCount++;
  7314. }
  7315. else
  7316. extra.setown(createComma(extra.getClear(), createExprAttribute(filepositionAtom, createConstant(false))));
  7317. }
  7318. extra.setown(createComma(extra.getClear(), createAttribute(_payload_Atom, createConstant((__int64) payloadCount))));
  7319. record.setown(createRecord(fields));
  7320. }
  7321. // Because of some oddities of the grammar, the 'record' and 'attributes' expected by an index statement
  7322. // come through with some of the latter attached to the former.
  7323. // For historical reasons, the payload attribute in particular may be either attached to the record via a no_comma,
  7324. // or be an attribute of the record itself.
  7325. // Either way, for an index statement, we want to pull it out of the record param and into the extra param
  7326. void HqlGram::extractIndexRecordAndExtra(SharedHqlExpr & record, SharedHqlExpr & extra)
  7327. {
  7328. while (record->getOperator() == no_comma)
  7329. {
  7330. extra.setown(createComma(LINK(record->queryChild(1)), extra.getClear()));
  7331. record.set(record->queryChild(0));
  7332. }
  7333. IHqlExpression *payload = record->queryAttribute(_payload_Atom);
  7334. if (payload)
  7335. {
  7336. extra.setown(createComma(extra.getClear(), LINK(payload)));
  7337. record.setown(removeAttribute(record, _payload_Atom));
  7338. }
  7339. }
  7340. void HqlGram::transferOptions(attribute & filenameAttr, attribute & optionsAttr)
  7341. {
  7342. if (filenameAttr.queryExpr()->getOperator() == no_comma)
  7343. {
  7344. OwnedHqlExpr filename = filenameAttr.getExpr();
  7345. do
  7346. {
  7347. optionsAttr.setExpr(createComma(LINK(filename->queryChild(1)), optionsAttr.getExpr()));
  7348. filename.set(filename->queryChild(0));
  7349. } while (filename->getOperator() == no_comma);
  7350. filenameAttr.setExpr(filename.getClear());
  7351. }
  7352. }
  7353. IHqlExpression * HqlGram::extractTransformFromExtra(SharedHqlExpr & extra)
  7354. {
  7355. IHqlExpression * ret = NULL;
  7356. if (extra)
  7357. {
  7358. HqlExprArray args;
  7359. extra->unwindList(args, no_comma);
  7360. if (args.item(0).isTransform())
  7361. {
  7362. ret = &args.item(0);
  7363. args.remove(0, true);
  7364. extra.setown(createComma(args));
  7365. }
  7366. }
  7367. return ret;
  7368. }
  7369. void HqlGram::checkBoolean(attribute &atr)
  7370. {
  7371. if (!atr.queryExpr()->isBoolean())
  7372. {
  7373. reportError(ERR_EXPECTED_BOOLEANEXP, atr, "Expected boolean expression");
  7374. // error recovery
  7375. atr.release().setExpr(createConstant(true));
  7376. }
  7377. }
  7378. void HqlGram::checkBooleanOrNumeric(attribute &atr)
  7379. {
  7380. ITypeInfo * type = atr.queryExprType();
  7381. if (!type || !(type->getTypeCode() == type_boolean || isNumericType(type)))
  7382. {
  7383. reportError(ERR_EXPECTED_BOOLEANEXP, atr,"Expected boolean or integer expression");
  7384. // error recovery
  7385. atr.getExpr()->Release();
  7386. atr.setExpr(createConstant(true));
  7387. }
  7388. }
  7389. void HqlGram::checkDataset(attribute &atr)
  7390. {
  7391. if (!atr.queryExpr()->isDataset())
  7392. {
  7393. reportError(ERR_EXPECTED_DATASET, atr, "Expected dataset expression");
  7394. atr.release().setExpr(createNullDataset());
  7395. }
  7396. }
  7397. void HqlGram::checkDictionary(attribute &atr)
  7398. {
  7399. if (!atr.queryExpr()->isDictionary())
  7400. {
  7401. reportError(ERR_EXPECTED_DATASET, atr, "Expected dictionary expression");
  7402. atr.release().setExpr(createNullDictionary());
  7403. }
  7404. }
  7405. void HqlGram::checkDatarow(attribute &atr)
  7406. {
  7407. if (!atr.queryExpr()->isDatarow())
  7408. {
  7409. reportError(ERR_EXPECTED_ROW, atr, "Expected datarow expression");
  7410. atr.release().setExpr(createRow(no_null, LINK(queryNullRecord())));
  7411. }
  7412. }
  7413. void HqlGram::checkList(attribute &atr)
  7414. {
  7415. if (!atr.queryExpr()->isList())
  7416. {
  7417. reportError(ERR_EXPECTED_LIST, atr, "Expected a list");
  7418. atr.release().setExpr(createValue(no_list, makeSetType(NULL)));
  7419. }
  7420. }
  7421. void HqlGram::checkScalar(attribute &atr)
  7422. {
  7423. if (!atr.queryExprType()->isScalar())
  7424. {
  7425. reportError(ERR_EXPECTED_SCALAR, atr, "Expected a single valued expression");
  7426. atr.release().setExpr(getSizetConstant(0));
  7427. }
  7428. }
  7429. void HqlGram::checkDedup(IHqlExpression *ds, IHqlExpression *flags, attribute &atr)
  7430. {
  7431. }
  7432. void HqlGram::checkDistributer(const ECLlocation & errPos, HqlExprArray & args)
  7433. {
  7434. IHqlExpression * input = &args.item(0);
  7435. IHqlExpression * inputPayload = queryAttribute(_payload_Atom, args);
  7436. ForEachItemIn(idx, args)
  7437. {
  7438. IHqlExpression & cur = args.item(idx);
  7439. if (cur.getOperator() == no_distributer)
  7440. {
  7441. IHqlExpression * index = cur.queryChild(0);
  7442. unsigned numKeyedFields = firstPayloadField(index);
  7443. unsigned inputKeyedFields = firstPayloadField(input->queryRecord(), inputPayload ? (unsigned)getIntValue(inputPayload->queryChild(0)) : 1);
  7444. if (numKeyedFields != inputKeyedFields)
  7445. reportError(ERR_DISTRIBUTED_MISSING, errPos, "Index and DISTRIBUTE(index) have different numbers of keyed fields");
  7446. checkRecordTypesSimilar(args.item(0).queryRecord(), cur.queryChild(0)->queryRecord(), errPos, numKeyedFields);
  7447. }
  7448. }
  7449. }
  7450. bool HqlGram::convertAllToAttribute(attribute &atr)
  7451. {
  7452. if (atr.getOperator() != no_all)
  7453. return false;
  7454. atr.release().setExpr(createAttribute(allAtom));
  7455. return true;
  7456. }
  7457. void HqlGram::checkValidRecordMode(IHqlExpression * dataset, attribute & atr, attribute & modeattr)
  7458. {
  7459. IHqlExpression * mode = dataset->queryChild(2);
  7460. switch (mode->getOperator())
  7461. {
  7462. case no_csv:
  7463. checkValidCsvRecord(atr, dataset->queryRecord());
  7464. break;
  7465. case no_xml:
  7466. if (!isValidXmlRecord(dataset->queryRecord()))
  7467. reportError(ERR_INVALID_XML_RECORD, atr, "XML cannot be used on this record structure");
  7468. break;
  7469. }
  7470. }
  7471. void HqlGram::checkValidCsvRecord(const attribute & errpos, IHqlExpression * record)
  7472. {
  7473. if (record)
  7474. {
  7475. IHqlExpression * badField = queryInvalidCsvRecordField(record);
  7476. if (badField)
  7477. reportError(ERR_INVALID_CSV_RECORD, errpos, "CSV cannot be used on this record structure (field %s)", str(badField->queryName()));
  7478. }
  7479. }
  7480. void HqlGram::checkValidPipeRecord(const attribute & errpos, IHqlExpression * record, IHqlExpression * attrs, IHqlExpression * expr)
  7481. {
  7482. if (queryAttributeInList(csvAtom, attrs) || (expr && expr->hasAttribute(csvAtom)))
  7483. checkValidCsvRecord(errpos, record);
  7484. }
  7485. int HqlGram::checkRecordTypesSimilar(IHqlExpression *left, IHqlExpression *right, const ECLlocation & errPos, unsigned maxFields)
  7486. {
  7487. if (recordTypesMatch(left, right))
  7488. return 0;
  7489. IHqlExpression * lrecord = left->queryRecord();
  7490. IHqlExpression * rrecord = right->queryRecord();
  7491. unsigned lnumChildren = lrecord->numChildren();
  7492. unsigned rnumChildren = rrecord->numChildren();
  7493. if (lnumChildren > maxFields) lnumChildren = maxFields;
  7494. if (rnumChildren > maxFields) rnumChildren = maxFields;
  7495. if(lnumChildren != rnumChildren)
  7496. {
  7497. if (getFieldCount(lrecord) != getFieldCount(rrecord))
  7498. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Datasets must have the same number of fields: %d vs %d", lnumChildren, rnumChildren);
  7499. else
  7500. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Datasets must have the same attributes");
  7501. return -1;
  7502. }
  7503. for (unsigned idx = 0; idx < lnumChildren; idx++)
  7504. {
  7505. IHqlExpression *lfield = lrecord->queryChild(idx);
  7506. IHqlExpression *rfield = rrecord->queryChild(idx);
  7507. if (lfield->isAttribute() || rfield->isAttribute())
  7508. {
  7509. if (lfield != rfield)
  7510. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Record attributes differ: %d vs %d", lnumChildren, rnumChildren);
  7511. }
  7512. assertex(lfield);
  7513. assertex(rfield);
  7514. ITypeInfo * lchildrectype = lfield->queryRecordType();
  7515. ITypeInfo * rchildrectype = rfield->queryRecordType();
  7516. if(lchildrectype == rchildrectype) // both can be NULL.
  7517. {
  7518. // both are not not record types
  7519. ITypeInfo * lType = lfield->queryType();
  7520. ITypeInfo * rType = rfield->queryType();
  7521. if(!isSameBasicType(lType, rType))
  7522. {
  7523. StringBuffer ltype, rtype;
  7524. getFriendlyTypeStr(lfield, ltype);
  7525. getFriendlyTypeStr(rfield, rtype);
  7526. IHqlAlienTypeInfo * lAlien = queryAlienType(lType);
  7527. IHqlAlienTypeInfo * rAlien = queryAlienType(rType);
  7528. if (lAlien && rAlien &&
  7529. queryExpression(lType)->queryFunctionDefinition() == queryExpression(rType)->queryFunctionDefinition())
  7530. {
  7531. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Fields %s and %s use incompatible instances of the same user type %s",str(lfield->queryName()), str(rfield->queryName()), ltype.str());
  7532. }
  7533. else
  7534. {
  7535. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Type mismatch for corresponding fields %s (%s) vs %s (%s)",str(lfield->queryName()), ltype.str(), str(rfield->queryName()), rtype.str());
  7536. }
  7537. }
  7538. }
  7539. else if(lchildrectype == NULL || rchildrectype == NULL)
  7540. {
  7541. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Datasets must have the same types for field %d: one is Record, the other is not", idx+1);
  7542. return -1;
  7543. }
  7544. // recursive call to check sub fields.
  7545. if(lchildrectype && rchildrectype)
  7546. return checkRecordTypesSimilar(lfield, rfield, errPos);
  7547. }
  7548. return 0;
  7549. }
  7550. bool HqlGram::checkRecordCreateTransform(HqlExprArray & assigns, IHqlExpression *leftExpr, IHqlExpression *leftSelect, IHqlExpression *rightExpr, IHqlExpression *rightSelect, const ECLlocation & errPos)
  7551. {
  7552. if (leftExpr->getOperator() != rightExpr->getOperator())
  7553. {
  7554. if (leftExpr->isAttribute() || rightExpr->isAttribute())
  7555. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Datasets must have the same attributes");
  7556. else
  7557. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Datasets must have the same structure");
  7558. return false;
  7559. }
  7560. switch (rightExpr->getOperator())
  7561. {
  7562. case no_ifblock:
  7563. return checkRecordCreateTransform(assigns, leftExpr->queryChild(1), leftSelect, rightExpr->queryChild(1), rightSelect, errPos);
  7564. case no_record:
  7565. {
  7566. unsigned lnumChildren = leftExpr->numChildren();
  7567. unsigned rnumChildren = rightExpr->numChildren();
  7568. if (lnumChildren != rnumChildren)
  7569. {
  7570. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Datasets must have the same number of fields: %d vs %d", lnumChildren, rnumChildren);
  7571. return false;
  7572. }
  7573. for (unsigned i= 0; i < lnumChildren; i++)
  7574. if (!checkRecordCreateTransform(assigns, leftExpr->queryChild(i), leftSelect, rightExpr->queryChild(i), rightSelect, errPos))
  7575. return false;
  7576. return true;
  7577. }
  7578. case no_attr:
  7579. case no_attr_expr:
  7580. case no_attr_link:
  7581. return true;
  7582. case no_field:
  7583. {
  7584. OwnedHqlExpr leftSelected = createSelectExpr(LINK(leftSelect), LINK(leftExpr));
  7585. OwnedHqlExpr rightSelected = createSelectExpr(LINK(rightSelect), LINK(rightExpr));
  7586. if (isSameBasicType(leftExpr->queryType(), rightExpr->queryType()))
  7587. {
  7588. assigns.append(*createAssign(LINK(leftSelected), LINK(rightSelected)));
  7589. return true;
  7590. }
  7591. IAtom * leftName = leftExpr->queryName();
  7592. IAtom * rightName = rightExpr->queryName();
  7593. if (leftName != rightName)
  7594. {
  7595. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Name mismatch for corresponding fields %s vs %s",str(leftName), str(rightName));
  7596. return false;
  7597. }
  7598. IHqlExpression * leftRecord = leftExpr->queryRecord();
  7599. IHqlExpression * rightRecord = rightExpr->queryRecord();
  7600. if (!leftRecord || !rightRecord)
  7601. {
  7602. if (!leftRecord && !rightRecord)
  7603. {
  7604. StringBuffer ltype, rtype;
  7605. getFriendlyTypeStr(leftExpr, ltype);
  7606. getFriendlyTypeStr(rightExpr, rtype);
  7607. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Type mismatch for corresponding fields %s (%s) vs %s (%s)",str(leftName), ltype.str(), str(rightName), rtype.str());
  7608. }
  7609. else
  7610. reportError(ERR_TYPEMISMATCH_DATASET, errPos, "Datasets must have the same types for field %s vs %s: one is Record, the other is not", str(leftName), str(rightName));
  7611. return false;
  7612. }
  7613. if (rightExpr->isDatarow())
  7614. return checkRecordCreateTransform(assigns, leftRecord, leftSelected, rightRecord, rightSelected, errPos);
  7615. assigns.append(*createAssign(LINK(leftSelected), checkEnsureRecordsMatch(leftSelected, rightSelected, errPos, false)));
  7616. return true;
  7617. }
  7618. }
  7619. UNIMPLEMENTED;
  7620. return false;
  7621. }
  7622. IHqlExpression * HqlGram::checkEnsureRecordsMatch(IHqlExpression * left, IHqlExpression * right, const ECLlocation & errPos, bool rightIsRow)
  7623. {
  7624. //Need to add a project to make the field names correct, otherwise problems occur if one the left side is optimized away,
  7625. //because that causes the record type and fields to change.
  7626. if (recordTypesMatch(left, right))
  7627. return LINK(right);
  7628. if (checkRecordTypesSimilar(left, right, errPos) != 0)
  7629. return LINK(left); // error conditional - return something compatible with left
  7630. HqlExprArray assigns;
  7631. OwnedHqlExpr seq = createActiveSelectorSequence(right, NULL);
  7632. OwnedHqlExpr rightSelect = createSelector(no_left, right, seq);
  7633. OwnedHqlExpr leftSelect = getSelf(left);
  7634. if (!checkRecordCreateTransform(assigns, left->queryRecord(), leftSelect, right->queryRecord(), rightSelect, errPos))
  7635. return LINK(right);
  7636. IHqlExpression * transform = createValue(no_transform, makeTransformType(LINK(left->queryRecordType())), assigns);
  7637. HqlExprArray args;
  7638. args.append(*LINK(right));
  7639. args.append(*transform);
  7640. args.append(*LINK(seq));
  7641. //args.append(*createUniqueId());
  7642. if (rightIsRow)
  7643. return createRow(no_projectrow, args);
  7644. else
  7645. return createDataset(no_hqlproject, args);
  7646. }
  7647. void HqlGram::ensureMapToRecordsMatch(OwnedHqlExpr & defaultExpr, HqlExprArray & args, const attribute & errpos, bool isRow)
  7648. {
  7649. //The record of the final result should match the record of the first argument.
  7650. IHqlExpression * expected = (args.ordinality() != 0) ? &args.item(0) : defaultExpr.get();
  7651. bool groupingDiffers = false;
  7652. ForEachItemIn(i, args)
  7653. {
  7654. IHqlExpression & mapTo = args.item(i);
  7655. IHqlExpression * value = mapTo.queryChild(1);
  7656. if (isGrouped(value) != isGrouped(expected))
  7657. groupingDiffers = true;
  7658. OwnedHqlExpr checked = checkEnsureRecordsMatch(expected, value, errpos.pos, isRow);
  7659. if (value != checked)
  7660. {
  7661. args.replace(*replaceChild(&mapTo, 1, checked), i);
  7662. reportWarning(CategoryCast, ERR_TYPE_INCOMPATIBLE, errpos.pos, "Datasets in list have slightly different records");
  7663. }
  7664. }
  7665. if (defaultExpr)
  7666. {
  7667. if (isGrouped(defaultExpr) != isGrouped(expected))
  7668. groupingDiffers = true;
  7669. OwnedHqlExpr checked = checkEnsureRecordsMatch(expected, defaultExpr, errpos.pos, isRow);
  7670. if (defaultExpr != checked)
  7671. {
  7672. defaultExpr.set(checked);
  7673. reportWarning(CategoryCast, ERR_TYPE_INCOMPATIBLE, errpos.pos, "Default value has a slightly different record");
  7674. }
  7675. }
  7676. if (groupingDiffers)
  7677. reportError(ERR_GROUPING_MISMATCH, errpos, "Branches of the condition have different grouping");
  7678. }
  7679. void HqlGram::checkMergeSortOrder(attribute &atr, IHqlExpression *ds1, IHqlExpression *ds2, IHqlExpression * sortorder)
  7680. {
  7681. if (!recordTypesMatch(ds1, ds2))
  7682. reportError(ERR_TYPE_INCOMPATIBLE, atr, "Datasets in list must have identical records");
  7683. return;
  7684. }
  7685. void HqlGram::checkRecordTypesMatch(IHqlExpression *ds1, IHqlExpression *ds2, const attribute &errpos)
  7686. {
  7687. if (!recordTypesMatch(ds1, ds2))
  7688. reportError(ERR_TYPE_INCOMPATIBLE, errpos, "Arguments must have the same record type");
  7689. return;
  7690. }
  7691. IHqlExpression * HqlGram::createScopedSequenceExpr()
  7692. {
  7693. unsigned numScopes = defineScopes.ordinality();
  7694. //Not sure this test is correct for forward scopes...
  7695. if (numScopes == minimumScopeIndex)
  7696. return createSequenceExpr();
  7697. assertex(numScopes >= 2);
  7698. ActiveScopeInfo & targetScope = defineScopes.item(numScopes-2);
  7699. if (!targetScope.isParametered)
  7700. return createSequenceExpr();
  7701. HqlExprArray & parameters = targetScope.activeParameters;
  7702. StringBuffer paramName;
  7703. paramName.append("_implicit_hidden_").append(parameters.ordinality());
  7704. OwnedHqlExpr value = createSequenceExpr();
  7705. HqlExprArray attrs;
  7706. attrs.append(*createAttribute(_hidden_Atom));
  7707. IHqlExpression * param = createParameter(createIdAtom(paramName.str()), parameters.ordinality(), value->getType(), attrs);
  7708. parameters.append(*param);
  7709. targetScope.activeDefaults.append(*LINK(value));
  7710. return LINK(param);
  7711. }
  7712. static bool isZeroSize(IHqlExpression * expr)
  7713. {
  7714. switch (expr->getOperator())
  7715. {
  7716. case no_record:
  7717. {
  7718. ForEachChild(i, expr)
  7719. if (!isZeroSize(expr->queryChild(i)))
  7720. return false;
  7721. return true;
  7722. }
  7723. case no_ifblock:
  7724. {
  7725. OwnedHqlExpr folded = foldExprIfConstant(expr->queryChild(0));
  7726. IValue * value = folded->queryValue();
  7727. if (value && !value->getBoolValue())
  7728. return true;
  7729. //Not really sure what to do...
  7730. return isZeroSize(expr->queryChild(1));
  7731. }
  7732. case no_field:
  7733. {
  7734. ITypeInfo * type = expr->queryType();
  7735. switch (type->getTypeCode())
  7736. {
  7737. case type_record:
  7738. case type_row:
  7739. return isZeroSize(expr->queryRecord());
  7740. case type_alien:
  7741. //more
  7742. return false;
  7743. case type_bitfield:
  7744. return false;
  7745. default:
  7746. return type->getSize() == 0;
  7747. }
  7748. }
  7749. }
  7750. return true;
  7751. }
  7752. void HqlGram::checkRecordIsValid(const attribute &atr, IHqlExpression *record)
  7753. {
  7754. if (isZeroSize(record))
  7755. reportError(ERR_ZEROSIZE_RECORD, atr, "Record must not be zero length");
  7756. }
  7757. void HqlGram::checkMergeInputSorted(attribute &atr, bool isLocal)
  7758. {
  7759. IHqlExpression * expr = atr.queryExpr();
  7760. if (appearsToBeSorted(expr, isLocal, true))
  7761. return;
  7762. if (!isLocal && appearsToBeSorted(expr, true, true))
  7763. {
  7764. reportWarning(CategoryUnexpected, WRN_MERGE_NOT_SORTED, atr.pos, "INPUT to MERGE appears to be sorted locally but not globally");
  7765. return;
  7766. }
  7767. if (isGrouped(expr))
  7768. {
  7769. switch (expr->getOperator())
  7770. {
  7771. case no_sort:
  7772. reportError(WRN_MERGE_NOT_SORTED, atr, "SORT on MERGE input should be applied to an ungrouped dataset");
  7773. return;
  7774. case no_sorted:
  7775. reportError(WRN_MERGE_NOT_SORTED, atr, "SORTED on MERGE input should be applied to an ungrouped dataset");
  7776. return;
  7777. }
  7778. }
  7779. if (isGrouped(expr) && appearsToBeSorted(expr, false, false))
  7780. reportWarning(CategoryUnexpected, WRN_MERGE_NOT_SORTED, atr.pos, "Input to MERGE is only sorted with the group");
  7781. else
  7782. reportWarning(CategoryUnexpected, WRN_MERGE_NOT_SORTED, atr.pos, "Input to MERGE doesn't appear to be sorted");
  7783. }
  7784. void HqlGram::checkGrouped(attribute & atr)
  7785. {
  7786. if (!isGrouped(atr.queryExpr()))
  7787. reportError(ERR_ROLLUP_NOT_GROUPED, atr, "Input to activity must be grouped");
  7788. }
  7789. void HqlGram::checkRegrouping(const ECLlocation & errPos, HqlExprArray & args)
  7790. {
  7791. IHqlExpression * left = &args.item(0);
  7792. ForEachItemIn(i, args)
  7793. {
  7794. args.replace(*checkEnsureRecordsMatch(left, &args.item(i), errPos, false), i);
  7795. IHqlExpression * cur = &args.item(i);
  7796. if (!isGrouped(cur))
  7797. reportError(ERR_ROLLUP_NOT_GROUPED, errPos, "Input %d to REGROUP must be grouped", i);
  7798. }
  7799. }
  7800. void HqlGram::checkRecordsMatch(attribute & atr, HqlExprArray & args)
  7801. {
  7802. IHqlExpression * left = &args.item(0);
  7803. ForEachItemIn(i, args)
  7804. {
  7805. IHqlExpression & cur = args.item(i);
  7806. if (!cur.isAttribute() && !recordTypesMatch(&cur, left))
  7807. reportError(ERR_TYPE_INCOMPATIBLE, atr, "Datasets in list must have identical records");
  7808. }
  7809. }
  7810. void HqlGram::checkNotAlreadyDefined(IIdAtom * name, IHqlScope * scope, const attribute & idattr)
  7811. {
  7812. OwnedHqlExpr expr = scope->lookupSymbol(name, LSFsharedOK|LSFignoreBase, lookupCtx);
  7813. if (expr)
  7814. {
  7815. if (legacyImportSemantics && isImport(expr))
  7816. reportWarning(CategoryConfuse, ERR_ID_REDEFINE, idattr.pos, "Identifier '%s' hides previous import", str(name));
  7817. else
  7818. reportError(ERR_ID_REDEFINE, idattr, "Identifier '%s' is already defined", str(name));
  7819. }
  7820. }
  7821. void HqlGram::checkNotAlreadyDefined(IIdAtom * name, const attribute & idattr)
  7822. {
  7823. ActiveScopeInfo & activeScope = defineScopes.tos();
  7824. if (activeScope.localScope)
  7825. checkNotAlreadyDefined(name, activeScope.localScope, idattr);
  7826. checkNotAlreadyDefined(name, activeScope.privateScope, idattr);
  7827. unsigned numScopes = defineScopes.ordinality();
  7828. if ((numScopes > 1) && defineScopes.item(numScopes-2).queryParameter(name))
  7829. reportError(ERR_ID_REDEFINE, idattr, "Identifier '%s' is already defined as a parameter", str(name));
  7830. }
  7831. IHqlScope * HqlGram::queryPrimaryScope(bool isPrivate)
  7832. {
  7833. ActiveScopeInfo & cur = defineScopes.item(0);
  7834. if (isPrivate)
  7835. return cur.privateScope;
  7836. return cur.localScope;
  7837. }
  7838. IHqlExpression * HqlGram::addSideEffects(IHqlExpression * expr)
  7839. {
  7840. unsigned first = defineScopes.tos().firstSideEffect;
  7841. if (parseResults.ordinality() <= first)
  7842. return LINK(expr);
  7843. #ifdef USE_WHEN_FOR_SIDEEFFECTS
  7844. if (expr->isDataset())
  7845. {
  7846. // ensureActions(parseResults, first, parseResults.ordinality());
  7847. IHqlExpression * actions = createActionList(parseResults, first, parseResults.ordinality());
  7848. parseResults.trunc(first);
  7849. return createDataset(no_executewhen, LINK(expr), actions);
  7850. }
  7851. #endif
  7852. #if 0
  7853. IHqlExpression * actions = createActionList(parseResults, first, parseResults.ordinality());
  7854. parseResults.trunc(first);
  7855. return createCompound(actions, LINK(expr));
  7856. #endif
  7857. //Slightly weird - but side-effects need to be nested so they are associated with the correct attribute/RETURN
  7858. //So scope contains the index of the number of side effects active when it is created, and these are preserved
  7859. IHqlExpression * compound = NULL;
  7860. while (parseResults.ordinality() > first)
  7861. {
  7862. OwnedHqlExpr next = &parseResults.popGet();
  7863. if (!next->isAction())
  7864. {
  7865. //Retain any side-effects that were attached to the item being ignored.
  7866. while (next->getOperator() == no_compound)
  7867. {
  7868. parseResults.append(*LINK(next->queryChild(0)));
  7869. next.set(next->queryChild(1));
  7870. }
  7871. ECLlocation location(next);
  7872. reportWarning(CategoryIgnored, ERR_RESULT_IGNORED, location, "Expression ignored");
  7873. }
  7874. else
  7875. compound = createCompound(next.getClear(), compound);
  7876. }
  7877. return createCompound(compound, LINK(expr));
  7878. }
  7879. void HqlGram::createAppendFiles(attribute & targetAttr, attribute & leftAttr, attribute & rightAttr, IAtom * kind)
  7880. {
  7881. OwnedHqlExpr left = leftAttr.getExpr();
  7882. OwnedHqlExpr right = rightAttr.getExpr();
  7883. if (left->isDatarow())
  7884. left.setown(createDatasetFromRow(LINK(left)));
  7885. right.setown(checkEnsureRecordsMatch(left, right, rightAttr.pos, right->isDatarow()));
  7886. if (right->isDatarow())
  7887. right.setown(createDatasetFromRow(LINK(right)));
  7888. IHqlExpression * attr = kind ? createAttribute(kind) : NULL;
  7889. targetAttr.setExpr(createDataset(no_addfiles, LINK(left), createComma(LINK(right), attr)));
  7890. targetAttr.setPosition(leftAttr);
  7891. }
  7892. void HqlGram::createAppendDictionaries(attribute & targetAttr, attribute & leftAttr, attribute & rightAttr, IAtom * kind)
  7893. {
  7894. OwnedHqlExpr left = leftAttr.getExpr();
  7895. OwnedHqlExpr right = rightAttr.getExpr();
  7896. assertex(left->isDictionary());
  7897. if (!right->isDictionary())
  7898. reportError(WRN_UNSUPPORTED_FEATURE, rightAttr, "Only dictionary may be appended to dictionary");
  7899. right.setown(checkEnsureRecordsMatch(left, right, rightAttr.pos, right->isDatarow()));
  7900. // TODO: support for dict + row, dict + dataset
  7901. // if (right->isDatarow())
  7902. // right.setown(createDatasetFromRow(LINK(right)));
  7903. IHqlExpression * attr = kind ? createAttribute(kind) : NULL;
  7904. targetAttr.setExpr(createDictionary(no_addfiles, LINK(left), createComma(LINK(right), attr)));
  7905. targetAttr.setPosition(leftAttr);
  7906. }
  7907. IHqlExpression * HqlGram::processIfProduction(attribute & condAttr, attribute & trueAttr, attribute * falseAttr)
  7908. {
  7909. OwnedITypeInfo type;
  7910. if (falseAttr)
  7911. type.setown(checkPromoteIfType(trueAttr, *falseAttr)); // convert to (ds,ds)(dr,dr),(list,list),(scalar, scalar)
  7912. OwnedHqlExpr cond = condAttr.getExpr();
  7913. OwnedHqlExpr left = trueAttr.getExpr();
  7914. OwnedHqlExpr right = falseAttr ? falseAttr->getExpr() : NULL;
  7915. if (!right)
  7916. {
  7917. if (left->isDatarow())
  7918. {
  7919. OwnedHqlExpr transform = createClearTransform(queryOriginalRecord(left), trueAttr);
  7920. right.setown(createRow(no_createrow, LINK(transform)));
  7921. }
  7922. else
  7923. right.setown(createNullExpr(left));
  7924. }
  7925. if (left->queryRecord() && falseAttr)
  7926. right.setown(checkEnsureRecordsMatch(left, right, falseAttr->pos, false));
  7927. if (isGrouped(left) != isGrouped(right))
  7928. reportError(ERR_GROUPING_MISMATCH, trueAttr, "Branches of the condition have different grouping");
  7929. if (cond->isConstant())
  7930. {
  7931. OwnedHqlExpr folded = quickFoldExpression(cond);
  7932. if (folded->queryValue())
  7933. return folded->queryValue()->getBoolValue() ? left.getClear() : right.getClear();
  7934. }
  7935. return ::createIf(cond.getClear(), left.getClear(), right.getClear());
  7936. }
  7937. bool HqlGram::isVirtualFunction(DefineIdSt * defineid, const attribute & errpos)
  7938. {
  7939. if (defineid->scope & (EXPORT_FLAG | SHARED_FLAG))
  7940. {
  7941. IHqlScope * scope = defineScopes.tos().localScope;
  7942. if (defineid->scope & VIRTUAL_FLAG)
  7943. {
  7944. if (scope && defineScopes.ordinality() > minimumScopeIndex)
  7945. return true;
  7946. reportError(ERR_BAD_VIRTUAL, errpos, "VIRTUAL can only be used inside a local module definition");
  7947. return false;
  7948. }
  7949. if (scope)
  7950. {
  7951. IHqlExpression * scopeExpr = scope->queryExpression();
  7952. if (scopeExpr->hasAttribute(interfaceAtom) || scopeExpr->hasAttribute(virtualAtom))
  7953. return true;
  7954. }
  7955. }
  7956. if (defineid->scope & VIRTUAL_FLAG)
  7957. reportError(ERR_BAD_VIRTUAL, errpos, "EXPORT or SHARED required on a virtual definition");
  7958. return false;
  7959. }
  7960. //Allow the types to be grouped by different expressions, and sorted by different fields.
  7961. static bool isEquivalentType(ITypeInfo * derivedType, ITypeInfo * baseType)
  7962. {
  7963. loop
  7964. {
  7965. if (isSameUnqualifiedType(derivedType, baseType))
  7966. return true;
  7967. if (derivedType->getTypeCode() != baseType->getTypeCode())
  7968. return false;
  7969. switch (derivedType->getTypeCode())
  7970. {
  7971. case type_table:
  7972. case type_groupedtable:
  7973. case type_row:
  7974. {
  7975. derivedType = derivedType->queryChildType();
  7976. baseType = baseType->queryChildType();
  7977. if (!derivedType || !baseType)
  7978. return false;
  7979. break;
  7980. }
  7981. case type_scope:
  7982. return baseType->assignableFrom(derivedType);
  7983. default:
  7984. return false;
  7985. }
  7986. }
  7987. }
  7988. bool HqlGram::areSymbolsCompatible(IHqlExpression * expr, bool isParametered, HqlExprArray & parameters, IHqlExpression * prevValue)
  7989. {
  7990. bool ok = false;
  7991. if (isParametered)
  7992. {
  7993. if (prevValue->isFunction())
  7994. {
  7995. ITypeInfo * exprReturnType = stripFunctionType(expr->queryType());
  7996. ITypeInfo * prevReturnType = stripFunctionType(prevValue->queryType());
  7997. IHqlExpression * formals = queryFunctionParameters(prevValue);
  7998. if (formals->numChildren() == parameters.ordinality() &&
  7999. isEquivalentType(exprReturnType, prevReturnType))
  8000. {
  8001. ok = true;
  8002. ForEachItemIn(iParam, parameters)
  8003. {
  8004. IHqlExpression * curParam = &parameters.item(iParam);
  8005. IHqlExpression * curBaseParam = formals->queryChild(iParam);
  8006. if ((curParam->queryName() != curBaseParam->queryName()) ||
  8007. !isEquivalentType(curParam->queryType(), curBaseParam->queryType()))
  8008. ok = false;
  8009. }
  8010. }
  8011. }
  8012. }
  8013. else
  8014. {
  8015. if (!prevValue->isFunction())
  8016. ok = isEquivalentType(expr->queryType(), prevValue->queryType());
  8017. }
  8018. return ok;
  8019. }
  8020. void HqlGram::checkDerivedCompatible(IIdAtom * name, IHqlExpression * scope, IHqlExpression * expr, bool isParametered, HqlExprArray & parameters, attribute const & errpos)
  8021. {
  8022. ForEachChild(i, scope)
  8023. {
  8024. IHqlScope * base = scope->queryChild(i)->queryScope();
  8025. if (base)
  8026. {
  8027. OwnedHqlExpr match = base->lookupSymbol(name, LSFsharedOK|LSFignoreBase, lookupCtx);
  8028. if (match)
  8029. {
  8030. if (!canBeVirtual(match))
  8031. reportError(ERR_MISMATCH_PROTO, errpos, "Definition %s, cannot override this kind of definition", str(name));
  8032. else
  8033. {
  8034. if (!areSymbolsCompatible(expr, isParametered, parameters, match))
  8035. reportError(ERR_MISMATCH_PROTO, errpos, "Prototypes for %s in base and derived modules must match", str(name));
  8036. }
  8037. }
  8038. }
  8039. }
  8040. }
  8041. bool HqlGram::checkAllowed(const attribute & errpos, const char *category, const char *description)
  8042. {
  8043. if (lookupCtx.queryParseContext().codegenCtx && !lookupCtx.queryParseContext().codegenCtx->allowAccess(category, inSignedModule))
  8044. {
  8045. if (!inSignedModule && lookupCtx.queryParseContext().codegenCtx->allowAccess(category, true))
  8046. reportWarning(CategorySecurity, WRN_REQUIRES_SIGNED, errpos.pos, "%s is only permitted in a signed module", description);
  8047. else
  8048. reportWarning(CategorySecurity, WRN_DISALLOWED, errpos.pos, "%s is not permitted by your security settings", description);
  8049. return false;
  8050. }
  8051. return true;
  8052. }
  8053. bool HqlGram::okToAddSideEffects(IHqlExpression * expr)
  8054. {
  8055. switch (expr->getOperator())
  8056. {
  8057. case no_transform:
  8058. case no_record:
  8059. case no_macro:
  8060. case no_remotescope:
  8061. case no_mergedscope:
  8062. case no_privatescope:
  8063. case no_type:
  8064. case no_typedef:
  8065. case no_forwardscope:
  8066. case no_enum:
  8067. return false;
  8068. default:
  8069. {
  8070. ITypeInfo * type = expr->queryType();
  8071. if (!type)
  8072. return false;
  8073. type_t etc = type->getTypeCode();
  8074. switch (etc)
  8075. {
  8076. case type_pattern:
  8077. case type_rule:
  8078. case type_token:
  8079. case type_feature:
  8080. case type_event:
  8081. case type_scope: // Tend to get lost!
  8082. return false;
  8083. }
  8084. break;
  8085. }
  8086. }
  8087. return true;
  8088. }
  8089. IHqlExpression * HqlGram::associateSideEffects(IHqlExpression * expr, const ECLlocation & errpos)
  8090. {
  8091. if (sideEffectsPending())
  8092. {
  8093. if (legacyWhenSemantics)
  8094. {
  8095. if (okToAddSideEffects(expr))
  8096. return addSideEffects(expr);
  8097. if (errorHandler && !errorDisabled)
  8098. {
  8099. if (expr->isScope())
  8100. {
  8101. Owned<IError> error = createError(CategorySyntax, SeverityError, ERR_RESULT_IGNORED_SCOPE, "Cannot associate a side effect with a module - action will be lost", str(errpos.sourcePath), errpos.lineno, errpos.column, errpos.position);
  8102. //Unusual processing. Create a warning and save it in the parse context
  8103. //The reason is that this error is reporting "the associated side-effects will be lost" - but
  8104. //the same will apply to the warning, and if it's lost there will be no way to report it later...
  8105. lookupCtx.queryParseContext().orphanedWarnings.append(*error.getClear());
  8106. }
  8107. else
  8108. reportError(ERR_RESULT_IGNORED, errpos, "Cannot associate a side effect with this type of definition - action must precede an expression");
  8109. }
  8110. }
  8111. else
  8112. {
  8113. reportError(ERR_RESULT_IGNORED, errpos, "WHEN must be used to associate an action with a definition");
  8114. }
  8115. clearSideEffects();
  8116. }
  8117. return LINK(expr);
  8118. }
  8119. void HqlGram::doDefineSymbol(DefineIdSt * defineid, IHqlExpression * _expr, IHqlExpression * failure, const attribute & idattr, int assignPos, int semiColonPos, bool isParametered)
  8120. {
  8121. OwnedHqlExpr expr = _expr;
  8122. // env symbol
  8123. IIdAtom * name = defineid->id;
  8124. checkNotAlreadyDefined(name, idattr);
  8125. checkSensibleId(idattr, name);
  8126. ActiveScopeInfo & activeScope = defineScopes.tos();
  8127. if (activeScope.templateAttrContext)
  8128. expr.setown(createTemplateFunctionContext(expr.getClear(), closeScope(activeScope.templateAttrContext.getClear())));
  8129. if (!activeScope.localScope)
  8130. {
  8131. expr.setown(associateSideEffects(expr, idattr.pos));
  8132. //Ignore SHARED and EXPORT flags
  8133. if (defineid->scope & (EXPORT_FLAG | SHARED_FLAG))
  8134. reportWarning(CategorySyntax, WRN_EXPORT_IGNORED, idattr.pos, "EXPORT/SHARED qualifiers are ignored in this context");
  8135. defineid->scope = 0;
  8136. defineSymbolInScope(activeScope.privateScope, defineid, expr.getClear(), failure, idattr, assignPos, semiColonPos, isParametered, activeScope.activeParameters, activeScope.createDefaults());
  8137. }
  8138. else
  8139. {
  8140. // define the symbol
  8141. if (defineid->scope & (EXPORT_FLAG | SHARED_FLAG))
  8142. {
  8143. if (expectedAttribute && (lower(expectedAttribute) != lower(name)) && (activeScope.localScope == parseScope))
  8144. {
  8145. OwnedHqlExpr resolved = parseScope->lookupSymbol(expectedAttribute, LSFsharedOK, lookupCtx);
  8146. if (resolved)
  8147. {
  8148. reportError(ERR_UNEXPECTED_PUBLIC_ID, idattr.pos, "Definition of '%s' has a trailing public definition '%s'", str(expectedAttribute), str(name));
  8149. }
  8150. else
  8151. {
  8152. //Make this warning come out now - otherwise a subsequent error about an undefined symbol makes less sense.
  8153. RestoreValueBlock<bool> block(associateWarnings, false);
  8154. reportWarning(CategorySyntax, ERR_UNEXPECTED_PUBLIC_ID, idattr.pos, "Name of exported symbol '%s' does not match the expected name '%s'", str(name), str(expectedAttribute));
  8155. }
  8156. defineid->scope = 0;
  8157. }
  8158. }
  8159. if (defineid->scope & (EXPORT_FLAG | SHARED_FLAG))
  8160. {
  8161. if (isQuery && !insideNestedScope())
  8162. {
  8163. //If this is a global query, and not inside a nested attribute, then keep any actions on the global list of results
  8164. if (!legacyWhenSemantics)
  8165. {
  8166. //Should we give a warning here?? export/shared would not be legal if this was within the repository
  8167. }
  8168. }
  8169. else
  8170. {
  8171. //Otherwise, actions are associated with the symbol just being exported.
  8172. expr.setown(associateSideEffects(expr, idattr.pos));
  8173. }
  8174. IHqlExpression * scopeExpr = queryExpression(activeScope.localScope);
  8175. if (scopeExpr->getOperator() == no_virtualscope)
  8176. checkDerivedCompatible(name, scopeExpr, expr, isParametered, activeScope.activeParameters, idattr);
  8177. if (expectedAttribute && !insideNestedScope())
  8178. lookupCtx.notePrivateSymbols(activeScope.privateScope);
  8179. //static int i = 0;
  8180. //PrintLog("Kill private scope: %d at %s:%d because of %s", ++i, filename->str(), idattr.lineno, current_id->str());
  8181. activeScope.newPrivateScope();
  8182. defineSymbolInScope(activeScope.localScope, defineid, expr.getClear(), failure, idattr, assignPos, semiColonPos, isParametered, activeScope.activeParameters, activeScope.createDefaults());
  8183. lastpos = semiColonPos+1;
  8184. }
  8185. else
  8186. {
  8187. defineSymbolInScope(activeScope.privateScope, defineid, expr.getClear(), failure, idattr, assignPos, semiColonPos, isParametered, activeScope.activeParameters, activeScope.createDefaults());
  8188. }
  8189. }
  8190. ::Release(failure);
  8191. // clean up
  8192. activeScope.resetParameters();
  8193. current_id = NULL;
  8194. current_type = NULL;
  8195. delete defineid;
  8196. }
  8197. IHqlExpression * HqlGram::attachPendingWarnings(IHqlExpression * ownedExpr)
  8198. {
  8199. //Now attach some warnings...
  8200. ForEachItemInRev(i, pendingWarnings)
  8201. ownedExpr = createWarningAnnotation(ownedExpr, &OLINK(pendingWarnings.item(i)));
  8202. pendingWarnings.kill();
  8203. return ownedExpr;
  8204. }
  8205. void HqlGram::doAttachPendingWarnings(attribute & exprAttr)
  8206. {
  8207. IHqlExpression * expr = exprAttr.getExpr();
  8208. if (expr)
  8209. expr = attachPendingWarnings(expr);
  8210. exprAttr.setExpr(expr);
  8211. }
  8212. IHqlExpression * HqlGram::attachMetaAttributes(IHqlExpression * ownedExpr, HqlExprArray & meta)
  8213. {
  8214. if (meta.ordinality())
  8215. ownedExpr = createMetaAnnotation(ownedExpr, meta);
  8216. return ownedExpr;
  8217. }
  8218. void HqlGram::defineSymbolInScope(IHqlScope * scope, DefineIdSt * defineid, IHqlExpression * expr, IHqlExpression * failure, const attribute & idattr, int assignPos, int semiColonPos, bool isParametered, HqlExprArray & parameters, IHqlExpression * defaults)
  8219. {
  8220. IHqlExpression * scopeExpr = queryExpression(scope);
  8221. IIdAtom * moduleName = NULL;
  8222. if (!inType)
  8223. moduleName = createIdAtom(scope->queryFullName());
  8224. unsigned symbolFlags = 0;
  8225. if (scopeExpr && scopeExpr->getOperator() == no_virtualscope)
  8226. symbolFlags |= ob_member;
  8227. if (defineid->scope & VIRTUAL_FLAG)
  8228. {
  8229. symbolFlags |= ob_virtual;
  8230. ITypeInfo * type = expr->queryType();
  8231. if (type && type->isScalar() && type->getSize() == 0)
  8232. {
  8233. StringBuffer typeText;
  8234. type->getECLType(typeText);
  8235. reportError(ERR_ZERO_SIZE_VIRTUAL, idattr, "A VIRTUAL with zero length type %s makes no sense", typeText.str());
  8236. }
  8237. }
  8238. HqlExprCopyArray activeParameters;
  8239. gatherActiveParameters(activeParameters);
  8240. HqlExprArray meta;
  8241. expr = attachWorkflowOwn(meta, expr, failure, &activeParameters);
  8242. if (isParametered)
  8243. {
  8244. IHqlExpression * formals = createValue(no_sortlist, makeSortListType(NULL), parameters);
  8245. expr = createFunctionDefinition(defineid->id, expr, formals, defaults, NULL);
  8246. }
  8247. expr = attachPendingWarnings(expr);
  8248. expr = attachMetaAttributes(expr, meta);
  8249. IPropertyTree * doc = defineid->queryDoc();
  8250. if (doc)
  8251. expr = createJavadocAnnotation(expr, LINK(doc));
  8252. scope->defineSymbol(defineid->id, moduleName, expr, (defineid->scope & EXPORT_FLAG) != 0, (defineid->scope & SHARED_FLAG) != 0, symbolFlags, lexObject->query_FileContents(), idattr.pos.lineno, idattr.pos.column, idattr.pos.position, assignPos+2, semiColonPos+1);
  8253. }
  8254. void HqlGram::defineSymbolProduction(attribute & nameattr, attribute & paramattr, attribute & assignattr, attribute * valueattr, attribute * failattr, attribute & semiattr)
  8255. {
  8256. OwnedHqlExpr expr;
  8257. IHqlExpression * failure = NULL;
  8258. DefineIdSt* defineid = nameattr.getDefineId();
  8259. IIdAtom * name = defineid->id;
  8260. Owned<ITypeInfo> type = defineid->getType();
  8261. assertex(name);
  8262. ActiveScopeInfo & activeScope = defineScopes.tos();
  8263. if (valueattr && failattr)
  8264. {
  8265. if (isExceptionalCase(nameattr,*valueattr,*failattr))
  8266. {
  8267. activeScope.resetParameters();
  8268. delete defineid;
  8269. return;
  8270. }
  8271. failure = failattr->getExpr();
  8272. if (failure && (valueattr->queryExpr()->getOperator() == no_typedef))
  8273. reportError(ERR_WORKFLOW_ILLEGAL, *valueattr, "Workflow actions are illegal on a typedef");
  8274. checkWorkflowScheduling(failure, *failattr);
  8275. checkFormals(defineid->id,activeScope.activeParameters,activeScope.activeDefaults,*valueattr);
  8276. expr.setown(valueattr->getExpr());
  8277. }
  8278. else
  8279. {
  8280. expr.setown(createPureVirtual(type));
  8281. defineid->scope |= VIRTUAL_FLAG;
  8282. if (!(defineid->scope & (EXPORT_FLAG|SHARED_FLAG)))
  8283. reportError(ERR_SHOULD_BE_EXPORTED, nameattr, "Pure definitions should be exported or shared");
  8284. }
  8285. ITypeInfo *etype = expr->queryType();
  8286. if (isSaved(failure) && !type)
  8287. {
  8288. size32_t exprTypeSize = etype->getSize();
  8289. if (queryOperatorInList(no_stored, failure) && (exprTypeSize != UNKNOWN_LENGTH))
  8290. {
  8291. if (isStringType(etype) || isUnicodeType(etype))
  8292. type.setown(getStretchedType(UNKNOWN_LENGTH, etype));
  8293. }
  8294. if ((etype->getTypeCode() == type_set) && etype->queryChildType() == NULL)
  8295. reportError(ERR_ZEROLENSTORED, nameattr, "Type must be specified for this stored list");
  8296. }
  8297. // type specific handling
  8298. IHqlExpression * base = queryNonDelayedBaseAttribute(expr);
  8299. node_operator op = base->getOperator();
  8300. switch(op)
  8301. {
  8302. case no_service: // service
  8303. if (type)
  8304. {
  8305. reportError(ERR_SVC_NOYPENEEDED, nameattr, "Service can not have a type");
  8306. type.clear();
  8307. }
  8308. if (activeScope.isParametered)
  8309. {
  8310. reportError(ERR_SVC_NOPARAMALLOWED, nameattr, "Service can not have any parameters");
  8311. activeScope.resetParameters();
  8312. }
  8313. break;
  8314. case no_macro:
  8315. if (!activeScope.isParametered)
  8316. {
  8317. //reportError(ERR_MACRO_NOPARAMDEFINED, "Macro needs formal parameters; use () if no parameter needed", nameattr);
  8318. activeScope.isParametered = true;
  8319. }
  8320. break;
  8321. case no_externalcall:
  8322. // I'm not convinced this works at all - code appears to
  8323. // translate a external dataset returning a function into a dataset with a functional mode.
  8324. if (etype && etype->getTypeCode()==type_record)
  8325. {
  8326. IHqlExpression *recordDef = queryExpression(etype);
  8327. expr.setown(createDatasetF(no_table, createConstant(str(name)), LINK(recordDef), LINK(expr), NULL));
  8328. }
  8329. break;
  8330. case no_virtualscope:
  8331. {
  8332. IHqlExpression * libraryInterface = queryAttributeChild(base, libraryAtom, 0);
  8333. if (libraryInterface)
  8334. {
  8335. //check the parameters for this symbol match the parameters on the library attribute
  8336. checkLibraryParametersMatch(nameattr, activeScope.isParametered, activeScope.activeParameters, libraryInterface);
  8337. }
  8338. break;
  8339. }
  8340. }
  8341. if (type && expr->isTransform())
  8342. {
  8343. ITypeInfo * recordType = queryRecordType(type);
  8344. assertex(recordType);
  8345. type.setown(makeTransformType(LINK(recordType)));
  8346. }
  8347. IHqlScope * localScope = activeScope.localScope;
  8348. IHqlExpression * localScopeExpr = queryExpression(localScope);
  8349. if (localScope && localScopeExpr->getOperator() == no_virtualscope)
  8350. {
  8351. OwnedHqlExpr anyMatch = localScope->lookupSymbol(name, LSFsharedOK, lookupCtx);
  8352. OwnedHqlExpr localMatch = localScope->lookupSymbol(name, LSFsharedOK|LSFignoreBase, lookupCtx);
  8353. if (localScopeExpr->hasAttribute(virtualAtom) || localScopeExpr->hasAttribute(interfaceAtom))
  8354. {
  8355. if (canBeVirtual(expr))
  8356. defineid->scope |= VIRTUAL_FLAG;
  8357. }
  8358. if (!(defineid->scope & (EXPORT_FLAG|SHARED_FLAG)))
  8359. {
  8360. if (anyMatch && !localMatch)
  8361. {
  8362. //only report error in base class clash, others will be reported later.
  8363. if (!localMatch)
  8364. reportError(ERR_SHOULD_BE_EXPORTED, nameattr, "Private symbol %s clashes with public symbol in base module", str(name));
  8365. }
  8366. if (localScopeExpr->hasAttribute(interfaceAtom))
  8367. {
  8368. // defineid->scope |= EXPORT_FLAG;
  8369. reportError(ERR_SHOULD_BE_EXPORTED, nameattr, "Symbol %s in INTERFACE should be EXPORTed or SHARED", str(name));
  8370. }
  8371. }
  8372. else
  8373. {
  8374. if (anyMatch && !localScopeExpr->hasAttribute(_virtualSeq_Atom))
  8375. {
  8376. //Not quite right - it is a problem if the place it is defined in isn't virtual
  8377. reportError(ERR_CANNOT_REDEFINE, nameattr, "Cannot redefine definition %s from a non-virtual MODULE", str(name));
  8378. }
  8379. else if (anyMatch && !localMatch)
  8380. {
  8381. if (isVirtualSymbol(anyMatch))
  8382. defineid->scope |= VIRTUAL_FLAG;
  8383. ITypeInfo * matchType = stripFunctionType(anyMatch->queryType());
  8384. //check the parameters and return type (if specified) are compatible, promote expression return type to same
  8385. if (type)
  8386. {
  8387. if (!isSameFullyUnqualifiedType(type, matchType))
  8388. {
  8389. //allow dataset with no record to match, as long as base type is the same
  8390. if (queryRecord(type) != queryNullRecord() || (type->getTypeCode() != matchType->getTypeCode()))
  8391. {
  8392. reportError(ERR_SAME_TYPE_REQUIRED, nameattr, "Explicit type for %s doesn't match definition in base module", str(name));
  8393. }
  8394. else
  8395. {
  8396. type.set(matchType);
  8397. }
  8398. }
  8399. }
  8400. else
  8401. {
  8402. if (matchType->getTypeCode() == type_scope)
  8403. {
  8404. if (!matchType->assignableFrom(etype))
  8405. {
  8406. canNotAssignTypeError(type, etype, paramattr);
  8407. expr.setown(createNullExpr(matchType));
  8408. }
  8409. }
  8410. else
  8411. type.set(matchType);
  8412. }
  8413. }
  8414. }
  8415. }
  8416. // type cast if necessary
  8417. if (type && etype)
  8418. {
  8419. if (type != etype)
  8420. {
  8421. if (!type->assignableFrom(etype))
  8422. {
  8423. if (queryRecord(type) != queryNullRecord())
  8424. {
  8425. canNotAssignTypeError(type,etype,paramattr);
  8426. switch (type->getTypeCode())
  8427. {
  8428. case type_record:
  8429. expr.set(queryNullRecord());
  8430. break;
  8431. default:
  8432. expr.setown(createNullExpr(type));
  8433. break;
  8434. }
  8435. }
  8436. }
  8437. else
  8438. {
  8439. switch (etype->getTypeCode())
  8440. {
  8441. case type_table:
  8442. case type_groupedtable:
  8443. case type_record:
  8444. case type_row:
  8445. case type_transform:
  8446. case type_dictionary:
  8447. break;
  8448. default:
  8449. expr.setown(forceEnsureExprType(expr, type));
  8450. break;
  8451. }
  8452. }
  8453. }
  8454. }
  8455. // env symbol
  8456. doDefineSymbol(defineid, expr.getClear(), failure, nameattr, assignattr.pos.position, semiattr.pos.position, activeScope.isParametered);
  8457. }
  8458. void HqlGram::definePatternSymbolProduction(attribute & nameattr, const attribute & assignAttr, attribute & valueAttr, attribute & workflowAttr, const attribute & semiattr)
  8459. {
  8460. DefineIdSt* defineid = nameattr.getDefineId();
  8461. checkPatternFailure(workflowAttr);
  8462. IHqlExpression * failure = workflowAttr.getExpr();
  8463. checkFormals(defineid->id,defineScopes.tos().activeParameters,defineScopes.tos().activeDefaults,valueAttr);
  8464. IIdAtom * name = defineid->id;
  8465. Owned<ITypeInfo> idType = defineid->getType();
  8466. IHqlExpression *expr = valueAttr.getExpr();
  8467. ITypeInfo *etype = expr->queryType();
  8468. if (idType->getTypeCode() != etype->getTypeCode())
  8469. {
  8470. //If a token is being defined from a pattern add an implicit token creator.
  8471. if ((idType->getTypeCode() == type_token) &&
  8472. (etype->getTypeCode() == type_pattern))
  8473. expr = createValue(no_pat_imptoken, makeTokenType(), expr);
  8474. }
  8475. if ((idType->getTypeCode() == type_rule) && (etype->getTypeCode() == type_rule))
  8476. {
  8477. ITypeInfo * iRecord = idType->queryChildType();
  8478. ITypeInfo * eRecord = etype->queryChildType();
  8479. if (iRecord != eRecord)
  8480. {
  8481. if (!iRecord || !eRecord || !recordTypesMatch(iRecord, eRecord))
  8482. reportError(ERR_PATTERN_TYPE_MATCH, nameattr, "Declared rule type must match type of productions");
  8483. }
  8484. }
  8485. IHqlExpression *features = getFeatureParams();
  8486. if (features)
  8487. expr = createValue(no_pat_featureparam, expr->getType(), expr, features);
  8488. assertex(name);
  8489. {
  8490. IIdAtom * moduleId = globalScope->queryId();
  8491. HqlExprArray args;
  8492. args.append(*expr);
  8493. args.append(*createId(name));
  8494. if (moduleId)
  8495. args.append(*createId(moduleId));
  8496. if (queryParametered())
  8497. args.append(*createAttribute(_function_Atom));
  8498. expr = createValue(no_pat_instance, expr->getType(), args);
  8499. }
  8500. doDefineSymbol(defineid, expr, failure, nameattr, assignAttr.pos.position, semiattr.pos.position, queryParametered());
  8501. }
  8502. //-- SAS style conditional assignments
  8503. void HqlGram::expandScopeEntries(HqlExprArrayArray & branches, IHqlExpression * scope)
  8504. {
  8505. HqlExprArrayItem & next = *new HqlExprArrayItem;
  8506. if (scope)
  8507. {
  8508. scope->queryScope()->getSymbols(next.array);
  8509. next.array.sort(compareSymbolsByName);
  8510. }
  8511. branches.append(next);
  8512. }
  8513. bool HqlGram::checkCompatibleSymbol(const attribute & errpos, IHqlExpression * prevValue, IHqlExpression * newValue)
  8514. {
  8515. // if (!areSymbolsCompatible(IHqlExpression * expr, bool isParametered, HqlExprArray & parameters, IHqlExpression * prevValue)
  8516. return true;
  8517. }
  8518. IHqlExpression * HqlGram::extractBranchMatch(const attribute & errpos, IHqlExpression & curSym, HqlExprArray & values)
  8519. {
  8520. IIdAtom * id = curSym.queryId();
  8521. IAtom * name = lower(id);
  8522. ForEachItemIn(i, values)
  8523. {
  8524. IHqlExpression & cur = values.item(i);
  8525. if (cur.queryName() == name)
  8526. {
  8527. if (!checkCompatibleSymbol(errpos, &curSym, &cur))
  8528. return NULL;
  8529. OwnedHqlExpr ret = LINK(&cur);
  8530. //check the types of the attributes/functions match. May need to remap parameters of functions.
  8531. values.remove(i);
  8532. return ret.getClear();
  8533. }
  8534. }
  8535. //No Match found, check if is was previously defined in the current scope (?what about nesting?)
  8536. OwnedHqlExpr match = lookupSymbol(id, errpos);
  8537. if (!match)
  8538. {
  8539. //MORE If this was used as a temporary variable just within this branch, then that's ok.
  8540. // The following test is no good though, we need to check if reused only in this branch.
  8541. // if (curSym.isShared())
  8542. // return NULL;
  8543. reportWarning(CategoryMistake, WRN_COND_ASSIGN_NO_PREV, errpos.pos, "Conditional assignment to %s isn't defined in all branches, and has no previous definition", str(id));
  8544. return NULL;
  8545. }
  8546. if (!checkCompatibleSymbol(errpos, &curSym, match))
  8547. return NULL;
  8548. return LINK(match);
  8549. }
  8550. ITypeInfo * HqlGram::extractBranchMatches(const attribute & errpos, IHqlExpression & curSym, HqlExprArrayArray & branches, HqlExprArray & extracted)
  8551. {
  8552. //This is a n^2 algorithm, but I really don't expect very large numbers of conditional assignments. Hopefully that will remain true.
  8553. ForEachItemIn(i, branches)
  8554. {
  8555. HqlExprArrayItem & curArray = branches.item(i);
  8556. IHqlExpression * match = extractBranchMatch(errpos, curSym, curArray.array);
  8557. if (!match)
  8558. return NULL;
  8559. extracted.append(*match);
  8560. }
  8561. return promoteToSameType(extracted, errpos, NULL, true);
  8562. }
  8563. void HqlGram::processIfScope(const attribute & errpos, IHqlExpression * cond, IHqlExpression * trueScope, IHqlExpression * falseScope)
  8564. {
  8565. HqlExprArrayArray branches;
  8566. expandScopeEntries(branches, trueScope);
  8567. HqlExprArray falseBranches;
  8568. if (falseScope)
  8569. falseScope->unwindList(falseBranches, no_comma);
  8570. OwnedHqlExpr elseScope;
  8571. if (falseBranches.ordinality())
  8572. {
  8573. if (falseBranches.tos().getOperator() != no_mapto)
  8574. elseScope.setown(&falseBranches.popGet());
  8575. }
  8576. ForEachItemIn(iFalse, falseBranches)
  8577. expandScopeEntries(branches, falseBranches.item(iFalse).queryChild(1));
  8578. expandScopeEntries(branches, elseScope);
  8579. ActiveScopeInfo & activeScope = defineScopes.tos();
  8580. IHqlScope * defineScope = activeScope.privateScope;
  8581. ForEachItemIn(i, branches)
  8582. {
  8583. HqlExprArrayItem & curArray = branches.item(i);
  8584. ForEachItemInRev(j, curArray.array)
  8585. {
  8586. HqlExprArray matches;
  8587. IHqlExpression & curSym = curArray.array.item(j);
  8588. IIdAtom * id = curSym.queryId();
  8589. OwnedITypeInfo condType = extractBranchMatches(errpos, curSym, branches, matches);
  8590. if (condType)
  8591. {
  8592. OwnedHqlExpr value;
  8593. unsigned numMatches = matches.ordinality();
  8594. if (numMatches > 2)
  8595. {
  8596. //Multi way elseif -> create a map expression
  8597. HqlExprArray args;
  8598. for (unsigned i=0; i < numMatches-1; i++)
  8599. {
  8600. IHqlExpression * test = (i == 0) ? cond : falseBranches.item(i-1).queryChild(0);
  8601. args.append(*createValue(no_mapto, LINK(condType), LINK(test), LINK(matches.item(i).queryBody())));
  8602. }
  8603. args.append(*LINK(matches.item(numMatches-1).queryBody()));
  8604. value.setown(createTypedValue(no_map, condType, args));
  8605. }
  8606. else
  8607. {
  8608. HqlExprArray args;
  8609. args.append(*LINK(cond));
  8610. args.append(*LINK(matches.item(0).queryBody()));
  8611. args.append(*LINK(matches.item(1).queryBody()));
  8612. value.setown(createTypedValue(no_if, condType, args));
  8613. }
  8614. OwnedHqlExpr newSym = createSymbolFromValue(&curSym, value);
  8615. if (activeScope.localScope)
  8616. {
  8617. OwnedHqlExpr match = activeScope.localScope->lookupSymbol(id, LSFsharedOK|LSFignoreBase, lookupCtx);
  8618. if (match)
  8619. reportError(ERR_ID_REDEFINE, errpos, "Identifier '%s' is already defined as a public symbol in this context", str(id));
  8620. }
  8621. defineScope->defineSymbol(newSym.getClear());
  8622. }
  8623. }
  8624. }
  8625. }
  8626. // virtual scope processing code
  8627. void HqlGram::cloneInheritedAttributes(IHqlScope * scope, const attribute & errpos)
  8628. {
  8629. IHqlExpression * scopeExpr = queryExpression(scope);
  8630. AtomArray inherited;
  8631. IHqlExpression * virtualSeqAttr = scopeExpr->queryAttribute(_virtualSeq_Atom);
  8632. ForEachChild(i, scopeExpr)
  8633. {
  8634. IHqlExpression * cur = scopeExpr->queryChild(i);
  8635. IHqlScope * curBase = cur->queryScope();
  8636. if (curBase)
  8637. {
  8638. IHqlExpression * baseVirtualAttr = cur->queryAttribute(_virtualSeq_Atom);
  8639. bool baseIsLibrary = cur->getOperator() == no_libraryscopeinstance;
  8640. //Find all the symbols exported by this base module
  8641. HqlExprArray syms;
  8642. curBase->getSymbols(syms);
  8643. syms.sort(compareSymbolsByName);
  8644. ForEachItemIn(iSym, syms)
  8645. {
  8646. IIdAtom * id = syms.item(iSym).queryId();
  8647. IAtom * name = lower(id);
  8648. OwnedHqlExpr baseSym = curBase->lookupSymbol(id, LSFsharedOK|LSFfromderived, lookupCtx);
  8649. OwnedHqlExpr match = scope->lookupSymbol(id, LSFsharedOK|LSFignoreBase, lookupCtx);
  8650. LinkedHqlExpr mapped = baseSym;
  8651. //Replace any references to the base module attribute with this new module.
  8652. if (baseVirtualAttr)
  8653. mapped.setown(quickFullReplaceExpression(mapped, baseVirtualAttr, virtualSeqAttr));
  8654. if (match)
  8655. {
  8656. if (inherited.contains(*name) && (match->getOperator() != no_purevirtual))
  8657. {
  8658. //Inheriting the definition from more than one base module => check they are compatible.
  8659. //Ignore differences in the named symbol. Should think about setting start/end to 0. What would it break?
  8660. if (mapped->queryBody() != match->queryBody())
  8661. {
  8662. //MORE: Could allow it to be ambiguous (by creating a no_purevirtual), but better to require immediate resolution
  8663. reportError(ERR_AMBIGUOUS_DEF, errpos, "Definition %s must be specified, it has different definitions in base modules", str(id));
  8664. }
  8665. }
  8666. }
  8667. else
  8668. {
  8669. //If this base class is unbound then we need a different kind of delayed reference..
  8670. if (!curBase->allBasesFullyBound())
  8671. {
  8672. assertex(virtualSeqAttr || baseIsLibrary);
  8673. if (virtualSeqAttr)
  8674. {
  8675. mapped.setown(createDelayedReference(no_unboundselect, virtualSeqAttr, mapped, LSFsharedOK|LSFfromderived, lookupCtx));
  8676. }
  8677. }
  8678. scope->defineSymbol(mapped.getClear());
  8679. inherited.append(*name);
  8680. }
  8681. }
  8682. }
  8683. }
  8684. if (virtualSeqAttr)
  8685. scopeExpr->addOperand(errpos.pos.createLocationAttr());
  8686. }
  8687. void HqlGram::checkExportedModule(const attribute & errpos, IHqlExpression * scopeExpr)
  8688. {
  8689. checkNonGlobalModule(errpos, scopeExpr);
  8690. IHqlExpression * interfaceExpr = scopeExpr;
  8691. HqlExprArray symbols;
  8692. interfaceExpr->queryScope()->getSymbols(symbols);
  8693. IHqlScope * scope = scopeExpr->queryScope();
  8694. ForEachItemIn(i, symbols)
  8695. {
  8696. IHqlExpression & cur = symbols.item(i);
  8697. if (isExported(&cur))
  8698. {
  8699. IIdAtom * id = cur.queryId();
  8700. OwnedHqlExpr value = scope->lookupSymbol(id, LSFpublic, lookupCtx);
  8701. if (value)
  8702. {
  8703. if (value->isFunction())
  8704. reportError(ERR_BAD_LIBRARY_SYMBOL, errpos, "Library modules cannot export functional definition %s", str(id));
  8705. else if (value->isDataset() || value->isDatarow() || value->queryType()->isScalar())
  8706. {
  8707. }
  8708. else if (value->isList())
  8709. reportError(ERR_BAD_LIBRARY_SYMBOL, errpos, "Library modules cannot export list definition %s (use a dataset instead)", str(id));
  8710. else
  8711. {
  8712. //Should we report an error, or should we just ignore it? Probably doesn't cause any problems as long as caught
  8713. //on invalid use.
  8714. //reportError(ERR_BAD_LIBRARY_SYMBOL, errpos, "Library modules cannot export functional definition %s", str(name));
  8715. }
  8716. }
  8717. }
  8718. }
  8719. }
  8720. void HqlGram::checkLibraryParametersMatch(const attribute & errpos, bool isParametered, const HqlExprArray & activeParameters, IHqlExpression * definition)
  8721. {
  8722. if (definition->getOperator() == no_funcdef)
  8723. {
  8724. if (isParametered)
  8725. {
  8726. IHqlExpression * formals = definition->queryChild(1);
  8727. if (formals->numChildren() == activeParameters.ordinality())
  8728. {
  8729. ForEachItemIn(i, activeParameters)
  8730. {
  8731. IHqlExpression & cur = activeParameters.item(i);
  8732. IHqlExpression * expected = formals->queryChild(i);
  8733. if ((cur.queryName() != expected->queryName()) || (cur.queryType() != expected->queryType()))
  8734. reportError(ERR_PROTOTYPE_MISMATCH, errpos, "Parameter %s does not match the appropriate parameter as the LIBRARY interface it implements", str(cur.queryName()));
  8735. }
  8736. }
  8737. else
  8738. reportError(ERR_PROTOTYPE_MISMATCH, errpos, "Symbol does not have the same number of parameters as the LIBRARY interface it implements");
  8739. }
  8740. // Not quite sure if the following is actually valid - example of aliasing the library, but mluber76.xhql uses it.
  8741. // else
  8742. // reportError(ERR_PROTOTYPE_MISMATCH, errpos, "Symbol is not functional, whilst LIBRARY(interface) is");
  8743. }
  8744. else
  8745. {
  8746. if (isParametered)
  8747. {
  8748. //Could report this as an error, but I think I'd prefer it to be accepted.
  8749. //reportError(ERR_PROTOTYPE_MISMATCH, errpos, "Symbol is functional, whilst LIBRARY(interface) is not");
  8750. }
  8751. }
  8752. }
  8753. void HqlGram::checkNonGlobalModule(const attribute & errpos, IHqlExpression * scopeExpr)
  8754. {
  8755. if ((scopeExpr->getOperator() == no_remotescope) || (scopeExpr->getOperator() == no_mergedscope))
  8756. reportError(ERR_NO_GLOBAL_MODULE, errpos, "Global module cannot be used in this context");
  8757. }
  8758. IHqlExpression * HqlGram::createLibraryInstance(const attribute & errpos, IHqlExpression * name, IHqlExpression * func, HqlExprArray & actuals)
  8759. {
  8760. if (!checkParameters(func, actuals, errpos))
  8761. return createNullScope();
  8762. //Create a library scope, but parameterised with the real serialized parameters, rather than the logical ecl parameters
  8763. HqlExprArray oldSymbols, newSymbols, args;
  8764. IHqlExpression * body = func->queryChild(0);
  8765. //MORE: Check that none of the parameters to body are dependent on the parameters
  8766. ForEachChild(iBody, body)
  8767. {
  8768. IHqlExpression * child = body->queryChild(iBody);
  8769. if (!child->isAttribute() && !child->isFullyBound())
  8770. {
  8771. reportError(ERR_PROTOTYPE_MISMATCH, errpos, "LIBRARY interface definition cannot be dependent on the parameters");
  8772. return createNullScope();
  8773. }
  8774. }
  8775. if (body->hasAttribute(libraryAtom))
  8776. reportWarning(CategorySyntax, WRN_NOT_INTERFACE, errpos.pos, "LIBRARY() seems to reference an implementation rather than the interface definition");
  8777. IHqlExpression * internalAttr = queryAttributeInList(internalAtom,name);
  8778. if (internalAttr)
  8779. {
  8780. IHqlExpression * internalFunc = internalAttr->queryChild(0);
  8781. IHqlExpression * internalModule = internalFunc->queryChild(0);
  8782. IHqlExpression * libraryAttr = internalModule->queryAttribute(libraryAtom);
  8783. if (!libraryAttr || func != libraryAttr->queryChild(0))
  8784. reportError(ERR_PROTOTYPE_MISMATCH, errpos, "Module referenced in INTERNAL() doesn't implement the required library interface");
  8785. }
  8786. bool needToMapOutputs = false;
  8787. body->queryScope()->getSymbols(oldSymbols);
  8788. ForEachItemIn(i, oldSymbols)
  8789. {
  8790. IHqlExpression & cur = oldSymbols.item(i);
  8791. if (isExported(&cur) && !cur.isFunction())
  8792. {
  8793. OwnedHqlExpr newValue;
  8794. if (cur.isDataset() || cur.isDatarow())
  8795. {
  8796. newValue.setown(createPureVirtual(cur.queryType()));
  8797. }
  8798. else
  8799. {
  8800. //non dataset returns are nasty! Need to be converted to selects from datasets...
  8801. OwnedHqlExpr field = createField(unknownId, cur.getType(), NULL, NULL);
  8802. OwnedHqlExpr newRecord = createRecord(field);
  8803. OwnedHqlExpr ds = createDataset(no_null, LINK(newRecord));
  8804. newValue.setown(createPureVirtual(ds->queryType()));
  8805. needToMapOutputs = true;
  8806. }
  8807. OwnedHqlExpr newSymbol = cur.cloneAllAnnotations(newValue);
  8808. assertex(isVirtualSymbol(newSymbol));
  8809. newSymbols.append(*newSymbol.getClear());
  8810. }
  8811. }
  8812. unwindChildren(args, body);
  8813. name->unwindList(args, no_comma);
  8814. args.append(*createExprAttribute(implementsAtom, LINK(func)));
  8815. IHqlScope * libraryScope = createLibraryScope();
  8816. OwnedHqlExpr newBody = populateScopeAndClose(libraryScope, args, newSymbols);
  8817. LibraryInputMapper inputMapper(func);
  8818. OwnedHqlExpr newParameters = createValueSafe(no_sortlist, makeSortListType(NULL), inputMapper.queryRealParameters());
  8819. OwnedHqlExpr newFunction = createFunctionDefinition(func->queryId(), newBody.getClear(), newParameters.getClear(), NULL, NULL);
  8820. HqlExprArray realActuals;
  8821. inputMapper.mapLogicalToReal(realActuals, actuals);
  8822. OwnedHqlExpr bound = bindParameters(errpos, newFunction, realActuals);
  8823. if (!needToMapOutputs)
  8824. return bound.getClear();
  8825. //Really nasty... if any of the outputs are scalar, then we need to create a wrapping module which maps
  8826. //the scalar values to selects from the datasets we've created in the underlying library module
  8827. //mapModule := module(body^)
  8828. // x := library(a,b,c,d).x
  8829. // s := library(a,b,c,d).s[1].f
  8830. IHqlScope * boundScope = bound->queryScope();
  8831. HqlExprArray mappingArgs, mappingSymbols;
  8832. ForEachItemIn(iMap, oldSymbols)
  8833. {
  8834. IHqlExpression & cur = oldSymbols.item(iMap);
  8835. if (isExported(&cur) && !cur.isFunction())
  8836. {
  8837. OwnedHqlExpr boundSymbol = boundScope->lookupSymbol(cur.queryId(),LSFpublic,lookupCtx);
  8838. assertex(boundSymbol);
  8839. LinkedHqlExpr newValue = boundSymbol->queryBody();
  8840. if (!cur.isDataset() && !cur.isDatarow())
  8841. {
  8842. //This was a scalar, so need to select the value from it.
  8843. assertex(newValue->isDataset());
  8844. IHqlExpression * field = newValue->queryRecord()->queryChild(0);
  8845. OwnedHqlExpr select = createRow(no_selectnth, newValue.getClear(), createConstantOne());
  8846. newValue.setown(createSelectExpr(select.getClear(), LINK(field))); // no newAtom because not normalised yet
  8847. }
  8848. mappingSymbols.append(*cur.cloneAllAnnotations(newValue));
  8849. }
  8850. }
  8851. ForEachChild(i2, body)
  8852. {
  8853. IHqlExpression * cur = body->queryChild(i2);
  8854. //Base ourselves on any base classes that the body contains
  8855. if (cur->isScope())
  8856. mappingArgs.append(*LINK(cur));
  8857. }
  8858. IHqlScope * mappingScope = createVirtualScope();
  8859. return populateScopeAndClose(mappingScope, mappingArgs, mappingSymbols);
  8860. }
  8861. //==========================================================================================================
  8862. IHqlExpression * HqlGram::createEvaluateOutputModule(const attribute & errpos, IHqlExpression * scopeExpr, IHqlExpression * ifaceExpr, node_operator outputOp, IIdAtom *matchId)
  8863. {
  8864. if (!ifaceExpr->queryType()->assignableFrom(scopeExpr->queryType()))
  8865. reportError(ERR_NOT_BASE_MODULE, errpos, "Module doesn't implement the interface supplied");
  8866. return ::createEvaluateOutputModule(lookupCtx, scopeExpr, ifaceExpr, lookupCtx.queryExpandCallsWhenBound(), outputOp, matchId);
  8867. }
  8868. IHqlExpression * HqlGram::createStoredModule(const attribute & errpos, IHqlExpression * scopeExpr)
  8869. {
  8870. if (!scopeExpr->queryAttribute(_virtualSeq_Atom))
  8871. reportError(ERR_NOT_INTERFACE, errpos, "Argument must be an interface or virtual module");
  8872. return ::createStoredModule(scopeExpr);
  8873. }
  8874. //==========================================================================================================
  8875. static IHqlExpression * createSingleValueTransform(IHqlExpression * record, IHqlExpression * value)
  8876. {
  8877. IHqlExpression * field = record->queryChild(0);
  8878. OwnedHqlExpr self = getSelf(record);
  8879. OwnedHqlExpr lhs = createSelectExpr(LINK(self), LINK(field));
  8880. OwnedHqlExpr assign = createAssign(lhs.getClear(), LINK(value));
  8881. return createValue(no_transform, makeTransformType(record->getType()), assign.getClear());
  8882. }
  8883. IHqlExpression * HqlGram::createIffDataset(IHqlExpression * record, IHqlExpression * value)
  8884. {
  8885. IHqlExpression * field = record->queryChild(0);
  8886. if (value->getOperator() == no_select)
  8887. {
  8888. IHqlExpression * lhs = value->queryChild(0);
  8889. IHqlExpression * rhs = value->queryChild(1);
  8890. if ((lhs->getOperator() == no_selectnth) && matchesConstantValue(lhs->queryChild(1), 1))
  8891. {
  8892. IHqlExpression * ds = lhs->queryChild(0);
  8893. if (rhs == field)
  8894. return LINK(ds);
  8895. OwnedHqlExpr seq = createActiveSelectorSequence(ds, NULL);
  8896. OwnedHqlExpr left = createSelector(no_left, ds, seq);
  8897. OwnedHqlExpr selectedValue = createSelectExpr(LINK(left), LINK(rhs));
  8898. OwnedHqlExpr transform = createSingleValueTransform(record, selectedValue);
  8899. return createDatasetF(no_hqlproject, LINK(ds), LINK(transform), LINK(seq), NULL);
  8900. }
  8901. }
  8902. OwnedHqlExpr transform = createSingleValueTransform(record, value);
  8903. return createDataset(no_inlinetable, createValue(no_transformlist, makeNullType(), transform.getClear()), LINK(record));
  8904. }
  8905. IHqlExpression * HqlGram::createIff(attribute & condAttr, attribute & leftAttr, attribute & rightAttr)
  8906. {
  8907. ITypeInfo * type = checkPromoteIfType(leftAttr, rightAttr);
  8908. OwnedHqlExpr left = leftAttr.getExpr();
  8909. OwnedHqlExpr right = rightAttr.getExpr();
  8910. OwnedHqlExpr field = createField(valueId, type, NULL, NULL);
  8911. OwnedHqlExpr record = createRecord(field);
  8912. OwnedHqlExpr lhs = createIffDataset(record, left);
  8913. OwnedHqlExpr rhs = createIffDataset(record, right);
  8914. OwnedHqlExpr ifDs = createDatasetF(no_if, condAttr.getExpr(), lhs.getClear(), rhs.getClear(), NULL);
  8915. OwnedHqlExpr row1 = createRow(no_selectnth, ifDs.getClear(), getSizetConstant(1));
  8916. return createSelectExpr(LINK(row1), LINK(field));
  8917. }
  8918. IHqlExpression * HqlGram::createListIndex(attribute & list, attribute & which, IHqlExpression * attr)
  8919. {
  8920. OwnedHqlExpr expr = list.getExpr();
  8921. ITypeInfo * childType = expr->queryType()->queryChildType();
  8922. if (expr->getOperator() == no_all)
  8923. {
  8924. reportError(ERR_LIST_INDEXINGALL, which, "Indexing ALL is undefined");
  8925. if (!childType)
  8926. childType = defaultIntegralType;
  8927. }
  8928. else if (!childType)
  8929. {
  8930. reportError(ERR_ELEMENT_NO_TYPE, list, "List element has unknown type");
  8931. childType = defaultIntegralType;
  8932. }
  8933. if (which.queryExpr()->getOperator() == no_comma)
  8934. reportError(ERR_NO_MULTI_ARRAY, list, "Multi dimension array index is not supported");
  8935. if (childType && isDatasetType(childType))
  8936. return createDataset(no_rowsetindex, expr.getClear(), createComma(which.getExpr(), attr));
  8937. else
  8938. return createList(no_index, LINK(childType), createComma(expr.getClear(), which.getExpr(), attr));
  8939. }
  8940. void HqlGram::checkCompatibleTransforms(HqlExprArray & values, IHqlExpression * record, attribute & errpos)
  8941. {
  8942. ForEachItemIn(i, values)
  8943. {
  8944. IHqlExpression * curRecord = values.item(i).queryRecord();
  8945. if (!recordTypesMatch(curRecord, record))
  8946. {
  8947. reportError(ERR_TYPE_INCOMPATIBLE, errpos, "All TRANSFORMS must return the same record type");
  8948. break;
  8949. }
  8950. }
  8951. }
  8952. void HqlGram::canNotAssignTypeError(ITypeInfo* expected, ITypeInfo* given, const attribute& errpos)
  8953. {
  8954. StringBuffer msg("Incompatible types: can not assign ");
  8955. getFriendlyTypeStr(given, msg).append(" to ");
  8956. getFriendlyTypeStr(expected, msg);
  8957. reportError(ERR_TYPE_INCOMPATIBLE, errpos, "%s", msg.str());
  8958. }
  8959. void HqlGram::canNotAssignTypeWarn(ITypeInfo* expected, ITypeInfo* given, const attribute& errpos)
  8960. {
  8961. StringBuffer msg("Incompatible types: should cast ");
  8962. getFriendlyTypeStr(given, msg).append(" to a ");
  8963. getFriendlyTypeStr(expected, msg);
  8964. reportWarning(CategoryCast, ERR_TYPE_INCOMPATIBLE, errpos.pos, "%s", msg.str());
  8965. }
  8966. IIdAtom * HqlGram::getNameFromExpr(attribute& attr)
  8967. {
  8968. OwnedHqlExpr expr = attr.getExpr();
  8969. loop
  8970. {
  8971. IHqlExpression * name = queryNamedSymbol(expr);
  8972. if (name)
  8973. return name->queryId();
  8974. switch (expr->getOperator())
  8975. {
  8976. case no_select:
  8977. expr.set(expr->queryChild(1));
  8978. break;
  8979. case no_indirect:
  8980. expr.set(expr->queryChild(0));
  8981. break;
  8982. default:
  8983. {
  8984. IIdAtom * id = expr->queryId();
  8985. if (id && (lower(id) != lower(unnamedId)))
  8986. return id;
  8987. reportError(ERR_EXPECTED_IDENTIFIER, attr, "Expected an identifier");
  8988. return unknownId;
  8989. }
  8990. }
  8991. }
  8992. }
  8993. IIdAtom * HqlGram::createFieldNameFromExpr(IHqlExpression * expr)
  8994. {
  8995. // while (expr->getOperator() == no_indirect)
  8996. // expr = expr->queryChild(0);
  8997. IIdAtom * name = expr->queryId();
  8998. if (!name)
  8999. {
  9000. switch (expr->getOperator())
  9001. {
  9002. case no_select:
  9003. return createFieldNameFromExpr(expr->queryChild(1));
  9004. case no_indirect:
  9005. case no_cast:
  9006. case no_implicitcast:
  9007. return createFieldNameFromExpr(expr->queryChild(0));
  9008. case no_countgroup:
  9009. name = createUnnamedFieldId("_unnamed_cnt_");
  9010. break;
  9011. case no_existsgroup:
  9012. name = createUnnamedFieldId("_unnamed_exists_");
  9013. break;
  9014. case no_vargroup:
  9015. case no_avegroup:
  9016. case no_maxgroup:
  9017. case no_mingroup:
  9018. case no_sumgroup:
  9019. {
  9020. StringBuffer temp;
  9021. temp.append("_unnamed_").append(getOpString(expr->getOperator())).append("_");
  9022. temp.toLowerCase();
  9023. temp.append(lower(createFieldNameFromExpr(expr->queryChild(0))));
  9024. name = createUnnamedFieldId(temp.str());
  9025. }
  9026. break;
  9027. case no_covargroup:
  9028. case no_corrgroup:
  9029. {
  9030. StringBuffer temp;
  9031. temp.append("_unnamed_").append(getOpString(expr->getOperator())).append("_");
  9032. temp.toLowerCase();
  9033. temp.append(lower(createFieldNameFromExpr(expr->queryChild(0))));
  9034. temp.append("_");
  9035. temp.append(lower(createFieldNameFromExpr(expr->queryChild(1))));
  9036. name = createUnnamedFieldId(temp.str());
  9037. }
  9038. break;
  9039. }
  9040. }
  9041. return name;
  9042. }
  9043. inline bool isDollarModule(IHqlExpression * expr)
  9044. {
  9045. return expr->isAttribute() && (expr->queryName() == selfAtom);
  9046. }
  9047. inline bool isRootModule(IHqlExpression * expr)
  9048. {
  9049. return expr->isAttribute() && (expr->queryName() == _root_Atom);
  9050. }
  9051. IHqlExpression * HqlGram::resolveImportModule(const attribute & errpos, IHqlExpression * expr)
  9052. {
  9053. if (isDollarModule(expr))
  9054. return LINK(queryExpression(globalScope));
  9055. if (isRootModule(expr))
  9056. return LINK(queryExpression(lookupCtx.queryRepository()->queryRootScope()));
  9057. IAtom * name = expr->queryName();
  9058. if ((name != _dot_Atom) && (name != _container_Atom))
  9059. {
  9060. if (!lookupCtx.queryRepository())
  9061. {
  9062. //This never happens in practice since a null repository is generally passed.
  9063. reportError(ERR_MODULE_UNKNOWN, "Import not supported with no repository specified",
  9064. lexObject->getActualLineNo(),
  9065. lexObject->getActualColumn(),
  9066. lexObject->get_yyPosition());
  9067. return NULL;
  9068. }
  9069. IIdAtom * id = expr->queryId();
  9070. OwnedHqlExpr importMatch = lookupCtx.queryRepository()->queryRootScope()->lookupSymbol(id, LSFimport, lookupCtx);
  9071. if (!importMatch)
  9072. importMatch.setown(parseScope->lookupSymbol(id, LSFsharedOK, lookupCtx));
  9073. if (!importMatch || !importMatch->queryScope())
  9074. {
  9075. if (lookupCtx.queryParseContext().ignoreUnknownImport)
  9076. return NULL;
  9077. StringBuffer msg;
  9078. if (!importMatch)
  9079. msg.appendf("Import names unknown module \"%s\"", str(id));
  9080. else
  9081. msg.appendf("Import item \"%s\" is not a module", str(id));
  9082. reportError(ERR_MODULE_UNKNOWN, msg.str(),
  9083. lexObject->getActualLineNo(),
  9084. lexObject->getActualColumn(),
  9085. lexObject->get_yyPosition());
  9086. return NULL;
  9087. }
  9088. return importMatch.getClear();
  9089. }
  9090. OwnedHqlExpr parent = resolveImportModule(errpos, expr->queryChild(0));
  9091. if (!parent)
  9092. return NULL;
  9093. const char * parentName = str(parent->queryId());
  9094. if (name == _container_Atom)
  9095. {
  9096. const char * containerName = str(parent->queryFullContainerId());
  9097. //This is a bit ugly - remove the last qualified module, and resolve the name again. A more "correct" method
  9098. //saving container pointers hit problems because remote scopes within CHqlMergedScope containers have a remote
  9099. //scope as the parent, rather than the merged scope...
  9100. if (containerName)
  9101. {
  9102. OwnedHqlExpr matched = getResolveAttributeFullPath(containerName, LSFpublic, lookupCtx);
  9103. if (matched)
  9104. return matched.getClear();
  9105. }
  9106. else
  9107. {
  9108. //A null parent must be because it is within the global scope, or is the global scope
  9109. if (parentName)
  9110. return LINK(lookupCtx.queryRepository()->queryRootScope()->queryExpression());
  9111. }
  9112. if (parentName)
  9113. reportError(ERR_CANNOT_ACCESS_CONTAINER, errpos, "Cannot access container for Object '%s'", parentName);
  9114. else
  9115. reportError(ERR_CANNOT_ACCESS_CONTAINER, errpos, "Cannot access container for the root module");
  9116. return NULL;
  9117. }
  9118. IIdAtom * childId = expr->queryChild(1)->queryId();
  9119. OwnedHqlExpr resolved = parent->queryScope()->lookupSymbol(childId, LSFpublic, lookupCtx);
  9120. if (!resolved)
  9121. {
  9122. if (!parentName)
  9123. parentName = "$";
  9124. reportError(ERR_OBJ_NOSUCHFIELD, errpos, "Object '%s' does not have a field named '%s'", parentName, str(childId));
  9125. return NULL;
  9126. }
  9127. IHqlScope * ret = resolved->queryScope();
  9128. if (!ret)
  9129. {
  9130. reportError(ERR_OBJ_NOSUCHFIELD, errpos, "'%s' is not a module", str(childId));
  9131. return NULL;
  9132. }
  9133. return resolved.getClear();
  9134. }
  9135. void HqlGram::processImportAll(attribute & modulesAttr)
  9136. {
  9137. HqlExprArray modules;
  9138. modulesAttr.unwindCommaList(modules);
  9139. ForEachItemIn(i, modules)
  9140. {
  9141. OwnedHqlExpr module = resolveImportModule(modulesAttr, &modules.item(i));
  9142. if (module)
  9143. {
  9144. IHqlScope * moduleScope = module->queryScope();
  9145. if (!defaultScopes.contains(*moduleScope))
  9146. defaultScopes.append(*LINK(moduleScope));
  9147. if (!isDollarModule(&modules.item(i)))
  9148. defineImport(modulesAttr, module, module->queryId());
  9149. }
  9150. }
  9151. }
  9152. void HqlGram::processImport(attribute & modulesAttr, IIdAtom * aliasName)
  9153. {
  9154. HqlExprArray modules;
  9155. modulesAttr.unwindCommaList(modules);
  9156. if (aliasName && (modules.ordinality() > 1))
  9157. {
  9158. reportError(ERR_BAD_IMPORT, modulesAttr, "Expected a single module with an alias");
  9159. return;
  9160. }
  9161. ForEachItemIn(i, modules)
  9162. {
  9163. IHqlExpression & cur = modules.item(i);
  9164. //IMPORT $; is a no-op. Don't add the real name of the $ module into scope
  9165. if (!aliasName)
  9166. {
  9167. if (isDollarModule(&cur))
  9168. continue;
  9169. if (isRootModule(&cur))
  9170. {
  9171. reportError(ERR_BAD_IMPORT, modulesAttr, "An alias name must be provided when importing ^");
  9172. return;
  9173. }
  9174. }
  9175. OwnedHqlExpr module = resolveImportModule(modulesAttr, &cur);
  9176. if (module)
  9177. {
  9178. IIdAtom * newName = aliasName ? aliasName : module->queryId();
  9179. defineImport(modulesAttr, module, newName);
  9180. IHqlScope * moduleScope = module->queryScope();
  9181. if (moduleScope->isImplicit())
  9182. defaultScopes.append(*LINK(moduleScope));
  9183. }
  9184. }
  9185. }
  9186. void HqlGram::processImport(attribute & membersAttr, attribute & modulesAttr, IIdAtom * aliasName)
  9187. {
  9188. HqlExprArray modules;
  9189. HqlExprArray members;
  9190. modulesAttr.unwindCommaList(modules);
  9191. membersAttr.unwindCommaList(members);
  9192. ForEachItemIn(i1, members)
  9193. {
  9194. if (members.item(i1).queryName() == _dot_Atom)
  9195. {
  9196. reportError(ERR_BAD_IMPORT, membersAttr, "Only top level members can be imported");
  9197. return;
  9198. }
  9199. }
  9200. if (modules.ordinality() > 1)
  9201. {
  9202. reportError(ERR_BAD_IMPORT, modulesAttr, "Expected a single module reference");
  9203. return;
  9204. }
  9205. if (aliasName && (members.ordinality() > 1))
  9206. {
  9207. reportError(ERR_BAD_IMPORT, modulesAttr, "Expected a single definition with an alias");
  9208. return;
  9209. }
  9210. OwnedHqlExpr module = resolveImportModule(modulesAttr, &modules.item(0));
  9211. if (!module)
  9212. return;
  9213. IHqlScope * moduleScope = module->queryScope();
  9214. ForEachItemIn(i, members)
  9215. {
  9216. IIdAtom * id = members.item(i).queryId();
  9217. Owned<IHqlExpression> resolved = moduleScope->lookupSymbol(id, LSFpublic, lookupCtx);
  9218. if (resolved)
  9219. {
  9220. IIdAtom * newName = aliasName ? aliasName : id;
  9221. defineImport(membersAttr, resolved, newName);
  9222. }
  9223. else
  9224. reportError(ERR_OBJ_NOSUCHFIELD, modulesAttr, "Module '%s' does not contain a definition named '%s'", str(module->queryName()), str(id));
  9225. }
  9226. }
  9227. void HqlGram::defineImport(const attribute & errpos, IHqlExpression * imported, IIdAtom * newName)
  9228. {
  9229. if (!imported || !newName)
  9230. return;
  9231. Owned<IHqlExpression> previous = parseScope->lookupSymbol(newName,LSFsharedOK,lookupCtx);
  9232. if (previous)
  9233. {
  9234. if (previous->queryBody() == imported->queryBody())
  9235. return;
  9236. reportWarning(CategoryConfuse, ERR_ID_REDEFINE, errpos.pos, "import hides previously defined identifier");
  9237. }
  9238. parseScope->defineSymbol(newName, NULL, LINK(imported), false, false, ob_import, NULL, errpos.pos.lineno, errpos.pos.column, errpos.pos.position, 0, errpos.pos.position);
  9239. }
  9240. IHqlExpression * HqlGram::expandedSortListByReference(attribute * module, attribute & list)
  9241. {
  9242. OwnedHqlExpr ds;
  9243. if (module)
  9244. {
  9245. ds.setown(module->getExpr());
  9246. }
  9247. else
  9248. {
  9249. ds.set(queryTopScope());
  9250. if (!ds || !ds->queryRecord())
  9251. {
  9252. reportError(ERR_OBJ_NOACTIVEDATASET, list, "No active dataset to resolve field list");
  9253. return getSizetConstant(0);
  9254. }
  9255. }
  9256. OwnedHqlExpr sortlist = list.getExpr();
  9257. switch (sortlist->getOperator())
  9258. {
  9259. case no_param:
  9260. return LINK(sortlist);
  9261. case no_sortlist:
  9262. break;
  9263. default:
  9264. throwUnexpected();
  9265. }
  9266. OwnedHqlExpr ret;
  9267. ForEachChild(i, sortlist)
  9268. {
  9269. ret.setown(createComma(ret.getClear(), createIndirectSelect(LINK(ds), LINK(sortlist->queryChild(i)), list)));
  9270. }
  9271. return ret.getClear();
  9272. }
  9273. static void getTokenText(StringBuffer & msg, int token)
  9274. {
  9275. switch (token)
  9276. {
  9277. case ABS: msg.append("ABS"); break;
  9278. case ACOS: msg.append("ACOS"); break;
  9279. case AFTER: msg.append("AFTER"); break;
  9280. case AGGREGATE: msg.append("AGGREGATE"); break;
  9281. case ALIAS: msg.append("__ALIAS__"); break;
  9282. case ALL: msg.append("ALL"); break;
  9283. case ALLNODES: msg.append("ALLNODES"); break;
  9284. case AND: msg.append("AND"); break;
  9285. case ANDAND: msg.append("&&"); break;
  9286. case ANY: msg.append("ANY"); break;
  9287. case APPLY: msg.append("APPLY"); break;
  9288. case _ARRAY_: msg.append("_ARRAY_"); break;
  9289. case AS: msg.append("AS"); break;
  9290. case ASCII: msg.append("ASCII"); break;
  9291. case ASIN: msg.append("ASIN"); break;
  9292. case TOK_ASSERT: msg.append("ASSERT"); break;
  9293. case ASSTRING: msg.append("ASSTRING"); break;
  9294. case ATAN: msg.append("ATAN"); break;
  9295. case ATAN2: msg.append("ATAN2"); break;
  9296. case ATMOST: msg.append("ATMOST"); break;
  9297. case AVE: msg.append("AVE"); break;
  9298. case BACKUP: msg.append("BACKUP"); break;
  9299. case BEFORE: msg.append("BEFORE"); break;
  9300. case BEST: msg.append("BEST"); break;
  9301. case BETWEEN: msg.append("BETWEEN"); break;
  9302. case BIG: msg.append("BIG_ENDIAN"); break;
  9303. case TOK_BITMAP: msg.append("BITMAP"); break;
  9304. case BLOB: msg.append("BLOB"); break;
  9305. case BNOT: msg.append("BNOT"); break;
  9306. case BUILD: msg.append("BUILD"); break;
  9307. case CARDINALITY: msg.append("CARDINALITY"); break;
  9308. case CASE: msg.append("CASE"); break;
  9309. case TOK_CATCH: msg.append("CATCH"); break;
  9310. case CHECKPOINT: msg.append("CHECKPOINT"); break;
  9311. case CHOOSE: msg.append("CHOOSE"); break;
  9312. case CHOOSEN: msg.append("CHOOSEN"); break;
  9313. case CHOOSENALL: msg.append("CHOOSEN:ALL"); break;
  9314. case CHOOSESETS: msg.append("CHOOSESETS"); break;
  9315. case CLUSTER: msg.append("CLUSTER"); break;
  9316. case CLUSTERSIZE: msg.append("CLUSTERSIZE"); break;
  9317. case COGROUP: msg.append("COGROUP"); break;
  9318. case COMBINE: msg.append("COMBINE"); break;
  9319. case __COMMON__: msg.append("__COMMON__"); break;
  9320. case __COMPOUND__: msg.append(""); break;
  9321. case COMPRESSED: msg.append("COMPRESSED"); break;
  9322. case __COMPRESSED__: msg.append("__COMPRESSED__"); break;
  9323. case TOK_CONST: msg.append("CONST"); break;
  9324. case CORRELATION: msg.append("CORRELATION"); break;
  9325. case COS: msg.append("COS"); break;
  9326. case COSH: msg.append("COSH"); break;
  9327. case COUNT: msg.append("COUNT"); break;
  9328. case COUNTER: msg.append("COUNTER"); break;
  9329. case COVARIANCE: msg.append("COVARIANCE"); break;
  9330. case CPPBODY: msg.append("BEGINC++"); break;
  9331. case TOK_CPP: msg.append("C++"); break;
  9332. case CRC: msg.append("HASHCRC"); break;
  9333. case CRON: msg.append("CRON"); break;
  9334. case CSV: msg.append("CSV"); break;
  9335. case DATASET: msg.append("DATASET"); break;
  9336. case __DEBUG__: msg.append("__DEBUG__"); break;
  9337. case DEDUP: msg.append("DEDUP"); break;
  9338. case DEFAULT: msg.append("DEFAULT"); break;
  9339. case DEFINE: msg.append("DEFINE"); break;
  9340. case DENORMALIZE: msg.append("DENORMALIZE"); break;
  9341. case DEPRECATED: msg.append("DEPRECATED"); break;
  9342. case DESC: msg.append("DESC"); break;
  9343. case DICTIONARY: msg.append("DICTIONARY"); break;
  9344. case DISTRIBUTE: msg.append("DISTRIBUTE"); break;
  9345. case DISTRIBUTED: msg.append("DISTRIBUTED"); break;
  9346. case DISTRIBUTION: msg.append("DISTRIBUTION"); break;
  9347. case DIV: msg.append("DIV"); break;
  9348. case DOTDOT: msg.append(".."); break;
  9349. case DYNAMIC: msg.append("DYNAMIC"); break;
  9350. case EBCDIC: msg.append("EBCDIC"); break;
  9351. case ECLCRC: msg.append("ECLCRC"); break;
  9352. case ELSE: msg.append("ELSE"); break;
  9353. case ELSEIF: msg.append("ELSEIF"); break;
  9354. case EMBED: msg.append("EMBED"); break;
  9355. case EMBEDDED: msg.append("EMBEDDED"); break;
  9356. case _EMPTY_: msg.append("_EMPTY_"); break;
  9357. case ENCODING: msg.append("ENCODING"); break;
  9358. case ENCRYPT: msg.append("ENCRYPT"); break;
  9359. case ENCRYPTED: msg.append("ENCRYPTED"); break;
  9360. case END: msg.append("END"); break;
  9361. case ENDCPP: msg.append("ENDCPP"); break;
  9362. case ENDEMBED: msg.append("ENDEMBED"); break;
  9363. case ENTH: msg.append("ENTH"); break;
  9364. case ENUM: msg.append("ENUM"); break;
  9365. case TOK_ERROR: msg.append("ERROR"); break;
  9366. case ESCAPE: msg.append("ESCAPE"); break;
  9367. case EVALUATE: msg.append("EVALUATE"); break;
  9368. case EVENT: msg.append("EVENT"); break;
  9369. case EVENTEXTRA: msg.append("EVENTEXTRA"); break;
  9370. case EVENTNAME: msg.append("EVENTNAME"); break;
  9371. case EXCEPT: msg.append("EXCEPT"); break;
  9372. case EXCLUSIVE: msg.append("EXCLUSIVE"); break;
  9373. case EXISTS: msg.append("EXISTS"); break;
  9374. case EXP: msg.append("expression"); break;
  9375. case EXPIRE: msg.append("EXPIRE"); break;
  9376. case EXPORT: msg.append("EXPORT"); break;
  9377. case EXTEND: msg.append("EXTEND"); break;
  9378. case FAIL: msg.append("FAIL"); break;
  9379. case FAILCODE: msg.append("FAILCODE"); break;
  9380. case FAILMESSAGE: msg.append("FAILMESSAGE"); break;
  9381. case FAILURE: msg.append("FAILURE"); break;
  9382. case FEATURE: msg.append("FEATURE"); break;
  9383. case FETCH: msg.append("FETCH"); break;
  9384. case FEW: msg.append("FEW"); break;
  9385. case TOK_FALSE: msg.append("FALSE"); break;
  9386. case FIELD_REF: msg.append("<?>"); break;
  9387. case FIELDS_REF: msg.append("<\?\?>"); break;
  9388. case FILEPOSITION: msg.append("FILEPOSITION"); break;
  9389. case FILTERED: msg.append("FILTERED"); break;
  9390. case FIRST: msg.append("FIRST"); break;
  9391. case TOK_FIXED: msg.append("FIXED"); break;
  9392. case FLAT: msg.append("FLAT"); break;
  9393. case FORMAT_ATTR: msg.append("FORMAT"); break;
  9394. case FORWARD: msg.append("FORWARD"); break;
  9395. case FROM: msg.append("FROM"); break;
  9396. case FROMUNICODE: msg.append("FROMUNICODE"); break;
  9397. case FROMJSON: msg.append("FROMJSON"); break;
  9398. case FROMXML: msg.append("FROMXML"); break;
  9399. case FULL: msg.append("FULL"); break;
  9400. case FUNCTION: msg.append("FULL"); break;
  9401. case GETENV: msg.append("GETENV"); break;
  9402. case GLOBAL: msg.append("GLOBAL"); break;
  9403. case GRAPH: msg.append("GRAPH"); break;
  9404. case GROUP: msg.append("GROUP"); break;
  9405. case GROUPBY: msg.append("GROUPBY"); break;
  9406. case GROUPED: msg.append("GROUPED"); break;
  9407. case __GROUPED__: msg.append("__GROUPED__"); break;
  9408. case GUARD: msg.append("GUARD"); break;
  9409. case HASH: msg.append("HASH"); break;
  9410. case HASH32: msg.append("HASH32"); break;
  9411. case HASH64: msg.append("HASH64"); break;
  9412. case HASHMD5: msg.append("HASHMD5"); break;
  9413. case HAVING: msg.append("HAVING"); break;
  9414. case HEADING: msg.append("HEADING"); break;
  9415. case HINT: msg.append("HINT"); break;
  9416. case HOLE: msg.append("HOLE"); break;
  9417. case IF: msg.append("IF"); break;
  9418. case IFF: msg.append("IFF"); break;
  9419. case IFBLOCK: msg.append("IFBLOCK"); break;
  9420. case TOK_IGNORE: msg.append("IGNORE"); break;
  9421. case IMPLEMENTS: msg.append("IMPLEMENTS"); break;
  9422. case IMPORT: msg.append("IMPORT"); break;
  9423. case INDEPENDENT: msg.append("INDEPENDENT"); break;
  9424. case INDEX: msg.append("INDEX"); break;
  9425. case INLINE: msg.append("INLINE"); break;
  9426. case TOK_IN: msg.append("IN"); break;
  9427. case INNER: msg.append("INNER"); break;
  9428. case INTERFACE: msg.append("INTERFACE"); break;
  9429. case INTERNAL: msg.append("INTERNAL"); break;
  9430. case INTFORMAT: msg.append("INTFORMAT"); break;
  9431. case ISNULL: msg.append("ISNULL"); break;
  9432. case ISVALID: msg.append("ISVALID"); break;
  9433. case ITERATE: msg.append("ITERATE"); break;
  9434. case JOIN: msg.append("JOIN"); break;
  9435. case JOINED: msg.append("JOINED"); break;
  9436. case JSON_TOKEN: msg.append("JSON"); break;
  9437. case KEEP: msg.append("KEEP"); break;
  9438. case KEYDIFF: msg.append("KEYDIFF"); break;
  9439. case KEYED: msg.append("KEYED"); break;
  9440. case KEYPATCH: msg.append("KEYPATCH"); break;
  9441. case KEYUNICODE: msg.append("KEYUNICODE"); break;
  9442. case LABELED: msg.append("LABELED"); break;
  9443. case LAST: msg.append("LAST"); break;
  9444. case LEFT: msg.append("LEFT"); break;
  9445. case LENGTH: msg.append("LENGTH"); break;
  9446. case LIBRARY: msg.append("LIBRARY"); break;
  9447. case LIMIT: msg.append("LIMIT"); break;
  9448. case LINKCOUNTED: msg.append("LINKCOUNTED"); break;
  9449. case LITERAL: msg.append("LITERAL"); break;
  9450. case LITTLE: msg.append("LITTLE_ENDIAN"); break;
  9451. case LN: msg.append("LN"); break;
  9452. case LOADXML: msg.append("LOADXML"); break;
  9453. case LOCAL: msg.append("LOCAL"); break;
  9454. case LOCALE: msg.append("LOCALE"); break;
  9455. case LOCALFILEPOSITION: msg.append("LOCALFILEPOSITION"); break;
  9456. case TOK_LOG: msg.append("LOG"); break;
  9457. case LOGICALFILENAME: msg.append("LOGICALFILENAME"); break;
  9458. case LOOKUP: msg.append("LOOKUP"); break;
  9459. case LOOP: msg.append("LOOP"); break;
  9460. case LZW: msg.append("LZW"); break;
  9461. case MANY: msg.append("MANY"); break;
  9462. case MAP: msg.append("MAP"); break;
  9463. case MATCHED: msg.append("MATCHED"); break;
  9464. case MATCHLENGTH: msg.append("MATCHLENGTH"); break;
  9465. case MATCHPOSITION: msg.append("MATCHPOSITION"); break;
  9466. case MATCHROW: msg.append("MATCHROW"); break;
  9467. case MATCHTEXT: msg.append("MATCHTEXT"); break;
  9468. case MATCHUNICODE: msg.append("MATCHUNICODE"); break;
  9469. case MATCHUTF8: msg.append("MATCHUTF8"); break;
  9470. case MAX: msg.append("MAX"); break;
  9471. case MAXCOUNT: msg.append("MAXCOUNT"); break;
  9472. case MAXLENGTH: msg.append("MAXLENGTH"); break;
  9473. case MAXSIZE: msg.append("MAXSIZE"); break;
  9474. case MERGE: msg.append("MERGE"); break;
  9475. case MERGE_ATTR: msg.append("MERGE"); break;
  9476. case MERGEJOIN: msg.append("MERGEJOIN"); break;
  9477. case MIN: msg.append("MIN"); break;
  9478. case MODULE: msg.append("MODULE"); break;
  9479. case MOFN: msg.append("MOFN"); break;
  9480. case MULTIPLE: msg.append("MULTIPLE"); break;
  9481. case NAMED: msg.append("NAMED"); break;
  9482. case NAMEOF: msg.append("__NAMEOF__"); break;
  9483. case NAMESPACE: msg.append("NAMESPACE"); break;
  9484. case NOBOUNDCHECK: msg.append("NOBOUNDCHECK"); break;
  9485. case NOCASE: msg.append("NOCASE"); break;
  9486. case NOCOMBINE: msg.append("NOCOMBINE"); break;
  9487. case NOFOLD: msg.append("NOFOLD"); break;
  9488. case NOHOIST: msg.append("NOHOIST"); break;
  9489. case NOLOCAL: msg.append("NOLOCAL"); break;
  9490. case NONEMPTY: msg.append("NONEMPTY"); break;
  9491. case NOOVERWRITE: msg.append("NOOVERWRITE"); break;
  9492. case NORMALIZE: msg.append("NORMALIZE"); break;
  9493. case NOROOT: msg.append("NOROOT"); break;
  9494. case NOSCAN: msg.append("NOSCAN"); break;
  9495. case NOSORT: msg.append("NOSORT"); break;
  9496. case __NOSTREAMING__: msg.append(""); break; // internal
  9497. case NOT: msg.append("NOT"); break;
  9498. case NOTHOR: msg.append("NOTHOR"); break;
  9499. case NOTIFY: msg.append("NOTIFY"); break;
  9500. case NOTRIM: msg.append("NOTRIM"); break;
  9501. case NOXPATH: msg.append("NOXPATH"); break;
  9502. case OF: msg.append("OF"); break;
  9503. case OMITTED: msg.append("OMITTED"); break;
  9504. case ONCE: msg.append("ONCE"); break;
  9505. case ONFAIL: msg.append("ONFAIL"); break;
  9506. case ONLY: msg.append("ONLY"); break;
  9507. case ONWARNING: msg.append("ONWARNING"); break;
  9508. case OPT: msg.append("OPT"); break;
  9509. case OR : msg.append("OR "); break;
  9510. case ORDER: msg.append("ORDER"); break;
  9511. case ORDERED: msg.append("ORDERED"); break;
  9512. case OUTER: msg.append("OUTER"); break;
  9513. case OUTPUT: msg.append("OUTPUT"); break;
  9514. case TOK_OUT: msg.append("OUT"); break;
  9515. case OVERWRITE: msg.append("OVERWRITE"); break;
  9516. case __OWNED__: msg.append("__OWNED__"); break;
  9517. case PACKED: msg.append("PACKED"); break;
  9518. case PARALLEL: msg.append("PARALLEL"); break;
  9519. case PARSE: msg.append("PARSE"); break;
  9520. case PARTITION: msg.append("PARTITION"); break;
  9521. case PARTITION_ATTR: msg.append("PARTITION"); break;
  9522. case TOK_PATTERN: msg.append("PATTERN"); break;
  9523. case PENALTY: msg.append("PENALTY"); break;
  9524. case PERSIST: msg.append("PERSIST"); break;
  9525. case PHYSICALFILENAME: msg.append("PHYSICALFILENAME"); break;
  9526. case PIPE: msg.append("PIPE"); break;
  9527. case __PLATFORM__: msg.append("__PLATFORM__"); break;
  9528. case POWER: msg.append("POWER"); break;
  9529. case PREFETCH: msg.append("PREFETCH"); break;
  9530. case PRELOAD: msg.append("PRELOAD"); break;
  9531. case PRIORITY: msg.append("PRIORITY"); break;
  9532. case PRIVATE: msg.append("PRIVATE"); break;
  9533. case PROCESS: msg.append("PROCESS"); break;
  9534. case PROJECT: msg.append("PROJECT"); break;
  9535. case PULL: msg.append("PULL"); break;
  9536. case PULLED: msg.append("PULLED"); break;
  9537. case QUANTILE: msg.append("QUANTILE"); break;
  9538. case QUOTE: msg.append("QUOTE"); break;
  9539. case RANDOM: msg.append("RANDOM"); break;
  9540. case RANGE: msg.append("RANGE"); break;
  9541. case RANK: msg.append("RANK"); break;
  9542. case RANKED: msg.append("RANKED"); break;
  9543. case REALFORMAT: msg.append("REALFORMAT"); break;
  9544. case RECORD: msg.append("RECORD"); break;
  9545. case RECORDOF: msg.append("RECORDOF"); break;
  9546. case RECOVERY: msg.append("RECOVERY"); break;
  9547. case REGEXFIND: msg.append("REGEXFIND"); break;
  9548. case REGEXREPLACE: msg.append("REGEXREPLACE"); break;
  9549. case REGROUP: msg.append("REGROUP"); break;
  9550. case REJECTED: msg.append("REJECTED"); break;
  9551. case RELATIONSHIP: msg.append("RELATIONSHIP"); break;
  9552. case REMOTE: msg.append("REMOTE"); break;
  9553. case REPEAT: msg.append("REPEAT"); break;
  9554. case RESPONSE: msg.append("RESPONSE"); break;
  9555. case RETRY: msg.append("RETRY"); break;
  9556. case RETURN: msg.append("RETURN"); break;
  9557. case RIGHT: msg.append("RIGHT"); break;
  9558. case RIGHT_NN: msg.append("RIGHT2"); break;
  9559. case ROLLUP: msg.append("ROLLUP"); break;
  9560. case ROUND: msg.append("ROUND"); break;
  9561. case ROUNDUP: msg.append("ROUNDUP"); break;
  9562. case ROW: msg.append("ROW"); break;
  9563. case ROWS: msg.append("ROWS"); break;
  9564. case ROWSET: msg.append("ROWSET"); break;
  9565. case ROWDIFF: msg.append("ROWDIFF"); break;
  9566. case RULE: msg.append("RULE"); break;
  9567. case SAMPLE: msg.append("SAMPLE"); break;
  9568. case SCAN: msg.append("SCAN"); break;
  9569. case SCORE: msg.append("SCORE"); break;
  9570. case SECTION: msg.append("SECTION"); break;
  9571. case SELF: msg.append("SELF"); break;
  9572. case SEPARATOR: msg.append("SEPARATOR"); break;
  9573. case __SEQUENCE__: msg.append("__SEQUENCE__"); break;
  9574. case SEQUENTIAL: msg.append("SEQUENTIAL"); break;
  9575. case SERVICE: msg.append("SERVICE"); break;
  9576. case SET: msg.append("SET"); break;
  9577. case SHARED: msg.append("SHARED"); break;
  9578. case SIN: msg.append("SIN"); break;
  9579. case SINGLE: msg.append("SINGLE"); break;
  9580. case SINH: msg.append("SINH"); break;
  9581. case SIZEOF: msg.append("SIZEOF"); break;
  9582. case SKEW: msg.append("SKEW"); break;
  9583. case SKIP: msg.append("SKIP"); break;
  9584. case SMART: msg.append("SMART"); break;
  9585. case SOAPACTION: msg.append("SOAPACTION"); break;
  9586. case __STAND_ALONE__: msg.append("__STAND_ALONE__"); break;
  9587. case HTTPHEADER: msg.append("HTTPHEADER"); break;
  9588. case PROXYADDRESS: msg.append("PROXYADDRESS"); break;
  9589. case HTTPCALL: msg.append("HTTPCALL"); break;
  9590. case SOAPCALL: msg.append("SOAPCALL"); break;
  9591. case SORT: msg.append("SORT"); break;
  9592. case SORTED: msg.append("SORTED"); break;
  9593. case SQL: msg.append("SQL"); break;
  9594. case SQRT: msg.append("SQRT"); break;
  9595. case STABLE: msg.append("STABLE"); break;
  9596. case STEPPED: msg.append("STEPPED"); break;
  9597. case STORED: msg.append("STORED"); break;
  9598. case STREAMED: msg.append("STREAMED"); break;
  9599. case SUBSORT: msg.append("SUBSORT"); break;
  9600. case SUCCESS: msg.append("SUCCESS"); break;
  9601. case SUM: msg.append("SUM"); break;
  9602. case SWAPPED: msg.append("SWAPPED"); break;
  9603. case TABLE: msg.append("TABLE"); break;
  9604. case TAN: msg.append("TAN"); break;
  9605. case TANH: msg.append("TANH"); break;
  9606. case TERMINATOR: msg.append("TERMINATOR"); break;
  9607. case THEN: msg.append("THEN"); break;
  9608. case THISNODE: msg.append("THISNODE"); break;
  9609. case THOR: msg.append("THOR"); break;
  9610. case THRESHOLD: msg.append("THRESHOLD"); break;
  9611. case TIMEOUT: msg.append("TIMEOUT"); break;
  9612. case TIMELIMIT: msg.append("TIMELIMIT"); break;
  9613. case TOKEN: msg.append("TOKEN"); break;
  9614. case TOJSON: msg.append("TOJSON"); break;
  9615. case TOPN: msg.append("TOPN"); break;
  9616. case TOUNICODE: msg.append("TOUNICODE"); break;
  9617. case TOXML: msg.append("TOXML"); break;
  9618. case TRACE: msg.append("TRACE"); break;
  9619. case TRANSFER: msg.append("TRANSFER"); break;
  9620. case TRANSFORM: msg.append("TRANSFORM"); break;
  9621. case TRIM: msg.append("TRIM"); break;
  9622. case TRUNCATE: msg.append("TRUNCATE"); break;
  9623. case TOK_TRUE: msg.append("TRUE"); break;
  9624. case TYPE: msg.append("TYPE"); break;
  9625. case TYPEOF: msg.append("TYPEOF"); break;
  9626. case UNGROUP: msg.append("UNGROUP"); break;
  9627. case UNICODEORDER: msg.append("UNICODEORDER"); break;
  9628. case UNORDERED: msg.append("UNORDERED"); break;
  9629. case UNSIGNED: msg.append("UNSIGNED"); break;
  9630. case UNSORTED: msg.append("UNSORTED"); break;
  9631. case UNSTABLE: msg.append("UNSTABLE"); break;
  9632. case UPDATE: msg.append("UPDATE"); break;
  9633. case USE: msg.append("USE"); break;
  9634. case VALIDATE: msg.append("VALIDATE"); break;
  9635. case VARIANCE: msg.append("VARIANCE"); break;
  9636. case VIRTUAL: msg.append("VIRTUAL"); break;
  9637. case WAIT: msg.append("WAIT"); break;
  9638. case TOK_WARNING: msg.append("WARNING"); break;
  9639. case WHEN: msg.append("WHEN"); break;
  9640. case WHICH: msg.append("WHICH"); break;
  9641. case WIDTH: msg.append("WIDTH"); break;
  9642. case WILD: msg.append("WILD"); break;
  9643. case WITHIN: msg.append("WITHIN"); break;
  9644. case WHOLE: msg.append("WHOLE"); break;
  9645. case WORKUNIT: msg.append("WORKUNIT"); break;
  9646. case XML_TOKEN: msg.append("XML"); break;
  9647. case XMLDECODE: msg.append("XMLDECODE"); break;
  9648. case XMLDEFAULT: msg.append("XMLDEFAULT"); break;
  9649. case XMLENCODE: msg.append("XMLENCODE"); break;
  9650. case XMLNS: msg.append("XMLNS"); break;
  9651. case XMLPROJECT: msg.append("XMLPROJECT"); break;
  9652. case XMLTEXT: msg.append("XMLTEXT"); break;
  9653. case XMLUNICODE: msg.append("XMLUNICODE"); break;
  9654. case XPATH: msg.append("XPATH"); break;
  9655. case HASH_CONSTANT: msg.append("#CONSTANT"); break;
  9656. case HASH_ONWARNING: msg.append("#ONWARNING"); break;
  9657. case HASH_OPTION: msg.append("#OPTION"); break;
  9658. case HASH_STORED: msg.append("#STORED"); break;
  9659. case HASH_LINK: msg.append("#LINK"); break;
  9660. case HASH_WORKUNIT: msg.append("#WORKUNIT"); break;
  9661. case HASH_WEBSERVICE: msg.append("#WEBSERVICE"); break;
  9662. case SIMPLE_TYPE: msg.append("type-name"); break;
  9663. case EQ: msg.append("="); break;
  9664. case NE: msg.append("<>"); break;
  9665. case LE: msg.append("<="); break;
  9666. case LT: msg.append("<"); break;
  9667. case GE: msg.append(">="); break;
  9668. case GT: msg.append(">"); break;
  9669. case ASSIGN: msg.append(":="); break;
  9670. case GOESTO: msg.append("=>"); break;
  9671. case SHIFTL: msg.append("<<"); break;
  9672. case SHIFTR: msg.append(">>"); break;
  9673. case DATASET_ID: msg.append("dataset"); break;
  9674. case DATAROW_ID: msg.append("datarow"); break;
  9675. case DICTIONARY_ID: msg.append("dictionary"); break;
  9676. case RECORD_ID: msg.append("record-name"); break;
  9677. case RECORD_FUNCTION: msg.append("record-name"); break;
  9678. case VALUE_ID: msg.append("identifier"); break;
  9679. case VALUE_ID_REF: msg.append("field reference"); break;
  9680. case UNKNOWN_ID: msg.append("identifier"); break;
  9681. case SCOPE_ID: msg.append("module-name"); break;
  9682. case ACTION_ID: msg.append("identifier"); break;
  9683. case TRANSFORM_ID: msg.append("transform-name"); break;
  9684. case ALIEN_ID: msg.append("type name"); break;
  9685. case PATTERN_ID: msg.append("pattern-name"); break;
  9686. case FEATURE_ID: msg.append("feature-name"); break;
  9687. case EVENT_ID: msg.append("identifier"); break;
  9688. case ENUM_ID: msg.append("identifier"); break;
  9689. case LIST_DATASET_ID: msg.append("identifier"); break;
  9690. case SORTLIST_ID: msg.append("field list"); break;
  9691. case TYPE_ID: msg.append("type name"); break;
  9692. case SET_TYPE_ID: msg.append("type name"); break;
  9693. case PATTERN_TYPE_ID: msg.append("type name"); break;
  9694. case DICTIONARY_TYPE_ID: msg.append("type name"); break;
  9695. case DATASET_TYPE_ID: msg.append("type name"); break;
  9696. case ACTION_FUNCTION: msg.append("action"); break;
  9697. case PATTERN_FUNCTION: msg.append("pattern"); break;
  9698. case EVENT_FUNCTION: msg.append("event"); break;
  9699. case SCOPE_FUNCTION: msg.append("module-name"); break;
  9700. case TRANSFORM_FUNCTION: msg.append("transform-name"); break;
  9701. case DATAROW_FUNCTION: msg.append("datarow"); break;
  9702. case DICTIONARY_FUNCTION: msg.append("dictionary"); break;
  9703. case LIST_DATASET_FUNCTION: msg.append("identifier"); break;
  9704. case VALUE_FUNCTION:
  9705. case DATASET_FUNCTION:
  9706. msg.append("function-name");
  9707. break;
  9708. case BOOL_CONST: msg.append("boolean"); break;
  9709. case REAL_CONST:
  9710. case INTEGER_CONST: msg.append("number"); break;
  9711. case STRING_CONST: msg.append("string"); break;
  9712. case UNICODE_CONST: msg.append("unicode-string"); break;
  9713. case DATA_CONST: msg.append("constant"); break;
  9714. case TYPE_LPAREN: msg.append("(>"); break;
  9715. case TYPE_RPAREN: msg.append("<)"); break;
  9716. case HASHBREAK: msg.append("#BREAK"); break;
  9717. case SKIPPED: msg.append("SKIPPED"); break;
  9718. case HASHEND: msg.append("#END"); break;
  9719. case HASHELIF: msg.append("#ELIF"); break; //? not in the lexer...
  9720. case MACRO: msg.append("MACRO"); break;
  9721. case COMPLEX_MACRO: msg.append("complex-macro"); break;
  9722. case VALUE_MACRO: msg.append("macro-name"); break;
  9723. case DEFINITIONS_MACRO: msg.append("macro-name"); break;
  9724. case ENDMACRO: msg.append("ENDMACRO"); break;
  9725. case INTERNAL_READ_NEXT_TOKEN: break;
  9726. default:
  9727. if (token < 128)
  9728. msg.appendf("'%c'", (char)token);
  9729. else
  9730. {
  9731. /* if fail, use "hqltest -internal" to find out why. */
  9732. msg.appendf("???");
  9733. //PrintLog("Internal error: Error handler unknown token %d", expected[i]);
  9734. assertex(!"Token not mapped to text");
  9735. }
  9736. }
  9737. }
  9738. inline bool containsToken(int first, const int * expected)
  9739. {
  9740. for (const int *finger = expected;*finger; finger++)
  9741. {
  9742. if (*finger == first)
  9743. return true;
  9744. }
  9745. return false;
  9746. }
  9747. inline void removeToken(int token, int * expected)
  9748. {
  9749. for (int *finger = expected;*finger; finger++)
  9750. {
  9751. if (*finger == token)
  9752. {
  9753. *finger = ' ';
  9754. break;
  9755. }
  9756. }
  9757. }
  9758. void HqlGram::simplify(int *expected, int first, ...)
  9759. {
  9760. if (!containsToken(first, expected))
  9761. return;
  9762. va_list args;
  9763. va_start(args, first);
  9764. for (;;)
  9765. {
  9766. int parm = va_arg(args, int);
  9767. if (!parm)
  9768. break;
  9769. removeToken(parm, expected);
  9770. }
  9771. va_end(args);
  9772. }
  9773. void HqlGram::simplifyExpected(int *expected)
  9774. {
  9775. //simplify checks if the first item in the list is expected next, and if so it removes all of the others as expected tokens.
  9776. simplify(expected, DISTRIBUTE, DISTRIBUTE, ASCII, CHOOSEN, CHOOSESETS, DEDUP, DISTRIBUTED, EBCDIC, ENTH, SAMPLE, SORT, SORTED, TABLE, DATASET, FETCH,
  9777. GROUP, GROUPED, KEYED, UNGROUP, JOIN, PULL, ROLLUP, ITERATE, PROJECT, NORMALIZE, PIPE, DENORMALIZE, CASE, MAP,
  9778. HTTPCALL, SOAPCALL, LIMIT, PARSE, FAIL, MERGE, PRELOAD, ROW, TOPN, ALIAS, LOCAL, NOFOLD, NOCOMBINE, NOHOIST, NOTHOR, IF, GLOBAL, __COMMON__, __COMPOUND__, TOK_ASSERT, _EMPTY_,
  9779. COMBINE, ROWS, REGROUP, XMLPROJECT, SKIP, LOOP, CLUSTER, NOLOCAL, REMOTE, PROCESS, ALLNODES, THISNODE, GRAPH, MERGEJOIN, STEPPED, NONEMPTY, HAVING,
  9780. TOK_CATCH, '@', SECTION, WHEN, IFF, COGROUP, HINT, INDEX, PARTITION, AGGREGATE, SUBSORT, TOK_ERROR, CHOOSE, TRACE, QUANTILE, 0);
  9781. simplify(expected, EXP, ABS, SIN, COS, TAN, SINH, COSH, TANH, ACOS, ASIN, ATAN, ATAN2,
  9782. COUNT, CHOOSE, MAP, CASE, IF, HASH, HASH32, HASH64, HASHMD5, CRC, LN, TOK_LOG, POWER, RANDOM, ROUND, ROUNDUP, SQRT,
  9783. TRUNCATE, LENGTH, TRIM, INTFORMAT, REALFORMAT, ASSTRING, TRANSFER, MAX, MIN, EVALUATE, SUM,
  9784. AVE, VARIANCE, COVARIANCE, CORRELATION, WHICH, REJECTED, SIZEOF, RANK, RANKED, COUNTER, '+', '-', '(', '~', TYPE_LPAREN, ROWDIFF, WORKUNIT,
  9785. FAILCODE, FAILMESSAGE, FROMUNICODE, __GROUPED__, ISNULL, ISVALID, XMLDECODE, XMLENCODE, XMLTEXT, XMLUNICODE,
  9786. MATCHED, MATCHLENGTH, MATCHPOSITION, MATCHTEXT, MATCHUNICODE, MATCHUTF8, NOFOLD, NOHOIST, NOTHOR, OPT, REGEXFIND, REGEXREPLACE, RELATIONSHIP, SEQUENTIAL, SKIP, TOUNICODE, UNICODEORDER, UNSORTED,
  9787. KEYUNICODE, TOK_TRUE, TOK_FALSE, BOOL_CONST, NOT, EXISTS, WITHIN, LEFT, RIGHT, SELF, '[', HTTPCALL, SOAPCALL, ALL, TOK_ERROR, TOK_CATCH, __COMMON__, __COMPOUND__, RECOVERY, CLUSTERSIZE, CHOOSENALL, BNOT, STEPPED, ECLCRC, NAMEOF,
  9788. TOXML, TOJSON, '@', SECTION, EVENTEXTRA, EVENTNAME, __SEQUENCE__, IFF, OMITTED, GETENV, __DEBUG__, __STAND_ALONE__, 0);
  9789. simplify(expected, DATA_CONST, REAL_CONST, STRING_CONST, INTEGER_CONST, UNICODE_CONST, 0);
  9790. simplify(expected, VALUE_MACRO, DEFINITIONS_MACRO, 0);
  9791. simplify(expected, DICTIONARY_ID, DICTIONARY_FUNCTION, DICTIONARY, 0);
  9792. simplify(expected, ACTION_ID, ORDERED, 0); // more include other actions
  9793. simplify(expected, VALUE_ID, DATASET_ID, DICTIONARY_ID, RECORD_ID, ACTION_ID, UNKNOWN_ID, SCOPE_ID, VALUE_FUNCTION, DATAROW_FUNCTION, DATASET_FUNCTION, DICTIONARY_FUNCTION, LIST_DATASET_FUNCTION, LIST_DATASET_ID, ALIEN_ID, TYPE_ID, SET_TYPE_ID, TRANSFORM_ID, TRANSFORM_FUNCTION, RECORD_FUNCTION, FEATURE_ID, EVENT_ID, EVENT_FUNCTION, SCOPE_FUNCTION, ENUM_ID, PATTERN_TYPE_ID, DICTIONARY_TYPE_ID, DATASET_TYPE_ID, 0);
  9794. simplify(expected, LIBRARY, LIBRARY, SCOPE_FUNCTION, STORED, PROJECT, INTERFACE, MODULE, 0);
  9795. simplify(expected, MATCHROW, MATCHROW, LEFT, RIGHT, IF, IFF, ROW, HTTPCALL, SOAPCALL, PROJECT, GLOBAL, NOFOLD, NOHOIST, ALLNODES, THISNODE, SKIP, DATAROW_FUNCTION, TRANSFER, RIGHT_NN, FROMXML, FROMJSON, 0);
  9796. simplify(expected, TRANSFORM_ID, TRANSFORM_FUNCTION, TRANSFORM, '@', 0);
  9797. simplify(expected, RECORD, RECORDOF, RECORD_ID, RECORD_FUNCTION, SCOPE_ID, VALUE_MACRO, '{', '@', 0);
  9798. simplify(expected, IFBLOCK, ANY, PACKED, BIG, LITTLE, 0);
  9799. simplify(expected, SCOPE_ID, '$', 0);
  9800. simplify(expected, SIMPLE_TYPE, _ARRAY_, LINKCOUNTED, EMBEDDED, STREAMED, 0);
  9801. simplify(expected, END, '}', 0);
  9802. }
  9803. void HqlGram::syntaxError(const char *s, int token, int *expected)
  9804. {
  9805. if (errorDisabled || !s || !errorHandler)
  9806. return;
  9807. int lineno = lexObject->getActualLineNo();
  9808. int column = lexObject->getActualColumn();
  9809. int pos = lexObject->get_yyPosition();
  9810. const char * yytext = lexObject->get_yyText();
  9811. if (yytext)
  9812. column -= strlen(yytext);
  9813. if (expected)
  9814. simplifyExpected(expected);
  9815. StringBuffer msg;
  9816. if (expected == NULL) // expected is NULL when fatal internal error occurs.
  9817. {
  9818. msg.append(s);
  9819. }
  9820. else if (token==UNKNOWN_ID)
  9821. {
  9822. msg.append("Unknown identifier");
  9823. if (yytext && *yytext)
  9824. msg.append(" \"").append(yytext).append('\"');
  9825. reportError(ERR_UNKNOWN_IDENTIFIER,msg.str(), lineno, column, pos);
  9826. return;
  9827. }
  9828. else if ((token == '.') && (expected[0] == ASSIGN) && !expected[1])
  9829. {
  9830. reportError(ERR_UNKNOWN_IDENTIFIER,"Unknown identifier before \".\" (expected :=)", lineno, column, pos);
  9831. return;
  9832. }
  9833. else switch(token)
  9834. {
  9835. case DATAROW_ID:
  9836. case DATASET_ID:
  9837. case DICTIONARY_ID:
  9838. case SCOPE_ID:
  9839. case VALUE_ID:
  9840. case VALUE_ID_REF:
  9841. case ACTION_ID:
  9842. case UNKNOWN_ID:
  9843. case ENUM_ID:
  9844. case RECORD_ID:
  9845. case ALIEN_ID:
  9846. case TRANSFORM_ID:
  9847. case PATTERN_ID:
  9848. case FEATURE_ID:
  9849. case EVENT_ID:
  9850. case LIST_DATASET_ID:
  9851. case DATAROW_FUNCTION:
  9852. case DATASET_FUNCTION:
  9853. case DICTIONARY_FUNCTION:
  9854. case VALUE_FUNCTION:
  9855. case ACTION_FUNCTION:
  9856. case PATTERN_FUNCTION:
  9857. case RECORD_FUNCTION:
  9858. case EVENT_FUNCTION:
  9859. case SCOPE_FUNCTION:
  9860. case TRANSFORM_FUNCTION:
  9861. case LIST_DATASET_FUNCTION:
  9862. case TYPE_ID:
  9863. case SET_TYPE_ID:
  9864. case PATTERN_TYPE_ID:
  9865. case DATASET_TYPE_ID:
  9866. case DICTIONARY_TYPE_ID:
  9867. {
  9868. for (int j = 0; expected[j] ; j++)
  9869. {
  9870. if (expected[j]==UNKNOWN_ID)
  9871. {
  9872. msg.append("Identifier '");
  9873. if (yytext && *yytext)
  9874. msg.append(yytext);
  9875. msg.append("' is already defined");
  9876. reportError(ERR_ID_REDEFINE,msg.str(), lineno, column, pos);
  9877. return;
  9878. }
  9879. }
  9880. // fall into...
  9881. }
  9882. default:
  9883. msg.append(s);
  9884. if (yytext && *yytext)
  9885. {
  9886. if (yytext[0]=='\n')
  9887. msg.append(" near the end of the line");
  9888. else
  9889. msg.append(" near \"").append(yytext).append('\"');
  9890. }
  9891. bool first = true;
  9892. for (int i = 0; expected[i] ; i++)
  9893. {
  9894. if (expected[i] == ' ')
  9895. continue;
  9896. if (first)
  9897. msg.append(" : expected ");
  9898. else
  9899. msg.append(", ");
  9900. first = false;
  9901. getTokenText(msg, expected[i]);
  9902. }
  9903. }
  9904. reportError(ERR_EXPECTED, msg.str(), lineno, column, pos);
  9905. }
  9906. void HqlGram::abortParsing()
  9907. {
  9908. // disable more error report
  9909. disableError();
  9910. lookupCtx.setAborting();
  9911. aborting = true;
  9912. }
  9913. IHqlExpression * HqlGram::createCheckMatchAttr(attribute & attr, type_t tc)
  9914. {
  9915. OwnedITypeInfo type;
  9916. switch (tc)
  9917. {
  9918. case type_unicode:
  9919. type.setown(makeUnicodeType(UNKNOWN_LENGTH, NULL));
  9920. break;
  9921. case type_string:
  9922. type.setown(makeStringType(UNKNOWN_LENGTH, NULL));
  9923. break;
  9924. case type_utf8:
  9925. type.setown(makeUtf8Type(UNKNOWN_LENGTH, NULL));
  9926. break;
  9927. default:
  9928. throwUnexpectedType(type);
  9929. }
  9930. OwnedHqlExpr arg = attr.getExpr();
  9931. if (arg->getOperator() == no_matchattr)
  9932. {
  9933. IHqlExpression * path= arg->isDatarow() ? arg->queryChild(1) : arg->queryChild(0);
  9934. return createValue(no_matchattr, LINK(type), LINK(path)); //, createUniqueId());
  9935. }
  9936. reportError(ERR_EXPECTED_ATTRIBUTE, attr, "Expected an attribute");
  9937. return createNullExpr(type);
  9938. }
  9939. void HqlGram::checkWorkflowScheduling(IHqlExpression * expr, attribute& errpos)
  9940. {
  9941. if (!expr)
  9942. return;
  9943. HqlExprArray args;
  9944. expr->unwindList(args, no_comma);
  9945. bool hasScheduling = false;
  9946. ForEachItemIn(idx, args)
  9947. {
  9948. IHqlExpression * cur = &args.item(idx);
  9949. switch (cur->getOperator())
  9950. {
  9951. case no_when:
  9952. case no_priority:
  9953. hasScheduling = true;
  9954. break;
  9955. }
  9956. }
  9957. if(hasScheduling)
  9958. reportError(ERR_SCHEDULING_DEFINITION, errpos, "Scheduling is not allowed on definitions");
  9959. }
  9960. void HqlGram::checkWorkflowMultiples(IHqlExpression * previousWorkflow, IHqlExpression * newWorkflow, attribute & errpos)
  9961. {
  9962. if(!previousWorkflow || !newWorkflow) return;
  9963. node_operator newOp = newWorkflow->getOperator();
  9964. HqlExprArray workflows;
  9965. previousWorkflow->unwindList(workflows, no_comma);
  9966. IAtom * newName = newWorkflow->queryName();
  9967. ForEachItemIn(idx, workflows)
  9968. {
  9969. IHqlExpression & cur = workflows.item(idx);
  9970. node_operator oldOp = cur.getOperator();
  9971. switch(newOp)
  9972. {
  9973. case no_persist:
  9974. case no_stored:
  9975. case no_checkpoint:
  9976. case no_once:
  9977. if((oldOp==no_persist)||(oldOp==no_stored)||(oldOp==no_once)||(oldOp==no_checkpoint))
  9978. reportError(ERR_MULTIPLE_WORKFLOW, errpos, "Multiple scoping controls are not allowed on an action or expression");
  9979. break;
  9980. case no_attr:
  9981. case no_attr_link:
  9982. case no_attr_expr:
  9983. if (cur.isAttribute() && cur.queryName() == newName)
  9984. {
  9985. if (newName != onWarningAtom)
  9986. {
  9987. StringBuffer buff;
  9988. buff.append("Multiple ").append(newName).append(" controls are not allowed on an expression");
  9989. reportError(ERR_MULTIPLE_WORKFLOW, errpos, "%s", buff.str());
  9990. }
  9991. }
  9992. break;
  9993. default:
  9994. if(oldOp == newOp)
  9995. {
  9996. StringBuffer buff;
  9997. buff.append("Multiple ").append(getOpString(newOp)).append(" controls are not allowed on an expression");
  9998. reportError(ERR_MULTIPLE_WORKFLOW, errpos, "%s", buff.str());
  9999. }
  10000. }
  10001. }
  10002. }
  10003. bool HqlGram::isSaved(IHqlExpression * failure)
  10004. {
  10005. if (!failure) return false;
  10006. HqlExprArray args;
  10007. failure->unwindList(args, no_comma);
  10008. ForEachItemIn(idx, args)
  10009. {
  10010. switch (args.item(idx).getOperator())
  10011. {
  10012. case no_persist:
  10013. case no_stored:
  10014. case no_checkpoint:
  10015. case no_global:
  10016. case no_once:
  10017. return true;
  10018. }
  10019. }
  10020. return false;
  10021. }
  10022. void HqlGram::checkPatternFailure(attribute & attr)
  10023. {
  10024. IHqlExpression * failure = attr.queryExpr();
  10025. if (!failure)
  10026. return;
  10027. HqlExprArray args;
  10028. failure->unwindList(args, no_comma);
  10029. ForEachItemIn(idx, args)
  10030. {
  10031. IHqlExpression & cur = args.item(idx);
  10032. if (!cur.isAttribute() || (cur.queryName() != defineAtom))
  10033. reportError(ERR_INVALIDPATTERNCLAUSE, attr, "Invalid clause for a pattern definition");
  10034. }
  10035. if (failure->getOperator() == no_comma)
  10036. reportError(ERR_INVALIDPATTERNCLAUSE, attr, "Only one define allowed on each pattern definition");
  10037. }
  10038. bool HqlGram::isExceptionalCase(attribute& defineid, attribute& object, attribute& failure)
  10039. {
  10040. bool isBad = false;
  10041. IHqlExpression *expr = object.queryExpr();
  10042. if (expr == NULL)
  10043. isBad = true;
  10044. else if (expr->getOperator()==no_loadxml)
  10045. {
  10046. reportError(ERR_LOADXML_NOANATTRIBUTE, defineid, "LOADXML is not an definition: it can be used only alone for test purpose");
  10047. isBad = true;
  10048. }
  10049. if (isBad)
  10050. {
  10051. defineid.release();
  10052. object.release();
  10053. failure.release();
  10054. }
  10055. return isBad;
  10056. }
  10057. static void expandDefJoinAttrs(IHqlExpression * newRec, IHqlExpression * record)
  10058. {
  10059. ForEachChild(i, record)
  10060. {
  10061. IHqlExpression * cur = record->queryChild(i);
  10062. switch (cur->getOperator())
  10063. {
  10064. case no_attr:
  10065. case no_attr_link:
  10066. case no_attr_expr:
  10067. if (!newRec->hasAttribute(cur->queryName()))
  10068. newRec->addOperand(LINK(cur));
  10069. break;
  10070. }
  10071. }
  10072. }
  10073. static void checkExtraCommonFields(IHqlSimpleScope * scope, IHqlExpression * record, bool * hasExtra, HqlExprCopyArray & common)
  10074. {
  10075. ForEachChild(i, record)
  10076. {
  10077. IHqlExpression * cur = record->queryChild(i);
  10078. switch (cur->getOperator())
  10079. {
  10080. case no_field:
  10081. {
  10082. OwnedHqlExpr match = scope->lookupSymbol(cur->queryId());
  10083. if (!match)
  10084. *hasExtra = true;
  10085. else
  10086. common.append(*match);
  10087. break;
  10088. }
  10089. case no_record:
  10090. checkExtraCommonFields(scope, cur, hasExtra, common);
  10091. break;
  10092. case no_ifblock:
  10093. checkExtraCommonFields(scope, cur->queryChild(1), hasExtra, common);
  10094. break;
  10095. }
  10096. }
  10097. }
  10098. static void expandDefJoinFields(IHqlExpression * newRec, IHqlSimpleScope * scope, IHqlExpression * record)
  10099. {
  10100. ForEachChild(i, record)
  10101. {
  10102. IHqlExpression * cur = record->queryChild(i);
  10103. switch (cur->getOperator())
  10104. {
  10105. case no_field:
  10106. {
  10107. OwnedHqlExpr match = scope->lookupSymbol(cur->queryId());
  10108. if (!match)
  10109. newRec->addOperand(LINK(cur));
  10110. break;
  10111. }
  10112. case no_record:
  10113. expandDefJoinFields(newRec, scope, cur);
  10114. break;
  10115. case no_ifblock:
  10116. expandDefJoinFields(newRec, scope, cur->queryChild(1));
  10117. break;
  10118. }
  10119. }
  10120. }
  10121. void HqlGram::addConditionalAssign(const attribute & errpos, IHqlExpression * self, IHqlExpression * leftSelect, IHqlExpression * rightSelect, IHqlExpression * field)
  10122. {
  10123. IHqlSimpleScope * rightScope = rightSelect->queryRecord()->querySimpleScope();
  10124. OwnedHqlExpr tgt = createSelectExpr(LINK(self), LINK(field));
  10125. OwnedHqlExpr leftSrc = createSelectExpr(LINK(leftSelect), LINK(field));
  10126. OwnedHqlExpr rightSrc = createSelectExpr(LINK(rightSelect), rightScope->lookupSymbol(field->queryId()));
  10127. if (field->isDatarow())
  10128. {
  10129. addConditionalRowAssign(errpos, tgt, leftSrc, rightSrc, field->queryRecord());
  10130. }
  10131. else
  10132. {
  10133. OwnedHqlExpr null = createNullExpr(leftSrc);
  10134. OwnedHqlExpr src = createIf(createBoolExpr(no_ne, LINK(leftSrc), LINK(null)), LINK(leftSrc), LINK(rightSrc));
  10135. addAssignment(errpos, tgt, src);
  10136. }
  10137. }
  10138. void HqlGram::addConditionalRowAssign(const attribute & errpos, IHqlExpression * self, IHqlExpression * leftSelect, IHqlExpression * rightSelect, IHqlExpression * record)
  10139. {
  10140. ForEachChild(i, record)
  10141. {
  10142. IHqlExpression * cur = record->queryChild(i);
  10143. switch (cur->getOperator())
  10144. {
  10145. case no_field:
  10146. addConditionalAssign(errpos, self, leftSelect, rightSelect, cur);
  10147. break;
  10148. case no_record:
  10149. addConditionalRowAssign(errpos, self, leftSelect, rightSelect, cur);
  10150. break;
  10151. case no_ifblock:
  10152. addConditionalRowAssign(errpos, self, leftSelect, rightSelect, cur->queryChild(1));
  10153. break;
  10154. }
  10155. }
  10156. }
  10157. IHqlExpression* HqlGram::createDefJoinTransform(IHqlExpression* left,IHqlExpression* right,attribute& errpos, IHqlExpression * seq, IHqlExpression * flags)
  10158. {
  10159. IHqlExpression * leftRecord = left->queryRecord();
  10160. IHqlExpression * rightRecord = right->queryRecord();
  10161. OwnedHqlExpr res_rec;
  10162. bool hasExtraFields = false;
  10163. HqlExprCopyArray commonFields;
  10164. checkExtraCommonFields(leftRecord->querySimpleScope(), rightRecord, &hasExtraFields, commonFields);
  10165. if (hasExtraFields)
  10166. {
  10167. //
  10168. // create result record
  10169. CHqlRecord * newRec = (CHqlRecord *)createRecord();
  10170. expandDefJoinAttrs(newRec, leftRecord);
  10171. expandDefJoinAttrs(newRec, rightRecord);
  10172. //Clone left - including ifblocks etc.
  10173. ForEachChild(i, leftRecord)
  10174. {
  10175. IHqlExpression *field = leftRecord->queryChild(i);
  10176. if (!field->isAttribute())
  10177. newRec->addOperand(LINK(field));
  10178. }
  10179. expandDefJoinFields(newRec, newRec->querySimpleScope(), rightRecord);
  10180. res_rec.setown(newRec->closeExpr());
  10181. }
  10182. else
  10183. res_rec.set(leftRecord);
  10184. // create transform
  10185. beginTransform(res_rec->queryRecordType());
  10186. OwnedHqlExpr self = createSelector(no_self, res_rec, NULL);
  10187. OwnedHqlExpr leftSelect = createSelector(no_left, left, seq);
  10188. OwnedHqlExpr rightSelect = createSelector(no_right, right, seq);
  10189. if (queryAttributeInList(fullouterAtom, flags) || queryAttributeInList(fullonlyAtom, flags))
  10190. {
  10191. ForEachItemIn(i, commonFields)
  10192. {
  10193. IHqlExpression & cur = commonFields.item(i);
  10194. addConditionalAssign(errpos, self, leftSelect, rightSelect, &cur);
  10195. }
  10196. }
  10197. if (queryAttributeInList(rightouterAtom, flags) || queryAttributeInList(rightonlyAtom, flags))
  10198. {
  10199. addAssignall(LINK(self), LINK(rightSelect), errpos);
  10200. addAssignall(LINK(self), LINK(leftSelect), errpos);
  10201. }
  10202. else
  10203. {
  10204. addAssignall(LINK(self), LINK(leftSelect), errpos);
  10205. addAssignall(LINK(self), LINK(rightSelect), errpos);
  10206. }
  10207. // close transform
  10208. checkAllAssigned(res_rec, errpos);
  10209. return endTransform(errpos);
  10210. }
  10211. IHqlExpression * HqlGram::createProjectRow(attribute & rowAttr, attribute & transformAttr, attribute & seqAttr)
  10212. {
  10213. OwnedHqlExpr row = rowAttr.getExpr();
  10214. OwnedHqlExpr transform = transformAttr.getExpr();
  10215. OwnedHqlExpr seq = seqAttr.getExpr();
  10216. return createRow(no_projectrow, row.getClear(), createComma(transform.getClear(), seq.getClear()));
  10217. }
  10218. void HqlGram::beginTransform(ITypeInfo * type)
  10219. {
  10220. if (curTransform)
  10221. {
  10222. TransformSaveInfo * saved = new TransformSaveInfo;
  10223. saved->curTransform.setown(curTransform);
  10224. saved->transformScope.setown(transformScope);
  10225. transformSaveStack.append(*saved);
  10226. }
  10227. curTransform = createOpenValue(no_transform, makeTransformType(LINK(type)));
  10228. transformScope = createPrivateScope();
  10229. enterScope(transformScope, false);
  10230. #ifdef FAST_FIND_FIELD
  10231. lockTransformMutex();
  10232. #endif
  10233. }
  10234. IHqlExpression * HqlGram::endTransform(const attribute &errpos)
  10235. {
  10236. if (!curTransform)
  10237. return NULL;
  10238. ::Release(transformScope);
  10239. transformScope = NULL;
  10240. leaveScope(errpos);
  10241. #ifdef FAST_FIND_FIELD
  10242. unlockTransformMutex();
  10243. #endif
  10244. IHqlExpression *ret = curTransform->closeExpr();
  10245. curTransform = NULL;
  10246. if (transformSaveStack.ordinality())
  10247. {
  10248. Owned<TransformSaveInfo> saved = &transformSaveStack.popGet();
  10249. transformScope = saved->transformScope.getClear();
  10250. curTransform = saved->curTransform.getClear();
  10251. }
  10252. return ret;
  10253. }
  10254. void HqlGram::beginRecord()
  10255. {
  10256. IHqlExpression *r = createRecord();
  10257. pushSelfScope(r);
  10258. pushRecord(r);
  10259. LinkedHqlExpr locale = queryDefaultLocale();
  10260. if (!locale)
  10261. locale.setown(createConstant(""));
  10262. pushLocale(locale.getClear());
  10263. }
  10264. void HqlGram::addRecordOption(attribute & attr)
  10265. {
  10266. OwnedHqlExpr expr = attr.getExpr();
  10267. if (expr->queryName() == localeAtom)
  10268. {
  10269. popLocale();
  10270. pushLocale(LINK(expr->queryChild(0)));
  10271. }
  10272. else
  10273. activeRecords.tos().addOperand(LINK(expr));
  10274. }
  10275. void HqlGram::checkSizeof(IHqlExpression* expr, attribute& errpos)
  10276. {
  10277. if (!expr || !expr->queryType())
  10278. return;
  10279. type_t tc = expr->queryType()->getTypeCode();
  10280. switch(tc)
  10281. {
  10282. case type_record:
  10283. case type_row:
  10284. {
  10285. //MORE: I'm not at all convinced about this code for type_row.
  10286. bool isDataset = expr->isDataset();
  10287. ForEachChild(idx,expr)
  10288. {
  10289. IHqlExpression *kid = expr->queryChild(idx);
  10290. if (kid->getOperator() == no_ifblock && isDataset)
  10291. reportError(ERR_SIZEOF_WRONGPARAM,errpos,"Can not determine the size of record with IFBLOCK");
  10292. else if (kid->getOperator() == no_field)
  10293. {
  10294. if (kid->isDataset())
  10295. checkSizeof(kid,errpos); // recursion
  10296. else if (kid->queryRecord())
  10297. checkSizeof(kid->queryRecord(),errpos); // recursion
  10298. else
  10299. checkSizeof(kid->queryType(),errpos,isDataset);
  10300. }
  10301. else if (kid->getOperator() == no_record)
  10302. checkSizeof(kid, errpos);
  10303. }
  10304. break;
  10305. }
  10306. default:
  10307. checkSizeof(expr->queryType(),errpos);
  10308. break;
  10309. }
  10310. }
  10311. void HqlGram::checkSizeof(ITypeInfo* type, attribute& errpos, bool isDataset)
  10312. {
  10313. if (type)
  10314. {
  10315. type_t tc = type->getTypeCode();
  10316. switch(tc)
  10317. {
  10318. case type_bitfield:
  10319. if (!isDataset)
  10320. reportError(ERR_SIZEOF_WRONGPARAM,errpos,"Can not determine the size of BITFIELD");
  10321. break;
  10322. case type_set:
  10323. reportError(ERR_SIZEOF_WRONGPARAM,errpos,"Can not determine the size of SET");
  10324. break;
  10325. case type_qstring:
  10326. if (type->getSize() == UNKNOWN_LENGTH)
  10327. reportError(ERR_SIZEOF_WRONGPARAM,errpos,"SIZEOF: QSTRING has unknown size");
  10328. break;
  10329. case type_varstring:
  10330. if (type->getSize() == UNKNOWN_LENGTH)
  10331. reportError(ERR_SIZEOF_WRONGPARAM,errpos,"SIZEOF: VARSTRING has unknown size");
  10332. break;
  10333. case type_string:
  10334. if (type->getSize() == UNKNOWN_LENGTH)
  10335. reportError(ERR_SIZEOF_WRONGPARAM,errpos,"SIZEOF: STRING has unknown size");
  10336. break;
  10337. case type_alien:
  10338. reportError(ERR_SIZEOF_WRONGPARAM,errpos,"SIZEOF: Can not determine the size of alien type ");
  10339. break;
  10340. default:
  10341. break;
  10342. }
  10343. }
  10344. }
  10345. void HqlGram::checkFieldMap(IHqlExpression* map, attribute& errpos)
  10346. {
  10347. HqlExprArray maps;
  10348. map->unwindList(maps, no_comma);
  10349. unsigned mapCount = maps.length();
  10350. // check duplication
  10351. for (unsigned i=0; i<mapCount; i+=2)
  10352. {
  10353. for (unsigned j=i+2;j<mapCount; j+=2)
  10354. if (maps.item(i).queryName()==maps.item(j).queryName())
  10355. reportError(ERR_DSPARM_MAPDUPLICATE, errpos, "Field '%s' is mapped more than once", str(maps.item(i).queryName()));
  10356. }
  10357. // Note: a->b, b->c is allowed. Even the following are allowed:
  10358. // a->b, b->c: switch two fields
  10359. // a->c, b->c: merge two fields
  10360. }
  10361. void HqlGram::setTemplateAttribute()
  10362. {
  10363. #ifndef NEW_VIRTUAL_DATASETS
  10364. ActiveScopeInfo & activeScope = defineScopes.tos();
  10365. if (!activeScope.templateAttrContext)
  10366. activeScope.templateAttrContext.setown(new CHqlContextScope());
  10367. #endif
  10368. }
  10369. IHqlExpression * reparseTemplateFunction(IHqlExpression * funcdef, IHqlScope *scope, HqlLookupContext & ctx, bool hasFieldMap)
  10370. {
  10371. // get func body text
  10372. IHqlExpression * symbol = queryAnnotation(funcdef, annotate_symbol);
  10373. assertex(symbol);
  10374. IHqlNamedAnnotation * nameExtra = static_cast<IHqlNamedAnnotation *>(symbol->queryAnnotation());
  10375. assertex(nameExtra);
  10376. Owned<IFileContents> contents = nameExtra->getBodyContents();
  10377. StringBuffer text;
  10378. text.append("=>").append(contents->length(), contents->getText());
  10379. //Could use a merge string implementation of IFileContents instead of expanding...
  10380. Owned<IFileContents> parseContents = createFileContentsFromText(text.str(), contents->querySourcePath());
  10381. HqlGram parser(scope, scope, parseContents, ctx, NULL, hasFieldMap, true);
  10382. unsigned startLine = funcdef->getStartLine();
  10383. //MORE: I need a better calculation of the column/line that the body begins at
  10384. //e.g. if multiple lines of parameters etc.
  10385. //I may need to add annotations to the funcdef to save the body column and the body line
  10386. parser.getLexer()->set_yyLineNo(startLine);
  10387. parser.getLexer()->set_yyColumn(1); // need to take off 2 for => that has been added.
  10388. //MORE: May also need to setup current_type
  10389. return parser.yyParse(true, false);
  10390. }
  10391. //===============================================================================================
  10392. PseudoPatternScope::PseudoPatternScope(IHqlExpression * _patternList) : CHqlScope(no_privatescope, NULL, NULL)
  10393. {
  10394. patternList = _patternList; // Do not link!
  10395. }
  10396. IHqlExpression * PseudoPatternScope::lookupSymbol(IIdAtom * name, unsigned lookupFlags, HqlLookupContext & ctx)
  10397. {
  10398. const char * text = str(name);
  10399. if (*text == '$')
  10400. {
  10401. unsigned index = atoi(text+1);
  10402. IHqlExpression * match = patternList->queryChild(index-1);
  10403. if (match)
  10404. {
  10405. Owned<ITypeInfo> retType;
  10406. ITypeInfo * type = match->queryType()->queryChildType();
  10407. IHqlExpression * indexExpr = createConstant((__int64)index-1);
  10408. if (type)
  10409. return createRow(no_matchattr, LINK(queryOriginalRecord(type)), indexExpr);
  10410. return createValue(no_matchattr, makeStringType(UNKNOWN_LENGTH, NULL), indexExpr);
  10411. }
  10412. }
  10413. return NULL;
  10414. }
  10415. //---------------------------------------------------------------------------------------------------------------------
  10416. extern HQL_API IHqlExpression * parseQuery(IHqlScope *scope, IFileContents * contents, HqlLookupContext & ctx, IXmlScope *xmlScope, IProperties * macroParams, bool loadImplicit)
  10417. {
  10418. assertex(scope);
  10419. try
  10420. {
  10421. ctx.noteBeginQuery(scope, contents);
  10422. HqlGram parser(scope, scope, contents, ctx, xmlScope, false, loadImplicit);
  10423. parser.setQuery(true);
  10424. parser.getLexer()->set_yyLineNo(1);
  10425. parser.getLexer()->set_yyColumn(1);
  10426. parser.getLexer()->setMacroParams(macroParams);
  10427. OwnedHqlExpr ret = parser.yyParse(false, true);
  10428. ctx.noteEndQuery();
  10429. return parser.clearFieldMap(ret.getClear());
  10430. }
  10431. catch (IException *E)
  10432. {
  10433. if (ctx.errs)
  10434. {
  10435. ISourcePath * sourcePath = contents->querySourcePath();
  10436. if (E->errorCode()==0)
  10437. {
  10438. StringBuffer s;
  10439. ctx.errs->reportError(ERR_INTERNALEXCEPTION, E->errorMessage(s).str(), str(sourcePath), 0, 0, 1);
  10440. }
  10441. else
  10442. {
  10443. StringBuffer s("Internal error: ");
  10444. E->errorMessage(s);
  10445. ctx.errs->reportError(ERR_INTERNALEXCEPTION, s.str(), str(sourcePath), 0, 0, 1);
  10446. }
  10447. }
  10448. E->Release();
  10449. }
  10450. return NULL;
  10451. }
  10452. extern HQL_API void parseModule(IHqlScope *scope, IFileContents * contents, HqlLookupContext & ctx, IXmlScope *xmlScope, bool loadImplicit)
  10453. {
  10454. assertex(scope);
  10455. try
  10456. {
  10457. HqlLookupContext moduleCtx(ctx);
  10458. moduleCtx.noteBeginModule(scope, contents);
  10459. HqlGram parser(scope, scope, contents, moduleCtx, xmlScope, false, loadImplicit);
  10460. parser.getLexer()->set_yyLineNo(1);
  10461. parser.getLexer()->set_yyColumn(1);
  10462. OwnedHqlExpr ret = parser.yyParse(false, true);
  10463. moduleCtx.noteEndModule();
  10464. }
  10465. catch (IException *E)
  10466. {
  10467. if (ctx.errs)
  10468. {
  10469. ISourcePath * sourcePath = contents->querySourcePath();
  10470. if (E->errorCode()==0)
  10471. {
  10472. StringBuffer s;
  10473. ctx.errs->reportError(ERR_INTERNALEXCEPTION, E->errorMessage(s).str(), str(sourcePath), 0, 0, 1);
  10474. }
  10475. else
  10476. {
  10477. StringBuffer s("Internal error: ");
  10478. E->errorMessage(s);
  10479. ctx.errs->reportError(ERR_INTERNALEXCEPTION, s.str(), str(sourcePath), 0, 0, 1);
  10480. }
  10481. }
  10482. E->Release();
  10483. }
  10484. }
  10485. extern HQL_API IHqlExpression * parseQuery(const char * text, IErrorReceiver * errs)
  10486. {
  10487. Owned<IHqlScope> scope = createScope();
  10488. HqlDummyLookupContext ctx(errs);
  10489. Owned<IFileContents> contents = createFileContentsFromText(text, NULL);
  10490. return parseQuery(scope, contents, ctx, NULL, NULL, true);
  10491. }
  10492. bool parseForwardModuleMember(HqlGramCtx & _parent, IHqlScope *scope, IHqlExpression * forwardSymbol, HqlLookupContext & ctx)
  10493. {
  10494. //The attribute will be added to the current scope as a side-effect of parsing the attribute.
  10495. IFileContents * contents = forwardSymbol->queryDefinitionText();
  10496. HqlGram parser(_parent, scope, contents, NULL, false);
  10497. parser.setExpectedAttribute(forwardSymbol->queryId());
  10498. parser.setAssociateWarnings(true);
  10499. parser.getLexer()->set_yyLineNo(forwardSymbol->getStartLine());
  10500. parser.getLexer()->set_yyColumn(forwardSymbol->getStartColumn());
  10501. unsigned prevErrors = ctx.errs->errCount();
  10502. ::Release(parser.yyParse(false, false));
  10503. return (prevErrors == ctx.errs->errCount());
  10504. }
  10505. void parseAttribute(IHqlScope * scope, IFileContents * contents, HqlLookupContext & ctx, IIdAtom * name)
  10506. {
  10507. HqlLookupContext attrCtx(ctx);
  10508. attrCtx.noteBeginAttribute(scope, contents, name);
  10509. //The attribute will be added to the current scope as a side-effect of parsing the attribute.
  10510. const char * moduleName = scope->queryFullName();
  10511. Owned<IHqlScope> globalScope = getResolveDottedScope(moduleName, LSFpublic, ctx);
  10512. HqlGram parser(globalScope, scope, contents, attrCtx, NULL, false, true);
  10513. parser.setExpectedAttribute(name);
  10514. parser.setAssociateWarnings(true);
  10515. parser.getLexer()->set_yyLineNo(1);
  10516. parser.getLexer()->set_yyColumn(1);
  10517. ::Release(parser.yyParse(false, false));
  10518. attrCtx.noteEndAttribute();
  10519. }
  10520. void testHqlInternals()
  10521. {
  10522. printf("Sizes: const(%u) expr(%u) select(%u) dataset(%u) annotation(%u) prop(%u)\n",
  10523. (unsigned)sizeof(CHqlConstant),
  10524. (unsigned)sizeof(CHqlExpressionWithType),
  10525. (unsigned)sizeof(CHqlSelectExpression),
  10526. (unsigned)sizeof(CHqlDataset),
  10527. (unsigned)sizeof(CHqlAnnotation),
  10528. (unsigned)sizeof(CHqlDynamicProperty)
  10529. );
  10530. //
  10531. // test getOpString()
  10532. int error = 0,i;
  10533. node_operator op;
  10534. printf("Testing getOpString()...\n");
  10535. for (op = no_none; op < no_last_op; op = (node_operator)(op+1))
  10536. {
  10537. try {
  10538. getOpString(op);
  10539. } catch (...) {
  10540. error++;
  10541. printf(" Error: getOpString(%d) is not defined\n",op);
  10542. }
  10543. const char * text = EclIR::getOperatorIRText(op);
  10544. if (!text || streq(text, "<unknown>"))
  10545. {
  10546. error++;
  10547. printf(" Error: getOperatorIRText(%d) is not defined\n",op);
  10548. }
  10549. }
  10550. for (type_t tc = (type_t)0; tc < type_max; tc = (type_t)(tc+1))
  10551. {
  10552. const char * text = EclIR::getTypeIRText(tc);
  10553. if (!text || streq(text, "<unknown>"))
  10554. {
  10555. error++;
  10556. printf(" Error: getTypeIRText(%d) is not defined\n",tc);
  10557. }
  10558. }
  10559. //
  10560. // test HqlGram::yyError
  10561. printf("Testing HqlGram::yyError() ...\n");
  10562. for (i= 258; i<YY_LAST_TOKEN;i++)
  10563. {
  10564. try {
  10565. StringBuffer temp;
  10566. getTokenText(temp, i);
  10567. } catch (...) {
  10568. error++;
  10569. printf(" Error: getTokenText() does not handle expected: %d\n",i);
  10570. }
  10571. }
  10572. //
  10573. // report test result
  10574. if (error)
  10575. printf("%d error%s found!\n", error, error<=1?"":"s");
  10576. else
  10577. printf("No errors\n");
  10578. }
  10579. IHqlExpression *HqlGram::yyParse(bool _parsingTemplateAttribute, bool catchAbort)
  10580. {
  10581. parsingTemplateAttribute = _parsingTemplateAttribute;
  10582. try
  10583. {
  10584. return doParse();
  10585. }
  10586. catch (IException * e)
  10587. {
  10588. if (e->errorCode() != ERR_ABORT_PARSING)
  10589. {
  10590. StringBuffer msg;
  10591. e->errorMessage(msg);
  10592. reportError(e->errorCode(), msg.str(), 0, 0, 0);
  10593. }
  10594. else if (!catchAbort)
  10595. throw;
  10596. e->Release();
  10597. return NULL;
  10598. }
  10599. catch(int)
  10600. {
  10601. return NULL;
  10602. }
  10603. catch (RELEASE_CATCH_ALL)
  10604. {
  10605. PrintLog("Unexpected exception caught");
  10606. return NULL;
  10607. }
  10608. }
  10609. extern int eclyyparse (HqlGram* parser);
  10610. IHqlExpression *HqlGram::doParse()
  10611. {
  10612. if (expectedAttribute)
  10613. {
  10614. if (queryExpression(containerScope)->getOperator() == no_forwardscope)
  10615. enterScope(containerScope, true);
  10616. if (legacyImportSemantics)
  10617. enterScope(globalScope, true);
  10618. //If expecting a particular attribute, add symbols to a private scope, and then copy result across
  10619. enterScope(parseScope, true);
  10620. }
  10621. else
  10622. {
  10623. //Either a query that is not part of the source tree, or an entire module (plugins/legacy support), parse direct into the scope
  10624. enterScope(containerScope, true);
  10625. }
  10626. minimumScopeIndex = defineScopes.ordinality();
  10627. unsigned prevErrors = errorHandler ? errorHandler->errCount() : 0;
  10628. if (eclyyparse(this) != 0)
  10629. return NULL;
  10630. unsigned nowErrors = errorHandler ? errorHandler->errCount() : 0;
  10631. lookupCtx.noteFinishedParse(defineScopes.tos().privateScope);
  10632. if (!parseConstantText)
  10633. lookupCtx.noteFinishedParse(parseScope);
  10634. if (prevErrors != nowErrors)
  10635. return NULL;
  10636. if (parsingTemplateAttribute)
  10637. {
  10638. if (parseResults.ordinality() == 0)
  10639. return NULL;
  10640. if (parseResults.ordinality() != 1)
  10641. reportError(ERR_EXPORT_OR_SHARE, "Expected a single result", 1, 1, 1);
  10642. return &parseResults.popGet();
  10643. }
  10644. if (expectedAttribute)
  10645. {
  10646. //If we are expecting an attribute, then we either have a list of side-effects which are returned as a compound object
  10647. //or we have a field defined in the parseScope which needs cloning into the container scope
  10648. OwnedHqlExpr resolved = parseScope->lookupSymbol(expectedAttribute, LSFsharedOK, lookupCtx);
  10649. //Cover an ugly case where a module with the same name as the attribute being defined has been imported.
  10650. //This should really have a isImport flag like export/shared to avoid false positives.
  10651. if (resolved && parseResults.ordinality())
  10652. {
  10653. if (resolved->queryScope() && isImport(resolved))
  10654. resolved.clear();
  10655. }
  10656. if (resolved)
  10657. {
  10658. if (!parseResults.empty())
  10659. {
  10660. ECLlocation location(&parseResults.item(0));
  10661. reportError(ERR_RESULT_IGNORED, location, "Definition contains actions after the EXPORT has been defined");
  10662. }
  10663. containerScope->defineSymbol(resolved.getClear());
  10664. return NULL;
  10665. }
  10666. }
  10667. if (parseResults.empty())
  10668. {
  10669. //if (expectedAttribute) .....
  10670. //An error about a missing definition will be reported by the caller so don't duplicate
  10671. return NULL;
  10672. }
  10673. //Check the results are ok - i.e. if a module, then only a single attribute
  10674. unsigned lastPos = parseResults.ordinality() - 1;
  10675. bool hadValue = false;
  10676. ForEachItemIn(i, parseResults)
  10677. {
  10678. IHqlExpression & cur = parseResults.item(i);
  10679. ECLlocation location(&cur);
  10680. if (cur.getOperator() == no_setmeta)
  10681. continue;
  10682. if (i == lastPos)
  10683. {
  10684. if (cur.isScope() && hadValue)
  10685. reportError(ERR_EXPORT_OR_SHARE, location, "A scope result cannot be combined with any other results");
  10686. }
  10687. else
  10688. {
  10689. hadValue = true;
  10690. //All but the last result should be actions.
  10691. if (!cur.isAction())
  10692. {
  10693. node_operator actionOp = no_none;
  10694. if (cur.isDataset())
  10695. actionOp = no_output;
  10696. else if (cur.isDatarow())
  10697. actionOp = no_output;
  10698. else if (cur.isList() || cur.queryType()->isScalar())
  10699. actionOp = no_outputscalar;
  10700. if (actionOp == no_none)
  10701. {
  10702. reportError(ERR_EXPORT_OR_SHARE, location, "Object cannot be used as an action");
  10703. }
  10704. else
  10705. parseResults.replace(*createValue(actionOp, makeVoidType(), LINK(&cur)), i);
  10706. }
  10707. }
  10708. }
  10709. OwnedHqlExpr actions = createCompound(parseResults);
  10710. actions.setown(attachPendingWarnings(actions.getClear()));
  10711. if (!expectedAttribute)
  10712. return actions.getClear();
  10713. IIdAtom * moduleName = createIdAtom(globalScope->queryFullName());
  10714. Owned<IFileContents> contents = LINK(lexObject->query_FileContents());
  10715. unsigned lengthText = 0;
  10716. containerScope->defineSymbol(expectedAttribute, moduleName, actions.getClear(), true, false, 0, contents, 1, 1, 0, 0, lengthText);
  10717. return NULL;
  10718. }