static IHqlExpression * queryLibraryInputSequence(IHqlExpression * expr) { IHqlExpression * arg = expr->queryChild(0); if (arg->isRecord()) arg = expr->queryChild(1); return arg; }
ForEachItemIn(i2, expandedOrder) { IHqlExpression * cur = &expandedOrder.item(i2); if (explicitStepped) { if (!extractCondition(stepArgs, cur)) { StringBuffer s; if (cur->getOperator() == no_select) s.append(cur->queryChild(1)->queryName()); else getExprECL(cur, s); throwError1(HQLERR_SteppingNotMatchSortCondition, s.str()); } if (stepArgs.ordinality() == 0) break; } else { if (!extractCondition(args, cur)) break; foundStepped = true; } if (compareLhs) break; }
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(); }
bool isSelectSortedTop(IHqlExpression * selectExpr) { IHqlExpression * index = selectExpr->queryChild(1); if (matchesConstantValue(index, 1)) { IHqlExpression * ds = selectExpr->queryChild(0); return ((ds->getOperator() == no_sort) || (ds->getOperator() == no_topn)); } return false; }
bool HqlGram::checkTemplateFunctionParameters(IHqlExpression* func, HqlExprArray& actuals, const attribute& errpos) { bool anyErrors = false; IHqlExpression * formals = func->queryChild(1); ForEachItemIn(idx, actuals) { IHqlExpression* formal = formals->queryChild(idx); if (isAbstractDataset(formal)) { IHqlExpression * actual = &actuals.item(idx); IHqlExpression* mapping = queryFieldMap(actual); bool hadError = false; OwnedHqlExpr ignore = processAbstractDataset(NULL, formal, actual, mapping, errpos, true, hadError); if (hadError) anyErrors = true; } }
IHqlExpression * HqlCppCaseInfo::buildIndexedMap(BuildCtx & ctx, IHqlExpression * test, unsigned lower, unsigned upper) { ITypeInfo * compareType = test->queryType()->queryPromotedType(); type_t compareTypeCode = compareType->getTypeCode(); HqlExprArray values; IHqlExpression * dft = queryActiveTableSelector(); // value doesn't matter as long as it will not occur unsigned num = (upper-lower+1); values.ensure(num); unsigned idx; for (idx = 0; idx < num; idx++) values.append(*LINK(dft)); ForEachItemIn(idx2, pairs) { IHqlExpression & cur = pairs.item(idx2); IValue * value = cur.queryChild(0)->queryValue(); unsigned replaceIndex; switch (compareTypeCode) { case type_int: replaceIndex = (int)value->getIntValue()-lower; break; case type_string: { StringBuffer temp; value->getStringValue(temp); replaceIndex = (int)(unsigned char)temp.charAt(0)-lower; break; } default: throwUnexpectedType(compareType); } IHqlExpression * mapTo = cur.queryChild(1); if (mapTo->getOperator() != no_constant) throwUnexpected(); if (replaceIndex >= num) translator.reportWarning(CategoryIgnored, HQLWRN_CaseCanNeverMatch, "CASE entry %d can never match the test condition", replaceIndex); else values.replace(*LINK(mapTo),replaceIndex); }
void HqlCppCaseInfo::addPair(IHqlExpression * expr) { pairs.append(*LINK(expr)); IHqlExpression * compareValue = expr->queryChild(0); if (!compareValue->queryValue()) constantCases = false; if (!expr->queryChild(1)->queryValue()) constantValues = false; if (cond && !complexCompare) { ITypeInfo * valueType = compareValue->queryType(); if (valueType != cond->queryType()) complexCompare = isCompare3Valued(compareValue->queryType()); } updateResultType(expr->queryChild(1)); }
CChildLimitedDatasetColumnInfo::CChildLimitedDatasetColumnInfo(CContainerInfo * _container, CMemberInfo * _prior, IHqlExpression * _column, RecordOffsetMap & map, unsigned defaultMaxRecordSize) : CColumnInfo(_container, _prior, _column) { IHqlExpression * count = column->queryAttribute(countAtom); if (count) countField.setown(foldHqlExpression(column->queryAttribute(countAtom)->queryChild(0))); else { IHqlExpression * size = column->queryAttribute(sizeofAtom); if (size) sizeField.setown(foldHqlExpression(size->queryChild(0))); else countField.setown(createConstantOne()); } if (countField) countField.setown(ensureExprType(countField, sizetType)); if (sizeField) sizeField.setown(ensureExprType(sizeField, sizetType)); ColumnToOffsetMap * offsetMap = map.queryMapping(column->queryRecord(), defaultMaxRecordSize); maxChildSize = offsetMap->getMaxSize(); fixedChildSize = offsetMap->isFixedWidth() ? maxChildSize : UNKNOWN_LENGTH; }
bool ECLlocation::extractLocationAttr(const IHqlExpression * location) { if (!location) { clear(); return false; } if (location->isAttribute()) { if (location->queryName() != _location_Atom) return false; IHqlExpression * sourceExpr = location->queryChild(3); if (sourceExpr) sourcePath = static_cast<ISourcePath *>(sourceExpr->queryUnknownExtra()); else sourcePath = NULL; lineno = (int)getIntValue(location->queryChild(0)); column = (int)getIntValue(location->queryChild(1)); position = (int)getIntValue(location->queryChild(2)); return true; } IHqlExpression * annotation = queryLocation(const_cast<IHqlExpression *>(location)); if (annotation) { sourcePath = annotation->querySourcePath(); lineno = annotation->getStartLine(); column = annotation->getStartColumn(); position = 0; return true; } return false; }
ForEachChild(i, record) { IHqlExpression * cur = record->queryChild(i); switch (cur->getOperator()) { case no_record: //MORE: If this is a public symbol it should be expanded, otherwise it will be elsewhere. expandRecordSymbolsMeta(metaTree, cur); break; case no_field: { IPropertyTree * field = metaTree->addPropTree("Field"); field->setProp("@name", str(cur->queryId())); StringBuffer ecltype; cur->queryType()->getECLType(ecltype); field->setProp("@type", ecltype); break; } case no_ifblock: { IPropertyTree * block = metaTree->addPropTree("IfBlock"); expandRecordSymbolsMeta(block, cur->queryChild(1)); break; } case no_attr: case no_attr_link: case no_attr_expr: { IPropertyTree * attr = metaTree->addPropTree("Attr"); attr->setProp("@name", str(cur->queryName())); break; } } }
void HqlCppCaseInfo::addPair(IHqlExpression * expr) { IHqlExpression * compareExpr = expr->queryChild(0); IHqlExpression * resultExpr = expr->queryChild(1); if (allResultsMatch && pairs.ordinality()) { if (pairs.tos().queryChild(1) != resultExpr) allResultsMatch = false; } pairs.append(*LINK(expr)); if (!compareExpr->queryValue()) { constantCases = false; } else if (constantCases) { if (!lowestCompareExpr || compareValues(compareExpr, lowestCompareExpr) < 0) lowestCompareExpr.set(compareExpr); if (!highestCompareExpr || compareValues(compareExpr, highestCompareExpr) > 0) highestCompareExpr.set(compareExpr); } if (!expr->queryChild(1)->queryValue()) constantValues = false; if (cond && !complexCompare) { ITypeInfo * valueType = compareExpr->queryType(); if (valueType != cond->queryType()) complexCompare = isCompare3Valued(compareExpr->queryType()); } updateResultType(resultExpr); }
static int compareSymbolsByPosition(IInterface * const * pleft, IInterface * const * pright) { IHqlExpression * left = static_cast<IHqlExpression *>(*pleft); IHqlExpression * right = static_cast<IHqlExpression *>(*pright); int startLeft = left->getStartLine(); int startRight = right->getStartLine(); if (startLeft != startRight) return startLeft < startRight ? -1 : +1; return stricmp(str(left->queryName()), str(right->queryName())); }
ForEachChild(i, record) { IHqlExpression * cur = record->queryChild(i); switch (cur->getOperator()) { case no_record: expandFieldNames(errorProcessor, out, cur, prefix, sep, formatFunc); break; case no_ifblock: expandFieldNames(errorProcessor, out, cur->queryChild(1), prefix, sep, formatFunc); break; case no_field: { StringBuffer lowerName; lowerName.append(cur->queryName()).toLowerCase(); if (formatFunc) { HqlExprArray args; args.append(*createConstant(lowerName.str())); OwnedHqlExpr bound = createBoundFunction(NULL, formatFunc, args, NULL, true); OwnedHqlExpr folded = foldHqlExpression(errorProcessor, bound, NULL, HFOthrowerror|HFOfoldimpure|HFOforcefold); assertex(folded->queryValue()); lowerName.clear(); getStringValue(lowerName, folded); } switch (cur->queryType()->getTypeCode()) { case type_record: case type_row: { unsigned len = prefix.length(); prefix.append(lowerName).append("."); expandFieldNames(errorProcessor, out, cur->queryRecord(), prefix, sep, formatFunc); prefix.setLength(len); break; } default: { if (out.length()) out.append(sep); out.append(prefix).append(lowerName); break; } } break; } } }
//Optimize IF(a,b,c) op x to IF(a,b op x, c OP x) //But be careful because it uncommons attributes increasing the size of the queries. static IHqlExpression * peepholeOptimizeCompare(BuildCtx & ctx, IHqlExpression * expr) { IHqlExpression * lhs = expr->queryChild(0); if (ctx.queryMatchExpr(lhs)) return LINK(expr); IHqlExpression * rhs = expr->queryChild(1); if (!rhs->isConstant() || (lhs->getOperator() != no_if)) return LINK(expr); IHqlExpression * ifCond = lhs->queryChild(0); IHqlExpression * ifTrue = lhs->queryChild(1); IHqlExpression * ifFalse = lhs->queryChild(2); assertex(ifFalse); node_operator op = expr->getOperator(); OwnedHqlExpr newTrue = createValue(op, makeBoolType(), LINK(ifTrue), LINK(rhs)); OwnedHqlExpr newFalse = createValue(op, makeBoolType(), LINK(ifFalse), LINK(rhs)); OwnedHqlExpr newIf = createValue(no_if, makeBoolType(), LINK(ifCond), peepholeOptimize(ctx, newTrue), peepholeOptimize(ctx, newFalse)); return expr->cloneAllAnnotations(newIf); }
IHqlExpression * PositionTransformer::createTransformed(IHqlExpression * _expr) { OwnedHqlExpr transformed = NewHqlTransformer::createTransformed(_expr); switch (transformed->getOperator()) { case no_table: { IHqlExpression * mode = transformed->queryChild(2); HqlExprArray fields; HqlExprArray args; if (mode->getOperator() == no_thor) { unwindChildren(fields, transformed->queryChild(1)); IHqlExpression * filePosAttr = createComma(createAttribute(virtualAtom, createAttribute(filepositionAtom)), insertedAttr.getLink()); IHqlExpression * sizeofAttr = createComma(createAttribute(virtualAtom, createAttribute(sizeofAtom)), insertedAttr.getLink()); fields.append(*createField(fileposName, makeIntType(8, false), NULL, filePosAttr)); fields.append(*createField(recordlenName, makeIntType(2, false), NULL, sizeofAttr)); unwindChildren(args, transformed); args.replace(*createRecord(fields), 1); return transformed->clone(args); } } break; case no_iterate: case no_hqlproject: { HqlExprArray args; HqlExprArray assigns; IHqlExpression * transform = transformed->queryChild(1); unwindChildren(args, transformed); unwindChildren(assigns, transform); IHqlExpression * inRecord = transformed->queryChild(0)->queryRecord(); IHqlExpression * outRecord = transform->queryRecord(); HqlExprArray fields; unwindChildren(fields, outRecord); ForEachChild(idx, inRecord) { IHqlExpression * child = inRecord->queryChild(idx); if (child->hasProperty(insertedAtom)) { IHqlExpression * newTarget = createField(child->queryName(), child->getType(), LINK(child), insertedAttr.getLink()); fields.append(*newTarget); assigns.append(*createValue(no_assign, makeVoidType(), newTarget, createSelectExpr(createValue(no_left), LINK(newTarget)))); } } IHqlExpression * newRecord = createRecord(fields); args.replace(*createValue(no_transform, newRecord->getType(), assigns), 1); return transformed->clone(args); } break; case no_join: //only ok if join first case no_rollup: case no_newaggregate: case no_aggregate: fail(); break; case no_usertable: case no_selectfields: { IHqlExpression * grouping = transformed->queryChild(2); if (grouping && (grouping->getOperator() != no_attr)) fail(); IHqlExpression * record = transformed->queryRecord(); HqlExprArray fields; unwindChildren(fields, transformed->queryChild(1)); ForEachChild(idx, record) { IHqlExpression * child = record->queryChild(idx); if (child->hasProperty(insertedAtom)) fields.append(*createField(child->queryName(), child->getType(), LINK(child), insertedAttr.getLink())); } HqlExprArray args; unwindChildren(args, transformed); args.replace(*createRecord(fields), 1); return transformed->clone(args); }
void LogicalGraphCreator::createGraphActivity(IHqlExpression * expr) { LogicalGraphInfo * extra = queryExtra(expr); if (extra->globalId && !inSubQuery()) { extra->id = extra->globalId; return; } //First generate children... //MORE: may want to do inputs first and dependents afterwards. IAtom * dependencyKind = dependencyAtom; unsigned first = getFirstActivityArgument(expr); unsigned last = first + getNumActivityArguments(expr); node_operator op = expr->getOperator(); HqlExprArray inputs, dependents; bool defaultInputs = true; switch (op) { case no_setresult: case no_map: last = first; dependencyKind = NULL; break; case no_select: if (!isNewSelector(expr)) { last = first; } break; case no_addfiles: expandUnnamedFunnel(inputs, expr->queryBody()); defaultInputs = false; break; case no_colon: { if (!isWorkflowExpanded(expr)) defaultInputs = false; gatherWorkflowActivities(expr, dependents); inputs.append(*LINK(expr->queryChild(0))); defaultInputs = false; break; } case no_forcelocal: case no_forcenolocal: case no_allnodes: case no_thisnode: { IHqlExpression * child = expr->queryChild(0); createSubGraphActivity(child); addDependent(dependents, child); defaultInputs = false; break; } } if (defaultInputs) { ForEachChild(i, expr) { IHqlExpression * cur = expr->queryChild(i); if ((i >= first && i < last) && !cur->isAttribute()) inputs.append(*LINK(cur)); else if (includeChildInDependents(expr, i)) gatherGraphActivities(cur, dependents); } }
IHqlExpression * HqlCppCaseInfo::buildIndexedMap(BuildCtx & ctx, const CHqlBoundExpr & test) { ITypeInfo * compareType = test.queryType()->queryPromotedType(); type_t compareTypeCode = compareType->getTypeCode(); HqlExprArray values; IHqlExpression * dft = queryActiveTableSelector(); // value doesn't matter as long as it will not occur __int64 lower = getIntValue(lowerTableBound, 0); unsigned num = (getIntValue(upperTableBound, 0)-lower)+1; CHqlBoundExpr indexExpr; switch (compareTypeCode) { case type_int: indexExpr.set(test); break; case type_string: indexExpr.expr.setown(createValue(no_index, makeCharType(), LINK(test.expr), getZero())); indexExpr.expr.setown(createValue(no_cast, makeIntType(1, false), LINK(indexExpr.expr))); break; default: throwUnexpectedType(compareType); } if (useRangeIndex && (num != 1)) translator.ensureSimpleExpr(ctx, indexExpr); OwnedHqlExpr mapped; ITypeInfo * retType = resultType; //if num == pairs.ordinality() and all results are identical, avoid the table lookup. if (allResultsMatch && (num == pairs.ordinality())) { mapped.set(pairs.item(0).queryChild(1)); } else { values.ensure(num); unsigned idx; for (idx = 0; idx < num; idx++) values.append(*LINK(dft)); ForEachItemIn(idx2, pairs) { IHqlExpression & cur = pairs.item(idx2); IValue * value = cur.queryChild(0)->queryValue(); unsigned replaceIndex; switch (compareTypeCode) { case type_int: replaceIndex = (unsigned)(value->getIntValue()-lower); break; case type_string: { StringBuffer temp; value->getStringValue(temp); replaceIndex = (unsigned)((unsigned char)temp.charAt(0)-lower); break; } default: throwUnexpectedType(compareType); } IHqlExpression * mapTo = cur.queryChild(1); if (mapTo->getOperator() != no_constant) throwUnexpected(); if (replaceIndex >= num) translator.reportWarning(CategoryIgnored, HQLWRN_CaseCanNeverMatch, "CASE entry %d can never match the test condition", replaceIndex); else values.replace(*LINK(mapTo),replaceIndex); } //Now replace the placeholders with the default values. for (idx = 0; idx < num; idx++) { if (&values.item(idx) == dft) values.replace(*defaultValue.getLink(),idx); } // use a var string type to get better C++ generated... ITypeInfo * storeType = getArrayElementType(resultType); ITypeInfo * listType = makeArrayType(storeType, values.ordinality()); OwnedHqlExpr lvalues = createValue(no_list, listType, values); CHqlBoundExpr boundTable; translator.buildExpr(ctx, lvalues, boundTable); LinkedHqlExpr tableIndex = indexExpr.expr; if (getIntValue(lowerTableBound, 0)) tableIndex.setown(createValue(no_sub, tableIndex->getType(), LINK(tableIndex), LINK(lowerTableBound))); IHqlExpression * ret = createValue(no_index, LINK(retType), LINK(boundTable.expr), LINK(tableIndex)); mapped.setown(createTranslatedOwned(ret)); }
//MORE: Really this should create no_selects for the sub records, but pass on that for the moment. void DataSourceMetaData::gatherFields(IHqlExpression * expr, bool isConditional) { switch (expr->getOperator()) { case no_record: gatherChildFields(expr, isConditional); break; case no_ifblock: { OwnedITypeInfo boolType = makeBoolType(); OwnedITypeInfo voidType = makeVoidType(); isStoredFixedWidth = false; fields.append(*new DataSourceMetaItem(FVFFbeginif, NULL, NULL, boolType)); gatherChildFields(expr->queryChild(1), true); fields.append(*new DataSourceMetaItem(FVFFendif, NULL, NULL, voidType)); break; } case no_field: { if (expr->hasProperty(__ifblockAtom)) break; Linked<ITypeInfo> type = expr->queryType(); IAtom * name = expr->queryName(); IHqlExpression * nameAttr = expr->queryProperty(namedAtom); StringBuffer outname; if (nameAttr && nameAttr->queryChild(0)->queryValue()) nameAttr->queryChild(0)->queryValue()->getStringValue(outname); else outname.append(name).toLowerCase(); StringBuffer xpathtext; const char * xpath = NULL; IHqlExpression * xpathAttr = expr->queryProperty(xpathAtom); if (xpathAttr && xpathAttr->queryChild(0)->queryValue()) xpath = xpathAttr->queryChild(0)->queryValue()->getStringValue(xpathtext); if (isKey() && expr->hasProperty(blobAtom)) type.setown(makeIntType(8, false)); type_t tc = type->getTypeCode(); if (tc == type_row) { OwnedITypeInfo voidType = makeVoidType(); fields.append(*new DataSourceMetaItem(FVFFbeginrecord, outname, xpath, voidType)); gatherChildFields(expr->queryRecord(), isConditional); fields.append(*new DataSourceMetaItem(FVFFendrecord, outname, xpath, voidType)); } else if ((tc == type_table) || (tc == type_groupedtable)) { isStoredFixedWidth = false; fields.append(*new DataSourceDatasetItem(outname, xpath, expr)); } else if (tc == type_set) { isStoredFixedWidth = false; fields.append(*new DataSourceSetItem(outname, xpath, type)); } else { if (type->getTypeCode() == type_alien) { IHqlAlienTypeInfo * alien = queryAlienType(type); type.set(alien->queryPhysicalType()); } addSimpleField(outname, xpath, type); } break; } } }
//MORE: Really this should create no_selects for the sub records, but pass on that for the moment. void DataSourceMetaData::gatherFields(IHqlExpression * expr, bool isConditional, bool *pMixedContent) { switch (expr->getOperator()) { case no_record: gatherChildFields(expr, isConditional, pMixedContent); break; case no_ifblock: { OwnedITypeInfo boolType = makeBoolType(); OwnedITypeInfo voidType = makeVoidType(); isStoredFixedWidth = false; fields.append(*new DataSourceMetaItem(FVFFbeginif, NULL, NULL, boolType)); gatherChildFields(expr->queryChild(1), true, pMixedContent); fields.append(*new DataSourceMetaItem(FVFFendif, NULL, NULL, voidType)); break; } case no_field: { if (expr->hasAttribute(__ifblockAtom)) break; Linked<ITypeInfo> type = expr->queryType(); IAtom * name = expr->queryName(); IHqlExpression * nameAttr = expr->queryAttribute(namedAtom); StringBuffer outname; if (nameAttr && nameAttr->queryChild(0)->queryValue()) nameAttr->queryChild(0)->queryValue()->getStringValue(outname); else outname.append(name).toLowerCase(); StringBuffer xpathtext; const char * xpath = NULL; IHqlExpression * xpathAttr = expr->queryAttribute(xpathAtom); if (xpathAttr && xpathAttr->queryChild(0)->queryValue()) xpath = xpathAttr->queryChild(0)->queryValue()->getStringValue(xpathtext); unsigned flag = FVFFnone; if (isKey() && expr->hasAttribute(blobAtom)) { type.setown(makeIntType(8, false)); flag = FVFFblob; } type_t tc = type->getTypeCode(); if (tc == type_row) { OwnedITypeInfo voidType = makeVoidType(); Owned<DataSourceMetaItem> begin = new DataSourceMetaItem(FVFFbeginrecord, outname, xpath, voidType); //inherit mixed content from child row with xpath('') bool *pItemMixedContent = (pMixedContent && xpath && !*xpath) ? pMixedContent : &(begin->hasMixedContent); fields.append(*begin.getClear()); gatherChildFields(expr->queryRecord(), isConditional, pItemMixedContent); fields.append(*new DataSourceMetaItem(FVFFendrecord, outname, xpath, voidType)); } else if ((tc == type_dictionary) || (tc == type_table) || (tc == type_groupedtable)) { isStoredFixedWidth = false; Owned<DataSourceDatasetItem> ds = new DataSourceDatasetItem(outname, xpath, expr); if (pMixedContent && xpath && !*xpath) *pMixedContent = ds->queryChildMeta()->hasMixedContent; fields.append(*ds.getClear()); } else if (tc == type_set) { isStoredFixedWidth = false; if (pMixedContent && xpath && !*xpath) *pMixedContent = true; fields.append(*new DataSourceSetItem(outname, xpath, type)); } else { if (type->getTypeCode() == type_alien) { IHqlAlienTypeInfo * alien = queryAlienType(type); type.set(alien->queryPhysicalType()); } if (pMixedContent && xpath && !*xpath) *pMixedContent = true; addSimpleField(outname, xpath, type, flag); } break; } } }
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(); }