Search in sources :

Example 1 with SqlBasicVisitor

use of org.apache.calcite.sql.util.SqlBasicVisitor 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 2 with SqlBasicVisitor

use of org.apache.calcite.sql.util.SqlBasicVisitor in project hazelcast by hazelcast.

the class HazelcastSqlValidator method containsStreamingSource.

/**
 * Goes over all the referenced tables in the given {@link SqlNode}
 * and returns true if any of them uses a streaming connector.
 */
public boolean containsStreamingSource(SqlNode node) {
    class FindStreamingTablesVisitor extends SqlBasicVisitor<Void> {

        boolean found;

        @Override
        public Void visit(SqlIdentifier id) {
            SqlValidatorTable table = getCatalogReader().getTable(id.names);
            // not every identifier is a table
            if (table != null) {
                HazelcastTable hazelcastTable = table.unwrap(HazelcastTable.class);
                if (hazelcastTable.getTarget() instanceof ViewTable) {
                    found = ((ViewTable) hazelcastTable.getTarget()).isStream();
                    return null;
                }
                SqlConnector connector = getJetSqlConnector(hazelcastTable.getTarget());
                if (connector.isStream()) {
                    found = true;
                    return null;
                }
            }
            return super.visit(id);
        }

        @Override
        public Void visit(SqlCall call) {
            SqlOperator operator = call.getOperator();
            if (operator instanceof HazelcastTableSourceFunction) {
                if (((HazelcastTableSourceFunction) operator).isStream()) {
                    found = true;
                    return null;
                }
            }
            return super.visit(call);
        }
    }
    FindStreamingTablesVisitor visitor = new FindStreamingTablesVisitor();
    node.accept(visitor);
    return visitor.found;
}
Also used : ViewTable(com.hazelcast.jet.sql.impl.connector.virtual.ViewTable) SqlCall(org.apache.calcite.sql.SqlCall) SqlOperator(org.apache.calcite.sql.SqlOperator) SqlValidatorTable(org.apache.calcite.sql.validate.SqlValidatorTable) HazelcastTableSourceFunction(com.hazelcast.jet.sql.impl.schema.HazelcastTableSourceFunction) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlConnectorUtil.getJetSqlConnector(com.hazelcast.jet.sql.impl.connector.SqlConnectorUtil.getJetSqlConnector) SqlConnector(com.hazelcast.jet.sql.impl.connector.SqlConnector) HazelcastTable(com.hazelcast.jet.sql.impl.schema.HazelcastTable) SqlBasicVisitor(org.apache.calcite.sql.util.SqlBasicVisitor)

Example 3 with SqlBasicVisitor

use of org.apache.calcite.sql.util.SqlBasicVisitor in project hazelcast by hazelcast.

the class HazelcastSqlValidator method countOrderingFunctions.

private static int countOrderingFunctions(SqlNode node) {
    class OrderingFunctionCounter extends SqlBasicVisitor<Void> {

        int count;

        @Override
        public Void visit(SqlCall call) {
            SqlOperator operator = call.getOperator();
            if (operator instanceof ImposeOrderFunction) {
                count++;
            }
            return super.visit(call);
        }
    }
    OrderingFunctionCounter counter = new OrderingFunctionCounter();
    node.accept(counter);
    return counter.count;
}
Also used : ImposeOrderFunction(com.hazelcast.jet.sql.impl.aggregate.function.ImposeOrderFunction) SqlCall(org.apache.calcite.sql.SqlCall) SqlOperator(org.apache.calcite.sql.SqlOperator) SqlBasicVisitor(org.apache.calcite.sql.util.SqlBasicVisitor)

Aggregations

SqlCall (org.apache.calcite.sql.SqlCall)3 SqlOperator (org.apache.calcite.sql.SqlOperator)3 SqlBasicVisitor (org.apache.calcite.sql.util.SqlBasicVisitor)3 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImposeOrderFunction (com.hazelcast.jet.sql.impl.aggregate.function.ImposeOrderFunction)1 SqlConnector (com.hazelcast.jet.sql.impl.connector.SqlConnector)1 SqlConnectorUtil.getJetSqlConnector (com.hazelcast.jet.sql.impl.connector.SqlConnectorUtil.getJetSqlConnector)1 ViewTable (com.hazelcast.jet.sql.impl.connector.virtual.ViewTable)1 HazelcastTable (com.hazelcast.jet.sql.impl.schema.HazelcastTable)1 HazelcastTableSourceFunction (com.hazelcast.jet.sql.impl.schema.HazelcastTableSourceFunction)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 TreeSet (java.util.TreeSet)1 RelCollation (org.apache.calcite.rel.RelCollation)1 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)1 RelNode (org.apache.calcite.rel.RelNode)1 RelFactories (org.apache.calcite.rel.core.RelFactories)1 RelDataType (org.apache.calcite.rel.type.RelDataType)1