Search in sources :

Example 6 with SqlInsert

use of org.apache.calcite.sql.SqlInsert in project hazelcast by hazelcast.

the class HazelcastTypeCoercion method coerceSourceRowType.

// originally copied from TypeCoercionImpl
private boolean coerceSourceRowType(SqlValidatorScope sourceScope, SqlNode query, int columnIndex, int totalColumns, RelDataType targetType) {
    switch(query.getKind()) {
        case INSERT:
            SqlInsert insert = (SqlInsert) query;
            return coerceSourceRowType(sourceScope, insert.getSource(), columnIndex, totalColumns, targetType);
        case UPDATE:
            // trailing elements of selectList are equal to elements of sourceExpressionList
            // see JetSqlValidator.validateUpdate()
            SqlUpdate update = (SqlUpdate) query;
            SqlNodeList selectList = update.getSourceSelect().getSelectList();
            return coerceSourceRowType(sourceScope, selectList, selectList.size() - totalColumns + columnIndex, targetType);
        default:
            return rowTypeCoercion(sourceScope, query, columnIndex, targetType);
    }
}
Also used : SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlInsert(org.apache.calcite.sql.SqlInsert) SqlUpdate(org.apache.calcite.sql.SqlUpdate)

Example 7 with SqlInsert

use of org.apache.calcite.sql.SqlInsert in project flink by apache.

the class SqlValidatorImpl method registerQuery.

/**
 * Registers a query in a parent scope.
 *
 * @param parentScope Parent scope which this scope turns to in order to resolve objects
 * @param usingScope Scope whose child list this scope should add itself to
 * @param node Query node
 * @param alias Name of this query within its parent. Must be specified if usingScope != null
 * @param checkUpdate if true, validate that the update feature is supported if validating the
 *     update statement
 */
