Search in sources :

Example 1 with SubqueryAnalyzer

use of io.crate.analyze.expressions.SubqueryAnalyzer in project crate by crate.

the class RelationAnalyzer method visitQuery.

@Override
protected AnalyzedRelation visitQuery(Query node, StatementAnalysisContext statementContext) {
    AnalyzedRelation childRelation = node.getQueryBody().accept(this, statementContext);
    if (node.getOrderBy().isEmpty() && node.getLimit().isEmpty() && node.getOffset().isEmpty()) {
        return childRelation;
    }
    // In case of Set Operation (UNION, INTERSECT EXCEPT) or VALUES clause,
    // the `node` contains the ORDER BY and/or LIMIT and/or OFFSET and wraps the
    // actual operation (eg: UNION) which is parsed into the `queryBody` of the `node`.
    // Use child relation to process expressions of the "root" Query node
    statementContext.startRelation();
    RelationAnalysisContext relationAnalysisContext = statementContext.currentRelationContext();
    relationAnalysisContext.addSourceRelation(childRelation);
    statementContext.endRelation();
    List<Symbol> childRelationFields = childRelation.outputs();
    var coordinatorTxnCtx = statementContext.transactionContext();
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(coordinatorTxnCtx, nodeCtx, statementContext.paramTyeHints(), new FullQualifiedNameFieldProvider(relationAnalysisContext.sources(), relationAnalysisContext.parentSources(), coordinatorTxnCtx.sessionContext().searchPath().currentSchema()), new SubqueryAnalyzer(this, statementContext));
    ExpressionAnalysisContext expressionAnalysisContext = relationAnalysisContext.expressionAnalysisContext();
    SelectAnalysis selectAnalysis = new SelectAnalysis(childRelationFields.size(), relationAnalysisContext.sources(), expressionAnalyzer, expressionAnalysisContext);
    for (Symbol field : childRelationFields) {
        selectAnalysis.add(Symbols.pathFromSymbol(field), field);
    }
    var normalizer = EvaluatingNormalizer.functionOnlyNormalizer(nodeCtx, f -> expressionAnalysisContext.isEagerNormalizationAllowed() && f.isDeterministic());
    return new QueriedSelectRelation(false, List.of(childRelation), List.of(), selectAnalysis.outputSymbols(), Literal.BOOLEAN_TRUE, List.of(), null, analyzeOrderBy(selectAnalysis, node.getOrderBy(), expressionAnalyzer, expressionAnalysisContext, false, false), longSymbolOrNull(node.getLimit(), expressionAnalyzer, expressionAnalysisContext, normalizer, coordinatorTxnCtx), longSymbolOrNull(node.getOffset(), expressionAnalyzer, expressionAnalysisContext, normalizer, coordinatorTxnCtx));
}
Also used : SelectAnalysis(io.crate.analyze.relations.select.SelectAnalysis) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) Symbol(io.crate.expression.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) QueriedSelectRelation(io.crate.analyze.QueriedSelectRelation) SubqueryAnalyzer(io.crate.analyze.expressions.SubqueryAnalyzer)

Example 2 with SubqueryAnalyzer

use of io.crate.analyze.expressions.SubqueryAnalyzer in project crate by crate.

the class DeleteAnalyzer method analyze.

