Search in sources :

Example 11 with Project

use of org.apache.calcite.rel.core.Project in project calcite by apache.

the class RelToSqlConverter method visit.

/**
 * @see #dispatch
 */
public Result visit(Filter e) {
    final RelNode input = e.getInput();
    Result x = visitChild(0, input);
    parseCorrelTable(e, x);
    if (input instanceof Aggregate) {
        final Builder builder;
        if (((Aggregate) input).getInput() instanceof Project) {
            builder = x.builder(e);
            builder.clauses.add(Clause.HAVING);
        } else {
            builder = x.builder(e, Clause.HAVING);
        }
        builder.setHaving(builder.context.toSql(null, e.getCondition()));
        return builder.result();
    } else {
        final Builder builder = x.builder(e, Clause.WHERE);
        builder.setWhere(builder.context.toSql(null, e.getCondition()));
        return builder.result();
    }
}
Also used : Project(org.apache.calcite.rel.core.Project) RelNode(org.apache.calcite.rel.RelNode) Aggregate(org.apache.calcite.rel.core.Aggregate)

Example 12 with Project

use of org.apache.calcite.rel.core.Project 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 13 with Project

use of org.apache.calcite.rel.core.Project in project calcite by apache.

the class RelBuilder method sortLimit.

/**
 * Creates a {@link Sort} by a list of expressions, with limit and offset.
 *
 * @param offset Number of rows to skip; non-positive means don't skip any
 * @param fetch Maximum number of rows to fetch; negative means no limit
 * @param nodes Sort expressions
 */
public RelBuilder sortLimit(int offset, int fetch, Iterable<? extends RexNode> nodes) {
    final List<RelFieldCollation> fieldCollations = new ArrayList<>();
    final List<RexNode> originalExtraNodes = fields();
    final List<RexNode> extraNodes = new ArrayList<>(originalExtraNodes);
    for (RexNode node : nodes) {
        final RelFieldCollation collation = collation(node, RelFieldCollation.Direction.ASCENDING, null, extraNodes);
        if (!RelCollations.ordinals(fieldCollations).contains(collation.getFieldIndex())) {
            fieldCollations.add(collation);
        }
    }
    final RexNode offsetNode = offset <= 0 ? null : literal(offset);
    final RexNode fetchNode = fetch < 0 ? null : literal(fetch);
    if (offsetNode == null && fetch == 0) {
        return empty();
    }
    if (offsetNode == null && fetchNode == null && fieldCollations.isEmpty()) {
        // sort is trivial
        return this;
    }
    final boolean addedFields = extraNodes.size() > originalExtraNodes.size();
    if (fieldCollations.isEmpty()) {
        assert !addedFields;
        RelNode top = peek();
        if (top instanceof Sort) {
            final Sort sort2 = (Sort) top;
            if (sort2.offset == null && sort2.fetch == null) {
                replaceTop(sort2.getInput());
                final RelNode sort = sortFactory.createSort(peek(), sort2.collation, offsetNode, fetchNode);
                replaceTop(sort);
                return this;
            }
        }
        if (top instanceof Project) {
            final Project project = (Project) top;
            if (project.getInput() instanceof Sort) {
                final Sort sort2 = (Sort) project.getInput();
                if (sort2.offset == null && sort2.fetch == null) {
                    final RelNode sort = sortFactory.createSort(sort2.getInput(), sort2.collation, offsetNode, fetchNode);
                    replaceTop(projectFactory.createProject(sort, project.getProjects(), Pair.right(project.getNamedProjects())));
                    return this;
                }
            }
        }
    }
    if (addedFields) {
        project(extraNodes);
    }
    final RelNode sort = sortFactory.createSort(peek(), RelCollations.of(fieldCollations), offsetNode, fetchNode);
    replaceTop(sort);
    if (addedFields) {
        project(originalExtraNodes);
    }
    return this;
}
Also used : Project(org.apache.calcite.rel.core.Project) RelNode(org.apache.calcite.rel.RelNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) ArrayList(java.util.ArrayList) Sort(org.apache.calcite.rel.core.Sort) RexNode(org.apache.calcite.rex.RexNode)

Example 14 with Project

use of org.apache.calcite.rel.core.Project in project calcite by apache.

the class RelBuilder method projectNamed.