private void registerQuery(SqlValidatorScope parentScope, SqlValidatorScope usingScope, SqlNode node, SqlNode enclosingNode, String alias, boolean forceNullable, boolean checkUpdate) {
    Objects.requireNonNull(node);
    Objects.requireNonNull(enclosingNode);
    Preconditions.checkArgument(usingScope == null || alias != null);
    SqlCall call;
    List<SqlNode> operands;
    switch(node.getKind()) {
        case SELECT:
            final SqlSelect select = (SqlSelect) node;
            final SelectNamespace selectNs = createSelectNamespace(select, enclosingNode);
            registerNamespace(usingScope, alias, selectNs, forceNullable);
            final SqlValidatorScope windowParentScope = (usingScope != null) ? usingScope : parentScope;
            SelectScope selectScope = new SelectScope(parentScope, windowParentScope, select);
            scopes.put(select, selectScope);
            // Start by registering the WHERE clause
            clauseScopes.put(IdPair.of(select, Clause.WHERE), selectScope);
            registerOperandSubQueries(selectScope, select, SqlSelect.WHERE_OPERAND);
            // Register FROM with the inherited scope 'parentScope', not
            // 'selectScope', otherwise tables in the FROM clause would be
            // able to see each other.
            final SqlNode from = select.getFrom();
            if (from != null) {
                final SqlNode newFrom = registerFrom(parentScope, selectScope, true, from, from, null, null, false, false);
                if (newFrom != from) {
                    select.setFrom(newFrom);
                }
            }
            // If this is an aggregating query, the SELECT list and HAVING
            // clause use a different scope, where you can only reference
            // columns which are in the GROUP BY clause.
            SqlValidatorScope aggScope = selectScope;
            if (isAggregate(select)) {
                aggScope = new AggregatingSelectScope(selectScope, select, false);
                clauseScopes.put(IdPair.of(select, Clause.SELECT), aggScope);
            } else {
                clauseScopes.put(IdPair.of(select, Clause.SELECT), selectScope);
            }
            if (select.getGroup() != null) {
                GroupByScope groupByScope = new GroupByScope(selectScope, select.getGroup(), select);
                clauseScopes.put(IdPair.of(select, Clause.GROUP_BY), groupByScope);
                registerSubQueries(groupByScope, select.getGroup());
            }
            registerOperandSubQueries(aggScope, select, SqlSelect.HAVING_OPERAND);
            registerSubQueries(aggScope, select.getSelectList());
            final SqlNodeList orderList = select.getOrderList();
            if (orderList != null) {
                // available to the ORDER BY clause.
                if (select.isDistinct()) {
                    aggScope = new AggregatingSelectScope(selectScope, select, true);
                }
                OrderByScope orderScope = new OrderByScope(aggScope, orderList, select);
                clauseScopes.put(IdPair.of(select, Clause.ORDER), orderScope);
                registerSubQueries(orderScope, orderList);
                if (!isAggregate(select)) {
                    // Since this is not an aggregating query,
                    // there cannot be any aggregates in the ORDER BY clause.
                    SqlNode agg = aggFinder.findAgg(orderList);
                    if (agg != null) {
                        throw newValidationError(agg, RESOURCE.aggregateIllegalInOrderBy());
                    }
                }
            }
            break;
        case INTERSECT:
            validateFeature(RESOURCE.sQLFeature_F302(), node.getParserPosition());
            registerSetop(parentScope, usingScope, node, node, alias, forceNullable);
            break;
        case EXCEPT:
            validateFeature(RESOURCE.sQLFeature_E071_03(), node.getParserPosition());
            registerSetop(parentScope, usingScope, node, node, alias, forceNullable);
            break;
        case UNION:
            registerSetop(parentScope, usingScope, node, node, alias, forceNullable);
            break;
        case WITH:
            registerWith(parentScope, usingScope, (SqlWith) node, enclosingNode, alias, forceNullable, checkUpdate);
            break;
        case VALUES:
            call = (SqlCall) node;
            scopes.put(call, parentScope);
            final TableConstructorNamespace tableConstructorNamespace = new TableConstructorNamespace(this, call, parentScope, enclosingNode);
            registerNamespace(usingScope, alias, tableConstructorNamespace, forceNullable);
            operands = call.getOperandList();
            for (int i = 0; i < operands.size(); ++i) {
                assert operands.get(i).getKind() == SqlKind.ROW;
                // FIXME jvs 9-Feb-2005:  Correlation should
                // be illegal in these sub-queries.  Same goes for
                // any non-lateral SELECT in the FROM list.
                registerOperandSubQueries(parentScope, call, i);
            }
            break;
        case INSERT:
            SqlInsert insertCall = (SqlInsert) node;
            InsertNamespace insertNs = new InsertNamespace(this, insertCall, enclosingNode, parentScope);
            registerNamespace(usingScope, null, insertNs, forceNullable);
            registerQuery(parentScope, usingScope, insertCall.getSource(), enclosingNode, null, false);
            break;
        case DELETE:
            SqlDelete deleteCall = (SqlDelete) node;
            DeleteNamespace deleteNs = new DeleteNamespace(this, deleteCall, enclosingNode, parentScope);
            registerNamespace(usingScope, null, deleteNs, forceNullable);
            registerQuery(parentScope, usingScope, deleteCall.getSourceSelect(), enclosingNode, null, false);
            break;
        case UPDATE:
            if (checkUpdate) {
                validateFeature(RESOURCE.sQLFeature_E101_03(), node.getParserPosition());
            }
            SqlUpdate updateCall = (SqlUpdate) node;
            UpdateNamespace updateNs = new UpdateNamespace(this, updateCall, enclosingNode, parentScope);
            registerNamespace(usingScope, null, updateNs, forceNullable);
            registerQuery(parentScope, usingScope, updateCall.getSourceSelect(), enclosingNode, null, false);
            break;
        case MERGE:
            validateFeature(RESOURCE.sQLFeature_F312(), node.getParserPosition());
            SqlMerge mergeCall = (SqlMerge) node;
            MergeNamespace mergeNs = new MergeNamespace(this, mergeCall, enclosingNode, parentScope);
            registerNamespace(usingScope, null, mergeNs, forceNullable);
            registerQuery(parentScope, usingScope, mergeCall.getSourceSelect(), enclosingNode, null, false);
            // validation check
            if (mergeCall.getUpdateCall() != null) {
                registerQuery(clauseScopes.get(IdPair.of(mergeCall.getSourceSelect(), Clause.WHERE)), null, mergeCall.getUpdateCall(), enclosingNode, null, false, false);
            }
            if (mergeCall.getInsertCall() != null) {
                registerQuery(parentScope, null, mergeCall.getInsertCall(), enclosingNode, null, false);
            }
            break;
        case UNNEST:
            call = (SqlCall) node;
            final UnnestNamespace unnestNs = new UnnestNamespace(this, call, parentScope, enclosingNode);
            registerNamespace(usingScope, alias, unnestNs, forceNullable);
            registerOperandSubQueries(parentScope, call, 0);
            scopes.put(node, parentScope);
            break;
        case OTHER_FUNCTION:
            call = (SqlCall) node;
            ProcedureNamespace procNs = new ProcedureNamespace(this, parentScope, call, enclosingNode);
            registerNamespace(usingScope, alias, procNs, forceNullable);
            registerSubQueries(parentScope, call);
            break;
        case MULTISET_QUERY_CONSTRUCTOR:
        case MULTISET_VALUE_CONSTRUCTOR:
            validateFeature(RESOURCE.sQLFeature_S271(), node.getParserPosition());
            call = (SqlCall) node;
            CollectScope cs = new CollectScope(parentScope, usingScope, call);
            final CollectNamespace tableConstructorNs = new CollectNamespace(call, cs, enclosingNode);
            final String alias2 = deriveAlias(node, nextGeneratedId++);
            registerNamespace(usingScope, alias2, tableConstructorNs, forceNullable);
            operands = call.getOperandList();
            for (int i = 0; i < operands.size(); i++) {
                registerOperandSubQueries(parentScope, call, i);
            }
            break;
        default:
            throw Util.unexpected(node.getKind());
    }
}
Also used : BitString(org.apache.calcite.util.BitString) SqlInsert(org.apache.calcite.sql.SqlInsert) SqlUpdate(org.apache.calcite.sql.SqlUpdate) SqlSelect(org.apache.calcite.sql.SqlSelect) SqlNode(org.apache.calcite.sql.SqlNode) SqlCall(org.apache.calcite.sql.SqlCall) SqlMerge(org.apache.calcite.sql.SqlMerge) SqlDelete(org.apache.calcite.sql.SqlDelete) SqlNodeList(org.apache.calcite.sql.SqlNodeList)

