Search in sources :

Example 56 with RelDataTypeField

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlToRelConverter method checkConvertedType.

private void checkConvertedType(SqlNode query, RelNode result) {
    if (query.isA(SqlKind.DML)) {
        return;
    }
    // Verify that conversion from SQL to relational algebra did
    // not perturb any type information.  (We can't do this if the
    // SQL statement is something like an INSERT which has no
    // validator type information associated with its result,
    // hence the namespace check above.)
    final List<RelDataTypeField> validatedFields = validator.getValidatedNodeType(query).getFieldList();
    final RelDataType validatedRowType = validator.getTypeFactory().createStructType(Pair.right(validatedFields), SqlValidatorUtil.uniquify(Pair.left(validatedFields), catalogReader.nameMatcher().isCaseSensitive()));
    final List<RelDataTypeField> convertedFields = result.getRowType().getFieldList().subList(0, validatedFields.size());
    final RelDataType convertedRowType = validator.getTypeFactory().createStructType(convertedFields);
    if (!RelOptUtil.equal("validated row type", validatedRowType, "converted row type", convertedRowType, Litmus.IGNORE)) {
        throw new AssertionError("Conversion to relational algebra failed to " + "preserve datatypes:\n" + "validated type:\n" + validatedRowType.getFullTypeString() + "\nconverted type:\n" + convertedRowType.getFullTypeString() + "\nrel:\n" + RelOptUtil.toString(result));
    }
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 57 with RelDataTypeField

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlToRelConverter method convertMerge.

private RelNode convertMerge(SqlMerge call) {
    RelOptTable targetTable = getTargetTable(call);
    // convert update column list from SqlIdentifier to String
    final List<String> targetColumnNameList = new ArrayList<>();
    final RelDataType targetRowType = targetTable.getRowType();
    SqlUpdate updateCall = call.getUpdateCall();
    if (updateCall != null) {
        for (SqlNode targetColumn : updateCall.getTargetColumnList()) {
            SqlIdentifier id = (SqlIdentifier) targetColumn;
            RelDataTypeField field = SqlValidatorUtil.getTargetField(targetRowType, typeFactory, id, catalogReader, targetTable);
            assert field != null : "column " + id.toString() + " not found";
            targetColumnNameList.add(field.getName());
        }
    }
    // replace the projection of the source select with a
    // projection that contains the following:
    // 1) the expressions corresponding to the new insert row (if there is
    // an insert)
    // 2) all columns from the target table (if there is an update)
    // 3) the set expressions in the update call (if there is an update)
    // first, convert the merge's source select to construct the columns
    // from the target table and the set expressions in the update call
    RelNode mergeSourceRel = convertSelect(call.getSourceSelect(), false);
    // then, convert the insert statement so we can get the insert
    // values expressions
    SqlInsert insertCall = call.getInsertCall();
    int nLevel1Exprs = 0;
    List<RexNode> level1InsertExprs = null;
    List<RexNode> level2InsertExprs = null;
    if (insertCall != null) {
        RelNode insertRel = convertInsert(insertCall);
        // if there are 2 level of projections in the insert source, combine
        // them into a single project; level1 refers to the topmost project;
        // the level1 projection contains references to the level2
        // expressions, except in the case where no target expression was
        // provided, in which case, the expression is the default value for
        // the column; or if the expressions directly map to the source
        // table
        level1InsertExprs = ((LogicalProject) insertRel.getInput(0)).getProjects();
        if (insertRel.getInput(0).getInput(0) instanceof LogicalProject) {
            level2InsertExprs = ((LogicalProject) insertRel.getInput(0).getInput(0)).getProjects();
        }
        nLevel1Exprs = level1InsertExprs.size();
    }
    LogicalJoin join = (LogicalJoin) mergeSourceRel.getInput(0);
    int nSourceFields = join.getLeft().getRowType().getFieldCount();
    final List<RexNode> projects = new ArrayList<>();
    for (int level1Idx = 0; level1Idx < nLevel1Exprs; level1Idx++) {
        if ((level2InsertExprs != null) && (level1InsertExprs.get(level1Idx) instanceof RexInputRef)) {
            int level2Idx = ((RexInputRef) level1InsertExprs.get(level1Idx)).getIndex();
            projects.add(level2InsertExprs.get(level2Idx));
        } else {
            projects.add(level1InsertExprs.get(level1Idx));
        }
    }
    if (updateCall != null) {
        final LogicalProject project = (LogicalProject) mergeSourceRel;
        projects.addAll(Util.skip(project.getProjects(), nSourceFields));
    }
    relBuilder.push(join).project(projects);
    return LogicalTableModify.create(targetTable, catalogReader, relBuilder.build(), LogicalTableModify.Operation.MERGE, targetColumnNameList, null, false);
}
Also used : ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlInsert(org.apache.calcite.sql.SqlInsert) SqlUpdate(org.apache.calcite.sql.SqlUpdate) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RexInputRef(org.apache.calcite.rex.RexInputRef) RelOptTable(org.apache.calcite.plan.RelOptTable) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) SqlNode(org.apache.calcite.sql.SqlNode) RexNode(org.apache.calcite.rex.RexNode)

