Search in sources :

Example 16 with SqlIdentifier

use of org.apache.calcite.sql.SqlIdentifier in project calcite by apache.

the class SqlValidatorImpl method findAllValidFunctionNames.

private static void findAllValidFunctionNames(List<String> names, SqlValidator validator, Collection<SqlMoniker> result, SqlParserPos pos) {
    // a function name can only be 1 part
    if (names.size() > 1) {
        return;
    }
    for (SqlOperator op : validator.getOperatorTable().getOperatorList()) {
        SqlIdentifier curOpId = new SqlIdentifier(op.getName(), pos);
        final SqlCall call = SqlUtil.makeCall(validator.getOperatorTable(), curOpId);
        if (call != null) {
            result.add(new SqlMonikerImpl(op.getName(), SqlMonikerType.FUNCTION));
        } else {
            if ((op.getSyntax() == SqlSyntax.FUNCTION) || (op.getSyntax() == SqlSyntax.PREFIX)) {
                if (op.getOperandTypeChecker() != null) {
                    String sig = op.getAllowedSignatures();
                    sig = sig.replaceAll("'", "");
                    result.add(new SqlMonikerImpl(sig, SqlMonikerType.FUNCTION));
                    continue;
                }
                result.add(new SqlMonikerImpl(op.getName(), SqlMonikerType.FUNCTION));
            }
        }
    }
}
Also used : SqlOperator(org.apache.calcite.sql.SqlOperator) SqlCall(org.apache.calcite.sql.SqlCall) BitString(org.apache.calcite.util.BitString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier)

Example 17 with SqlIdentifier

use of org.apache.calcite.sql.SqlIdentifier in project calcite by apache.

the class SqlValidatorImpl method getFieldOrigin.

private List<String> getFieldOrigin(SqlNode sqlQuery, int i) {
    if (sqlQuery instanceof SqlSelect) {
        SqlSelect sqlSelect = (SqlSelect) sqlQuery;
        final SelectScope scope = getRawSelectScope(sqlSelect);
        final List<SqlNode> selectList = scope.getExpandedSelectList();
        final SqlNode selectItem = stripAs(selectList.get(i));
        if (selectItem instanceof SqlIdentifier) {
            final SqlQualified qualified = scope.fullyQualify((SqlIdentifier) selectItem);
            SqlValidatorNamespace namespace = qualified.namespace;
            final SqlValidatorTable table = namespace.getTable();
            if (table == null) {
                return null;
            }
            final List<String> origin = new ArrayList<>(table.getQualifiedName());
            for (String name : qualified.suffix()) {
                namespace = namespace.lookupChild(name);
                if (namespace == null) {
                    return null;
                }
                origin.add(name);
            }
            return origin;
        }
        return null;
    } else if (sqlQuery instanceof SqlOrderBy) {
        return getFieldOrigin(((SqlOrderBy) sqlQuery).query, i);
    } else {
        return null;
    }
}
Also used : SqlSelect(org.apache.calcite.sql.SqlSelect) ArrayList(java.util.ArrayList) BitString(org.apache.calcite.util.BitString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlOrderBy(org.apache.calcite.sql.SqlOrderBy) SqlNode(org.apache.calcite.sql.SqlNode)

Example 18 with SqlIdentifier

use of org.apache.calcite.sql.SqlIdentifier 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 19 with SqlIdentifier

use of org.apache.calcite.sql.SqlIdentifier 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 20 with SqlIdentifier

use of org.apache.calcite.sql.SqlIdentifier in project calcite by apache.

the class SqlToRelConverter method collectInsertTargets.

/**
 * Given an INSERT statement, collects the list of names to be populated and
 * the expressions to put in them.
 *
 * @param call              Insert statement
 * @param sourceRef         Expression representing a row from the source
 *                          relational expression
 * @param targetColumnNames List of target column names, to be populated
 * @param columnExprs       List of expressions, to be populated
 */
protected void collectInsertTargets(SqlInsert call, final RexNode sourceRef, final List<String> targetColumnNames, List<RexNode> columnExprs) {
    final RelOptTable targetTable = getTargetTable(call);
    final RelDataType tableRowType = targetTable.getRowType();
    SqlNodeList targetColumnList = call.getTargetColumnList();
    if (targetColumnList == null) {
        if (validator.getConformance().isInsertSubsetColumnsAllowed()) {
            final RelDataType targetRowType = typeFactory.createStructType(tableRowType.getFieldList().subList(0, sourceRef.getType().getFieldCount()));
            targetColumnNames.addAll(targetRowType.getFieldNames());
        } else {
            targetColumnNames.addAll(tableRowType.getFieldNames());
        }
    } else {
        for (int i = 0; i < targetColumnList.size(); i++) {
            SqlIdentifier id = (SqlIdentifier) targetColumnList.get(i);
            RelDataTypeField field = SqlValidatorUtil.getTargetField(tableRowType, typeFactory, id, catalogReader, targetTable);
            assert field != null : "column " + id.toString() + " not found";
            targetColumnNames.add(field.getName());
        }
    }
    final Blackboard bb = createInsertBlackboard(targetTable, sourceRef, targetColumnNames);
    // Next, assign expressions for generated columns.
    final List<ColumnStrategy> strategies = targetTable.getColumnStrategies();
    for (String columnName : targetColumnNames) {
        final int i = tableRowType.getFieldNames().indexOf(columnName);
        final RexNode expr;
        switch(strategies.get(i)) {
            case STORED:
                final InitializerExpressionFactory f = Util.first(targetTable.unwrap(InitializerExpressionFactory.class), NullInitializerExpressionFactory.INSTANCE);
                expr = f.newColumnDefaultValue(targetTable, i, bb);
                break;
            case VIRTUAL:
                expr = null;
                break;
            default:
                expr = bb.nameToNodeMap.get(columnName);
        }
        columnExprs.add(expr);
    }
    // Remove virtual columns from the list.
    for (int i = 0; i < targetColumnNames.size(); i++) {
        if (columnExprs.get(i) == null) {
            columnExprs.remove(i);
            targetColumnNames.remove(i);
            --i;
        }
    }
}
Also used : ColumnStrategy(org.apache.calcite.schema.ColumnStrategy) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelOptTable(org.apache.calcite.plan.RelOptTable) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)131 SqlNode (org.apache.calcite.sql.SqlNode)84 RelDataType (org.apache.calcite.rel.type.RelDataType)46 SqlNodeList (org.apache.calcite.sql.SqlNodeList)43 ArrayList (java.util.ArrayList)41 SqlCall (org.apache.calcite.sql.SqlCall)32 BitString (org.apache.calcite.util.BitString)28 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)21 SqlSelect (org.apache.calcite.sql.SqlSelect)21 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)12 SchemaPlus (org.apache.calcite.schema.SchemaPlus)11 SqlOperator (org.apache.calcite.sql.SqlOperator)11 NlsString (org.apache.calcite.util.NlsString)11 List (java.util.List)9 Map (java.util.Map)9 RelOptTable (org.apache.calcite.plan.RelOptTable)9 RexNode (org.apache.calcite.rex.RexNode)9 AbstractSchema (org.apache.drill.exec.store.AbstractSchema)9 ImmutableList (com.google.common.collect.ImmutableList)8 RelNode (org.apache.calcite.rel.RelNode)7