hqlsource.ipp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #ifndef __HQLSOURCE_IPP_
  15. #define __HQLSOURCE_IPP_
  16. IHqlExpression * convertToPhysicalTable(IHqlExpression * tableExpr, bool ensureSerialized);
  17. enum KeyedKind { KeyedYes, KeyedNo, KeyedExtend };
  18. struct KeyCondition : public CInterface
  19. {
  20. public:
  21. KeyCondition() { keyedKind = KeyedNo; isWild = false; generated = false; wasKeyed = false; }
  22. KeyCondition(IHqlExpression * _selector, IHqlExpression * _expr, KeyedKind _keyedKind)
  23. { selector.set(_selector); expr.set(_expr); keyedKind = _keyedKind; isWild = false; generated = false; wasKeyed = isKeyed(); }
  24. bool isKeyed() { return (keyedKind != KeyedNo); }
  25. HqlExprAttr selector;
  26. HqlExprAttr expr;
  27. KeyedKind keyedKind;
  28. bool isWild;
  29. bool generated;
  30. bool wasKeyed;
  31. };
  32. typedef CIArrayOf<KeyCondition> KeyConditionArray;
  33. class KeyConditionInfo : public CInterface
  34. {
  35. public:
  36. void appendPreFilter(IHqlExpression * expr) { extendAndCondition(preFilter, expr); }
  37. void appendPostFilter(IHqlExpression * expr) { extendAndCondition(postFilter, expr); }
  38. void appendCondition(KeyCondition & next) { conditions.append(next); }
  39. IHqlExpression * createConjunction();
  40. public:
  41. HqlExprAttr preFilter; // before activity executed
  42. HqlExprAttr postFilter; // after candidate record returned
  43. KeyConditionArray conditions;
  44. };
  45. //---------------------------------------------------------------------------
  46. enum KeyFailureReason { KFRunknown, KFRnokey, KFRor, KFRtoocomplex, KFRcast }; // ordered
  47. class KeyFailureInfo
  48. {
  49. public:
  50. KeyFailureInfo() { code = KFRunknown; }
  51. void clear() { code = KFRunknown; }
  52. void merge(const KeyFailureInfo & other);
  53. void reportError(HqlCppTranslator & translator, IHqlExpression * condition);
  54. void set(KeyFailureReason _code) { code = _code; }
  55. void set(KeyFailureReason _code, IHqlExpression * _field) { code = _code; field.set(_field); }
  56. protected:
  57. KeyFailureReason code;
  58. OwnedHqlExpr field;
  59. };
  60. struct BuildMonitorState
  61. {
  62. BuildMonitorState(BuildCtx & _funcctx, const char * _listName) : funcctx(_funcctx)
  63. {
  64. listName = _listName;
  65. curOffset = 0;
  66. wildOffset = (unsigned) -1;
  67. numActiveSets = 0;
  68. warnedAllConditionsWild = false;
  69. doneImplicitWarning = true;
  70. wildWasKeyed = false;
  71. }
  72. inline bool wildPending() { return wildOffset != (unsigned)-1; }
  73. inline void clearWild() { wildOffset = (unsigned) -1; }
  74. const char * getSetName();
  75. void popSetName();
  76. //Constant while building monitors
  77. BuildCtx & funcctx;
  78. const char * listName;
  79. //State variables used when generating
  80. OwnedHqlExpr implicitWildField;
  81. unsigned numActiveSets;
  82. CIArrayOf<StringAttrItem> setNames;
  83. bool doneImplicitWarning;
  84. bool warnedAllConditionsWild;
  85. bool wildWasKeyed;
  86. unsigned curOffset;
  87. unsigned wildOffset;
  88. };
  89. enum MonitorFilterKind { NoMonitorFilter, MonitorFilterSkipEmpty, MonitorFilterSkipAll };
  90. struct KeySelectorInfo
  91. {
  92. public:
  93. KeySelectorInfo(KeyedKind _keyedKind, IHqlExpression * _selector, IHqlExpression * _expandedSelector, size32_t _offset, size32_t _size, bool _mapOffset, bool _isComputed)
  94. {
  95. keyedKind = _keyedKind;
  96. selector = _selector;
  97. expandedSelector = _expandedSelector;
  98. offset = _offset;
  99. size = _size;
  100. expandNeeded = (selector->queryType() != expandedSelector->queryType());
  101. mapOffset = _mapOffset;
  102. isComputed = _isComputed;
  103. }
  104. IHqlExpression * selector;
  105. IHqlExpression * expandedSelector;
  106. size32_t offset;
  107. size32_t size;
  108. KeyedKind keyedKind;
  109. bool expandNeeded;
  110. bool mapOffset;
  111. bool isComputed;
  112. };
  113. class MonitorExtractor
  114. {
  115. public:
  116. MonitorExtractor(IHqlExpression * _tableExpr, HqlCppTranslator & _translator, int _numKeyableFields, bool _allowTranslatedConds);
  117. void appendFilter(IHqlExpression * expr) { keyed.appendPostFilter(expr); }
  118. void buildSegments(BuildCtx & ctx, const char * listName, bool _ignoreUnkeyed);
  119. void extractFilters(IHqlExpression * filter, SharedHqlExpr & extraFilter);
  120. void extractFilters(HqlExprArray & exprs, SharedHqlExpr & extraFilter);
  121. void extractFiltersFromFilterDs(IHqlExpression * expr);
  122. void extractAllFilters(IHqlExpression * filter);
  123. IHqlExpression * queryExtraFilter() { return keyed.postFilter; }
  124. IHqlExpression * getClearExtraFilter() { return keyed.postFilter.getClear(); }
  125. bool isCleanlyKeyedExplicitly() { return cleanlyKeyedExplicitly; }
  126. bool isKeyedExplicitly() { return keyedExplicitly; }
  127. bool isFiltered() { return keyed.postFilter || isKeyed(); }
  128. bool isKeyed();
  129. void optimizeSegments(IHqlExpression * leftRecord);
  130. IHqlExpression * queryGlobalGuard() { return keyed.preFilter; }
  131. void reportFailureReason(IHqlExpression * cond) { failReason.reportError(translator, cond); }
  132. const char * queryKeyName(StringBuffer & s);
  133. void preventMerge(IHqlExpression * select) { if (select) noMergeSelects.append(*select); }
  134. bool isEqualityFilterBefore(IHqlExpression * select);
  135. unsigned queryKeySelectIndex(IHqlExpression * select) { return keyableSelects.find(*select); }
  136. bool createGroupingMonitor(BuildCtx ctx, const char * listName, IHqlExpression * select, unsigned & maxOffset);
  137. protected:
  138. void buildArbitaryKeySegment(BuildMonitorState & buildState, BuildCtx & ctx, unsigned curSize, IHqlExpression * condition);
  139. void buildEmptyKeySegment(BuildMonitorState & buildState, BuildCtx & ctx, KeySelectorInfo & selectorInfo);
  140. void buildWildKeySegment(BuildMonitorState & buildState, BuildCtx & ctx, KeySelectorInfo & selectorInfo);
  141. void buildWildKeySegment(BuildMonitorState & buildState, BuildCtx & ctx, unsigned offset, unsigned size);
  142. void buildKeySegment(BuildMonitorState & buildState, BuildCtx & ctx, unsigned whichField, unsigned curSize);
  143. void buildKeySegmentExpr(BuildMonitorState & buildState, KeySelectorInfo & selectorInfo, BuildCtx & ctx, const char * target, IHqlExpression & thisKey, MonitorFilterKind filterKind);
  144. void buildKeySegmentCompareExpr(BuildMonitorState & buildState, KeySelectorInfo & selectorInfo, BuildCtx & ctx, const char * requiredSet, IHqlExpression & thisKey);
  145. void buildKeySegmentInExpr(BuildMonitorState & buildState, KeySelectorInfo & selectorInfo, BuildCtx & ctx, const char * target, IHqlExpression & thisKey, MonitorFilterKind filterKind);
  146. bool buildSingleKeyMonitor(StringBuffer & createMonitorText, KeySelectorInfo & selectorInfo, BuildCtx & ctx, IHqlExpression & thisKey);
  147. void callAddAll(BuildCtx & ctx, IHqlExpression * targetVar);
  148. IHqlExpression * castToFieldAndBack(IHqlExpression * left, IHqlExpression * right);
  149. bool containsTableSelects(IHqlExpression * expr);
  150. IHqlExpression * createRangeCompare(IHqlExpression * selector, IHqlExpression * value, IHqlExpression * lengthExpr, bool compareEqual);
  151. void createStringSet(BuildCtx & ctx, const char * target, unsigned size, ITypeInfo * type);
  152. KeyCondition * createTranslatedCondition(IHqlExpression * cond, KeyedKind keyedKind);
  153. bool extractBoolFieldFilter(KeyConditionInfo & matches, IHqlExpression * selector, KeyedKind keyedKind, bool compareValue);
  154. bool extractFilters(KeyConditionInfo & matches, IHqlExpression * filter, KeyedKind keyedKind);
  155. void extractFoldedWildFields(IHqlExpression * expr);
  156. bool extractIfFilter(KeyConditionInfo & matches, IHqlExpression * expr, KeyedKind keyedKind);
  157. bool extractSimpleCompareFilter(KeyConditionInfo & state, IHqlExpression * expr, KeyedKind keyedKind);
  158. void expandKeyableFields();
  159. void expandSelects(IHqlExpression * expr, IHqlSimpleScope * expandedScope, IHqlExpression * keySelector, IHqlExpression * expandedSelector);;
  160. bool extractOrFilter(KeyConditionInfo & matches, IHqlExpression * filter, KeyedKind keyedKind);
  161. void generateFormatWrapping(StringBuffer & createMonitorText, IHqlExpression * selector, IHqlExpression * expandedSelector, unsigned curOffset);
  162. void generateOffsetWrapping(StringBuffer & createMonitorText, IHqlExpression * selector, unsigned curOffset);
  163. IHqlExpression * getMonitorValueAddress(BuildCtx & ctx, IHqlExpression * value);
  164. IHqlExpression * getRangeLimit(ITypeInfo * fieldType, IHqlExpression * lengthExpr, IHqlExpression * value, int whichBoundary);
  165. IHqlExpression * invertTransforms(IHqlExpression * left, IHqlExpression * right);
  166. bool isEqualityFilter(IHqlExpression * select);
  167. bool isKeySelect(IHqlExpression * select);
  168. bool isIndexInvariant(IHqlExpression * expr);
  169. bool isPrevSelectKeyed(IHqlExpression * select);
  170. bool matchSubstringFilter(KeyConditionInfo & matches, node_operator op, IHqlExpression * left, IHqlExpression * right, KeyedKind keyedKind, bool & duplicate);
  171. IHqlExpression * isKeyableFilter(IHqlExpression * left, IHqlExpression * right, bool & duplicate, node_operator compareOp, KeyFailureInfo & reason, KeyedKind keyedKind);
  172. bool okToKey(IHqlExpression * select, KeyedKind keyedKind);
  173. IHqlExpression * queryKeyableSelector(IHqlExpression * expr);
  174. IHqlExpression * querySimpleJoinValue(IHqlExpression * field);
  175. void extractCompareInformation(BuildCtx & ctx, IHqlExpression * expr, SharedHqlExpr & compare, SharedHqlExpr & normalized, IHqlExpression * expandedSelector, bool isTranslated);
  176. void extractCompareInformation(BuildCtx & ctx, IHqlExpression * lhs, IHqlExpression * value, SharedHqlExpr & compare, SharedHqlExpr & normalized, IHqlExpression * expandedSelector, bool isTranslated);
  177. IHqlExpression * unwindConjunction(HqlExprArray & matches, IHqlExpression * expr);
  178. protected:
  179. void spotSegmentCSE(BuildCtx & ctx);
  180. class SelectSpotter : public NewHqlTransformer
  181. {
  182. public:
  183. SelectSpotter(const HqlExprArray & _selects);
  184. void analyseExpr(IHqlExpression * expr);
  185. public:
  186. bool hasSelects;
  187. const HqlExprArray & selects;
  188. };
  189. protected:
  190. IHqlExpression * tableExpr;
  191. HqlCppTranslator & translator;
  192. // LinkedHqlExpr filter;
  193. // LinkedHqlExpr globalGuard;
  194. KeyConditionInfo keyed;
  195. UnsignedArray mergedSizes;
  196. unsigned numKeyableFields;
  197. KeyFailureInfo failReason;
  198. HqlExprAttr keyableRecord;
  199. HqlExprArray keyableSelects;
  200. // expanded record + selects have bitfields/alien/varstrings expanded to a fixed size basic type.
  201. HqlExprAttr expandedRecord;
  202. HqlExprArray expandedSelects;
  203. HqlExprCopyArray noMergeSelects; // don't merge these fields (even for wildcards) because they are separate stepping fields.
  204. unsigned firstOffsetField; // first field where the keyed offset is adjusted
  205. bool onlyHozedCompares;
  206. bool allowTranslatedConds;
  207. bool ignoreUnkeyed;
  208. bool cleanlyKeyedExplicitly;
  209. bool keyedExplicitly;
  210. bool allowDynamicFormatChange;
  211. };
  212. //---------------------------------------------------------------------------
  213. struct VirtualFieldsInfo
  214. {
  215. public:
  216. VirtualFieldsInfo()
  217. {
  218. virtualsAtEnd = true;
  219. requiresDeserialize = false;
  220. }
  221. IHqlExpression * createPhysicalRecord();
  222. void gatherVirtualFields(IHqlExpression * record, bool ignoreVirtuals, bool ensureSerialized);
  223. bool hasVirtuals() { return virtuals.ordinality() != 0; }
  224. bool hasVirtualsOrDeserialize() { return requiresDeserialize || virtuals.ordinality() != 0; }
  225. bool needFilePosition() { return virtuals.ordinality() > 0; }
  226. bool needFilePosition(bool local);
  227. public:
  228. HqlExprArray physicalFields;
  229. HqlExprArray selects;
  230. HqlExprArray virtuals;
  231. bool virtualsAtEnd;
  232. bool requiresDeserialize;
  233. };
  234. //---------------------------------------------------------------------------
  235. unsigned getProjectCount(IHqlExpression * expr);
  236. #endif