hqlsource.ipp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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 __HQLSOURCE_IPP_
  14. #define __HQLSOURCE_IPP_
  15. IHqlExpression * convertToPhysicalTable(IHqlExpression * tableExpr, bool ensureSerialized);
  16. enum KeyedKind { KeyedYes, KeyedNo, KeyedExtend };
  17. struct KeyCondition : public CInterface
  18. {
  19. public:
  20. KeyCondition() { keyedKind = KeyedNo; isWild = false; generated = false; wasKeyed = false; }
  21. KeyCondition(IHqlExpression * _selector, IHqlExpression * _expr, KeyedKind _keyedKind)
  22. { selector.set(_selector); expr.set(_expr); keyedKind = _keyedKind; isWild = false; generated = false; wasKeyed = isKeyed(); }
  23. bool isKeyed() { return (keyedKind != KeyedNo); }
  24. HqlExprAttr selector;
  25. HqlExprAttr expr;
  26. KeyedKind keyedKind;
  27. bool isWild;
  28. bool generated;
  29. bool wasKeyed;
  30. };
  31. typedef CIArrayOf<KeyCondition> KeyConditionArray;
  32. class KeyConditionInfo : public CInterface
  33. {
  34. public:
  35. void appendPreFilter(IHqlExpression * expr) { extendAndCondition(preFilter, expr); }
  36. void appendPostFilter(IHqlExpression * expr) { extendAndCondition(postFilter, expr); }
  37. void appendCondition(KeyCondition & next) { conditions.append(next); }
  38. IHqlExpression * createConjunction();
  39. public:
  40. HqlExprAttr preFilter; // before activity executed
  41. HqlExprAttr postFilter; // after candidate record returned
  42. KeyConditionArray conditions;
  43. };
  44. //---------------------------------------------------------------------------
  45. enum KeyFailureReason { KFRunknown, KFRnokey, KFRor, KFRtoocomplex, KFRcast }; // ordered
  46. class KeyFailureInfo
  47. {
  48. public:
  49. KeyFailureInfo() { code = KFRunknown; }
  50. void clear() { code = KFRunknown; }
  51. void merge(const KeyFailureInfo & other);
  52. void reportError(HqlCppTranslator & translator, IHqlExpression * condition);
  53. void set(KeyFailureReason _code) { code = _code; }
  54. void set(KeyFailureReason _code, IHqlExpression * _field) { code = _code; field.set(_field); }
  55. protected:
  56. KeyFailureReason code;
  57. OwnedHqlExpr field;
  58. };
  59. struct BuildMonitorState
  60. {
  61. BuildMonitorState(BuildCtx & _funcctx, const char * _listName) : funcctx(_funcctx)
  62. {
  63. listName = _listName;
  64. curFieldIdx = 0;
  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 curFieldIdx;
  87. unsigned curOffset;
  88. unsigned wildOffset;
  89. };
  90. enum MonitorFilterKind { NoMonitorFilter, MonitorFilterSkipEmpty, MonitorFilterSkipAll };
  91. struct KeySelectorInfo
  92. {
  93. public:
  94. KeySelectorInfo(KeyedKind _keyedKind, IHqlExpression * _selector, IHqlExpression * _expandedSelector, unsigned _fieldIdx, size32_t _offset, size32_t _size)
  95. {
  96. keyedKind = _keyedKind;
  97. selector = _selector;
  98. expandedSelector = _expandedSelector;
  99. fieldIdx = _fieldIdx;
  100. offset = _offset;
  101. size = _size;
  102. }
  103. IHqlExpression * selector;
  104. IHqlExpression * expandedSelector;
  105. unsigned fieldIdx;
  106. size32_t offset;
  107. size32_t size;
  108. KeyedKind keyedKind;
  109. };
  110. class MonitorExtractor
  111. {
  112. public:
  113. MonitorExtractor(IHqlExpression * _tableExpr, HqlCppTranslator & _translator, int _numKeyableFields, bool isDiskRead);
  114. void appendFilter(IHqlExpression * expr) { keyed.appendPostFilter(expr); }
  115. void buildSegments(BuildCtx & ctx, const char * listName, bool _ignoreUnkeyed);
  116. void extractFilters(IHqlExpression * filter, SharedHqlExpr & extraFilter);
  117. void extractFilters(HqlExprArray & exprs, SharedHqlExpr & extraFilter);
  118. void extractFiltersFromFilterDs(IHqlExpression * expr);
  119. void extractAllFilters(IHqlExpression * filter);
  120. IHqlExpression * queryExtraFilter() { return keyed.postFilter; }
  121. IHqlExpression * getClearExtraFilter() { return keyed.postFilter.getClear(); }
  122. bool isCleanlyKeyedExplicitly() { return cleanlyKeyedExplicitly; }
  123. bool isKeyedExplicitly() { return keyedExplicitly; }
  124. bool isFiltered() { return keyed.postFilter || isKeyed(); }
  125. bool isKeyed();
  126. IHqlExpression * queryGlobalGuard() { return keyed.preFilter; }
  127. void reportFailureReason(IHqlExpression * cond) { failReason.reportError(translator, cond); }
  128. const char * queryKeyName(StringBuffer & s);
  129. void preventMerge(IHqlExpression * select) { if (select) noMergeSelects.append(*select); }
  130. bool isEqualityFilterBefore(IHqlExpression * select);
  131. unsigned queryKeySelectIndex(IHqlExpression * select) { return keyableSelects.find(*select); }
  132. bool createGroupingMonitor(BuildCtx ctx, const char * listName, IHqlExpression * select, unsigned & maxOffset);
  133. protected:
  134. void buildEmptyKeySegment(BuildMonitorState & buildState, BuildCtx & ctx, KeySelectorInfo & selectorInfo);
  135. void buildKeySegment(BuildMonitorState & buildState, BuildCtx & ctx, unsigned whichField, unsigned curSize);
  136. void buildKeySegmentExpr(BuildMonitorState & buildState, KeySelectorInfo & selectorInfo, BuildCtx & ctx, const char * target, IHqlExpression & thisKey, MonitorFilterKind filterKind);
  137. void buildKeySegmentCompareExpr(BuildMonitorState & buildState, KeySelectorInfo & selectorInfo, BuildCtx & ctx, const char * requiredSet, IHqlExpression & thisKey);
  138. void buildKeySegmentInExpr(BuildMonitorState & buildState, KeySelectorInfo & selectorInfo, BuildCtx & ctx, const char * target, IHqlExpression & thisKey, MonitorFilterKind filterKind);
  139. bool buildSingleKeyMonitor(StringBuffer & createMonitorText, KeySelectorInfo & selectorInfo, BuildCtx & ctx, IHqlExpression & thisKey);
  140. void callAddAll(BuildCtx & ctx, IHqlExpression * targetVar);
  141. IHqlExpression * castToFieldAndBack(IHqlExpression * left, IHqlExpression * right);
  142. bool containsTableSelects(IHqlExpression * expr);
  143. IHqlExpression * createRangeCompare(IHqlExpression * selector, IHqlExpression * value, IHqlExpression * lengthExpr, bool compareEqual);
  144. void createStringSet(BuildCtx & ctx, const char * target, unsigned size, ITypeInfo * type);
  145. KeyCondition * createTranslatedCondition(IHqlExpression * cond, KeyedKind keyedKind);
  146. bool extractBoolFieldFilter(KeyConditionInfo & matches, IHqlExpression * selector, KeyedKind keyedKind, bool compareValue);
  147. bool extractFilters(KeyConditionInfo & matches, IHqlExpression * filter, KeyedKind keyedKind);
  148. void extractFoldedWildFields(IHqlExpression * expr);
  149. bool extractIfFilter(KeyConditionInfo & matches, IHqlExpression * expr, KeyedKind keyedKind);
  150. bool extractSimpleCompareFilter(KeyConditionInfo & state, IHqlExpression * expr, KeyedKind keyedKind);
  151. void expandKeyableFields();
  152. void expandSelects(IHqlExpression * expr, IHqlSimpleScope * expandedScope, IHqlExpression * keySelector, IHqlExpression * expandedSelector);;
  153. bool extractOrFilter(KeyConditionInfo & matches, IHqlExpression * filter, KeyedKind keyedKind);
  154. IHqlExpression * getMonitorValueAddress(BuildCtx & ctx, IHqlExpression * value);
  155. IHqlExpression * getRangeLimit(ITypeInfo * fieldType, IHqlExpression * lengthExpr, IHqlExpression * value, int whichBoundary);
  156. IHqlExpression * invertTransforms(IHqlExpression * left, IHqlExpression * right);
  157. bool isEqualityFilter(IHqlExpression * select);
  158. bool isKeySelect(IHqlExpression * select);
  159. bool isIndexInvariant(IHqlExpression * expr, bool includeRoot);
  160. bool isPrevSelectKeyed(IHqlExpression * select);
  161. bool matchSubstringFilter(KeyConditionInfo & matches, node_operator op, IHqlExpression * left, IHqlExpression * right, KeyedKind keyedKind, bool & duplicate);
  162. IHqlExpression * isKeyableFilter(IHqlExpression * left, IHqlExpression * right, bool & duplicate, node_operator compareOp, KeyFailureInfo & reason, KeyedKind keyedKind);
  163. bool okToKey(IHqlExpression * select, KeyedKind keyedKind);
  164. IHqlExpression * queryKeyableSelector(IHqlExpression * expr);
  165. IHqlExpression * querySimpleJoinValue(IHqlExpression * field);
  166. void extractCompareInformation(BuildCtx & ctx, IHqlExpression * expr, SharedHqlExpr & compare, SharedHqlExpr & normalized, IHqlExpression * expandedSelector);
  167. void extractCompareInformation(BuildCtx & ctx, IHqlExpression * lhs, IHqlExpression * value, SharedHqlExpr & compare, SharedHqlExpr & normalized, IHqlExpression * expandedSelector);
  168. IHqlExpression * unwindConjunction(HqlExprArray & matches, IHqlExpression * expr);
  169. protected:
  170. void spotSegmentCSE(BuildCtx & ctx);
  171. class SelectSpotter : public NewHqlTransformer
  172. {
  173. public:
  174. SelectSpotter(const HqlExprArray & _selects);
  175. void analyseExpr(IHqlExpression * expr);
  176. public:
  177. bool hasSelects;
  178. const HqlExprArray & selects;
  179. };
  180. protected:
  181. IHqlExpression * tableExpr;
  182. HqlCppTranslator & translator;
  183. // LinkedHqlExpr filter;
  184. // LinkedHqlExpr globalGuard;
  185. KeyConditionInfo keyed;
  186. unsigned numKeyableFields;
  187. KeyFailureInfo failReason;
  188. HqlExprAttr keyableRecord;
  189. HqlExprArray keyableSelects;
  190. // expanded record + selects have bitfields/alien/varstrings expanded to a fixed size basic type.
  191. HqlExprAttr expandedRecord;
  192. HqlExprArray expandedSelects;
  193. HqlExprCopyArray noMergeSelects; // don't merge these fields (even for wildcards) because they are separate stepping fields.
  194. unsigned firstOffsetField; // first field where the keyed offset is adjusted
  195. bool onlyHozedCompares;
  196. bool ignoreUnkeyed;
  197. bool cleanlyKeyedExplicitly;
  198. bool keyedExplicitly;
  199. bool allowDynamicFormatChange;
  200. };
  201. //---------------------------------------------------------------------------
  202. struct VirtualFieldsInfo
  203. {
  204. public:
  205. VirtualFieldsInfo()
  206. {
  207. simpleVirtualsAtEnd = true;
  208. requiresDeserialize = false;
  209. }
  210. IHqlExpression * createPhysicalRecord();
  211. void gatherVirtualFields(IHqlExpression * record, bool ignoreVirtuals, bool ensureSerialized);
  212. bool hasVirtuals() { return virtuals.ordinality() != 0; }
  213. bool hasVirtualsOrDeserialize() { return requiresDeserialize || virtuals.ordinality() != 0; }
  214. bool needFilePosition() { return virtuals.ordinality() > 0; }
  215. bool needFilePosition(bool local);
  216. public:
  217. HqlExprArray physicalFields;
  218. HqlExprArray selects;
  219. HqlExprArray virtuals;
  220. bool simpleVirtualsAtEnd;
  221. bool requiresDeserialize;
  222. };
  223. //---------------------------------------------------------------------------
  224. unsigned getProjectCount(IHqlExpression * expr);
  225. IHqlExpression * createMetadataIndexRecord(IHqlExpression * record, bool hasInternalFilePosition);
  226. #endif