/**
 * Creates a {@link org.apache.calcite.rel.core.Project} of the given
 * expressions and field names, and optionally optimizing.
 *
 * <p>If {@code fieldNames} is null, or if a particular entry in
 * {@code fieldNames} is null, derives field names from the input
 * expressions.
 *
 * <p>If {@code force} is false,
 * and the input is a {@code Project},
 * and the expressions  make the trivial projection ($0, $1, ...),
 * modifies the input.
 *
 * @param nodes       Expressions
 * @param fieldNames  Suggested field names, or null to generate
 * @param force       Whether to create a renaming Project if the
 *                    projections are trivial
 */
public RelBuilder projectNamed(Iterable<? extends RexNode> nodes, Iterable<String> fieldNames, boolean force) {
    @SuppressWarnings("unchecked") final List<? extends RexNode> nodeList = nodes instanceof List ? (List) nodes : ImmutableList.copyOf(nodes);
    final List<String> fieldNameList = fieldNames == null ? null : fieldNames instanceof List ? (List<String>) fieldNames : ImmutableNullableList.copyOf(fieldNames);
    final RelNode input = peek();
    final RelDataType rowType = RexUtil.createStructType(cluster.getTypeFactory(), nodeList, fieldNameList, SqlValidatorUtil.F_SUGGESTER);
    if (!force && RexUtil.isIdentity(nodeList, input.getRowType())) {
        if (input instanceof Project && fieldNames != null) {
            // Rename columns of child projection if desired field names are given.
            final Frame frame = stack.pop();
            final Project childProject = (Project) frame.rel;
            final Project newInput = childProject.copy(childProject.getTraitSet(), childProject.getInput(), childProject.getProjects(), rowType);
            stack.push(new Frame(newInput, frame.fields));
        }
    } else {
        project(nodeList, rowType.getFieldNames(), force);
    }
    return this;
}
Also used : Project(org.apache.calcite.rel.core.Project) RelNode(org.apache.calcite.rel.RelNode) AbstractList(java.util.AbstractList) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) ImmutableNullableList(org.apache.calcite.util.ImmutableNullableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString)

Example 15 with Project

use of org.apache.calcite.rel.core.Project in project calcite by apache.

the class RelFieldTrimmer method trimFields.

/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.logical.LogicalTableScan}.
 */
public TrimResult trimFields(final TableScan tableAccessRel, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final int fieldCount = tableAccessRel.getRowType().getFieldCount();
    if (fieldsUsed.equals(ImmutableBitSet.range(fieldCount)) && extraFields.isEmpty()) {
        // then no need to introduce another RelNode
        return trimFields((RelNode) tableAccessRel, fieldsUsed, extraFields);
    }
    final RelNode newTableAccessRel = tableAccessRel.project(fieldsUsed, extraFields, relBuilder);
    // pretend that one field is used.
    if (fieldsUsed.cardinality() == 0) {
        RelNode input = newTableAccessRel;
        if (input instanceof Project) {
            // The table has implemented the project in the obvious way - by
            // creating project with 0 fields. Strip it away, and create our own
            // project with one field.
            Project project = (Project) input;
            if (project.getRowType().getFieldCount() == 0) {
                input = project.getInput();
            }
        }
        return dummyProject(fieldCount, input);
    }
    final Mapping mapping = createMapping(fieldsUsed, fieldCount);
    return result(newTableAccessRel, mapping);
}
Also used : Project(org.apache.calcite.rel.core.Project) RelNode(org.apache.calcite.rel.RelNode) Mapping(org.apache.calcite.util.mapping.Mapping)

Aggregations

Project (org.apache.calcite.rel.core.Project)143 RexNode (org.apache.calcite.rex.RexNode)77 RelNode (org.apache.calcite.rel.RelNode)71 ArrayList (java.util.ArrayList)46 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)35 RexBuilder (org.apache.calcite.rex.RexBuilder)28 RelDataType (org.apache.calcite.rel.type.RelDataType)26 Aggregate (org.apache.calcite.rel.core.Aggregate)22 Filter (org.apache.calcite.rel.core.Filter)22 Join (org.apache.calcite.rel.core.Join)22 List (java.util.List)19 RexLiteral (org.apache.calcite.rex.RexLiteral)19 AggregateCall (org.apache.calcite.rel.core.AggregateCall)18 Sort (org.apache.calcite.rel.core.Sort)18 Test (org.junit.Test)18 RelBuilder (org.apache.calcite.tools.RelBuilder)17 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)16 HiveProject (org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject)16 Collectors (java.util.stream.Collectors)15 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)15