Search in sources :

Example 81 with SqlCall

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

the class SqlToRelConverter method convertFrom.

/**
 * Converts a FROM clause into a relational expression.
 *
 * @param bb   Scope within which to resolve identifiers
 * @param from FROM clause of a query. Examples include:
 *
 *             <ul>
 *             <li>a single table ("SALES.EMP"),
 *             <li>an aliased table ("EMP AS E"),
 *             <li>a list of tables ("EMP, DEPT"),
 *             <li>an ANSI Join expression ("EMP JOIN DEPT ON EMP.DEPTNO =
 *             DEPT.DEPTNO"),
 *             <li>a VALUES clause ("VALUES ('Fred', 20)"),
 *             <li>a query ("(SELECT * FROM EMP WHERE GENDER = 'F')"),
 *             <li>or any combination of the above.
 *             </ul>
 */
protected void convertFrom(Blackboard bb, SqlNode from) {
    if (from == null) {
        bb.setRoot(LogicalValues.createOneRow(cluster), false);
        return;
    }
    final SqlCall call;
    final SqlNode[] operands;
    switch(from.getKind()) {
        case MATCH_RECOGNIZE:
            convertMatchRecognize(bb, (SqlCall) from);
            return;
        case AS:
            call = (SqlCall) from;
            convertFrom(bb, call.operand(0));
            if (call.operandCount() > 2 && bb.root instanceof Values) {
                final List<String> fieldNames = new ArrayList<>();
                for (SqlNode node : Util.skip(call.getOperandList(), 2)) {
                    fieldNames.add(((SqlIdentifier) node).getSimple());
                }
                bb.setRoot(relBuilder.push(bb.root).rename(fieldNames).build(), true);
            }
            return;
        case WITH_ITEM:
            convertFrom(bb, ((SqlWithItem) from).query);
            return;
        case WITH:
            convertFrom(bb, ((SqlWith) from).body);
            return;
        case TABLESAMPLE:
            operands = ((SqlBasicCall) from).getOperands();
            SqlSampleSpec sampleSpec = SqlLiteral.sampleValue(operands[1]);
            if (sampleSpec instanceof SqlSampleSpec.SqlSubstitutionSampleSpec) {
                String sampleName = ((SqlSampleSpec.SqlSubstitutionSampleSpec) sampleSpec).getName();
                datasetStack.push(sampleName);
                convertFrom(bb, operands[0]);
                datasetStack.pop();
            } else if (sampleSpec instanceof SqlSampleSpec.SqlTableSampleSpec) {
                SqlSampleSpec.SqlTableSampleSpec tableSampleSpec = (SqlSampleSpec.SqlTableSampleSpec) sampleSpec;
                convertFrom(bb, operands[0]);
                RelOptSamplingParameters params = new RelOptSamplingParameters(tableSampleSpec.isBernoulli(), tableSampleSpec.getSamplePercentage(), tableSampleSpec.isRepeatable(), tableSampleSpec.getRepeatableSeed());
                bb.setRoot(new Sample(cluster, bb.root, params), false);
            } else {
                throw new AssertionError("unknown TABLESAMPLE type: " + sampleSpec);
            }
            return;
        case IDENTIFIER:
            convertIdentifier(bb, (SqlIdentifier) from, null);
            return;
        case EXTEND:
            call = (SqlCall) from;
            SqlIdentifier id = (SqlIdentifier) call.getOperandList().get(0);
            SqlNodeList extendedColumns = (SqlNodeList) call.getOperandList().get(1);
            convertIdentifier(bb, id, extendedColumns);
            return;
        case JOIN:
            final SqlJoin join = (SqlJoin) from;
            final SqlValidatorScope scope = validator.getJoinScope(from);
            final Blackboard fromBlackboard = createBlackboard(scope, null, false);
            SqlNode left = join.getLeft();
            SqlNode right = join.getRight();
            final boolean isNatural = join.isNatural();
            final JoinType joinType = join.getJoinType();
            final SqlValidatorScope leftScope = Util.first(validator.getJoinScope(left), ((DelegatingScope) bb.scope).getParent());
            final Blackboard leftBlackboard = createBlackboard(leftScope, null, false);
            final SqlValidatorScope rightScope = Util.first(validator.getJoinScope(right), ((DelegatingScope) bb.scope).getParent());
            final Blackboard rightBlackboard = createBlackboard(rightScope, null, false);
            convertFrom(leftBlackboard, left);
            RelNode leftRel = leftBlackboard.root;
            convertFrom(rightBlackboard, right);
            RelNode rightRel = rightBlackboard.root;
            JoinRelType convertedJoinType = convertJoinType(joinType);
            RexNode conditionExp;
            final SqlValidatorNamespace leftNamespace = validator.getNamespace(left);
            final SqlValidatorNamespace rightNamespace = validator.getNamespace(right);
            if (isNatural) {
                final RelDataType leftRowType = leftNamespace.getRowType();
                final RelDataType rightRowType = rightNamespace.getRowType();
                final List<String> columnList = SqlValidatorUtil.deriveNaturalJoinColumnList(leftRowType, rightRowType);
                conditionExp = convertUsing(leftNamespace, rightNamespace, columnList);
            } else {
                conditionExp = convertJoinCondition(fromBlackboard, leftNamespace, rightNamespace, join.getCondition(), join.getConditionType(), leftRel, rightRel);
            }
            final RelNode joinRel = createJoin(fromBlackboard, leftRel, rightRel, conditionExp, convertedJoinType);
            bb.setRoot(joinRel, false);
            return;
        case SELECT:
        case INTERSECT:
        case EXCEPT:
        case UNION:
            final RelNode rel = convertQueryRecursive(from, false, null).project();
            bb.setRoot(rel, true);
            return;
        case VALUES:
            convertValuesImpl(bb, (SqlCall) from, null);
            return;
        case UNNEST:
            call = (SqlCall) from;
            final List<SqlNode> nodes = call.getOperandList();
            final SqlUnnestOperator operator = (SqlUnnestOperator) call.getOperator();
            for (SqlNode node : nodes) {
                replaceSubQueries(bb, node, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
            }
            final List<RexNode> exprs = new ArrayList<>();
            final List<String> fieldNames = new ArrayList<>();
            for (Ord<SqlNode> node : Ord.zip(nodes)) {
                exprs.add(bb.convertExpression(node.e));
                fieldNames.add(validator.deriveAlias(node.e, node.i));
            }
            RelNode child = (null != bb.root) ? bb.root : LogicalValues.createOneRow(cluster);
            relBuilder.push(child).projectNamed(exprs, fieldNames, false);
            Uncollect uncollect = new Uncollect(cluster, cluster.traitSetOf(Convention.NONE), relBuilder.build(), operator.withOrdinality);
            bb.setRoot(uncollect, true);
            return;
        case COLLECTION_TABLE:
            call = (SqlCall) from;
            // Dig out real call; TABLE() wrapper is just syntactic.
            assert call.getOperandList().size() == 1;
            final SqlCall call2 = call.operand(0);
            convertCollectionTable(bb, call2);
            return;
        default:
            throw new AssertionError("not a join operator " + from);
    }
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) Uncollect(org.apache.calcite.rel.core.Uncollect) Values(org.apache.calcite.rel.core.Values) LogicalValues(org.apache.calcite.rel.logical.LogicalValues) ArrayList(java.util.ArrayList) SqlUnnestOperator(org.apache.calcite.sql.SqlUnnestOperator) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) RelOptSamplingParameters(org.apache.calcite.plan.RelOptSamplingParameters) SqlNode(org.apache.calcite.sql.SqlNode) SqlCall(org.apache.calcite.sql.SqlCall) Sample(org.apache.calcite.rel.core.Sample) SqlSampleSpec(org.apache.calcite.sql.SqlSampleSpec) JoinType(org.apache.calcite.sql.JoinType) SemiJoinType(org.apache.calcite.sql.SemiJoinType) JoinRelType(org.apache.calcite.rel.core.JoinRelType) RelNode(org.apache.calcite.rel.RelNode) SqlJoin(org.apache.calcite.sql.SqlJoin) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace) RexNode(org.apache.calcite.rex.RexNode)

