hqlttcpp.ipp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307
  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. #ifndef __HQLTTCPP_IPP_
  14. #define __HQLTTCPP_IPP_
  15. #include "hqlcpp.hpp"
  16. #include "hqlcpp.ipp"
  17. #include "hqlhtcpp.ipp"
  18. #include "hqltrans.ipp"
  19. //---------------------------------------------------------------------------
  20. class NewThorStoredReplacer : public QuickHqlTransformer
  21. {
  22. public:
  23. NewThorStoredReplacer(HqlCppTranslator & _translator, IWorkUnit * _wu, ICodegenContextCallback * _logger);
  24. virtual void doAnalyse(IHqlExpression * expr);
  25. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  26. bool needToTransform();
  27. protected:
  28. HqlCppTranslator & translator;
  29. IWorkUnit * wu;
  30. ICodegenContextCallback * ctxCallback;
  31. HqlExprArray commands;
  32. HqlExprArray storedNames;
  33. HqlExprArray storedValues;
  34. HqlExprCopyArray activeReplacements;
  35. BoolArray storedIsConstant;
  36. bool foldStored;
  37. bool seenMeta;
  38. };
  39. //---------------------------------------------------------------------------
  40. enum YesNoOption { OptionUnknown, OptionNo, OptionMaybe, OptionSome, OptionYes }; //NB: last 3 IN ascending order of definiteness.
  41. class HqlThorBoundaryInfo : public NewTransformInfo
  42. {
  43. public:
  44. HqlThorBoundaryInfo(IHqlExpression * _original) : NewTransformInfo(_original) { normalize = OptionUnknown; }
  45. public:
  46. YesNoOption normalize;
  47. };
  48. class HqlThorBoundaryTransformer : public NewHqlTransformer
  49. {
  50. public:
  51. HqlThorBoundaryTransformer(IConstWorkUnit * wu, bool _isRoxie, unsigned _maxRootMaybes, bool _resourceConditionalActions, bool _resourceSequential);
  52. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  53. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(HqlThorBoundaryInfo, expr); }
  54. inline HqlThorBoundaryInfo * queryBodyExtra(IHqlExpression * expr) { return static_cast<HqlThorBoundaryInfo *>(queryTransformExtra(expr->queryBody())); }
  55. void transformRoot(const HqlExprArray & in, HqlExprArray & out);
  56. protected:
  57. void transformCompound(HqlExprArray & result, node_operator compoundOp, const HqlExprArray & args, unsigned MaxMaybes);
  58. protected:
  59. YesNoOption calcNormalizeThor(IHqlExpression * expr);
  60. YesNoOption normalizeThor(IHqlExpression * expr);
  61. protected:
  62. IConstWorkUnit * wu;
  63. unsigned maxRootMaybes;
  64. bool isRoxie;
  65. bool resourceConditionalActions;
  66. bool resourceSequential;
  67. };
  68. //---------------------------------------------------------------------------
  69. class ThorScalarInfo : public HoistingTransformInfo
  70. {
  71. public:
  72. ThorScalarInfo(IHqlExpression * _original) : HoistingTransformInfo(_original) { }
  73. public:
  74. HqlExprAttr transformed[2];
  75. HqlExprAttr transformedSelector[2];
  76. };
  77. class ThorScalarTransformer : public HoistingHqlTransformer
  78. {
  79. public:
  80. ThorScalarTransformer(const HqlCppOptions & _options);
  81. virtual void doAnalyseExpr(IHqlExpression * expr);
  82. IHqlExpression * createTransformed(IHqlExpression * expr);
  83. inline bool needToTransform() { return seenCandidate || containsUnknownIndependentContents; }
  84. protected:
  85. void createHoisted(IHqlExpression * expr, SharedHqlExpr & setResultStmt, SharedHqlExpr & getResult, bool addWrapper);
  86. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(ThorScalarInfo, expr); }
  87. virtual IHqlExpression * queryAlreadyTransformed(IHqlExpression * expr);
  88. virtual IHqlExpression * queryAlreadyTransformedSelector(IHqlExpression * expr);
  89. virtual void setTransformed(IHqlExpression * expr, IHqlExpression * transformed);
  90. virtual void setTransformedSelector(IHqlExpression * expr, IHqlExpression * transformed);
  91. virtual IHqlExpression * doTransformIndependent(IHqlExpression * expr)
  92. {
  93. ThorScalarTransformer nested(options);
  94. nested.setParent(this);
  95. nested.analyse(expr, 0);
  96. if (nested.needToTransform())
  97. return nested.transformRoot(expr);
  98. return LINK(expr);
  99. }
  100. //This is unusual that it is queryExtra() instead of queryBodyExtra() - since it is used to store the transformed
  101. //values, not any extra information.
  102. inline ThorScalarInfo * queryExtra(IHqlExpression * expr) { return static_cast<ThorScalarInfo *>(queryTransformExtra(expr)); }
  103. inline bool isConditional() { return isConditionalDepth != 0; }
  104. protected:
  105. const HqlCppOptions & options;
  106. unsigned isConditionalDepth;
  107. bool seenCandidate;
  108. };
  109. //---------------------------------------------------------------------------
  110. class SequenceNumberInfo : public NewTransformInfo
  111. {
  112. public:
  113. SequenceNumberInfo(IHqlExpression * expr) : NewTransformInfo(expr), getsSequence(false) {}
  114. void setGetsSequence() { getsSequence = true; }
  115. virtual IHqlExpression * queryTransformed() { if(getsSequence) return NULL; else return NewTransformInfo::queryTransformed(); } //must transform again if expression takes sequence number, as require different sequence number each time
  116. private:
  117. bool getsSequence;
  118. };
  119. class SequenceNumberAllocator : public NewHqlTransformer
  120. {
  121. public:
  122. SequenceNumberAllocator(HqlCppTranslator & _translator);
  123. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  124. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(SequenceNumberInfo, expr); }
  125. //queryExtra() instead of queryBodyExtra() because it is used to modify how queryTransform() acts.
  126. //NOTE: I'm not sure this really works e.g., if the transformed expression is a sequence list.
  127. SequenceNumberInfo * queryExtra(IHqlExpression * expr) { return dynamic_cast<SequenceNumberInfo *>(queryTransformExtra(expr)); }
  128. unsigned getMaxSequence() { return sequence; }
  129. protected:
  130. void nextSequence(HqlExprArray & args, IHqlExpression * name, IAtom * overwriteAction, IHqlExpression * value, bool needAttr, bool * duplicate);
  131. virtual IHqlExpression * doTransformRootExpr(IHqlExpression * expr);
  132. IHqlExpression * attachSequenceNumber(IHqlExpression * expr);
  133. protected:
  134. HqlCppTranslator & translator; // should really be an error handler - could do with refactoring.
  135. unsigned applyDepth;
  136. unsigned sequence;
  137. MapOwnedHqlToOwnedHql namedMap;
  138. };
  139. //---------------------------------------------------------------------------
  140. class ThorHqlTransformer : public NewHqlTransformer
  141. {
  142. public:
  143. ThorHqlTransformer(HqlCppTranslator & _translator, ClusterType _targetClusterType, IConstWorkUnit * _wu, unsigned & _implicitFunctionId);
  144. protected:
  145. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  146. protected:
  147. IHqlExpression * getMergeTransform(IHqlExpression * dataset, IHqlExpression * transform);
  148. IHqlExpression * normalizeChooseN(IHqlExpression * expr);
  149. IHqlExpression * normalizeCoGroup(IHqlExpression * expr);
  150. IHqlExpression * normalizeDedup(IHqlExpression * expr);
  151. // IHqlExpression * normalizeIndexBuild(IHqlExpression * expr);
  152. IHqlExpression * normalizeGroup(IHqlExpression * expr);
  153. IHqlExpression * normalizeJoinAndGroup(IHqlExpression * expr);
  154. IHqlExpression * normalizeJoinOrDenormalize(IHqlExpression * expr);
  155. IHqlExpression * normalizeTableToAggregate(IHqlExpression * expr, bool canOptimizeCasts);
  156. IHqlExpression * normalizeTableGrouping(IHqlExpression * expr);
  157. IHqlExpression * normalizeMergeAggregate(IHqlExpression * expr);
  158. IHqlExpression * normalizePrefetchAggregate(IHqlExpression * expr);
  159. IHqlExpression * normalizeRollup(IHqlExpression * expr);
  160. IHqlExpression * normalizeScalarAggregate(IHqlExpression * expr);
  161. IHqlExpression * normalizeSelect(IHqlExpression * expr);
  162. IHqlExpression * normalizeSubSort(IHqlExpression * expr);
  163. IHqlExpression * normalizeSort(IHqlExpression * expr);
  164. IHqlExpression * normalizeSortSteppedIndex(IHqlExpression * expr, IAtom * attrName);
  165. IHqlExpression * normalizeTempTable(IHqlExpression * expr);
  166. IHqlExpression * skipGroupsWithinGroup(IHqlExpression * expr, bool isLocal);
  167. IHqlExpression * skipOverGroups(IHqlExpression * dataset, bool isLocal);
  168. bool isLightweightJoinCandidate(IHqlExpression * expr, bool isLocal, bool isLimitedSubstringJoin);
  169. protected:
  170. typedef NewHqlTransformer PARENT;
  171. HqlCppTranslator & translator;
  172. const HqlCppOptions & options;
  173. ClusterType targetClusterType;
  174. unsigned topNlimit;
  175. unsigned & implicitFunctionId;
  176. bool groupAllDistribute;
  177. };
  178. //---------------------------------------------------------------------------
  179. class SetResultToExtractTransformer : public NewHqlTransformer
  180. {
  181. public:
  182. SetResultToExtractTransformer();
  183. protected:
  184. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  185. protected:
  186. typedef NewHqlTransformer PARENT;
  187. };
  188. //---------------------------------------------------------------------------
  189. class CompoundSourceInfo : public NewTransformInfo
  190. {
  191. public:
  192. CompoundSourceInfo(IHqlExpression * _original);
  193. bool canMergeLimit(IHqlExpression * expr, ClusterType targetClusterType) const;
  194. void ensureCompound();
  195. bool isAggregate() const;
  196. inline bool isShared() { return splitCount > 1; }
  197. bool inherit(const CompoundSourceInfo & other, node_operator newSourceOp = no_none);
  198. inline bool isNoteUsageFirst()
  199. {
  200. noteUsage();
  201. return (splitCount == 1);
  202. }
  203. inline void noteUsage() { if (splitCount < 10) splitCount++; }
  204. inline bool isBinary() const { return mode != no_csv && mode != no_xml && mode != no_json; }
  205. inline bool hasAnyLimit() const { return isLimited || hasChoosen; }
  206. void reset();
  207. public:
  208. HqlExprAttr uid;
  209. node_operator sourceOp;
  210. node_operator mode;
  211. byte splitCount;
  212. bool forceCompound:1;
  213. bool isBoundary:1;
  214. bool isCloned:1;
  215. bool isLimited:1;
  216. bool hasChoosen:1;
  217. bool hasSkipLimit:1;
  218. bool isPreloaded:1;
  219. bool isFiltered:1;
  220. bool isPostFiltered:1;
  221. bool isCreateRowLimited:1;
  222. bool hasOnFail:1;
  223. };
  224. enum
  225. {
  226. CSFpreload = 0x0001,
  227. CSFindex = 0x0002,
  228. CSFignoreShared = 0x0010,
  229. CSFnewdisk = 0x0020,
  230. CSFnewindex = 0x0040,
  231. CSFnewchild = 0x0080,
  232. CSFnewinline = 0x0100,
  233. CSFcompoundSpill= 0x0200,
  234. };
  235. //MORE: Could remove dependency on insideCompound if it was ok to have compound operators scattered through the
  236. // contents of a compound item. Probably would cause few problems, and would make life simpler
  237. class CompoundSourceTransformer : public NewHqlTransformer
  238. {
  239. public:
  240. CompoundSourceTransformer(HqlCppTranslator & _translator, unsigned _flags);
  241. IHqlExpression * process(IHqlExpression * expr);
  242. virtual void analyseExpr(IHqlExpression * expr);
  243. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  244. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  245. protected:
  246. bool childrenAreShared(IHqlExpression * expr);
  247. bool createCompoundSource(IHqlExpression * expr);
  248. CompoundSourceInfo * queryBodyExtra(IHqlExpression * expr) { return (CompoundSourceInfo *)queryTransformExtra(expr->queryBody()); }
  249. void analyseGatherInfo(IHqlExpression * expr);
  250. void analyseMarkBoundaries(IHqlExpression * expr);
  251. bool needToCloneLimit(IHqlExpression * expr, node_operator sourceOp);
  252. protected:
  253. HqlCppTranslator & translator;
  254. ClusterType targetClusterType;
  255. unsigned flags;
  256. bool insideCompound;
  257. bool candidate;
  258. };
  259. //---------------------------------------------------------------------------
  260. class CompoundActivityTransformer : public NewHqlTransformer
  261. {
  262. public:
  263. CompoundActivityTransformer(ClusterType _targetClusterType);
  264. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  265. protected:
  266. ClusterType targetClusterType;
  267. };
  268. //---------------------------------------------------------------------------
  269. class OptimizeActivityInfo : public NewTransformInfo
  270. {
  271. public:
  272. OptimizeActivityInfo(IHqlExpression * _original) : NewTransformInfo(_original) { setNumUses(0); }
  273. inline bool isShared() { return getNumUses() > 1; }
  274. inline void noteUsed() { setNumUses(getNumUses()+1); }
  275. inline void inherit(const OptimizeActivityInfo * other)
  276. {
  277. setNumUses(getNumUses() + other->getNumUses());
  278. }
  279. private:
  280. inline byte getNumUses() const { return spareByte1; }
  281. inline void setNumUses(unsigned value) { spareByte1 = value < 100 ? value : 100; }
  282. using NewTransformInfo::spareByte1; // used to hold a numUses()
  283. };
  284. //Various activity optimizations which can be done if nodes aren't shared
  285. //sort(ds,x)[n] -> topn(ds,x,n)[n]
  286. //count(x) > n -> count(choosen(x,n+1)) > n
  287. class OptimizeActivityTransformer : public NewHqlTransformer
  288. {
  289. public:
  290. OptimizeActivityTransformer(unsigned _wfid, bool _optimizeCountCompare, bool _optimizeNonEmpty);
  291. virtual void analyseExpr(IHqlExpression * expr);
  292. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  293. protected:
  294. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(OptimizeActivityInfo, expr); }
  295. IHqlExpression * doCreateTransformed(IHqlExpression * expr);
  296. IHqlExpression * insertChoosen(IHqlExpression * lhs, IHqlExpression * limit, __int64 limitDelta);
  297. IHqlExpression * optimizeCompare(IHqlExpression * lhs, IHqlExpression * rhs, node_operator op);
  298. OptimizeActivityInfo * queryBodyExtra(IHqlExpression * expr) { return (OptimizeActivityInfo *)queryTransformExtra(expr->queryBody()); }
  299. inline bool isShared(IHqlExpression * expr) { return queryBodyExtra(expr)->isShared(); }
  300. protected:
  301. unsigned wfid;
  302. bool optimizeCountCompare;
  303. bool optimizeNonEmpty;
  304. };
  305. //---------------------------------------------------------------------------
  306. class WorkflowTransformInfo : public NewTransformInfo
  307. {
  308. public:
  309. WorkflowTransformInfo(IHqlExpression * expr) : NewTransformInfo(expr) { wfid = 0; lastWfid = 0; manyWorkflow = false; firstUseIsConditional = false; }
  310. UnsignedArray const & queryDependencies() const { return dependencies; }
  311. void addDependency(unsigned dep)
  312. {
  313. if (dependencies.find(dep) == NotFound)
  314. dependencies.append(dep);
  315. }
  316. inline bool isCommonUpCandidate() { return manyWorkflow && !firstUseIsConditional; }
  317. inline bool noteWorkflow(unsigned wfid, bool isConditional)
  318. {
  319. if (lastWfid)
  320. {
  321. if (wfid != lastWfid)
  322. {
  323. manyWorkflow = true;
  324. lastWfid = wfid;
  325. }
  326. return true;
  327. }
  328. lastWfid = wfid;
  329. firstUseIsConditional = isConditional;
  330. return false;
  331. }
  332. private:
  333. UnsignedArray dependencies;
  334. unsigned short wfid;
  335. unsigned short lastWfid; // used during analysis
  336. bool firstUseIsConditional;
  337. bool manyWorkflow;
  338. };
  339. class ContingencyData
  340. {
  341. public:
  342. ContingencyData() : success(0), failure(0), recovery(0), retries(0), contingencyFor(0) {}
  343. unsigned success;
  344. unsigned failure;
  345. unsigned recovery;
  346. unsigned retries;
  347. unsigned contingencyFor;
  348. };
  349. class ScheduleData
  350. {
  351. public:
  352. ScheduleData() : independent(false), now(true), priority(50), counting(false), count(0) {}
  353. bool independent;
  354. bool now;
  355. StringBuffer eventName;
  356. StringBuffer eventText;
  357. int priority;
  358. bool counting;
  359. unsigned count;
  360. };
  361. class WorkflowTransformer : public NewHqlTransformer
  362. {
  363. public:
  364. WorkflowTransformer(IWorkUnit * _wu, HqlCppTranslator & _translator);
  365. void analyseAll(const HqlExprArray & in);
  366. void transformRoot(const HqlExprArray & in, WorkflowArray & out);
  367. protected:
  368. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(WorkflowTransformInfo, expr); }
  369. IWorkflowItem * addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, IHqlExpression * cluster, const char * label)
  370. {
  371. ContingencyData conts;
  372. return addWorkflowToWorkunit(wfid, type, mode, dependencies, conts, cluster, label);
  373. }
  374. IWorkflowItem * addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, ContingencyData const & conts, IHqlExpression * cluster, const char * label);
  375. IWorkflowItem * addWorkflowContingencyToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, IHqlExpression * cluster, unsigned wfidFor, const char * label) { ContingencyData conts; conts.contingencyFor = wfidFor; return addWorkflowToWorkunit(wfid, type, mode, dependencies, conts, cluster, label); }
  376. void setWorkflowPersist(IWorkflowItem * wf, char const * persistName, unsigned persistWfid, int numPersistInstances, bool refresh);
  377. void setWorkflowSchedule(IWorkflowItem * wf, ScheduleData const & sched);
  378. void setWorkflowCritical(IWorkflowItem * wf, char const * criticalName);
  379. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  380. void inheritDependencies(IHqlExpression * expr);
  381. void copyDependencies(WorkflowTransformInfo * source, WorkflowTransformInfo * dest);
  382. void copySetValueDependencies(WorkflowTransformInfo * source, IHqlExpression * expr);
  383. void extractDependentInputs(UnsignedArray & visited, DependenciesUsed & dependencies, const UnsignedArray & wfids);
  384. WorkflowItem * findWorkflowItem(unsigned wfid);
  385. unsigned splitValue(IHqlExpression * value);
  386. IHqlExpression * extractWorkflow(IHqlExpression * untransformed, IHqlExpression * transformed);
  387. IHqlExpression * extractClusterWorkflow(IHqlExpression * expr);
  388. IHqlExpression * extractCommonWorkflow(IHqlExpression * expr, IHqlExpression * transformed);
  389. IHqlExpression * transformInternalCall(IHqlExpression * transformed);
  390. IHqlExpression * transformInternalFunction(IHqlExpression * transformed);
  391. IHqlExpression * createCompoundWorkflow(IHqlExpression * expr);
  392. IHqlExpression * createIfWorkflow(IHqlExpression * expr);
  393. IHqlExpression * createParallelWorkflow(IHqlExpression * expr);
  394. IHqlExpression * createSequentialWorkflow(IHqlExpression * expr);
  395. IHqlExpression * createWaitWorkflow(IHqlExpression * expr);
  396. IHqlExpression * transformRootAction(IHqlExpression * expr);
  397. IHqlExpression * transformSequentialEtc(IHqlExpression * expr);
  398. IWorkflowItem * lookupWorkflowItem(unsigned wfid);
  399. IHqlExpression * createWorkflowAction(unsigned wfid);
  400. unsigned ensureWorkflowAction(IHqlExpression * expr);
  401. void ensureWorkflowAction(UnsignedArray & dependencies, IHqlExpression * expr);
  402. WorkflowItem * createWorkflowItem(IHqlExpression * expr, unsigned wfid, node_operator workflowOp, const char * label);
  403. void percolateScheduledIds();
  404. void percolateScheduledIds(UnsignedArray & visited, const UnsignedArray & dependencies, unsigned rootWfid);
  405. void cacheWorkflowDependencies(unsigned wfid, UnsignedArray & extra);
  406. inline bool hasDependencies(IHqlExpression * expr) { return queryDirectDependencies(expr).ordinality() != 0; }
  407. bool hasStoredDependencies(IHqlExpression * expr);
  408. UnsignedArray const & queryDependencies(unsigned wfid);
  409. UnsignedArray const & queryDirectDependencies(IHqlExpression * expr); // don't include children.
  410. void gatherIndirectDependencies(UnsignedArray & match, IHqlExpression * expr);
  411. inline WorkflowTransformInfo * queryBodyExtra(IHqlExpression * expr) { return static_cast<WorkflowTransformInfo *>(queryTransformExtra(expr->queryBody())); }
  412. inline unsigned markDependencies() { return cumulativeDependencies.ordinality(); }
  413. inline bool restoreDependencies(unsigned mark)
  414. {
  415. bool anyAdded = (mark == cumulativeDependencies.ordinality());
  416. cumulativeDependencies.trunc(mark);
  417. return anyAdded;
  418. }
  419. bool haveSameDependencies(IHqlExpression * expr1, IHqlExpression * expr2);
  420. bool includesNewDependencies(IHqlExpression * prev, IHqlExpression * next);
  421. bool hasNonTrivialDependencies(IHqlExpression * expr);
  422. void transformSequential(HqlExprArray & transformed);
  423. void analyseExpr(IHqlExpression * expr);
  424. void addWorkflowItem(WorkflowItem & item);
  425. protected:
  426. IWorkUnit * wu;
  427. HqlCppTranslator & translator;
  428. WorkflowArray workflow;
  429. WorkflowArray functions;
  430. unsigned wfidCount;
  431. HqlExprArray alreadyProcessed;
  432. HqlExprArray alreadyProcessedExpr;
  433. HqlExprArray alreadyProcessedUntransformed;
  434. HqlExprCopyArray activeLocations;
  435. unsigned trivialStoredWfid;
  436. unsigned onceWfid;
  437. unsigned nextInternalFunctionId;
  438. HqlExprArray trivialStoredExprs;
  439. HqlExprArray onceExprs;
  440. bool combineAllStored;
  441. bool combineTrivialStored;
  442. bool isRootAction;
  443. bool isRoxie;
  444. bool expandPersistInputDependencies;
  445. int multiplePersistInstances;
  446. UnsignedArray cumulativeDependencies;
  447. UnsignedArray emptyDependencies;
  448. UnsignedArray storedWfids;
  449. OwnedHqlExpr rootCluster; // currently unset, but if need to
  450. //used while analysing..
  451. unsigned activeWfid;
  452. bool isConditional;
  453. bool insideStored;
  454. };
  455. //------------------------------------------------------------------------
  456. class ExplicitGlobalTransformer : public HoistingHqlTransformer
  457. {
  458. public:
  459. ExplicitGlobalTransformer(IWorkUnit * _wu, HqlCppTranslator & _translator);
  460. inline bool needToTransform() const { return seenGlobalScope || containsUnknownIndependentContents; }
  461. protected:
  462. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  463. virtual void doAnalyseExpr(IHqlExpression * expr);
  464. virtual IHqlExpression * doTransformIndependent(IHqlExpression * expr)
  465. {
  466. if (containsUnknownIndependentContents || seenLocalGlobalScope)
  467. {
  468. ExplicitGlobalTransformer nested(wu, translator);
  469. nested.setParent(this);
  470. nested.analyse(expr, 0);
  471. if (nested.needToTransform())
  472. return nested.transformRoot(expr);
  473. }
  474. return LINK(expr);
  475. }
  476. private:
  477. IWorkUnit * wu;
  478. HqlCppTranslator & translator;
  479. bool seenGlobalScope;
  480. bool seenLocalGlobalScope;
  481. bool isRoxie;
  482. };
  483. class OptGlobalTransformer : public NewHqlTransformer
  484. {
  485. public:
  486. OptGlobalTransformer();
  487. inline bool needToTransform() const { return seenOptGlobal; }
  488. protected:
  489. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  490. virtual void analyseExpr(IHqlExpression * expr);
  491. private:
  492. bool seenOptGlobal;
  493. };
  494. class ScalarGlobalExtra : public HoistingTransformInfo
  495. {
  496. public:
  497. ScalarGlobalExtra(IHqlExpression * _original) : HoistingTransformInfo(_original)
  498. {
  499. numUses = 0;
  500. alreadyGlobal = false;
  501. createGlobal = false;
  502. visitedAllowHoist = false;
  503. isLocal = true;
  504. }
  505. public:
  506. unsigned numUses;
  507. bool alreadyGlobal; // Is the expression always global anyway
  508. bool createGlobal; // Is it worth attempting to mark this as global
  509. bool isLocal; // Are all references to this expression within new globals()
  510. bool visitedAllowHoist; // Has this expr been visited allowing globals to be marked?
  511. };
  512. //Only does anything to scalar expressions => don't need a mergingTransformer
  513. class ScalarGlobalTransformer : public HoistingHqlTransformer
  514. {
  515. public:
  516. ScalarGlobalTransformer(HqlCppTranslator & _translator);
  517. protected:
  518. virtual void analyseExpr(IHqlExpression * expr);
  519. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  520. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(ScalarGlobalExtra, expr); }
  521. virtual void doAnalyseExpr(IHqlExpression * expr);
  522. bool isComplex(IHqlExpression * expr, bool checkGlobal);
  523. virtual IHqlExpression * doTransformIndependent(IHqlExpression * expr)
  524. {
  525. ScalarGlobalTransformer nested(translator);
  526. nested.setParent(this);
  527. nested.analyse(expr, 0);
  528. return nested.transformRoot(expr);
  529. }
  530. inline ScalarGlobalExtra * queryBodyExtra(IHqlExpression * expr) { return static_cast<ScalarGlobalExtra*>(queryTransformExtra(expr->queryBody())); }
  531. static bool isCandidate(IHqlExpression * expr);
  532. static bool canCreateCandidate(IHqlExpression * expr);
  533. protected:
  534. HqlCppTranslator & translator;
  535. bool isGlobal;
  536. bool isOkToHoist;
  537. };
  538. class ScopeMigrateInfo : public HoistingTransformInfo
  539. {
  540. public:
  541. ScopeMigrateInfo(IHqlExpression * _original) : HoistingTransformInfo(_original) { maxActivityDepth = 0; }//useCount = 0; condUseCount = 0; }
  542. public:
  543. unsigned maxActivityDepth;
  544. // unsigned useCount;
  545. // unsigned condUseCount;
  546. };
  547. class NewScopeMigrateTransformer : public HoistingHqlTransformer
  548. {
  549. public:
  550. NewScopeMigrateTransformer(IWorkUnit * _wu, HqlCppTranslator & _translator);
  551. protected:
  552. virtual void analyseExpr(IHqlExpression * expr);
  553. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  554. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(ScopeMigrateInfo, expr); }
  555. virtual IHqlExpression * doTransformIndependent(IHqlExpression * expr)
  556. {
  557. NewScopeMigrateTransformer nested(wu, translator);
  558. nested.setParent(this);
  559. nested.analyse(expr, 0);
  560. return nested.transformRoot(expr);
  561. }
  562. IHqlExpression * hoist(IHqlExpression * expr, IHqlExpression * hoisted);
  563. IHqlExpression * transformCond(IHqlExpression * expr);
  564. inline ScopeMigrateInfo * queryBodyExtra(IHqlExpression * expr) { return static_cast<ScopeMigrateInfo *>(queryTransformExtra(expr->queryBody())); }
  565. private:
  566. IWorkUnit * wu;
  567. HqlCppTranslator & translator;
  568. bool isRoxie;
  569. bool minimizeWorkunitTemporaries;
  570. unsigned activityDepth;
  571. };
  572. class AutoScopeMigrateInfo : public NewTransformInfo
  573. {
  574. public:
  575. AutoScopeMigrateInfo(IHqlExpression * _original) : NewTransformInfo(_original) { useCount = 0; condUseCount = 0; manyGraphs = false; firstUseIsConditional = false; firstUseIsSequential = false; globalInsideChild = false; lastGraph = 0; }
  576. bool addGraph(unsigned graph);
  577. bool doAutoHoist(IHqlExpression * transformed, bool minimizeWorkunitTemporaries);
  578. public:
  579. unsigned useCount;
  580. unsigned condUseCount;
  581. unsigned lastGraph;
  582. bool manyGraphs;
  583. bool firstUseIsConditional;
  584. bool firstUseIsSequential;
  585. bool globalInsideChild;
  586. };
  587. class AutoScopeMigrateTransformer : public NewHqlTransformer
  588. {
  589. public:
  590. AutoScopeMigrateTransformer(IWorkUnit * _wu, HqlCppTranslator & _translator);
  591. void transformRoot(const HqlExprArray & in, HqlExprArray & out);
  592. bool worthTransforming() const { return hasCandidate; }
  593. protected:
  594. virtual void analyseExpr(IHqlExpression * expr);
  595. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  596. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(AutoScopeMigrateInfo, expr); }
  597. IHqlExpression * hoist(IHqlExpression * expr, IHqlExpression * hoisted);
  598. IHqlExpression * transformCond(IHqlExpression * expr);
  599. void doAnalyseExpr(IHqlExpression * expr);
  600. void doAnalyseConditionalExpr(IHqlExpression * expr, unsigned firstConditional);
  601. inline AutoScopeMigrateInfo * queryBodyExtra(IHqlExpression * expr) { return static_cast<AutoScopeMigrateInfo *>(queryTransformExtra(expr->queryBody())); }
  602. private:
  603. IWorkUnit * wu;
  604. HqlCppTranslator & translator;
  605. bool isRoxie;
  606. bool isConditional;
  607. bool hasCandidate;
  608. bool isSequential;
  609. unsigned curGraph;
  610. unsigned graphDepth = 0;
  611. HqlExprArray graphActions;
  612. unsigned activityDepth;
  613. HqlExprArray * globalTarget;
  614. };
  615. //---------------------------------------------------------------------------
  616. class TrivialGraphRemover : public NewHqlTransformer
  617. {
  618. public:
  619. TrivialGraphRemover();
  620. bool worthTransforming() const { return hasCandidate; }
  621. protected:
  622. virtual void analyseExpr(IHqlExpression * expr);
  623. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  624. bool isTrivialGraph(IHqlExpression * expr);
  625. private:
  626. bool hasCandidate;
  627. };
  628. //---------------------------------------------------------------------------
  629. class ThorCountTransformer : public NewHqlTransformer
  630. {
  631. public:
  632. ThorCountTransformer(HqlCppTranslator & _translator, bool _countDiskFuncOk);
  633. IHqlExpression * createTransformed(IHqlExpression * expr);
  634. protected:
  635. HqlCppTranslator & translator;
  636. bool countDiskFuncOk;
  637. };
  638. //---------------------------------------------------------------------------
  639. class FilteredIndexOptimizer : public NewHqlTransformer
  640. {
  641. public:
  642. FilteredIndexOptimizer(bool _processJoins, bool _processReads);
  643. protected:
  644. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  645. protected:
  646. bool processJoins;
  647. bool processReads;
  648. };
  649. //---------------------------------------------------------------------------
  650. class LocalUploadTransformer : public NewHqlTransformer
  651. {
  652. public:
  653. LocalUploadTransformer(IWorkUnit * _wu);
  654. protected:
  655. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  656. protected:
  657. IWorkUnit * wu;
  658. };
  659. //---------------------------------------------------------------------------
  660. class DFSLayoutTransformer : public NewHqlTransformer
  661. {
  662. public:
  663. DFSLayoutTransformer(IErrorReceiver &_errs, ICodegenContextCallback * _ctxCallback, HqlCppOptions const &_options);
  664. protected:
  665. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  666. protected:
  667. ICodegenContextCallback * ctxCallback;
  668. IErrorReceiver &errs;
  669. HqlCppOptions const &options;
  670. };
  671. //---------------------------------------------------------------------------
  672. class KeyedProjectTransformer : public NewHqlTransformer
  673. {
  674. public:
  675. KeyedProjectTransformer();
  676. protected:
  677. virtual IHqlExpression * createTransformed(IHqlExpression * expr) override;
  678. };
  679. //---------------------------------------------------------------------------
  680. class NestedSelectorInfo : public NewTransformInfo
  681. {
  682. public:
  683. NestedSelectorInfo(IHqlExpression * _original) : NewTransformInfo(_original) { isDenormalized = false; insertDenormalize = false; }
  684. public:
  685. bool isDenormalized;
  686. bool insertDenormalize;
  687. };
  688. class NestedSelectorNormalizer : public NewHqlTransformer
  689. {
  690. public:
  691. NestedSelectorNormalizer();
  692. virtual void analyseExpr(IHqlExpression * expr);
  693. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  694. inline bool requiresTransforming() { return spottedCandidate; }
  695. protected:
  696. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(NestedSelectorInfo, expr); }
  697. IHqlExpression * createNormalized(IHqlExpression * expr);
  698. NestedSelectorInfo * queryBodyExtra(IHqlExpression * expr) { return (NestedSelectorInfo *)queryTransformExtra(expr->queryBody()); }
  699. protected:
  700. bool spottedCandidate;
  701. };
  702. //---------------------------------------------------------------------------
  703. class LeftRightSelectorNormalizer : public NewHqlTransformer
  704. {
  705. public:
  706. LeftRightSelectorNormalizer(bool _allowAmbiguity);
  707. virtual void analyseExpr(IHqlExpression * expr);
  708. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  709. virtual IHqlExpression * createTransformedSelector(IHqlExpression * expr);
  710. inline bool containsAmbiguity() { return isAmbiguous; }
  711. protected:
  712. void checkAmbiguity(const HqlExprCopyArray & inScope, IHqlExpression * selector);
  713. protected:
  714. bool allowAmbiguity;
  715. bool isAmbiguous;
  716. };
  717. //---------------------------------------------------------------------------
  718. class SharedTableInfo : public CInterface
  719. {
  720. public:
  721. SharedTableInfo(IHqlExpression * _dataset, unsigned _depth) : dataset(_dataset), depth(_depth) {}
  722. IHqlExpression * dataset;
  723. unsigned depth;
  724. OwnedHqlExpr uid; // if (depth > 0)
  725. };
  726. class ImplicitAliasTransformInfo : public NewTransformInfo
  727. {
  728. public:
  729. ImplicitAliasTransformInfo(IHqlExpression * _expr) : NewTransformInfo(_expr) { containsAmbiguity = false; }
  730. void add(SharedTableInfo * table);
  731. void addAmbiguity(SharedTableInfo * table);
  732. void inherit(const ImplicitAliasTransformInfo * other);
  733. void merge(SharedTableInfo * table);
  734. SharedTableInfo * uses(IHqlExpression * tableBody) const;
  735. public:
  736. CIArrayOf<SharedTableInfo> sharedTables;
  737. Owned<SharedTableInfo> shared;
  738. OwnedHqlExpr rawLeft;
  739. OwnedHqlExpr rawRight;
  740. bool containsAmbiguity;
  741. };
  742. class ImplicitAliasTransformer : public NewHqlTransformer
  743. {
  744. public:
  745. ImplicitAliasTransformer();
  746. void process(HqlExprArray & exprs);
  747. inline bool hasAmbiguity() const { return seenAmbiguity; }
  748. protected:
  749. virtual void analyseExpr(IHqlExpression * expr);
  750. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  751. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  752. inline ImplicitAliasTransformInfo * queryExtra(IHqlExpression * expr) { return (ImplicitAliasTransformInfo *)queryTransformExtra(expr); }
  753. SharedTableInfo * createAmbiguityInfo(IHqlExpression * dataset, unsigned depth);
  754. protected:
  755. CIArrayOf<SharedTableInfo> ambiguousTables;
  756. bool seenAmbiguity;
  757. bool seenShared;
  758. };
  759. //---------------------------------------------------------------------------
  760. class LeftRightTransformInfo : public NewTransformInfo
  761. {
  762. public:
  763. LeftRightTransformInfo(IHqlExpression * _expr) : NewTransformInfo(_expr) { containsAmbiguity = false; }
  764. void add(SharedTableInfo * table);
  765. void addAmbiguity(SharedTableInfo * table);
  766. void inherit(const LeftRightTransformInfo * other);
  767. void merge(SharedTableInfo * table);
  768. bool noteUsed(IHqlExpression * seq);
  769. SharedTableInfo * uses(IHqlExpression * tableBody) const;
  770. public:
  771. CIArrayOf<SharedTableInfo> sharedTables;
  772. Owned<SharedTableInfo> shared;
  773. HqlExprCopyArray seqs;
  774. OwnedHqlExpr rawLeft;
  775. OwnedHqlExpr rawRight;
  776. bool containsAmbiguity;
  777. };
  778. /*
  779. This transformer is responsible for reducing the number of selseq used as sequence numbers - so that they only remain
  780. when nesting makes the selectors ambiguous. That allows expressions to be commoned up that wouldn't otherwise.
  781. */
  782. class LeftRightTransformer : public NewHqlTransformer
  783. {
  784. public:
  785. LeftRightTransformer();
  786. void process(HqlExprArray & exprs);
  787. protected:
  788. virtual void analyseExpr(IHqlExpression * expr);
  789. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  790. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  791. inline LeftRightTransformInfo * queryExtra(IHqlExpression * expr) { return (LeftRightTransformInfo *)queryTransformExtra(expr); }
  792. SharedTableInfo * createAmbiguityInfo(IHqlExpression * dataset, unsigned depth);
  793. void incUsage(IHqlExpression * expr, IHqlExpression * seq);
  794. protected:
  795. CIArrayOf<SharedTableInfo> ambiguousTables;
  796. bool seenShared;
  797. };
  798. //---------------------------------------------------------------------------
  799. class ForceLocalTransformInfo : public NewTransformInfo
  800. {
  801. friend class ForceLocalTransformer;
  802. public:
  803. ForceLocalTransformInfo(IHqlExpression * _expr) : NewTransformInfo(_expr) { }
  804. public:
  805. //Theoretically this should be [insideForceLocal][allNodesDepth], but using insideAllNodes instead will just some obscure selfnodes in wrong place.
  806. HqlExprAttr localTransformed[2][2];
  807. HqlExprAttr localTransformedSelector[2][2];
  808. };
  809. //MORE: I think this might need to be a scoped transformer to cope with the general case
  810. class ForceLocalTransformer : public NewHqlTransformer
  811. {
  812. public:
  813. ForceLocalTransformer(ClusterType _targetClusterType);
  814. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  815. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  816. virtual IHqlExpression * queryAlreadyTransformed(IHqlExpression * expr);
  817. virtual void setTransformed(IHqlExpression * expr, IHqlExpression * transformed);
  818. virtual IHqlExpression * queryAlreadyTransformedSelector(IHqlExpression * expr);
  819. virtual void setTransformedSelector(IHqlExpression * expr, IHqlExpression * transformed);
  820. protected:
  821. bool queryAddLocal(IHqlExpression * expr);
  822. inline bool insideAllNodes() { return allNodesDepth > 0; }
  823. //Another exception
  824. inline ForceLocalTransformInfo * queryExtra(IHqlExpression * expr) { return (ForceLocalTransformInfo *)queryTransformExtra(expr); }
  825. protected:
  826. ClusterType targetClusterType;
  827. bool insideForceLocal;
  828. unsigned allNodesDepth;
  829. };
  830. class HqlLinkedChildRowTransformer : public QuickHqlTransformer
  831. {
  832. public:
  833. HqlLinkedChildRowTransformer(bool _implicitLinkedChildRows);
  834. virtual IHqlExpression * createTransformedBody(IHqlExpression * expr);
  835. protected:
  836. IHqlExpression * ensureInputSerialized(IHqlExpression * expr);
  837. IHqlExpression * transformBuildIndex(IHqlExpression * expr);
  838. IHqlExpression * transformPipeThrough(IHqlExpression * expr);
  839. protected:
  840. bool implicitLinkedChildRows;
  841. };
  842. //---------------------------------------------------------------------------
  843. class HqlScopeTaggerInfo : public MergingTransformInfo
  844. {
  845. public:
  846. HqlScopeTaggerInfo(IHqlExpression * _expr);
  847. };
  848. class HqlScopeTagger : public ScopedDependentTransformer
  849. {
  850. typedef ScopedDependentTransformer Parent;
  851. public:
  852. HqlScopeTagger(IErrorReceiver & _errors, ErrorSeverityMapper & _errorMapper);
  853. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  854. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  855. protected:
  856. void checkActiveRow(IHqlExpression * expr);
  857. IHqlExpression * transformSelect(IHqlExpression * expr);
  858. IHqlExpression * transformAmbiguous(IHqlExpression * expr, bool isActiveOk);
  859. IHqlExpression * transformAmbiguousChildren(IHqlExpression * expr);
  860. IHqlExpression * transformCall(IHqlExpression * expr);
  861. IHqlExpression * transformNewDataset(IHqlExpression * expr, bool isActiveOk);
  862. IHqlExpression * transformRelated(IHqlExpression * expr);
  863. IHqlExpression * transformSelectorsAttr(IHqlExpression * expr);
  864. IHqlExpression * transformSizeof(IHqlExpression * expr);
  865. IHqlExpression * transformWithin(IHqlExpression * dataset, IHqlExpression * scope);
  866. void reportError(WarnErrorCategory category, const char * msg);
  867. void reportSelectorError(IHqlExpression * selector, IHqlExpression * expr);
  868. protected:
  869. IErrorReceiver & errors;
  870. ErrorSeverityMapper & errorMapper;
  871. };
  872. //---------------------------------------------------------------------------
  873. class ContainsCompoundTransformer : public QuickHqlTransformer
  874. {
  875. public:
  876. ContainsCompoundTransformer();
  877. protected:
  878. virtual void doAnalyseBody(IHqlExpression * expr);
  879. public:
  880. bool containsCompound;
  881. };
  882. bool containsCompound(const HqlExprArray & exprs);
  883. bool containsCompound(IHqlExpression * expr);
  884. //---------------------------------------------------------------------------
  885. class AnnotationTransformInfo : public NewTransformInfo
  886. {
  887. public:
  888. AnnotationTransformInfo(IHqlExpression * _expr) : NewTransformInfo(_expr) { }
  889. IHqlExpression * cloneAnnotations(IHqlExpression * body);
  890. void noteAnnotation(IHqlExpression * _annotation);
  891. public:
  892. HqlExprCopyArray annotations;
  893. };
  894. class AnnotationNormalizerTransformer : public NewHqlTransformer
  895. {
  896. public:
  897. AnnotationNormalizerTransformer();
  898. virtual void analyseExpr(IHqlExpression * expr);
  899. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  900. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  901. // virtual void analyseSelector(IHqlExpression * expr);
  902. // virtual IHqlExpression * transformSelector(IHqlExpression * expr);
  903. protected:
  904. AnnotationTransformInfo * queryLocationIndependentExtra(IHqlExpression * expr);
  905. };
  906. void normalizeAnnotations(HqlCppTranslator & translator, HqlExprArray & exprs);
  907. //---------------------------------------------------------------------------
  908. class NestedCompoundTransformer : public HoistingHqlTransformer
  909. {
  910. public:
  911. NestedCompoundTransformer(HqlCppTranslator & _translator);
  912. protected:
  913. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  914. virtual IHqlExpression * doTransformIndependent(IHqlExpression * expr)
  915. {
  916. if (!containsCompound(expr))
  917. return LINK(expr);
  918. NestedCompoundTransformer nested(translator);
  919. nested.setParent(this);
  920. nested.analyse(expr, 0); // analyse called so set up whether expressions are unconditional etc.
  921. return nested.transformRoot(expr);
  922. }
  923. public:
  924. HqlCppTranslator & translator;
  925. const HqlCppOptions & translatorOptions;
  926. };
  927. class HqlTreeNormalizerInfo : public NewTransformInfo
  928. {
  929. public:
  930. HqlTreeNormalizerInfo(IHqlExpression * _expr) : NewTransformInfo(_expr) { symbol = NULL; }
  931. void noteSymbol(IHqlExpression * _symbol);
  932. public:
  933. IHqlExpression * symbol;
  934. };
  935. class HqlTreeNormalizer : public NewHqlTransformer
  936. {
  937. typedef NewHqlTransformer Parent;
  938. public:
  939. HqlTreeNormalizer(HqlCppTranslator & _translator);
  940. virtual void analyseExpr(IHqlExpression * expr);
  941. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  942. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  943. bool querySeenForceLocal() const { return seenForceLocal; }
  944. bool querySeenLocalUpload() const { return seenLocalUpload; }
  945. protected:
  946. virtual IHqlExpression * createTransformedSelector(IHqlExpression * expr);
  947. virtual ITypeInfo * transformType(ITypeInfo * type);
  948. inline IHqlExpression * createTransformedBody(IHqlExpression * expr);
  949. IHqlExpression * convertSelectToProject(IHqlExpression * newRecord, IHqlExpression * expr);
  950. void convertRecordToAssigns(HqlExprArray & assigns, IHqlExpression * oldRecord, IHqlExpression * targetSelector, bool canOmit, bool onlyConstant);
  951. IHqlExpression * convertRecordToAssigns(IHqlExpression * oldRecord, bool canOmit, bool onlyConstant);
  952. IHqlExpression * removeDefaultsFromExpr(IHqlExpression * expr, unsigned recordChildIndex, node_operator newOp);
  953. IHqlExpression * optimizeAssignSkip(HqlExprArray & children, IHqlExpression * expr, IHqlExpression * cond, unsigned depth);
  954. IHqlExpression * queryTransformPatternDefine(IHqlExpression * expr);
  955. IHqlExpression * transformActionList(IHqlExpression * expr);
  956. IHqlExpression * transformCaseToChoose(IHqlExpression * expr);
  957. IHqlExpression * transformCaseToIfs(IHqlExpression * expr);
  958. IHqlExpression * transformExecuteWhen(IHqlExpression * expr);
  959. IHqlExpression * transformEvaluate(IHqlExpression * expr);
  960. IHqlExpression * transformIfAssert(node_operator newOp, IHqlExpression * expr);
  961. IHqlExpression * transformKeyIndex(IHqlExpression * expr);
  962. IHqlExpression * transformMerge(IHqlExpression * expr);
  963. IHqlExpression * transformNewKeyIndex(IHqlExpression * expr);
  964. IHqlExpression * transformPatNamedUse(IHqlExpression * expr);
  965. IHqlExpression * transformPatCheckIn(IHqlExpression * expr);
  966. IHqlExpression * transformMap(IHqlExpression * expr);
  967. IHqlExpression * transformTempRow(IHqlExpression * expr);
  968. IHqlExpression * transformTempTable(IHqlExpression * expr);
  969. IHqlExpression * transformTable(IHqlExpression * untransformed);
  970. IHqlExpression * transformWithinFilter(IHqlExpression * expr);
  971. bool transformTransform(HqlExprArray & children, IHqlExpression * expr);
  972. IHqlExpression * transformTransform(IHqlExpression * expr);
  973. IHqlExpression * validateKeyedJoin(IHqlExpression * expr);
  974. protected:
  975. IHqlExpression * transformChildrenNoAnnotations(IHqlExpression * expr);
  976. IHqlExpression * makeRecursiveName(IAtom * searchModule, IAtom * searchName);
  977. HqlTreeNormalizerInfo * queryLocationIndependentExtra(IHqlExpression * expr);
  978. IHqlExpression * transformSimpleConst(IHqlExpression * expr)
  979. {
  980. if (expr->isConstant())
  981. return transform(expr);
  982. return LINK(expr);
  983. }
  984. //Try and prevent this being called by accident - need to call quickFullReplaceExpression() instead
  985. //because the tree isn't normalized at this point
  986. void replaceExpression(IHqlExpression * expr, IHqlExpression * original, IHqlExpression * replacement);
  987. protected:
  988. HqlCppTranslator & translator;
  989. IErrorReceiver * errorProcessor;
  990. HqlExprArray forwardReferences;
  991. HqlExprArray defines;
  992. struct
  993. {
  994. bool assertSortedDistributed;
  995. bool removeAsserts;
  996. bool commonUniqueNameAttributes;
  997. bool sortIndexPayload;
  998. bool allowSections;
  999. bool normalizeExplicitCasts;
  1000. bool ensureRecordsHaveSymbols;
  1001. bool outputRowsAsDatasets;
  1002. bool constantFoldNormalize;
  1003. bool allowActivityForKeyedJoin;
  1004. bool implicitSubSort;
  1005. bool forceAllDatasetsParallel;
  1006. } options;
  1007. unsigned nextSequenceValue;
  1008. bool seenForceLocal;
  1009. bool seenLocalUpload;
  1010. };
  1011. void normalizeHqlTree(HqlCppTranslator & translator, HqlExprArray & exprs);
  1012. IHqlExpression * normalizeHqlTree(HqlCppTranslator & translator, IHqlExpression * expr);
  1013. // more: This really shouldn't need a translator argument - but it is a bit of a god class, and error reporting needs splitting from it.
  1014. IHqlExpression * normalizeExpression(HqlCppTranslator & translator, IHqlExpression * expr);
  1015. IHqlExpression * removeNamedSymbols(IHqlExpression * expr);
  1016. void hoistNestedCompound(HqlCppTranslator & _translator, HqlExprArray & exprs);
  1017. void hoistNestedCompound(HqlCppTranslator & _translator, WorkflowArray & workflow);
  1018. //---------------------------------------------------------------------------
  1019. void expandGlobalDatasets(WorkflowItem & curWorkflow, IWorkUnit * wu, HqlCppTranslator & translator);
  1020. void mergeThorGraphs(WorkflowItem & curWorkflow, bool resourceConditionalActions, bool resourceSequential);
  1021. void migrateExprToNaturalLevel(WorkflowItem & curWorkflow, IWorkUnit * wu, HqlCppTranslator & translator);
  1022. void removeTrivialGraphs(WorkflowItem & curWorkflow);
  1023. void extractWorkflow(HqlCppTranslator & translator, HqlExprArray & exprs, WorkflowArray & out);
  1024. void optimizeActivities(unsigned wfid, HqlExprArray & exprs, bool optimizeCountCompare, bool optimizeNonEmpty);
  1025. IHqlExpression * insertImplicitProjects(HqlCppTranslator & translator, IHqlExpression * expr, bool optimizeSpills);
  1026. void insertImplicitProjects(HqlCppTranslator & translator, HqlExprArray & exprs);
  1027. //------------------------------------------------------------------------
  1028. #endif