Example 58 with RelDataTypeField

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlToRelConverter method distinctify.

/**
 * Having translated 'SELECT ... FROM ... [GROUP BY ...] [HAVING ...]', adds
 * a relational expression to make the results unique.
 *
 * <p>If the SELECT clause contains duplicate expressions, adds
 * {@link org.apache.calcite.rel.logical.LogicalProject}s so that we are
 * grouping on the minimal set of keys. The performance gain isn't huge, but
 * it is difficult to detect these duplicate expressions later.
 *
 * @param bb               Blackboard
 * @param checkForDupExprs Check for duplicate expressions
 */
private void distinctify(Blackboard bb, boolean checkForDupExprs) {
    // Look for duplicate expressions in the project.
    // Say we have 'select x, y, x, z'.
    // Then dups will be {[2, 0]}
    // and oldToNew will be {[0, 0], [1, 1], [2, 0], [3, 2]}
    RelNode rel = bb.root;
    if (checkForDupExprs && (rel instanceof LogicalProject)) {
        LogicalProject project = (LogicalProject) rel;
        final List<RexNode> projectExprs = project.getProjects();
        final List<Integer> origins = new ArrayList<>();
        int dupCount = 0;
        for (int i = 0; i < projectExprs.size(); i++) {
            int x = findExpr(projectExprs.get(i), projectExprs, i);
            if (x >= 0) {
                origins.add(x);
                ++dupCount;
            } else {
                origins.add(i);
            }
        }
        if (dupCount == 0) {
            distinctify(bb, false);
            return;
        }
        final Map<Integer, Integer> squished = Maps.newHashMap();
        final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
        final List<Pair<RexNode, String>> newProjects = Lists.newArrayList();
        for (int i = 0; i < fields.size(); i++) {
            if (origins.get(i) == i) {
                squished.put(i, newProjects.size());
                newProjects.add(RexInputRef.of2(i, fields));
            }
        }
        rel = LogicalProject.create(rel, Pair.left(newProjects), Pair.right(newProjects));
        bb.root = rel;
        distinctify(bb, false);
        rel = bb.root;
        // Create the expressions to reverse the mapping.
        // Project($0, $1, $0, $2).
        final List<Pair<RexNode, String>> undoProjects = Lists.newArrayList();
        for (int i = 0; i < fields.size(); i++) {
            final int origin = origins.get(i);
            RelDataTypeField field = fields.get(i);
            undoProjects.add(Pair.of((RexNode) new RexInputRef(squished.get(origin), field.getType()), field.getName()));
        }
        rel = LogicalProject.create(rel, Pair.left(undoProjects), Pair.right(undoProjects));
        bb.setRoot(rel, false);
        return;
    }
    // Usual case: all of the expressions in the SELECT clause are
    // different.
    final ImmutableBitSet groupSet = ImmutableBitSet.range(rel.getRowType().getFieldCount());
    rel = createAggregate(bb, groupSet, ImmutableList.of(groupSet), ImmutableList.<AggregateCall>of());
    bb.setRoot(rel, false);
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode) Pair(org.apache.calcite.util.Pair)

Example 59 with RelDataTypeField

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlToRelConverter method toRel.