Example 8 with SqlInsert

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

the class SqlValidatorImpl method rewriteMerge.

private void rewriteMerge(SqlMerge call) {
    SqlNodeList selectList;
    SqlUpdate updateStmt = call.getUpdateCall();
    if (updateStmt != null) {
        // if we have an update statement, just clone the select list
        // from the update statement's source since it's the same as
        // what we want for the select list of the merge source -- '*'
        // followed by the update set expressions
        selectList = SqlNode.clone(updateStmt.getSourceSelect().getSelectList());
    } else {
        // otherwise, just use select *
        selectList = new SqlNodeList(SqlParserPos.ZERO);
        selectList.add(SqlIdentifier.star(SqlParserPos.ZERO));
    }
    SqlNode targetTable = call.getTargetTable();
    if (call.getAlias() != null) {
        targetTable = SqlValidatorUtil.addAlias(targetTable, call.getAlias().getSimple());
    }
    // Provided there is an insert substatement, the source select for
    // the merge is a left outer join between the source in the USING
    // clause and the target table; otherwise, the join is just an
    // inner join.  Need to clone the source table reference in order
    // for validation to work
    SqlNode sourceTableRef = call.getSourceTableRef();
    SqlInsert insertCall = call.getInsertCall();
    JoinType joinType = (insertCall == null) ? JoinType.INNER : JoinType.LEFT;
    final SqlNode leftJoinTerm = SqlNode.clone(sourceTableRef);
    SqlNode outerJoin = new SqlJoin(SqlParserPos.ZERO, leftJoinTerm, SqlLiteral.createBoolean(false, SqlParserPos.ZERO), joinType.symbol(SqlParserPos.ZERO), targetTable, JoinConditionType.ON.symbol(SqlParserPos.ZERO), call.getCondition());
    SqlSelect select = new SqlSelect(SqlParserPos.ZERO, null, selectList, outerJoin, null, null, null, null, null, null, null);
    call.setSourceSelect(select);
    // that via the from clause on the select
    if (insertCall != null) {
        SqlCall valuesCall = (SqlCall) insertCall.getSource();
        SqlCall rowCall = valuesCall.operand(0);
        selectList = new SqlNodeList(rowCall.getOperandList(), SqlParserPos.ZERO);
        final SqlNode insertSource = SqlNode.clone(sourceTableRef);
        select = new SqlSelect(SqlParserPos.ZERO, null, selectList, insertSource, null, null, null, null, null, null, null);
        insertCall.setSource(select);
    }
}
Also used : SqlSelect(org.apache.calcite.sql.SqlSelect) SqlJoin(org.apache.calcite.sql.SqlJoin) SqlCall(org.apache.calcite.sql.SqlCall) SqlNodeList(org.apache.calcite.sql.SqlNodeList) JoinType(org.apache.calcite.sql.JoinType) SqlInsert(org.apache.calcite.sql.SqlInsert) SqlUpdate(org.apache.calcite.sql.SqlUpdate) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

SqlInsert (org.apache.calcite.sql.SqlInsert)8 SqlNode (org.apache.calcite.sql.SqlNode)7 SqlUpdate (org.apache.calcite.sql.SqlUpdate)7 SqlSelect (org.apache.calcite.sql.SqlSelect)6 SqlNodeList (org.apache.calcite.sql.SqlNodeList)5 SqlCall (org.apache.calcite.sql.SqlCall)4 SqlDelete (org.apache.calcite.sql.SqlDelete)3 RelDataType (org.apache.calcite.rel.type.RelDataType)2 JoinType (org.apache.calcite.sql.JoinType)2 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)2 SqlJoin (org.apache.calcite.sql.SqlJoin)2 SqlMerge (org.apache.calcite.sql.SqlMerge)2 BitString (org.apache.calcite.util.BitString)2 ArrayList (java.util.ArrayList)1 RelOptTable (org.apache.calcite.plan.RelOptTable)1 RelNode (org.apache.calcite.rel.RelNode)1 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)1 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)1 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)1 RexInputRef (org.apache.calcite.rex.RexInputRef)1