hqltcppc2.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "jliball.hpp"
  14. #include "hql.hpp"
  15. #include "platform.h"
  16. #include "jlib.hpp"
  17. #include "jexcept.hpp"
  18. #include "jmisc.hpp"
  19. #include "hql.hpp"
  20. #include "hqlexpr.hpp"
  21. #include "hqlfunc.hpp"
  22. #include "hqlcpputil.hpp"
  23. #include "hqlfold.hpp"
  24. #include "hqlutil.hpp"
  25. #include "hqlstmt.hpp"
  26. #include "hqlwcpp.hpp"
  27. #include "hqlcpp.ipp"
  28. #include "hqltcppc.ipp"
  29. #include "hqlhtcpp.ipp"
  30. #include "hqlcerrors.hpp"
  31. #include "hqlcatom.hpp"
  32. #include "hqlpmap.hpp"
  33. #include "hqlthql.hpp"
  34. #include "hqlattr.hpp"
  35. #include "hqlusage.hpp"
  36. //#define TraceExprPrintLog(x, expr) PrintLog(x ": %s", expr->toString(StringBuffer()).str());
  37. //---------------------------------------------------------------------------
  38. CChildSetColumnInfo::CChildSetColumnInfo(CContainerInfo * _container, CMemberInfo * _prior, IHqlExpression * _column) : CColumnInfo(_container, _prior, _column)
  39. {
  40. }
  41. void CChildSetColumnInfo::buildColumnExpr(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, CHqlBoundExpr & bound)
  42. {
  43. OwnedHqlExpr address = getColumnAddress(translator, ctx, selector, boolType, 0);
  44. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, sizeof(bool));
  45. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(bool)+sizeof(size32_t));
  46. bound.isAll.setown(convertAddressToValue(address, boolType));
  47. bound.length.setown(convertAddressToValue(addressSize, sizetType));
  48. bound.expr.setown(convertAddressToValue(addressData, queryType()));
  49. }
  50. void CChildSetColumnInfo::gatherSize(SizeStruct & target)
  51. {
  52. addVariableSize(sizeof(bool) + sizeof(size32_t), target);
  53. }
  54. IHqlExpression * CChildSetColumnInfo::buildSizeOfUnbound(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector)
  55. {
  56. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, sizeof(bool));
  57. OwnedHqlExpr length = convertAddressToValue(addressSize, sizetType);
  58. OwnedHqlExpr boundSize = translator.getBoundSize(column->queryType(), length, NULL);
  59. return createValue(no_translated, LINK(sizetType), adjustValue(boundSize, sizeof(bool)+sizeof(size32_t)));
  60. }
  61. void CChildSetColumnInfo::buildDeserialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
  62. {
  63. OwnedHqlExpr address = getColumnAddress(translator, ctx, selector, boolType, 0);
  64. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, sizeof(bool));
  65. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(bool)+sizeof(size32_t));
  66. size32_t sizeExtra = sizeof(bool)+sizeof(size32_t);
  67. //Read the all flag and the size
  68. OwnedHqlExpr sizeAllSizet = getSizetConstant(sizeExtra);
  69. callDeserializeGetN(translator, ctx, helper, sizeAllSizet, address);
  70. OwnedHqlExpr targetSize = convertAddressToValue(addressSize, sizetType);
  71. OwnedHqlExpr unboundSize = createTranslated(targetSize);
  72. checkAssignOk(translator, ctx, selector, unboundSize, sizeExtra);
  73. callDeserializeGetN(translator, ctx, helper, targetSize, addressData);
  74. OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
  75. OwnedHqlExpr srcSize = adjustValue(targetSize, sizeExtra);
  76. ctx.associateExpr(sizeOfExpr, srcSize);
  77. }
  78. bool CChildSetColumnInfo::buildReadAhead(HqlCppTranslator & translator, BuildCtx & ctx, ReadAheadState & state)
  79. {
  80. OwnedHqlExpr sizeAllFlag = getSizetConstant(1);
  81. callDeserializerSkipInputTranslatedSize(translator, ctx, state.helper, sizeAllFlag);
  82. OwnedHqlExpr sizeOfItems = callDeserializerGetSize(translator, ctx, state.helper);
  83. callDeserializerSkipInputTranslatedSize(translator, ctx, state.helper, sizeOfItems);
  84. return true;
  85. }
  86. void CChildSetColumnInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value)
  87. {
  88. OwnedHqlExpr address = getColumnAddress(translator, ctx, selector, boolType, 0);
  89. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, sizeof(bool));
  90. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(bool)+sizeof(size32_t));
  91. OwnedHqlExpr isAllTarget = convertAddressToValue(address, boolType);
  92. OwnedHqlExpr lengthTarget = convertAddressToValue(addressSize, sizetType);
  93. ITypeInfo * columnType = column->queryType();
  94. ITypeInfo * elementType = columnType->queryChildType();
  95. OwnedHqlExpr value = ensureExprType(_value, columnType);
  96. OwnedHqlExpr inlineSize;
  97. switch (value->getOperator())
  98. {
  99. case no_list:
  100. if ((value->numChildren() != 0) && ::isFixedSize(elementType))
  101. inlineSize.setown(getSizetConstant(value->numChildren() * elementType->getSize()));
  102. break;
  103. }
  104. if (inlineSize)
  105. {
  106. checkAssignOk(translator, ctx, selector, inlineSize, sizeof(size32_t)+sizeof(bool));
  107. Owned<IHqlCppSetBuilder> builder = translator.createInlineSetBuilder(elementType, isAllTarget, inlineSize, addressData);
  108. builder->buildDeclare(ctx);
  109. translator.buildSetAssign(ctx, builder, value);
  110. CHqlBoundTarget boundTarget;
  111. boundTarget.length.set(lengthTarget);
  112. builder->buildFinish(ctx, boundTarget);
  113. }
  114. else
  115. {
  116. CHqlBoundExpr bound;
  117. if ((value->getOperator() == no_list) && value->numChildren())
  118. {
  119. CHqlBoundTarget tempTarget;
  120. translator.createTempFor(ctx, columnType, tempTarget, typemod_none, FormatNatural);
  121. translator.buildExprAssign(ctx, tempTarget, value);
  122. bound.setFromTarget(tempTarget);
  123. }
  124. else
  125. translator.buildExpr(ctx, value, bound);
  126. ensureSimpleLength(translator, ctx, bound);
  127. OwnedHqlExpr isAll = bound.getIsAll();
  128. OwnedHqlExpr length = translator.getBoundLength(bound);
  129. OwnedHqlExpr size = createValue(no_translated, LINK(sizetType), translator.getBoundSize(bound));
  130. checkAssignOk(translator, ctx, selector, size, sizeof(size32_t)+sizeof(bool));
  131. translator.assignBoundToTemp(ctx, isAllTarget, isAll);
  132. translator.assignBoundToTemp(ctx, lengthTarget, length);
  133. translator.buildBlockCopy(ctx, addressData, bound);
  134. ensureSimpleLength(translator, ctx, bound);
  135. OwnedHqlExpr boundSize = translator.getBoundSize(bound);
  136. associateSizeOf(ctx, selector, boundSize, sizeof(size32_t)+sizeof(bool));
  137. }
  138. }
  139. //---------------------------------------------------------------------------
  140. IHqlExpression * CMemberInfo::addDatasetLimits(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value)
  141. {
  142. LinkedHqlExpr value = _value;
  143. IHqlExpression * choosen = column->queryAttribute(choosenAtom);
  144. if (choosen)
  145. {
  146. LinkedHqlExpr choosenValue = choosen->queryChild(0);
  147. if (!choosenValue->queryValue())
  148. {
  149. OwnedHqlExpr self = container->getRelativeSelf();
  150. OwnedHqlExpr absoluteExpr = replaceSelector(choosenValue, querySelfReference(), self);
  151. choosenValue.setown(selector->queryRootRow()->bindToRow(absoluteExpr, querySelfReference()));
  152. }
  153. else
  154. {
  155. if (hasNoMoreRowsThan(value, getIntValue(choosenValue)))
  156. choosenValue.clear();
  157. }
  158. if (choosenValue)
  159. value.setown(createDataset(no_choosen, LINK(value), LINK(choosenValue)));
  160. }
  161. IHqlExpression * maxCount = queryAttributeChild(column, maxCountAtom, 0);
  162. if (maxCount && !hasNoMoreRowsThan(value, getIntValue(maxCount)))
  163. {
  164. //Generate a limit test if there isn't a limit that ensures it is small enough
  165. StringBuffer failText, columnText;
  166. expandSelectPathText(columnText, true).toLowerCase();
  167. failText.appendf("Too many rows assigned to field %s", columnText.str());
  168. OwnedHqlExpr fail = translator.createFailAction(failText.str(), maxCount, NULL, translator.queryCurrentActivityId(ctx));
  169. value.setown(createDataset(no_limit, LINK(value), createComma(LINK(maxCount), LINK(fail))));
  170. }
  171. return value.getClear();
  172. }
  173. bool CMemberInfo::hasDatasetLimits() const
  174. {
  175. if (column->queryAttribute(choosenAtom))
  176. return true;
  177. if (queryAttributeChild(column, maxCountAtom, 0))
  178. return true;
  179. return false;
  180. }
  181. CChildDatasetColumnInfo::CChildDatasetColumnInfo(CContainerInfo * _container, CMemberInfo * _prior, IHqlExpression * _column, RecordOffsetMap & map, unsigned defaultMaxRecordSize) : CColumnInfo(_container, _prior, _column)
  182. {
  183. ColumnToOffsetMap * offsetMap = map.queryMapping(column->queryRecord(), defaultMaxRecordSize);
  184. maxChildSize = offsetMap->getMaxSize();
  185. #ifdef _DEBUG
  186. assertex(!recordRequiresSerialization(column->queryRecord(), internalAtom));
  187. #endif
  188. }
  189. void CChildDatasetColumnInfo::buildColumnExpr(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, CHqlBoundExpr & bound)
  190. {
  191. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  192. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));
  193. bound.length.setown(convertAddressToValue(addressSize, sizetType));
  194. bound.expr.setown(convertAddressToValue(addressData, queryType()));
  195. }
  196. void CChildDatasetColumnInfo::gatherSize(SizeStruct & target)
  197. {
  198. addVariableSize(sizeof(size32_t), target);
  199. }
  200. void CColumnInfo::buildDeserializeChildLoop(HqlCppTranslator & translator, BuildCtx & loopctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
  201. {
  202. OwnedHqlExpr endMarker = loopctx.getTempDeclare(sizetType, NULL);
  203. HqlExprArray args;
  204. args.append(*LINK(helper));
  205. OwnedHqlExpr beginCall = translator.bindTranslatedFunctionCall(deserializerBeginNestedId, args);
  206. loopctx.addAssign(endMarker, beginCall);
  207. args.append(*LINK(helper));
  208. args.append(*LINK(endMarker));
  209. OwnedHqlExpr loopCall = createBoolExpr(no_not, translator.bindTranslatedFunctionCall(deserializerFinishedNestedId, args));
  210. loopctx.addLoop(loopCall, NULL, false);
  211. }
  212. void CColumnInfo::buildDeserializeToBuilder(HqlCppTranslator & translator, BuildCtx & ctx, IHqlCppDatasetBuilder * builder, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
  213. {
  214. BuildCtx loopctx(ctx);
  215. buildDeserializeChildLoop(translator, loopctx, selector, helper, serializeForm);
  216. BoundRow * selfRow = builder->buildDeserializeRow(loopctx, helper, serializeForm);
  217. builder->finishRow(loopctx, selfRow);
  218. }
  219. void CChildDatasetColumnInfo::buildDeserialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
  220. {
  221. IHqlExpression * record = column->queryRecord();
  222. assertex(!recordRequiresLinkCount(record)); // Why would it?
  223. if (column->isDictionary())
  224. {
  225. if (serializeForm == diskAtom)
  226. {
  227. //If we ever generate the meta definition for an internal serialization format then the following needs to be implemented
  228. UNIMPLEMENTED_X("deserialize serialized dictionary from disk");
  229. return;
  230. }
  231. }
  232. if (isConditional())
  233. checkAssignOk(translator, ctx, selector, queryZero(), sizeof(size32_t));
  234. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  235. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));
  236. //Read the all flag and the size
  237. OwnedHqlExpr sizeSizet = getSizetConstant(sizeof(size32_t));
  238. callDeserializeGetN(translator, ctx, helper, sizeSizet, addressSize);
  239. OwnedHqlExpr targetSize = convertAddressToValue(addressSize, sizetType);
  240. OwnedHqlExpr simpleSize = translator.ensureSimpleTranslatedExpr(ctx, targetSize);
  241. OwnedHqlExpr unboundSize = createTranslated(simpleSize);
  242. checkAssignOk(translator, ctx, selector, unboundSize, sizeof(size32_t));
  243. callDeserializeGetN(translator, ctx, helper, simpleSize, addressData);
  244. OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
  245. OwnedHqlExpr srcSize = adjustValue(simpleSize, sizeof(size32_t));
  246. ctx.associateExpr(sizeOfExpr, srcSize);
  247. }
  248. void CChildDatasetColumnInfo::buildSerialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
  249. {
  250. if (column->isDictionary())
  251. {
  252. if (serializeForm == diskAtom)
  253. {
  254. //If we ever generate the meta definition for an internal serialization format then the following needs to be implemented
  255. UNIMPLEMENTED_X("deserialize serialized dictionary from disk");
  256. }
  257. }
  258. CColumnInfo::buildSerialize(translator, ctx, selector, helper, serializeForm);
  259. }
  260. bool CChildDatasetColumnInfo::buildReadAhead(HqlCppTranslator & translator, BuildCtx & ctx, ReadAheadState & state)
  261. {
  262. OwnedHqlExpr sizeOfDataset = callDeserializerGetSize(translator, ctx, state.helper);
  263. callDeserializerSkipInputTranslatedSize(translator, ctx, state.helper, sizeOfDataset);
  264. return true;
  265. }
  266. IHqlExpression * CChildDatasetColumnInfo::buildSizeOfUnbound(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector)
  267. {
  268. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  269. OwnedHqlExpr length = convertAddressToValue(addressSize, sizetType);
  270. OwnedHqlExpr boundSize = translator.getBoundSize(column->queryType(), length, NULL);
  271. return createValue(no_translated, LINK(sizetType), adjustValue(boundSize, sizeof(size32_t)));
  272. }
  273. void CChildDatasetColumnInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value)
  274. {
  275. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  276. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));
  277. OwnedHqlExpr lengthTarget = convertAddressToValue(addressSize, sizetType);
  278. ITypeInfo * columnType = column->queryType();
  279. OwnedHqlExpr value = LINK(_value); //ensureExprType(_value, columnType);
  280. ITypeInfo * valueType = value->queryType();
  281. assertRecordTypesMatch(valueType, columnType);
  282. bool assignInline = false; // canEvaluateInline(value); // MORE: What is the test
  283. // bool assignInline = canAssignInline(&ctx, value) && !canEvaluateInline(&ctx, value);
  284. value.setown(addDatasetLimits(translator, ctx, selector, value));
  285. IHqlExpression * record = column->queryRecord();
  286. if (assignInline)
  287. {
  288. OwnedHqlExpr inlineSize = getSizetConstant(0);
  289. checkAssignOk(translator, ctx, selector, inlineSize, sizeof(size32_t));
  290. //Can only assign inline if we know the maximum length that will be assigned is 0.
  291. Owned<IHqlCppDatasetBuilder> builder = translator.createInlineDatasetBuilder(record, inlineSize, addressData);
  292. builder->buildDeclare(ctx);
  293. translator.buildDatasetAssign(ctx, builder, value);
  294. CHqlBoundTarget boundTarget;
  295. boundTarget.length.set(lengthTarget);
  296. builder->buildFinish(ctx, boundTarget);
  297. }
  298. else
  299. {
  300. CHqlBoundExpr bound;
  301. translator.buildDataset(ctx, value, bound, FormatBlockedDataset);
  302. translator.normalizeBoundExpr(ctx, bound);
  303. ensureSimpleLength(translator, ctx, bound);
  304. OwnedHqlExpr length = translator.getBoundLength(bound);
  305. OwnedHqlExpr size = createValue(no_translated, LINK(sizetType), translator.getBoundSize(bound));
  306. checkAssignOk(translator, ctx, selector, size, sizeof(size32_t));
  307. translator.assignBoundToTemp(ctx, lengthTarget, length);
  308. translator.buildBlockCopy(ctx, addressData, bound);
  309. //Use the size just calculated for the field
  310. OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
  311. OwnedHqlExpr boundSize = translator.getBoundSize(bound);
  312. OwnedHqlExpr srcSize = adjustValue(boundSize, sizeof(size32_t));
  313. ctx.associateExpr(sizeOfExpr, srcSize);
  314. }
  315. }
  316. AColumnInfo * CChildDatasetColumnInfo::lookupColumn(IHqlExpression * search)
  317. {
  318. throwError1(HQLERR_LookupNotActiveDataset, search->queryName()->str());
  319. return NULL;
  320. }
  321. //---------------------------------------------------------------------------
  322. CChildLimitedDatasetColumnInfo::CChildLimitedDatasetColumnInfo(CContainerInfo * _container, CMemberInfo * _prior, IHqlExpression * _column, RecordOffsetMap & map, unsigned defaultMaxRecordSize) : CColumnInfo(_container, _prior, _column)
  323. {
  324. IHqlExpression * count = column->queryAttribute(countAtom);
  325. if (count)
  326. countField.setown(foldHqlExpression(column->queryAttribute(countAtom)->queryChild(0)));
  327. else
  328. {
  329. IHqlExpression * size = column->queryAttribute(sizeofAtom);
  330. if (size)
  331. sizeField.setown(foldHqlExpression(size->queryChild(0)));
  332. else
  333. countField.setown(createConstantOne());
  334. }
  335. if (countField)
  336. countField.setown(ensureExprType(countField, sizetType));
  337. if (sizeField)
  338. sizeField.setown(ensureExprType(sizeField, sizetType));
  339. ColumnToOffsetMap * offsetMap = map.queryMapping(column->queryRecord(), defaultMaxRecordSize);
  340. maxChildSize = offsetMap->getMaxSize();
  341. fixedChildSize = offsetMap->isFixedWidth() ? maxChildSize : UNKNOWN_LENGTH;
  342. }
  343. void CChildLimitedDatasetColumnInfo::buildColumnExpr(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, CHqlBoundExpr & bound)
  344. {
  345. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), 0);
  346. if (countField)
  347. {
  348. OwnedHqlExpr mappedCount = replaceSelector(countField, querySelfReference(), selector->queryExpr()->queryChild(0));
  349. CHqlBoundExpr boundCount;
  350. translator.buildExpr(ctx, mappedCount, boundCount);
  351. bound.count.set(boundCount.expr);
  352. }
  353. else
  354. {
  355. OwnedHqlExpr mappedSize = replaceSelector(sizeField, querySelfReference(), selector->queryExpr()->queryChild(0));
  356. CHqlBoundExpr boundSize;
  357. translator.buildExpr(ctx, mappedSize, boundSize);
  358. bound.length.set(boundSize.expr);
  359. }
  360. bound.expr.setown(convertAddressToValue(addressData, queryType()));
  361. }
  362. void CChildLimitedDatasetColumnInfo::gatherSize(SizeStruct & target)
  363. {
  364. if (isFixedSize())
  365. {
  366. unsigned fixedSize;
  367. if (sizeField && sizeField->queryValue())
  368. fixedSize = (unsigned)getIntValue(sizeField);
  369. else
  370. {
  371. fixedSize = (unsigned)getIntValue(countField) * fixedChildSize;
  372. }
  373. if (isConditional())
  374. addVariableSize(fixedSize, target);
  375. else
  376. target.addFixed(fixedSize);
  377. }
  378. else
  379. {
  380. addVariableSize(0, target);
  381. }
  382. }
  383. IHqlExpression * CChildLimitedDatasetColumnInfo::buildSizeOfUnbound(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector)
  384. {
  385. CHqlBoundExpr bound;
  386. buildColumnExpr(translator, ctx, selector, bound);
  387. OwnedHqlExpr length = translator.getBoundLength(bound);
  388. return createTranslated(length);
  389. }
  390. bool CChildLimitedDatasetColumnInfo::isFixedSize()
  391. {
  392. if (sizeField && sizeField->queryValue())
  393. return true;
  394. if (countField && countField->queryValue() && (fixedChildSize != UNKNOWN_LENGTH))
  395. return true;
  396. return false; //MORE:
  397. }
  398. void CChildLimitedDatasetColumnInfo::buildDeserializeChildLoop(HqlCppTranslator & translator, BuildCtx & loopctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
  399. {
  400. OwnedHqlExpr mappedCount = replaceSelector(countField, querySelfReference(), selector->queryExpr()->queryChild(0));
  401. CHqlBoundExpr bound;
  402. translator.buildTempExpr(loopctx, mappedCount, bound);
  403. OwnedHqlExpr test = createValue(no_postdec, LINK(bound.expr));
  404. loopctx.addLoop(test, NULL, false);
  405. }
  406. bool CChildLimitedDatasetColumnInfo::prepareReadAhead(HqlCppTranslator & translator, ReadAheadState & state)
  407. {
  408. OwnedHqlExpr self = container->getRelativeSelf();
  409. if (sizeField)
  410. {
  411. OwnedHqlExpr mappedSize = replaceSelector(sizeField, querySelfReference(), self);
  412. gatherSelectExprs(state.requiredValues, mappedSize);
  413. }
  414. else if (countField)
  415. {
  416. OwnedHqlExpr mappedCount = replaceSelector(countField, querySelfReference(), self);
  417. gatherSelectExprs(state.requiredValues, mappedCount);
  418. }
  419. return true;
  420. }
  421. bool CChildLimitedDatasetColumnInfo::buildReadAhead(HqlCppTranslator & translator, BuildCtx & ctx, ReadAheadState & state)
  422. {
  423. try
  424. {
  425. OwnedHqlExpr self = container->getRelativeSelf();
  426. if (sizeField)
  427. {
  428. OwnedHqlExpr mappedSize = replaceSelector(sizeField, querySelfReference(), self);
  429. OwnedHqlExpr replacedSize = quickFullReplaceExpressions(mappedSize, state.requiredValues, state.mappedValues);
  430. if (containsSelector(replacedSize, queryRootSelf()))
  431. return false;
  432. callDeserializerSkipInputSize(translator, ctx, state. helper, replacedSize);
  433. return true;
  434. }
  435. else
  436. {
  437. OwnedHqlExpr mappedCount = replaceSelector(countField, querySelfReference(), self);
  438. OwnedHqlExpr replacedCount = quickFullReplaceExpressions(mappedCount, state.requiredValues, state.mappedValues);
  439. if (containsSelector(replacedCount, queryRootSelf()))
  440. return false;
  441. if (fixedChildSize != UNKNOWN_LENGTH)
  442. {
  443. OwnedHqlExpr scaledSize = multiplyValue(replacedCount, fixedChildSize);
  444. callDeserializerSkipInputSize(translator, ctx, state. helper, scaledSize);
  445. return true;
  446. }
  447. BuildCtx loopctx(ctx);
  448. CHqlBoundExpr bound;
  449. translator.buildTempExpr(loopctx, replacedCount, bound);
  450. OwnedHqlExpr test = createValue(no_postdec, LINK(bound.expr));
  451. loopctx.addLoop(test, NULL, false);
  452. StringBuffer prefetcherInstanceName;
  453. translator.ensureRowPrefetcher(prefetcherInstanceName, ctx, column->queryRecord());
  454. StringBuffer s;
  455. s.append(prefetcherInstanceName).append("->readAhead(");
  456. translator.generateExprCpp(s, state.helper).append(");");
  457. loopctx.addQuoted(s);
  458. return true;
  459. }
  460. }
  461. catch (IException * e)
  462. {
  463. //yuk yuk yuk!! Couldn't resolve the dataset count/size for some strange reason
  464. e->Release();
  465. }
  466. return false;
  467. }
  468. void CChildLimitedDatasetColumnInfo::buildDeserialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
  469. {
  470. assertex(!column->isDictionary());
  471. if (sizeField || !countField)
  472. {
  473. ctx.addQuoted("rtlFailUnexpected();");
  474. return;
  475. }
  476. //NB: The serialized form of a dataset with an external count is not the same as a normal dataset
  477. IHqlExpression * record = column->queryRecord();
  478. if (recordRequiresSerialization(record, serializeForm) || !translator.isFixedRecordSize(record))
  479. {
  480. Owned<IHqlCppDatasetBuilder> builder = translator.createBlockedDatasetBuilder(column->queryRecord());
  481. builder->buildDeclare(ctx);
  482. buildDeserializeToBuilder(translator, ctx, builder, selector, helper, serializeForm);
  483. CHqlBoundExpr bound;
  484. builder->buildFinish(ctx, bound);
  485. setColumnFromBuilder(translator, ctx, selector, builder);
  486. }
  487. else
  488. CColumnInfo::buildDeserialize(translator, ctx, selector, helper, serializeForm);
  489. }
  490. void CChildLimitedDatasetColumnInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * value)
  491. {
  492. if (sizeField)
  493. translator.throwError(HQLERR_CannotCreateSizedChildDataset);
  494. if (countField)
  495. {
  496. IHqlExpression * record = column->queryRecord();
  497. OwnedHqlExpr mappedCount = replaceSelector(countField, querySelfReference(), selector->queryExpr()->queryChild(0));
  498. Owned<IHqlCppDatasetBuilder> builder = translator.createLimitedDatasetBuilder(record, mappedCount);
  499. builder->buildDeclare(ctx);
  500. translator.buildDatasetAssign(ctx, builder, value);
  501. setColumnFromBuilder(translator, ctx, selector, builder);
  502. }
  503. }
  504. void CChildLimitedDatasetColumnInfo::setColumnFromBuilder(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlCppDatasetBuilder * builder)
  505. {
  506. CHqlBoundExpr bound;
  507. builder->buildFinish(ctx, bound);
  508. if (bound.length)
  509. bound.length.setown(translator.ensureSimpleTranslatedExpr(ctx, bound.length));
  510. OwnedHqlExpr size = createValue(no_translated, LINK(sizetType), translator.getBoundSize(bound));
  511. checkAssignOk(translator, ctx, selector, size, 0);
  512. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), 0);
  513. translator.buildBlockCopy(ctx, addressData, bound);
  514. //Use the size just calculated for the field
  515. OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
  516. OwnedHqlExpr srcSize = translator.getBoundSize(bound);
  517. ctx.associateExpr(sizeOfExpr, srcSize);
  518. }
  519. AColumnInfo * CChildLimitedDatasetColumnInfo::lookupColumn(IHqlExpression * search)
  520. {
  521. throwError1(HQLERR_LookupNotActiveDataset, search->queryName()->str());
  522. return NULL;
  523. }
  524. //--------------------------------------------------------------------------------------------
  525. CChildLinkedDatasetColumnInfo::CChildLinkedDatasetColumnInfo(CContainerInfo * _container, CMemberInfo * _prior, IHqlExpression * _column, RecordOffsetMap & map, unsigned defaultMaxRecordSize) : CColumnInfo(_container, _prior, _column)
  526. {
  527. ColumnToOffsetMap * offsetMap = map.queryMapping(column->queryRecord(), defaultMaxRecordSize);
  528. maxChildSize = offsetMap->getMaxSize();
  529. }
  530. void CChildLinkedDatasetColumnInfo::buildColumnExpr(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, CHqlBoundExpr & bound)
  531. {
  532. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  533. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));
  534. bound.count.setown(convertAddressToValue(addressSize, sizetType));
  535. bound.expr.setown(convertAddressToValue(addressData, queryType()));
  536. }
  537. void CChildLinkedDatasetColumnInfo::gatherSize(SizeStruct & target)
  538. {
  539. unsigned thisSize = sizeof(size32_t) + sizeof(byte * *);
  540. if (isConditional())
  541. addVariableSize(thisSize, target); // the size is used for ensure if condition is true
  542. else
  543. target.addFixed(thisSize);
  544. }
  545. IHqlExpression * CChildLinkedDatasetColumnInfo::buildSizeOfUnbound(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector)
  546. {
  547. return getSizetConstant(sizeof(size32_t) + sizeof(byte * *));
  548. }
  549. void CChildLinkedDatasetColumnInfo::buildDeserialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeFormat)
  550. {
  551. if (isConditional())
  552. checkAssignOk(translator, ctx, selector, queryZero(), sizeof(size32_t) + sizeof(byte * *));
  553. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  554. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));
  555. IHqlExpression * record = column->queryRecord();
  556. CHqlBoundTarget boundTarget;
  557. boundTarget.count.setown(convertAddressToValue(addressSize, sizetType));
  558. boundTarget.expr.setown(convertAddressToValue(addressData, queryType()));
  559. IIdAtom * func = NULL;
  560. HqlExprArray args;
  561. args.append(*translator.createSerializer(ctx, record, serializeFormat, deserializerAtom));
  562. if (column->isDictionary())
  563. {
  564. if (serializeFormat == diskAtom)
  565. {
  566. func = deserializeChildDictionaryFromDatasetFromStreamId;
  567. StringBuffer lookupHelperName;
  568. translator.buildDictionaryHashClass(record, lookupHelperName);
  569. args.append(*createQuoted(lookupHelperName.str(), makeBoolType()));
  570. }
  571. else
  572. func = deserializeChildDictionaryFromStreamId;
  573. }
  574. else
  575. func = deserializeChildRowsetFromStreamId;
  576. args.append(*LINK(helper));
  577. OwnedHqlExpr call = translator.bindFunctionCall(func, args, queryType());
  578. translator.buildExprAssign(ctx, boundTarget, call);
  579. }
  580. bool CChildLinkedDatasetColumnInfo::buildReadAhead(HqlCppTranslator & translator, BuildCtx & ctx, ReadAheadState & state)
  581. {
  582. OwnedHqlExpr sizeOfDataset = callDeserializerGetSize(translator, ctx, state.helper);
  583. callDeserializerSkipInputTranslatedSize(translator, ctx, state.helper, sizeOfDataset);
  584. return true;
  585. }
  586. void CChildLinkedDatasetColumnInfo::buildSerialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeFormat)
  587. {
  588. IHqlExpression * record = column->queryRecord();
  589. IIdAtom * func = NULL;
  590. HqlExprArray args;
  591. args.append(*LINK(helper));
  592. args.append(*translator.createSerializer(ctx, record, serializeFormat, serializerAtom));
  593. args.append(*LINK(selector->queryExpr()));
  594. if (column->isDictionary())
  595. {
  596. if (serializeFormat == diskAtom)
  597. func = serializeChildDictionaryToDatasetToStreamId;
  598. else
  599. func = serializeChildDictionaryToStreamId;
  600. }
  601. else
  602. func = serializeChildRowsetToStreamId;
  603. OwnedHqlExpr call = translator.bindTranslatedFunctionCall(func, args);
  604. translator.buildStmt(ctx, call);
  605. }
  606. bool CChildLinkedDatasetColumnInfo::modifyColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * value, node_operator op)
  607. {
  608. if (hasDatasetLimits() || (op != no_assign_addfiles))
  609. return false;
  610. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  611. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));
  612. ITypeInfo * resultType = queryType();
  613. ITypeInfo * valueType = value->queryType();
  614. assertex(recordTypesMatch(valueType, resultType));
  615. CHqlBoundTarget boundTarget;
  616. boundTarget.count.setown(convertAddressToValue(addressSize, sizetType));
  617. boundTarget.expr.setown(convertAddressToValue(addressData, queryType()));
  618. HqlExprArray args;
  619. args.append(*LINK(value));
  620. OwnedHqlExpr call = translator.bindFunctionCall(appendRowsToRowsetId, args, resultType);
  621. translator.buildDatasetAssign(ctx, boundTarget, call);
  622. return true;
  623. }
  624. void CChildLinkedDatasetColumnInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value)
  625. {
  626. OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
  627. OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));
  628. ITypeInfo * resultType = queryType();
  629. LinkedHqlExpr value = _value;
  630. ITypeInfo * valueType = value->queryType();
  631. assertRecordTypesMatch(resultType, valueType);
  632. value.setown(addDatasetLimits(translator, ctx, selector, value));
  633. CHqlBoundTarget boundTarget;
  634. boundTarget.count.setown(convertAddressToValue(addressSize, sizetType));
  635. boundTarget.expr.setown(convertAddressToValue(addressData, queryType()));
  636. if (value->getOperator() == no_null)
  637. value.setown(createNullExpr(column));
  638. translator.buildDatasetAssign(ctx, boundTarget, value);
  639. }
  640. AColumnInfo * CChildLinkedDatasetColumnInfo::lookupColumn(IHqlExpression * search)
  641. {
  642. throwError1(HQLERR_LookupNotActiveDataset, search->queryName()->str());
  643. return NULL;
  644. }