public AnalyzedDeleteStatement analyze(Delete delete, ParamTypeHints typeHints, CoordinatorTxnCtx txnContext) {
    StatementAnalysisContext stmtCtx = new StatementAnalysisContext(typeHints, Operation.DELETE, txnContext);
    final RelationAnalysisContext relationCtx = stmtCtx.startRelation();
    AnalyzedRelation relation = relationAnalyzer.analyze(delete.getRelation(), stmtCtx);
    stmtCtx.endRelation();
    MaybeAliasedStatement maybeAliasedStatement = MaybeAliasedStatement.analyze(relation);
    relation = maybeAliasedStatement.nonAliasedRelation();
    if (!(relation instanceof DocTableRelation)) {
        throw new UnsupportedOperationException("Cannot delete from relations other than base tables");
    }
    DocTableRelation table = (DocTableRelation) relation;
    EvaluatingNormalizer normalizer = new EvaluatingNormalizer(nodeCtx, RowGranularity.CLUSTER, null, table);
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(txnContext, nodeCtx, typeHints, new FullQualifiedNameFieldProvider(relationCtx.sources(), relationCtx.parentSources(), txnContext.sessionContext().searchPath().currentSchema()), new SubqueryAnalyzer(relationAnalyzer, new StatementAnalysisContext(typeHints, Operation.READ, txnContext)));
    Symbol query = Objects.requireNonNullElse(expressionAnalyzer.generateQuerySymbol(delete.getWhere(), new ExpressionAnalysisContext(txnContext.sessionContext())), Literal.BOOLEAN_TRUE);
    query = maybeAliasedStatement.maybeMapFields(query);
    Symbol normalizedQuery = normalizer.normalize(query, txnContext);
    return new AnalyzedDeleteStatement(table, normalizedQuery);
}
Also used : RelationAnalysisContext(io.crate.analyze.relations.RelationAnalysisContext) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) EvaluatingNormalizer(io.crate.expression.eval.EvaluatingNormalizer) Symbol(io.crate.expression.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) AnalyzedRelation(io.crate.analyze.relations.AnalyzedRelation) StatementAnalysisContext(io.crate.analyze.relations.StatementAnalysisContext) DocTableRelation(io.crate.analyze.relations.DocTableRelation) SubqueryAnalyzer(io.crate.analyze.expressions.SubqueryAnalyzer) FullQualifiedNameFieldProvider(io.crate.analyze.relations.FullQualifiedNameFieldProvider)

Example 3 with SubqueryAnalyzer

use of io.crate.analyze.expressions.SubqueryAnalyzer in project crate by crate.

the class SQLExecutor method asSymbol.

/**
 * Convert a expression to a symbol
 * If tables are used here they must also be registered in the SQLExecutor having used {@link Builder#addTable(String)}
 */
public Symbol asSymbol(String expression) {
    MapBuilder<RelationName, AnalyzedRelation> sources = MapBuilder.newMapBuilder();
    for (SchemaInfo schemaInfo : schemas) {
        for (TableInfo tableInfo : schemaInfo.getTables()) {
            if (tableInfo instanceof DocTableInfo) {
                RelationName relationName = tableInfo.ident();
                sources.put(relationName, new DocTableRelation(schemas.getTableInfo(relationName)));
            }
        }
    }
    CoordinatorTxnCtx coordinatorTxnCtx = new CoordinatorTxnCtx(sessionContext);
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(coordinatorTxnCtx, nodeCtx, ParamTypeHints.EMPTY, new FullQualifiedNameFieldProvider(sources.immutableMap(), ParentRelations.NO_PARENTS, sessionContext.searchPath().currentSchema()), new SubqueryAnalyzer(relAnalyzer, new StatementAnalysisContext(ParamTypeHints.EMPTY, Operation.READ, coordinatorTxnCtx)));
    ExpressionAnalysisContext expressionAnalysisContext = new ExpressionAnalysisContext(coordinatorTxnCtx.sessionContext());
    return expressionAnalyzer.convert(SqlParser.createExpression(expression), expressionAnalysisContext);
}
Also used : DocTableInfo(io.crate.metadata.doc.DocTableInfo) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) AnalyzedRelation(io.crate.analyze.relations.AnalyzedRelation) StatementAnalysisContext(io.crate.analyze.relations.StatementAnalysisContext) RelationName(io.crate.metadata.RelationName) DocTableRelation(io.crate.analyze.relations.DocTableRelation) TableInfo(io.crate.metadata.table.TableInfo) DocTableInfo(io.crate.metadata.doc.DocTableInfo) SubqueryAnalyzer(io.crate.analyze.expressions.SubqueryAnalyzer) PgCatalogSchemaInfo(io.crate.metadata.pgcatalog.PgCatalogSchemaInfo) SysSchemaInfo(io.crate.metadata.sys.SysSchemaInfo) BlobSchemaInfo(io.crate.metadata.blob.BlobSchemaInfo) InformationSchemaInfo(io.crate.metadata.information.InformationSchemaInfo) SchemaInfo(io.crate.metadata.table.SchemaInfo) FullQualifiedNameFieldProvider(io.crate.analyze.relations.FullQualifiedNameFieldProvider)

