예제 #1
0
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);
    }
예제 #2
0
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);
        }
예제 #3
0
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));
    }