Search in sources :

Example 1 with RexRangeRef

use of org.apache.calcite.rex.RexRangeRef in project calcite by apache.

the class SqlToRelConverter method translateIn.

private RexNode translateIn(RelOptUtil.Logic logic, RelNode root, final RexNode rex) {
    switch(logic) {
        case TRUE:
            return rexBuilder.makeLiteral(true);
        case TRUE_FALSE:
        case UNKNOWN_AS_FALSE:
            assert rex instanceof RexRangeRef;
            final int fieldCount = rex.getType().getFieldCount();
            RexNode rexNode = rexBuilder.makeFieldAccess(rex, fieldCount - 1);
            rexNode = rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, rexNode);
            // Then append the IS NOT NULL(leftKeysForIn).
            // 
            // RexRangeRef contains the following fields:
            // leftKeysForIn,
            // rightKeysForIn (the original sub-query select list),
            // nullIndicator
            // 
            // The first two lists contain the same number of fields.
            final int k = (fieldCount - 1) / 2;
            for (int i = 0; i < k; i++) {
                rexNode = rexBuilder.makeCall(SqlStdOperatorTable.AND, rexNode, rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, rexBuilder.makeFieldAccess(rex, i)));
            }
            return rexNode;
        case TRUE_FALSE_UNKNOWN:
        case UNKNOWN_AS_TRUE:
            // select e.deptno,
            // case
            // when ct.c = 0 then false
            // when dt.i is not null then true
            // when e.deptno is null then null
            // when ct.ck < ct.c then null
            // else false
            // end
            // from e
            // cross join (select count(*) as c, count(deptno) as ck from v) as ct
            // left join (select distinct deptno, true as i from v) as dt
            // on e.deptno = dt.deptno
            final Join join = (Join) root;
            final Project left = (Project) join.getLeft();
            final RelNode leftLeft = ((Join) left.getInput()).getLeft();
            final int leftLeftCount = leftLeft.getRowType().getFieldCount();
            final RelDataType longType = typeFactory.createSqlType(SqlTypeName.BIGINT);
            final RexNode cRef = rexBuilder.makeInputRef(root, leftLeftCount);
            final RexNode ckRef = rexBuilder.makeInputRef(root, leftLeftCount + 1);
            final RexNode iRef = rexBuilder.makeInputRef(root, root.getRowType().getFieldCount() - 1);
            final RexLiteral zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO, longType);
            final RexLiteral trueLiteral = rexBuilder.makeLiteral(true);
            final RexLiteral falseLiteral = rexBuilder.makeLiteral(false);
            final RexNode unknownLiteral = rexBuilder.makeNullLiteral(trueLiteral.getType());
            final ImmutableList.Builder<RexNode> args = ImmutableList.builder();
            args.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, cRef, zero), falseLiteral, rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, iRef), trueLiteral);
            final JoinInfo joinInfo = join.analyzeCondition();
            for (int leftKey : joinInfo.leftKeys) {
                final RexNode kRef = rexBuilder.makeInputRef(root, leftKey);
                args.add(rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, kRef), unknownLiteral);
            }
            args.add(rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, ckRef, cRef), unknownLiteral, falseLiteral);
            return rexBuilder.makeCall(SqlStdOperatorTable.CASE, args.build());
        default:
            throw new AssertionError(logic);
    }
}
Also used : RexRangeRef(org.apache.calcite.rex.RexRangeRef) JoinInfo(org.apache.calcite.rel.core.JoinInfo) Project(org.apache.calcite.rel.core.Project) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexLiteral(org.apache.calcite.rex.RexLiteral) RelNode(org.apache.calcite.rel.RelNode) ImmutableList(com.google.common.collect.ImmutableList) Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) SqlJoin(org.apache.calcite.sql.SqlJoin) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with RexRangeRef

use of org.apache.calcite.rex.RexRangeRef in project calcite by apache.

the class StandardConvertletTable method convertMultiset.

public RexNode convertMultiset(SqlRexContext cx, SqlMultisetValueConstructor op, SqlCall call) {
    final RelDataType originalType = cx.getValidator().getValidatedNodeType(call);
    RexRangeRef rr = cx.getSubQueryExpr(call);
    assert rr != null;
    RelDataType msType = rr.getType().getFieldList().get(0).getType();
    RexNode expr = cx.getRexBuilder().makeInputRef(msType, rr.getOffset());
    assert msType.getComponentType().isStruct();
    if (!originalType.getComponentType().isStruct()) {
        // If the type is not a struct, the multiset operator will have
        // wrapped the type as a record. Add a call to the $SLICE operator
        // to compensate. For example,
        // if '<ms>' has type 'RECORD (INTEGER x) MULTISET',
        // then '$SLICE(<ms>) has type 'INTEGER MULTISET'.
        // This will be removed as the expression is translated.
        expr = cx.getRexBuilder().makeCall(originalType, SqlStdOperatorTable.SLICE, ImmutableList.of(expr));
    }
    return expr;
}
Also used : RexRangeRef(org.apache.calcite.rex.RexRangeRef) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 3 with RexRangeRef

use of org.apache.calcite.rex.RexRangeRef in project calcite by apache.

the class StandardConvertletTable method convertMultisetQuery.

public RexNode convertMultisetQuery(SqlRexContext cx, SqlMultisetQueryConstructor op, SqlCall call) {
    final RelDataType originalType = cx.getValidator().getValidatedNodeType(call);
    RexRangeRef rr = cx.getSubQueryExpr(call);
    assert rr != null;
    RelDataType msType = rr.getType().getFieldList().get(0).getType();
    RexNode expr = cx.getRexBuilder().makeInputRef(msType, rr.getOffset());
    assert msType.getComponentType().isStruct();
    if (!originalType.getComponentType().isStruct()) {
        // If the type is not a struct, the multiset operator will have
        // wrapped the type as a record. Add a call to the $SLICE operator
        // to compensate. For example,
        // if '<ms>' has type 'RECORD (INTEGER x) MULTISET',
        // then '$SLICE(<ms>) has type 'INTEGER MULTISET'.
        // This will be removed as the expression is translated.
        expr = cx.getRexBuilder().makeCall(SqlStdOperatorTable.SLICE, expr);
    }
    return expr;
}
Also used : RexRangeRef(org.apache.calcite.rex.RexRangeRef) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelDataType (org.apache.calcite.rel.type.RelDataType)3 RexNode (org.apache.calcite.rex.RexNode)3 RexRangeRef (org.apache.calcite.rex.RexRangeRef)3 ImmutableList (com.google.common.collect.ImmutableList)1 RelNode (org.apache.calcite.rel.RelNode)1 Join (org.apache.calcite.rel.core.Join)1 JoinInfo (org.apache.calcite.rel.core.JoinInfo)1 Project (org.apache.calcite.rel.core.Project)1 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)1 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)1 RexLiteral (org.apache.calcite.rex.RexLiteral)1 SqlJoin (org.apache.calcite.sql.SqlJoin)1