public RelNode toRel(final RelOptTable table) {
    final RelNode scan = table.toRel(createToRelContext());
    final InitializerExpressionFactory ief = Util.first(table.unwrap(InitializerExpressionFactory.class), NullInitializerExpressionFactory.INSTANCE);
    // Lazily create a blackboard that contains all non-generated columns.
    final Supplier<Blackboard> bb = new Supplier<Blackboard>() {

        public Blackboard get() {
            RexNode sourceRef = rexBuilder.makeRangeReference(scan);
            return createInsertBlackboard(table, sourceRef, table.getRowType().getFieldNames());
        }
    };
    int virtualCount = 0;
    final List<RexNode> list = new ArrayList<>();
    for (RelDataTypeField f : table.getRowType().getFieldList()) {
        final ColumnStrategy strategy = ief.generationStrategy(table, f.getIndex());
        switch(strategy) {
            case VIRTUAL:
                list.add(ief.newColumnDefaultValue(table, f.getIndex(), bb.get()));
                ++virtualCount;
                break;
            default:
                list.add(rexBuilder.makeInputRef(scan, RelOptTableImpl.realOrdinal(table, f.getIndex())));
        }
    }
    if (virtualCount > 0) {
        relBuilder.push(scan);
        relBuilder.project(list);
        return relBuilder.build();
    }
    return scan;
}
Also used : ColumnStrategy(org.apache.calcite.schema.ColumnStrategy) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) Supplier(com.google.common.base.Supplier) RexNode(org.apache.calcite.rex.RexNode)

Example 60 with RelDataTypeField

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlToRelConverter method convertLiteralInValuesList.

private RexLiteral convertLiteralInValuesList(SqlNode sqlNode, Blackboard bb, RelDataType rowType, int iField) {
    if (!(sqlNode instanceof SqlLiteral)) {
        return null;
    }
    RelDataTypeField field = rowType.getFieldList().get(iField);
    RelDataType type = field.getType();
    if (type.isStruct()) {
        // don't use LogicalValues for those
        return null;
    }
    RexNode literalExpr = exprConverter.convertLiteral(bb, (SqlLiteral) sqlNode);
    if (!(literalExpr instanceof RexLiteral)) {
        assert literalExpr.isA(SqlKind.CAST);
        RexNode child = ((RexCall) literalExpr).getOperands().get(0);
        assert RexLiteral.isNullLiteral(child);
        // in LogicalValues digest, so it's OK to lose it here
        return (RexLiteral) child;
    }
    RexLiteral literal = (RexLiteral) literalExpr;
    Comparable value = literal.getValue();
    if (SqlTypeUtil.isExactNumeric(type) && SqlTypeUtil.hasScale(type)) {
        BigDecimal roundedValue = NumberUtil.rescaleBigDecimal((BigDecimal) value, type.getScale());
        return rexBuilder.makeExactLiteral(roundedValue, type);
    }
    if ((value instanceof NlsString) && (type.getSqlTypeName() == SqlTypeName.CHAR)) {
        // pad fixed character type
        NlsString unpadded = (NlsString) value;
        return rexBuilder.makeCharLiteral(new NlsString(Spaces.padRight(unpadded.getValue(), type.getPrecision()), unpadded.getCharsetName(), unpadded.getCollation()));
    }
    return literal;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) NlsString(org.apache.calcite.util.NlsString) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlLiteral(org.apache.calcite.sql.SqlLiteral) BigDecimal(java.math.BigDecimal) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)383 RelDataType (org.apache.calcite.rel.type.RelDataType)206 RexNode (org.apache.calcite.rex.RexNode)185 ArrayList (java.util.ArrayList)177 RelNode (org.apache.calcite.rel.RelNode)130 RexBuilder (org.apache.calcite.rex.RexBuilder)76 RexInputRef (org.apache.calcite.rex.RexInputRef)72 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)65 Pair (org.apache.calcite.util.Pair)55 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)47 HashMap (java.util.HashMap)39 Map (java.util.Map)35 AggregateCall (org.apache.calcite.rel.core.AggregateCall)35 SqlNode (org.apache.calcite.sql.SqlNode)32 ImmutableList (com.google.common.collect.ImmutableList)31 RelBuilder (org.apache.calcite.tools.RelBuilder)29 RelDataTypeFieldImpl (org.apache.calcite.rel.type.RelDataTypeFieldImpl)25 List (java.util.List)23 LinkedHashSet (java.util.LinkedHashSet)22 RelOptUtil (org.apache.calcite.plan.RelOptUtil)22