Search in sources :

Example 66 with SqlNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlNode 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 67 with SqlNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlNode in project calcite by apache.

the class SqlToRelConverter method convertCursor.

private RelNode convertCursor(Blackboard bb, SubQuery subQuery) {
    final SqlCall cursorCall = (SqlCall) subQuery.node;
    assert cursorCall.operandCount() == 1;
    SqlNode query = cursorCall.operand(0);
    RelNode converted = convertQuery(query, false, false).rel;
    int iCursor = bb.cursors.size();
    bb.cursors.add(converted);
    subQuery.expr = new RexInputRef(iCursor, converted.getRowType());
    return converted;
}
Also used : RelNode(org.apache.calcite.rel.RelNode) SqlCall(org.apache.calcite.sql.SqlCall) RexInputRef(org.apache.calcite.rex.RexInputRef) SqlNode(org.apache.calcite.sql.SqlNode)

Example 68 with SqlNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlNode in project calcite by apache.

the class SqlToRelConverter method convertToSingleValueSubq.

/**
 * Converts the RelNode tree for a select statement to a select that
 * produces a single value.
 *
 * @param query the query
 * @param plan   the original RelNode tree corresponding to the statement
 * @return the converted RelNode tree
 */
public RelNode convertToSingleValueSubq(SqlNode query, RelNode plan) {
    // Check whether query is guaranteed to produce a single value.
    if (query instanceof SqlSelect) {
        SqlSelect select = (SqlSelect) query;
        SqlNodeList selectList = select.getSelectList();
        SqlNodeList groupList = select.getGroup();
        if ((selectList.size() == 1) && ((groupList == null) || (groupList.size() == 0))) {
            SqlNode selectExpr = selectList.get(0);
            if (selectExpr instanceof SqlCall) {
                SqlCall selectExprCall = (SqlCall) selectExpr;
                if (Util.isSingleValue(selectExprCall)) {
                    return plan;
                }
            }
            // it is ensured to produce a single value
            if (select.getFetch() != null && select.getFetch() instanceof SqlNumericLiteral) {
                SqlNumericLiteral limitNum = (SqlNumericLiteral) select.getFetch();
                if (((BigDecimal) limitNum.getValue()).intValue() < 2) {
                    return plan;
                }
            }
        }
    } else if (query instanceof SqlCall) {
        // If the query is (values ...),
        // it is necessary to look into the operands to determine
        // whether SingleValueAgg is necessary
        SqlCall exprCall = (SqlCall) query;
        if (exprCall.getOperator() instanceof SqlValuesOperator && Util.isSingleValue(exprCall)) {
            return plan;
        }
    }
    // If not, project SingleValueAgg
    return RelOptUtil.createSingleValueAggRel(cluster, plan);
}
Also used : SqlSelect(org.apache.calcite.sql.SqlSelect) SqlValuesOperator(org.apache.calcite.sql.SqlValuesOperator) SqlCall(org.apache.calcite.sql.SqlCall) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNumericLiteral(org.apache.calcite.sql.SqlNumericLiteral) SqlNode(org.apache.calcite.sql.SqlNode)

Example 69 with SqlNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlNode in project calcite by apache.

the class SqlToRelConverter method convertMatchRecognize.

