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); }
static IHqlExpression * optimizedReplaceSelector(IHqlExpression * expr, IHqlExpression * oldDataset, IHqlExpression * newDataset) { switch (expr->getOperator()) { case no_constant: case no_attr: return LINK(expr); case no_select: { IHqlExpression * lhs = expr->queryChild(0); IHqlExpression * field = expr->queryChild(1); OwnedHqlExpr newLhs; if (expr->hasAttribute(newAtom)) { newLhs.setown(optimizedReplaceSelector(lhs, oldDataset, newDataset)); } else { if (lhs == oldDataset) { if (newDataset->getOperator() == no_newrow) return createNewSelectExpr(LINK(newDataset->queryChild(0)), LINK(field)); if (newDataset->getOperator() == no_activerow) newDataset = newDataset->queryChild(0); return createSelectExpr(LINK(newDataset->queryNormalizedSelector()), LINK(field)); } else newLhs.setown(optimizedReplaceSelector(lhs, oldDataset, newDataset)); } if (newLhs) return replaceChild(expr, 0, newLhs); return NULL; } case no_implicitcast: case no_cast: { IHqlExpression * newUncast = optimizedReplaceSelector(expr->queryChild(0), oldDataset, newDataset); if (!newUncast) return NULL; OwnedHqlExpr ret = createValue(expr->getOperator(), expr->getType(), newUncast); return expr->cloneAllAnnotations(ret); } case no_hash: case no_hash32: case no_hash64: case no_sortlist: case no_concat: case no_trim: case no_negate: case no_eq: case no_ne: case no_sizeof: case no_attr_expr: case no_add: { HqlExprArray args; ForEachChild(i, expr) { IHqlExpression * cur = expr->queryChild(i); IHqlExpression * newCur = optimizedReplaceSelector(cur, oldDataset, newDataset); if (!newCur) return NULL; args.append(*newCur); } return expr->clone(args); } }