IHqlExpression * CMemberInfo::addDatasetLimits(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value) { LinkedHqlExpr value = _value; IHqlExpression * choosen = column->queryAttribute(choosenAtom); if (choosen) { LinkedHqlExpr choosenValue = choosen->queryChild(0); if (!choosenValue->queryValue()) { OwnedHqlExpr self = container->getRelativeSelf(); OwnedHqlExpr absoluteExpr = replaceSelector(choosenValue, querySelfReference(), self); choosenValue.setown(selector->queryRootRow()->bindToRow(absoluteExpr, querySelfReference())); } else { if (hasNoMoreRowsThan(value, getIntValue(choosenValue))) choosenValue.clear(); } if (choosenValue) value.setown(createDataset(no_choosen, LINK(value), LINK(choosenValue))); } IHqlExpression * maxCount = queryAttributeChild(column, maxCountAtom, 0); if (maxCount && !hasNoMoreRowsThan(value, getIntValue(maxCount))) { //Generate a limit test if there isn't a limit that ensures it is small enough StringBuffer failText, columnText; expandSelectPathText(columnText, true).toLowerCase(); failText.appendf("Too many rows assigned to field %s", columnText.str()); OwnedHqlExpr fail = translator.createFailAction(failText.str(), maxCount, NULL, translator.queryCurrentActivityId(ctx)); value.setown(createDataset(no_limit, LINK(value), createComma(LINK(maxCount), LINK(fail)))); } return value.getClear(); }
IHqlExpression* HqlGram::processAbstractDataset(IHqlExpression* _expr, IHqlExpression* formal, IHqlExpression* actual, IHqlExpression * mapping, const attribute& errpos, bool errorIfNotFound, bool & hadError) { LinkedHqlExpr transformed = _expr; IHqlExpression* formalRecord = formal->queryRecord(); IHqlExpression* actualRecord = actual->queryRecord(); assertex(formalRecord && actualRecord); hadError = false; IHqlSimpleScope *actualScope = actualRecord->querySimpleScope(); unsigned numChildren = formalRecord->numChildren(); for (unsigned idx = 0; idx < numChildren; idx++) { IHqlExpression* kid = formalRecord->queryChild(idx); if ((kid->getOperator() == no_ifblock) || kid->isAttribute()) continue; IIdAtom * name = kid->queryId(); IIdAtom * mapto = fieldMapTo(mapping, name); OwnedHqlExpr match = actualScope->lookupSymbol(mapto); if (match) { if (!kid->queryType()->assignableFrom(match->queryType())) { StringBuffer fromType, toType; getFriendlyTypeStr(kid,fromType); getFriendlyTypeStr(match,toType); reportError(ERR_DSPARAM_TYPEMISMATCH, errpos, "Can not mapping type %s(field '%s') to %s(field '%s')", fromType.str(), str(kid->queryName()), toType.str(), str(match->queryName())); hadError = true; } //MORE: This should really be mapped in a single go if (transformed) transformed.setown(bindField(transformed, kid, match)); } else if (errorIfNotFound) { reportError(ERR_DSPARM_MISSINGFIELD,errpos,"Dataset %s has no field named '%s'", str(actual->queryName()), str(mapto)); hadError = true; } } return transformed.getClear(); }