Example 4 with SubqueryAnalyzer

use of io.crate.analyze.expressions.SubqueryAnalyzer in project crate by crate.

the class RelationAnalyzer method visitQuerySpecification.

@Override
protected AnalyzedRelation visitQuerySpecification(QuerySpecification node, StatementAnalysisContext statementContext) {
    List<Relation> from = node.getFrom().isEmpty() ? EMPTY_ROW_TABLE_RELATION : node.getFrom();
    RelationAnalysisContext currentRelationContext = statementContext.startRelation();
    for (Relation relation : from) {
        // different from relations have to be isolated from each other
        RelationAnalysisContext innerContext = statementContext.startRelation();
        relation.accept(this, statementContext);
        statementContext.endRelation();
        for (Map.Entry<RelationName, AnalyzedRelation> entry : innerContext.sources().entrySet()) {
            currentRelationContext.addSourceRelation(entry.getValue());
        }
        for (JoinPair joinPair : innerContext.joinPairs()) {
            currentRelationContext.addJoinPair(joinPair);
        }
    }
    RelationAnalysisContext context = statementContext.currentRelationContext();
    CoordinatorTxnCtx coordinatorTxnCtx = statementContext.transactionContext();
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(coordinatorTxnCtx, nodeCtx, statementContext.paramTyeHints(), new FullQualifiedNameFieldProvider(context.sources(), context.parentSources(), coordinatorTxnCtx.sessionContext().searchPath().currentSchema()), new SubqueryAnalyzer(this, statementContext));
    ExpressionAnalysisContext expressionAnalysisContext = context.expressionAnalysisContext();
    expressionAnalysisContext.windows(node.getWindows());
    SelectAnalysis selectAnalysis = SelectAnalyzer.analyzeSelectItems(node.getSelect().getSelectItems(), context.sources(), expressionAnalyzer, expressionAnalysisContext);
    List<Symbol> groupBy = analyzeGroupBy(selectAnalysis, node.getGroupBy(), expressionAnalyzer, expressionAnalysisContext);
    if (!node.getGroupBy().isEmpty() || expressionAnalysisContext.hasAggregates()) {
        GroupAndAggregateSemantics.validate(selectAnalysis.outputSymbols(), groupBy);
    }
    boolean isDistinct = node.getSelect().isDistinct();
    Symbol where = expressionAnalyzer.generateQuerySymbol(node.getWhere(), expressionAnalysisContext);
    WhereClauseValidator.validate(where);
    var normalizer = EvaluatingNormalizer.functionOnlyNormalizer(nodeCtx, f -> expressionAnalysisContext.isEagerNormalizationAllowed() && f.isDeterministic());
    QueriedSelectRelation relation = new QueriedSelectRelation(isDistinct, List.copyOf(context.sources().values()), context.joinPairs(), selectAnalysis.outputSymbols(), where, groupBy, analyzeHaving(node.getHaving(), groupBy, expressionAnalyzer, context.expressionAnalysisContext()), analyzeOrderBy(selectAnalysis, node.getOrderBy(), expressionAnalyzer, expressionAnalysisContext, expressionAnalysisContext.hasAggregates() || !groupBy.isEmpty(), isDistinct), longSymbolOrNull(node.getLimit(), expressionAnalyzer, expressionAnalysisContext, normalizer, coordinatorTxnCtx), longSymbolOrNull(node.getOffset(), expressionAnalyzer, expressionAnalysisContext, normalizer, coordinatorTxnCtx));
    statementContext.endRelation();
    return relation;
}
Also used : SelectAnalysis(io.crate.analyze.relations.select.SelectAnalysis) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) Symbol(io.crate.expression.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) Relation(io.crate.sql.tree.Relation) QueriedSelectRelation(io.crate.analyze.QueriedSelectRelation) AliasedRelation(io.crate.sql.tree.AliasedRelation) QueriedSelectRelation(io.crate.analyze.QueriedSelectRelation) RelationName(io.crate.metadata.RelationName) SubqueryAnalyzer(io.crate.analyze.expressions.SubqueryAnalyzer) Map(java.util.Map)

Example 5 with SubqueryAnalyzer

use of io.crate.analyze.expressions.SubqueryAnalyzer in project crate by crate.