protected void convertMatchRecognize(Blackboard bb, SqlCall call) {
    final SqlMatchRecognize matchRecognize = (SqlMatchRecognize) call;
    final SqlValidatorNamespace ns = validator.getNamespace(matchRecognize);
    final SqlValidatorScope scope = validator.getMatchRecognizeScope(matchRecognize);
    final Blackboard matchBb = createBlackboard(scope, null, false);
    final RelDataType rowType = ns.getRowType();
    // convert inner query, could be a table name or a derived table
    SqlNode expr = matchRecognize.getTableRef();
    convertFrom(matchBb, expr);
    final RelNode input = matchBb.root;
    // PARTITION BY
    final SqlNodeList partitionList = matchRecognize.getPartitionList();
    final List<RexNode> partitionKeys = new ArrayList<>();
    for (SqlNode partition : partitionList) {
        RexNode e = matchBb.convertExpression(partition);
        partitionKeys.add(e);
    }
    // ORDER BY
    final SqlNodeList orderList = matchRecognize.getOrderList();
    final List<RelFieldCollation> orderKeys = new ArrayList<>();
    for (SqlNode order : orderList) {
        final RelFieldCollation.Direction direction;
        switch(order.getKind()) {
            case DESCENDING:
                direction = RelFieldCollation.Direction.DESCENDING;
                order = ((SqlCall) order).operand(0);
                break;
            case NULLS_FIRST:
            case NULLS_LAST:
                throw new AssertionError();
            default:
                direction = RelFieldCollation.Direction.ASCENDING;
                break;
        }
        final RelFieldCollation.NullDirection nullDirection = validator.getDefaultNullCollation().last(desc(direction)) ? RelFieldCollation.NullDirection.LAST : RelFieldCollation.NullDirection.FIRST;
        RexNode e = matchBb.convertExpression(order);
        orderKeys.add(new RelFieldCollation(((RexInputRef) e).getIndex(), direction, nullDirection));
    }
    final RelCollation orders = cluster.traitSet().canonize(RelCollations.of(orderKeys));
    // convert pattern
    final Set<String> patternVarsSet = new HashSet<>();
    SqlNode pattern = matchRecognize.getPattern();
    final SqlBasicVisitor<RexNode> patternVarVisitor = new SqlBasicVisitor<RexNode>() {

        @Override
        public RexNode visit(SqlCall call) {
            List<SqlNode> operands = call.getOperandList();
            List<RexNode> newOperands = Lists.newArrayList();
            for (SqlNode node : operands) {
                newOperands.add(node.accept(this));
            }
            return rexBuilder.makeCall(validator.getUnknownType(), call.getOperator(), newOperands);
        }

        @Override
        public RexNode visit(SqlIdentifier id) {
            assert id.isSimple();
            patternVarsSet.add(id.getSimple());
            return rexBuilder.makeLiteral(id.getSimple());
        }

        @Override
        public RexNode visit(SqlLiteral literal) {
            if (literal instanceof SqlNumericLiteral) {
                return rexBuilder.makeExactLiteral(BigDecimal.valueOf(literal.intValue(true)));
            } else {
                return rexBuilder.makeLiteral(literal.booleanValue());
            }
        }
    };
    final RexNode patternNode = pattern.accept(patternVarVisitor);
    SqlLiteral interval = matchRecognize.getInterval();
    RexNode intervalNode = null;
    if (interval != null) {
        intervalNode = matchBb.convertLiteral(interval);
    }
    // convert subset
    final SqlNodeList subsets = matchRecognize.getSubsetList();
    final Map<String, TreeSet<String>> subsetMap = Maps.newHashMap();
    for (SqlNode node : subsets) {
        List<SqlNode> operands = ((SqlCall) node).getOperandList();
        SqlIdentifier left = (SqlIdentifier) operands.get(0);
        patternVarsSet.add(left.getSimple());
        SqlNodeList rights = (SqlNodeList) operands.get(1);
        final TreeSet<String> list = new TreeSet<String>();
        for (SqlNode right : rights) {
            assert right instanceof SqlIdentifier;
            list.add(((SqlIdentifier) right).getSimple());
        }
        subsetMap.put(left.getSimple(), list);
    }
    SqlNode afterMatch = matchRecognize.getAfter();
    if (afterMatch == null) {
        afterMatch = SqlMatchRecognize.AfterOption.SKIP_TO_NEXT_ROW.symbol(SqlParserPos.ZERO);
    }
    final RexNode after;
    if (afterMatch instanceof SqlCall) {
        List<SqlNode> operands = ((SqlCall) afterMatch).getOperandList();
        SqlOperator operator = ((SqlCall) afterMatch).getOperator();
        assert operands.size() == 1;
        SqlIdentifier id = (SqlIdentifier) operands.get(0);
        assert patternVarsSet.contains(id.getSimple()) : id.getSimple() + " not defined in pattern";
        RexNode rex = rexBuilder.makeLiteral(id.getSimple());
        after = rexBuilder.makeCall(validator.getUnknownType(), operator, ImmutableList.of(rex));
    } else {
        after = matchBb.convertExpression(afterMatch);
    }
    matchBb.setPatternVarRef(true);
    // convert measures
    final ImmutableMap.Builder<String, RexNode> measureNodes = ImmutableMap.builder();
    for (SqlNode measure : matchRecognize.getMeasureList()) {
        List<SqlNode> operands = ((SqlCall) measure).getOperandList();
        String alias = ((SqlIdentifier) operands.get(1)).getSimple();
        RexNode rex = matchBb.convertExpression(operands.get(0));
        measureNodes.put(alias, rex);
    }
    // convert definitions
    final ImmutableMap.Builder<String, RexNode> definitionNodes = ImmutableMap.builder();
    for (SqlNode def : matchRecognize.getPatternDefList()) {
        List<SqlNode> operands = ((SqlCall) def).getOperandList();
        String alias = ((SqlIdentifier) operands.get(1)).getSimple();
        RexNode rex = matchBb.convertExpression(operands.get(0));
        definitionNodes.put(alias, rex);
    }
    final SqlLiteral rowsPerMatch = matchRecognize.getRowsPerMatch();
    final boolean allRows = rowsPerMatch != null && rowsPerMatch.getValue() == SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS;
    matchBb.setPatternVarRef(false);
    final RelFactories.MatchFactory factory = RelFactories.DEFAULT_MATCH_FACTORY;
    final RelNode rel = factory.createMatch(input, patternNode, rowType, matchRecognize.getStrictStart().booleanValue(), matchRecognize.getStrictEnd().booleanValue(), definitionNodes.build(), measureNodes.build(), after, subsetMap, allRows, partitionKeys, orders, intervalNode);
    bb.setRoot(rel, false);
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) SqlOperator(org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) TreeSet(java.util.TreeSet) SqlBasicVisitor(org.apache.calcite.sql.util.SqlBasicVisitor) RelFactories(org.apache.calcite.rel.core.RelFactories) SqlNode(org.apache.calcite.sql.SqlNode) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) SqlCall(org.apache.calcite.sql.SqlCall) SqlMatchRecognize(org.apache.calcite.sql.SqlMatchRecognize) ImmutableMap(com.google.common.collect.ImmutableMap) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RexInputRef(org.apache.calcite.rex.RexInputRef) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace) SqlLiteral(org.apache.calcite.sql.SqlLiteral) SqlNumericLiteral(org.apache.calcite.sql.SqlNumericLiteral) RexNode(org.apache.calcite.rex.RexNode)