Example 82 with SqlCall

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

the class SqlToRelConverter method convertValuesImpl.

/**
 * Converts a values clause (as in "INSERT INTO T(x,y) VALUES (1,2)") into a
 * relational expression.
 *
 * @param bb            Blackboard
 * @param values        Call to SQL VALUES operator
 * @param targetRowType Target row type
 */
private void convertValuesImpl(Blackboard bb, SqlCall values, RelDataType targetRowType) {
    // Attempt direct conversion to LogicalValues; if that fails, deal with
    // fancy stuff like sub-queries below.
    RelNode valuesRel = convertRowValues(bb, values, values.getOperandList(), true, targetRowType);
    if (valuesRel != null) {
        bb.setRoot(valuesRel, true);
        return;
    }
    final List<RelNode> unionRels = new ArrayList<>();
    for (SqlNode rowConstructor1 : values.getOperandList()) {
        SqlCall rowConstructor = (SqlCall) rowConstructor1;
        Blackboard tmpBb = createBlackboard(bb.scope, null, false);
        replaceSubQueries(tmpBb, rowConstructor, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
        final List<Pair<RexNode, String>> exps = new ArrayList<>();
        for (Ord<SqlNode> operand : Ord.zip(rowConstructor.getOperandList())) {
            exps.add(Pair.of(tmpBb.convertExpression(operand.e), validator.deriveAlias(operand.e, operand.i)));
        }
        RelNode in = (null == tmpBb.root) ? LogicalValues.createOneRow(cluster) : tmpBb.root;
        unionRels.add(relBuilder.push(in).project(Pair.left(exps), Pair.right(exps)).build());
    }
    if (unionRels.size() == 0) {
        throw new AssertionError("empty values clause");
    } else if (unionRels.size() == 1) {
        bb.setRoot(unionRels.get(0), true);
    } else {
        bb.setRoot(LogicalUnion.create(unionRels, true), true);
    }
// REVIEW jvs 22-Jan-2004:  should I add
// mapScopeToLux.put(validator.getScope(values),bb.root);
// ?
}
Also used : RelNode(org.apache.calcite.rel.RelNode) SqlCall(org.apache.calcite.sql.SqlCall) ArrayList(java.util.ArrayList) SqlNode(org.apache.calcite.sql.SqlNode) Pair(org.apache.calcite.util.Pair)

Example 83 with SqlCall

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

the class StandardConvertletTable method convertOverlapsOperand.

private Pair<RexNode, RexNode> convertOverlapsOperand(SqlRexContext cx, SqlParserPos pos, SqlNode operand) {
    final SqlNode a0;
    final SqlNode a1;
    switch(operand.getKind()) {
        case ROW:
            a0 = ((SqlCall) operand).operand(0);
            final SqlNode a10 = ((SqlCall) operand).operand(1);
            final RelDataType t1 = cx.getValidator().getValidatedNodeType(a10);
            if (SqlTypeUtil.isInterval(t1)) {
                // make t1 = t0 + t1 when t1 is an interval.
                a1 = plus(pos, a0, a10);
            } else {
                a1 = a10;
            }
            break;
        default:
            a0 = operand;
            a1 = operand;
    }
    final RexNode r0 = cx.convertExpression(a0);
    final RexNode r1 = cx.convertExpression(a1);
    return Pair.of(r0, r1);
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlNode(org.apache.calcite.sql.SqlNode) RexNode(org.apache.calcite.rex.RexNode)

Example 84 with SqlCall

use of org.apache.calcite.sql.SqlCall 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)

Example 85 with SqlCall

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

the class SqlValidatorImpl method validateNoAggs.

/**
 * Throws an error if there is an aggregate or windowed aggregate in the
 * given clause.
 *
 * @param aggFinder Finder for the particular kind(s) of aggregate function
 * @param node      Parse tree
 * @param clause    Name of clause: "WHERE", "GROUP BY", "ON"
 */
private void validateNoAggs(AggFinder aggFinder, SqlNode node, String clause) {
    final SqlCall agg = aggFinder.findAgg(node);
    if (agg == null) {
        return;
    }
    final SqlOperator op = agg.getOperator();
    if (op == SqlStdOperatorTable.OVER) {
        throw newValidationError(agg, RESOURCE.windowedAggregateIllegalInClause(clause));
    } else if (op.isGroup() || op.isGroupAuxiliary()) {
        throw newValidationError(agg, RESOURCE.groupFunctionMustAppearInGroupByClause(op.getName()));
    } else {
        throw newValidationError(agg, RESOURCE.aggregateIllegalInClause(clause));
    }
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) SqlOperator(org.apache.calcite.sql.SqlOperator)

Aggregations

SqlCall (org.apache.calcite.sql.SqlCall)108 SqlNode (org.apache.calcite.sql.SqlNode)81 SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)32 SqlNodeList (org.apache.calcite.sql.SqlNodeList)32 RelDataType (org.apache.calcite.rel.type.RelDataType)30 SqlOperator (org.apache.calcite.sql.SqlOperator)26 BitString (org.apache.calcite.util.BitString)19 ArrayList (java.util.ArrayList)18 SqlSelect (org.apache.calcite.sql.SqlSelect)17 RexNode (org.apache.calcite.rex.RexNode)13 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)12 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)11 SqlLiteral (org.apache.calcite.sql.SqlLiteral)11 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9 SqlKind (org.apache.calcite.sql.SqlKind)9 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)9 List (java.util.List)8 SqlCallBinding (org.apache.calcite.sql.SqlCallBinding)8 Pair (org.apache.calcite.util.Pair)8 RelNode (org.apache.calcite.rel.RelNode)7