the class RelationAnalyzer method visitJoin.

@Override
protected AnalyzedRelation visitJoin(Join node, StatementAnalysisContext statementContext) {
    AnalyzedRelation leftRel = node.getLeft().accept(this, statementContext);
    AnalyzedRelation rightRel = node.getRight().accept(this, statementContext);
    RelationAnalysisContext relationContext = statementContext.currentRelationContext();
    Optional<JoinCriteria> optCriteria = node.getCriteria();
    Symbol joinCondition = null;
    if (optCriteria.isPresent()) {
        JoinCriteria joinCriteria = optCriteria.get();
        if (joinCriteria instanceof JoinOn || joinCriteria instanceof JoinUsing) {
            final CoordinatorTxnCtx coordinatorTxnCtx = statementContext.transactionContext();
            ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(coordinatorTxnCtx, nodeCtx, statementContext.paramTyeHints(), new FullQualifiedNameFieldProvider(relationContext.sources(), relationContext.parentSources(), coordinatorTxnCtx.sessionContext().searchPath().currentSchema()), new SubqueryAnalyzer(this, statementContext));
            Expression expr;
            if (joinCriteria instanceof JoinOn) {
                expr = ((JoinOn) joinCriteria).getExpression();
            } else {
                expr = JoinUsing.toExpression(leftRel.relationName().toQualifiedName(), rightRel.relationName().toQualifiedName(), ((JoinUsing) joinCriteria).getColumns());
            }
            try {
                joinCondition = expressionAnalyzer.convert(expr, relationContext.expressionAnalysisContext());
            } catch (RelationUnknown e) {
                throw new RelationValidationException(e.getTableIdents(), String.format(Locale.ENGLISH, "missing FROM-clause entry for relation '%s'", e.getTableIdents()));
            }
        } else {
            throw new UnsupportedOperationException(String.format(Locale.ENGLISH, "join criteria %s not supported", joinCriteria.getClass().getSimpleName()));
        }
    }
    relationContext.addJoinType(JoinType.values()[node.getType().ordinal()], joinCondition);
    return null;
}
Also used : CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) RelationUnknown(io.crate.exceptions.RelationUnknown) Symbol(io.crate.expression.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) RelationValidationException(io.crate.exceptions.RelationValidationException) JoinUsing(io.crate.sql.tree.JoinUsing) Expression(io.crate.sql.tree.Expression) JoinCriteria(io.crate.sql.tree.JoinCriteria) SubqueryAnalyzer(io.crate.analyze.expressions.SubqueryAnalyzer) JoinOn(io.crate.sql.tree.JoinOn)

Aggregations

ExpressionAnalyzer (io.crate.analyze.expressions.ExpressionAnalyzer)7 SubqueryAnalyzer (io.crate.analyze.expressions.SubqueryAnalyzer)7 ExpressionAnalysisContext (io.crate.analyze.expressions.ExpressionAnalysisContext)6 Symbol (io.crate.expression.symbol.Symbol)6 SelectAnalysis (io.crate.analyze.relations.select.SelectAnalysis)4 CoordinatorTxnCtx (io.crate.metadata.CoordinatorTxnCtx)4 QueriedSelectRelation (io.crate.analyze.QueriedSelectRelation)3 AnalyzedRelation (io.crate.analyze.relations.AnalyzedRelation)3 FullQualifiedNameFieldProvider (io.crate.analyze.relations.FullQualifiedNameFieldProvider)3 StatementAnalysisContext (io.crate.analyze.relations.StatementAnalysisContext)3 EvaluatingNormalizer (io.crate.expression.eval.EvaluatingNormalizer)3 RelationName (io.crate.metadata.RelationName)3 DocTableRelation (io.crate.analyze.relations.DocTableRelation)2 RelationAnalysisContext (io.crate.analyze.relations.RelationAnalysisContext)2 RelationUnknown (io.crate.exceptions.RelationUnknown)2 RelationValidationException (io.crate.exceptions.RelationValidationException)2 AliasedRelation (io.crate.sql.tree.AliasedRelation)2 Expression (io.crate.sql.tree.Expression)2 JoinCriteria (io.crate.sql.tree.JoinCriteria)2 JoinOn (io.crate.sql.tree.JoinOn)2