Example 70 with SqlNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlNode in project calcite by apache.

the class SqlToRelConverter method convertSelectList.

private void convertSelectList(Blackboard bb, SqlSelect select, List<SqlNode> orderList) {
    SqlNodeList selectList = select.getSelectList();
    selectList = validator.expandStar(selectList, select, false);
    replaceSubQueries(bb, selectList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
    List<String> fieldNames = new ArrayList<>();
    final List<RexNode> exprs = new ArrayList<>();
    final Collection<String> aliases = new TreeSet<>();
    // Project any system fields. (Must be done before regular select items,
    // because offsets may be affected.)
    final List<SqlMonotonicity> columnMonotonicityList = new ArrayList<>();
    extraSelectItems(bb, select, exprs, fieldNames, aliases, columnMonotonicityList);
    // Project select clause.
    int i = -1;
    for (SqlNode expr : selectList) {
        ++i;
        exprs.add(bb.convertExpression(expr));
        fieldNames.add(deriveAlias(expr, aliases, i));
    }
    // Project extra fields for sorting.
    for (SqlNode expr : orderList) {
        ++i;
        SqlNode expr2 = validator.expandOrderExpr(select, expr);
        exprs.add(bb.convertExpression(expr2));
        fieldNames.add(deriveAlias(expr, aliases, i));
    }
    fieldNames = SqlValidatorUtil.uniquify(fieldNames, catalogReader.nameMatcher().isCaseSensitive());
    relBuilder.push(bb.root).projectNamed(exprs, fieldNames, true);
    bb.setRoot(relBuilder.build(), false);
    assert bb.columnMonotonicities.isEmpty();
    bb.columnMonotonicities.addAll(columnMonotonicityList);
    for (SqlNode selectItem : selectList) {
        bb.columnMonotonicities.add(selectItem.getMonotonicity(bb.scope));
    }
}
Also used : TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) SqlNodeList(org.apache.calcite.sql.SqlNodeList) NlsString(org.apache.calcite.util.NlsString) RexNode(org.apache.calcite.rex.RexNode) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlNode (org.apache.calcite.sql.SqlNode)510 RelDataType (org.apache.calcite.rel.type.RelDataType)141 SqlNodeList (org.apache.calcite.sql.SqlNodeList)98 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)84 SqlCall (org.apache.calcite.sql.SqlCall)81 ArrayList (java.util.ArrayList)78 RelNode (org.apache.calcite.rel.RelNode)60 Test (org.junit.Test)59 BitString (org.apache.calcite.util.BitString)46 SqlSelect (org.apache.calcite.sql.SqlSelect)45 SqlWriter (org.apache.calcite.sql.SqlWriter)42 RexNode (org.apache.calcite.rex.RexNode)40 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)33 RelOptPlanner (org.apache.calcite.plan.RelOptPlanner)25 SqlLiteral (org.apache.calcite.sql.SqlLiteral)23 SqlOperator (org.apache.calcite.sql.SqlOperator)23 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)22 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)21 ImmutableList (com.google.common.collect.ImmutableList)20 SqlValidator (org.apache.calcite.sql.validate.SqlValidator)20