hqlstmt.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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 HQLSTMT_HPP
  14. #define HQLSTMT_HPP
  15. #ifdef HQLCPP_EXPORTS
  16. #define HQLCPP_API DECL_EXPORT
  17. #else
  18. #define HQLCPP_API DECL_IMPORT
  19. #endif
  20. interface IHqlStmt;
  21. struct BuildOptions;
  22. class BuildCtx;
  23. class HqlStmt;
  24. class HqlCompoundStmt;
  25. class HqlStmts;
  26. class HqlCppInstance;
  27. class CHqlBoundExpr;
  28. class all_result_types;
  29. interface IFunctionInfo;
  30. //---------------------------------------------------------------------------
  31. // used to represent an association of something already calculated in the context
  32. // e.g. a cursor, temporary value, or even dependency information.
  33. //These are represented using unique bits, so that a mask can be stored to indicate which associations are held
  34. enum AssocKind
  35. {
  36. AssocExpr = 0x0000001,
  37. AssocActivity = 0x0000002,
  38. AssocCursor = 0x0000004,
  39. AssocClass = 0x0000008,
  40. AssocRow = 0x0000010,
  41. AssocActivityInstance = 0x0000020,
  42. AssocExtract = 0x0000040,
  43. AssocExtractContext = 0x0000080,
  44. AssocSubQuery = 0x0000100,
  45. AssocGraphNode = 0x0000200,
  46. AssocSubGraph = 0x0000400,
  47. AssocStmt = 0x0000800,
  48. AssocSequentialSearch = 0x0001000,
  49. };
  50. class CHqlBoundExpr;
  51. struct HQLCPP_API HqlExprAssociation : public CInterface
  52. {
  53. public:
  54. HqlExprAssociation(IHqlExpression * _represents) { represents.set(_represents); }
  55. virtual bool isAlias() { return false; }
  56. virtual bool isRowAssociation() { return false; }
  57. virtual AssocKind getKind() = 0;
  58. virtual IHqlExpression * queryExpr() const { UNIMPLEMENTED; }
  59. virtual void getBound(CHqlBoundExpr & result);
  60. public:
  61. HqlExprAttr represents;
  62. };
  63. interface IAssociationVisitor
  64. {
  65. virtual bool visit(HqlExprAssociation & assoc) = 0; // return true if done
  66. };
  67. //---------------------------------------------------------------------------
  68. // Class used to represent current location for generating source code statements.
  69. class CHqlBoundExpr;
  70. class HQLCPP_API BuildCtx : public CInterface
  71. {
  72. friend class AssociationIterator;
  73. public:
  74. BuildCtx(HqlCppInstance & _state, IAtom * section);
  75. BuildCtx(HqlCppInstance & _state);
  76. BuildCtx(BuildCtx & _owner);
  77. BuildCtx(BuildCtx & _owner, IHqlStmt * container);
  78. ~BuildCtx();
  79. IHqlStmt * addAssign(IHqlExpression * target, IHqlExpression * value);
  80. IHqlStmt * addAssignLink(IHqlExpression * target, IHqlExpression * value);
  81. IHqlStmt * addAssignIncrement(IHqlExpression * target, IHqlExpression * value);
  82. IHqlStmt * addAssignDecrement(IHqlExpression * target, IHqlExpression * value);
  83. IHqlStmt * addAlias(IHqlStmt * stmt);
  84. IHqlStmt * addBlock();
  85. IHqlStmt * addBreak();
  86. IHqlStmt * addCase(IHqlStmt * owner, IHqlExpression * condition);
  87. IHqlStmt * addCatch(IHqlExpression * caught);
  88. IHqlStmt * addConditionalGroup(IHqlStmt * stmt); // generated if stmt->isIncluded() is true
  89. IHqlStmt * addContinue();
  90. IHqlStmt * addDeclare(IHqlExpression * name, IHqlExpression * value=NULL);
  91. IHqlStmt * addDeclareExternal(IHqlExpression * name);
  92. IHqlStmt * addDeclareAssign(IHqlExpression * name, IHqlExpression * value);
  93. IHqlStmt * addDefault(IHqlStmt * owner);
  94. IHqlStmt * addExpr(IHqlExpression * condition);
  95. IHqlStmt * addExprOwn(IHqlExpression * condition);
  96. IHqlStmt * addReturn(IHqlExpression * value);
  97. IHqlStmt * addFilter(IHqlExpression * condition);
  98. IHqlStmt * addFunction(IHqlExpression * funcdef);
  99. IHqlStmt * addGoto(const char * labelText);
  100. IHqlStmt * addGroup(); // like a block but no {}
  101. IHqlStmt * addGroupPass(IHqlExpression * pass);
  102. IHqlStmt * addIndirection(const BuildCtx & _parent); // pretend this is generated in the parent context (add a modified container)
  103. IHqlStmt * addLabel(const char * labelText);
  104. IHqlStmt * addLine(const char * filename = NULL, unsigned lineNum = 0);
  105. IHqlStmt * addLoop(IHqlExpression * cond, IHqlExpression * next, bool atEnd);
  106. IHqlStmt * addQuoted(const char * text);
  107. IHqlStmt * addQuotedLiteral(const char * text); // must only be used for constant C++ strings - avoids a memory clone
  108. IHqlStmt * addQuotedF(const char * text, ...) __attribute__((format(printf, 2, 3)));
  109. IHqlStmt * addQuotedCompound(const char * text, const char * extra);
  110. IHqlStmt * addQuotedCompoundLiteral(const char * text, const char * extra = NULL);
  111. IHqlStmt * addQuotedCompoundOpt(const char * text, const char * extra = NULL);
  112. IHqlStmt * addQuotedFunction(const char * text, bool dynamicText = false); // Eventually all calls should be replaced with MemberFunction objects
  113. IHqlStmt * addQuoted(StringBuffer & text) { return addQuoted(text.str()); }
  114. IHqlStmt * addSwitch(IHqlExpression * condition);
  115. IHqlStmt * addThrow(IHqlExpression * thrown);
  116. IHqlStmt * addTry();
  117. void associate(HqlExprAssociation & next);
  118. void associateOwn(HqlExprAssociation & next);
  119. HqlExprAssociation * associateExpr(IHqlExpression * represents, IHqlExpression * expr);
  120. HqlExprAssociation * associateExpr(IHqlExpression * represents, const CHqlBoundExpr & bound);
  121. bool hasAssociation(HqlExprAssociation & search, bool unconditional);
  122. bool isSameLocation(const BuildCtx & other) const;
  123. HqlExprAssociation * queryAssociation(IHqlExpression * dataset, AssocKind kind, HqlExprCopyArray * selectors);
  124. HqlExprAssociation * queryFirstAssociation(AssocKind kind);
  125. HqlExprAssociation * queryFirstCommonAssociation(AssocKind kind);
  126. void walkAssociations(AssocKind searchMask, IAssociationVisitor & visitor); // Function to walk associations filtered by kind
  127. HqlExprAssociation * queryMatchExpr(IHqlExpression * expr);
  128. bool getMatchExpr(IHqlExpression * expr, CHqlBoundExpr & bound);
  129. IHqlExpression * getTempDeclare(ITypeInfo * type, IHqlExpression * value);
  130. bool isOuterContext() const;
  131. void needFunction(IFunctionInfo & helper);
  132. void needFunction(IAtom * name);
  133. void removeAssociation(HqlExprAssociation * search);
  134. IHqlStmt * replaceExpr(IHqlStmt * stmt, IHqlExpression * expr); // use with extreme care!
  135. IHqlStmt * selectBestContext(IHqlExpression * expr);
  136. void selectContainer();
  137. void selectElse(IHqlStmt * filter);
  138. void setNextConstructor() { setNextPriority(ConPrio); }
  139. void setNextDestructor() { setNextPriority(DesPrio); }
  140. void setNextNormal() { setNextPriority(NormalPrio); }
  141. void setNextPriority(unsigned newPrio);
  142. unsigned setPriority(unsigned newPrio);
  143. void set(IAtom * section);
  144. void set(BuildCtx & _owner);
  145. public:
  146. enum { ConPrio = 1, NormalPrio = 5000, DesPrio = 9999, OutermostScopePrio };
  147. protected:
  148. HqlStmt * appendCompound(HqlCompoundStmt * next);
  149. HqlStmt * appendSimple(HqlStmt * next);
  150. void appendToOutermostScope(HqlStmt * next);
  151. void init(HqlStmts * _root);
  152. bool isChildOf(HqlStmt * stmt, HqlStmts * stmts);
  153. void recordDefine(HqlStmt * declare);
  154. IHqlStmt * recursiveGetBestContext(HqlStmts * searchStmts, HqlExprCopyArray & required);
  155. void selectCompound(IHqlStmt * stmt);
  156. private:
  157. BuildCtx(BuildCtx & owner, HqlStmts * _root);
  158. protected:
  159. HqlStmts * root;
  160. HqlStmts * curStmts;
  161. bool ignoreInput;
  162. unsigned curPriority;
  163. unsigned nextPriority;
  164. HqlCppInstance & state;
  165. };
  166. enum StmtKind {
  167. null_stmt,
  168. assign_stmt, block_stmt, group_stmt, declare_stmt,
  169. expr_stmt,
  170. return_stmt,
  171. quote_stmt,
  172. quote_compound_stmt,
  173. quote_compoundopt_stmt,
  174. filter_stmt,
  175. goto_stmt, label_stmt,
  176. switch_stmt, case_stmt, default_stmt,
  177. loop_stmt, break_stmt,
  178. pass_stmt, external_stmt,
  179. indirect_stmt,
  180. assigninc_stmt, assigndec_stmt,
  181. alias_stmt,
  182. line_stmt,
  183. continue_stmt,
  184. function_stmt,
  185. assign_link_stmt,
  186. try_stmt,
  187. catch_stmt,
  188. throw_stmt,
  189. };
  190. interface IHqlStmt : public IInterface
  191. {
  192. public:
  193. virtual StringBuffer & getTextExtra(StringBuffer & out) const = 0;
  194. virtual bool isIncluded() const = 0;
  195. virtual StmtKind getStmt() const = 0;
  196. virtual unsigned numChildren() const = 0;
  197. virtual IHqlStmt * queryChild(unsigned index) const = 0;
  198. virtual IHqlExpression *queryExpr(unsigned index) const = 0;
  199. //used when creating the statement graph
  200. virtual void mergeScopeWithContainer() = 0;
  201. virtual void setIncomplete(bool incomplete) = 0;
  202. virtual void setIncluded(bool _included) = 0;
  203. virtual void finishedFramework() = 0;
  204. };
  205. class HqlCppTranslator;
  206. void peepholeOptimize(HqlCppInstance & instance, HqlCppTranslator & translator);
  207. class AssociationIterator
  208. {
  209. public:
  210. AssociationIterator(BuildCtx & ctx);
  211. bool first();
  212. bool isValid() { return curStmts != NULL; }
  213. inline bool next() { return doNext(); }
  214. HqlExprAssociation & get();
  215. protected:
  216. virtual bool doNext();
  217. protected:
  218. HqlStmts * rootStmts;
  219. unsigned curIdx;
  220. unsigned searchMask;
  221. HqlStmts * curStmts;
  222. };
  223. class FilteredAssociationIterator : public AssociationIterator
  224. {
  225. public:
  226. FilteredAssociationIterator(BuildCtx & ctx, AssocKind _searchKind) : AssociationIterator(ctx)
  227. {
  228. searchKind = _searchKind;
  229. searchMask = searchKind;
  230. }
  231. virtual bool doNext();
  232. protected:
  233. AssocKind searchKind;
  234. };
  235. class BoundRow;
  236. class RowAssociationIterator : public AssociationIterator
  237. {
  238. public:
  239. RowAssociationIterator(BuildCtx & ctx) : AssociationIterator(ctx)
  240. {
  241. searchMask = AssocRow|AssocCursor;
  242. }
  243. virtual bool doNext();
  244. BoundRow & get() { return (BoundRow &)AssociationIterator::get(); }
  245. };
  246. /*
  247. * This class is used to temporarily add a group into the BuildCtx to avoid problems with declaring variables too
  248. * early, and then merges any associations into the parent statement once creating the result is complete.
  249. */
  250. class TemporaryGroup
  251. {
  252. public:
  253. TemporaryGroup(BuildCtx & ctx)
  254. {
  255. group = ctx.addGroup();
  256. group->setIncomplete(true);
  257. }
  258. ~TemporaryGroup()
  259. {
  260. group->setIncomplete(false);
  261. group->mergeScopeWithContainer();
  262. }
  263. private:
  264. IHqlStmt * group;
  265. };
  266. unsigned calcTotalChildren(const IHqlStmt * stmt);
  267. IHqlExpression * stripTranslatedCasts(IHqlExpression * e);
  268. IHqlExpression * peepholeAddExpr(IHqlExpression * left, IHqlExpression * right);
  269. bool rightFollowsLeft(IHqlExpression * left, IHqlExpression * leftLen, IHqlExpression * right);
  270. extern HQLCPP_API void outputSizeStmts();
  271. /* If TRACK_SEARCH_DISTANCE is defined it returns the distance spent searching for an matching association - otherwise 0 */
  272. extern HQLCPP_API unsigned __int64 querySearchDistance();
  273. #endif