Search in sources :

Example 1 with Symbol

use of io.crate.analyze.symbol.Symbol in project crate by crate.

the class WhereClauseAnalyzer method tieBreakPartitionQueries.

private static WhereClause tieBreakPartitionQueries(EvaluatingNormalizer normalizer, Map<Symbol, List<Literal>> queryPartitionMap, WhereClause whereClause, TransactionContext transactionContext) throws UnsupportedOperationException {
    /*
         * Got multiple normalized queries which all could match.
         * This might be the case if one partition resolved to null
         *
         * e.g.
         *
         *  p = 1 and x = 2
         *
         * might lead to
         *
         *  null and x = 2
         *  true and x = 2
         *
         * At this point it is unknown if they really match.
         * In order to figure out if they could potentially match all conditions involving references are now set to true
         *
         *  null and true   -> can't match
         *  true and true   -> can match, can use this query + partition
         *
         * If there is still more than 1 query that can match it's not possible to execute the query :(
         */
    List<Tuple<Symbol, List<Literal>>> canMatch = new ArrayList<>();
    SymbolToTrueVisitor symbolToTrueVisitor = new SymbolToTrueVisitor();
    for (Map.Entry<Symbol, List<Literal>> entry : queryPartitionMap.entrySet()) {
        Symbol query = entry.getKey();
        List<Literal> partitions = entry.getValue();
        Symbol symbol = symbolToTrueVisitor.process(query, null);
        Symbol normalized = normalizer.normalize(symbol, transactionContext);
        assert normalized instanceof Literal : "after normalization and replacing all reference occurrences with true there must only be a literal left";
        Object value = ((Literal) normalized).value();
        if (value != null && (Boolean) value) {
            canMatch.add(new Tuple<>(query, partitions));
        }
    }
    if (canMatch.size() == 1) {
        Tuple<Symbol, List<Literal>> symbolListTuple = canMatch.get(0);
        WhereClause where = new WhereClause(symbolListTuple.v1(), whereClause.docKeys().orElse(null), new ArrayList<String>(symbolListTuple.v2().size()));
        where.partitions(symbolListTuple.v2());
        return where;
    }
    throw new UnsupportedOperationException("logical conjunction of the conditions in the WHERE clause which " + "involve partitioned columns led to a query that can't be executed.");
}
Also used : Symbol(io.crate.analyze.symbol.Symbol) WhereClause(io.crate.analyze.WhereClause) SymbolToTrueVisitor(io.crate.analyze.SymbolToTrueVisitor) Literal(io.crate.analyze.symbol.Literal) ImmutableList(com.google.common.collect.ImmutableList) Tuple(org.elasticsearch.common.collect.Tuple)

Example 2 with Symbol

use of io.crate.analyze.symbol.Symbol in project crate by crate.

the class WhereClauseAnalyzer method resolvePartitions.

private static WhereClause resolvePartitions(WhereClause whereClause, DocTableInfo tableInfo, Functions functions, TransactionContext transactionContext) {
    assert tableInfo.isPartitioned() : "table must be partitioned in order to resolve partitions";
    assert whereClause.partitions().isEmpty() : "partitions must not be analyzed twice";
    if (tableInfo.partitions().isEmpty()) {
        // table is partitioned but has no data / no partitions
        return WhereClause.NO_MATCH;
    }
    PartitionReferenceResolver partitionReferenceResolver = preparePartitionResolver(tableInfo.partitionedByColumns());
    EvaluatingNormalizer normalizer = new EvaluatingNormalizer(functions, RowGranularity.PARTITION, ReplaceMode.COPY, partitionReferenceResolver, null);
    Symbol normalized;
    Map<Symbol, List<Literal>> queryPartitionMap = new HashMap<>();
    for (PartitionName partitionName : tableInfo.partitions()) {
        for (PartitionExpression partitionExpression : partitionReferenceResolver.expressions()) {
            partitionExpression.setNextRow(partitionName);
        }
        normalized = normalizer.normalize(whereClause.query(), transactionContext);
        assert normalized != null : "normalizing a query must not return null";
        if (normalized.equals(whereClause.query())) {
            // no partition columns inside the where clause
            return whereClause;
        }
        boolean canMatch = WhereClause.canMatch(normalized);
        if (canMatch) {
            List<Literal> partitions = queryPartitionMap.get(normalized);
            if (partitions == null) {
                partitions = new ArrayList<>();
                queryPartitionMap.put(normalized, partitions);
            }
            partitions.add(Literal.of(partitionName.asIndexName()));
        }
    }
    if (queryPartitionMap.size() == 1) {
        Map.Entry<Symbol, List<Literal>> entry = Iterables.getOnlyElement(queryPartitionMap.entrySet());
        whereClause = new WhereClause(entry.getKey(), whereClause.docKeys().orElse(null), new ArrayList<String>(entry.getValue().size()));
        whereClause.partitions(entry.getValue());
        return whereClause;
    } else if (queryPartitionMap.size() > 0) {
        return tieBreakPartitionQueries(normalizer, queryPartitionMap, whereClause, transactionContext);
    } else {
        return WhereClause.NO_MATCH;
    }
}
Also used : EvaluatingNormalizer(io.crate.analyze.EvaluatingNormalizer) Symbol(io.crate.analyze.symbol.Symbol) WhereClause(io.crate.analyze.WhereClause) PartitionExpression(io.crate.operation.reference.partitioned.PartitionExpression) Literal(io.crate.analyze.symbol.Literal) ImmutableList(com.google.common.collect.ImmutableList)

Example 3 with Symbol

use of io.crate.analyze.symbol.Symbol in project crate by crate.

the class DeleteAnalyzer method analyze.

public AnalyzedStatement analyze(Delete node, Analysis analysis) {
    int numNested = 1;
    Function<ParameterExpression, Symbol> convertParamFunction = analysis.parameterContext();
    StatementAnalysisContext statementAnalysisContext = new StatementAnalysisContext(analysis.sessionContext(), convertParamFunction, Operation.DELETE, analysis.transactionContext());
    RelationAnalysisContext relationAnalysisContext = statementAnalysisContext.startRelation();
    AnalyzedRelation analyzedRelation = relationAnalyzer.analyze(node.getRelation(), statementAnalysisContext);
    assert analyzedRelation instanceof DocTableRelation : "analyzedRelation must be DocTableRelation";
    DocTableRelation docTableRelation = (DocTableRelation) analyzedRelation;
    EvaluatingNormalizer normalizer = new EvaluatingNormalizer(functions, RowGranularity.CLUSTER, ReplaceMode.MUTATE, null, docTableRelation);
    DeleteAnalyzedStatement deleteAnalyzedStatement = new DeleteAnalyzedStatement(docTableRelation);
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(functions, analysis.sessionContext(), convertParamFunction, new FullQualifedNameFieldProvider(relationAnalysisContext.sources()), null);
    ExpressionAnalysisContext expressionAnalysisContext = new ExpressionAnalysisContext();
    WhereClauseAnalyzer whereClauseAnalyzer = new WhereClauseAnalyzer(functions, deleteAnalyzedStatement.analyzedRelation());
    if (analysis.parameterContext().hasBulkParams()) {
        numNested = analysis.parameterContext().numBulkParams();
    }
    TransactionContext transactionContext = analysis.transactionContext();
    for (int i = 0; i < numNested; i++) {
        analysis.parameterContext().setBulkIdx(i);
        Symbol query = expressionAnalyzer.generateQuerySymbol(node.getWhere(), expressionAnalysisContext);
        WhereClause whereClause = new WhereClause(normalizer.normalize(query, transactionContext));
        whereClause = validate(whereClauseAnalyzer.analyze(whereClause, transactionContext));
        deleteAnalyzedStatement.whereClauses.add(whereClause);
    }
    statementAnalysisContext.endRelation();
    return deleteAnalyzedStatement;
}
Also used : ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) Symbol(io.crate.analyze.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) TransactionContext(io.crate.metadata.TransactionContext) ParameterExpression(io.crate.sql.tree.ParameterExpression) WhereClauseAnalyzer(io.crate.analyze.where.WhereClauseAnalyzer)

Example 4 with Symbol

use of io.crate.analyze.symbol.Symbol in project crate by crate.

the class UpdateAnalyzer method analyze.

public AnalyzedStatement analyze(Update node, Analysis analysis) {
    StatementAnalysisContext statementAnalysisContext = new StatementAnalysisContext(analysis.sessionContext(), analysis.parameterContext(), Operation.UPDATE, analysis.transactionContext());
    RelationAnalysisContext currentRelationContext = statementAnalysisContext.startRelation();
    AnalyzedRelation analyzedRelation = relationAnalyzer.analyze(node.relation(), statementAnalysisContext);
    FieldResolver fieldResolver = (FieldResolver) analyzedRelation;
    EvaluatingNormalizer normalizer = new EvaluatingNormalizer(functions, RowGranularity.CLUSTER, ReplaceMode.MUTATE, null, fieldResolver);
    FieldProvider columnFieldProvider = new NameFieldProvider(analyzedRelation);
    ExpressionAnalyzer columnExpressionAnalyzer = new ExpressionAnalyzer(functions, analysis.sessionContext(), analysis.parameterContext(), columnFieldProvider, null);
    columnExpressionAnalyzer.setResolveFieldsOperation(Operation.UPDATE);
    assert Iterables.getOnlyElement(currentRelationContext.sources().values()) == analyzedRelation : "currentRelationContext.sources().values() must have one element and equal to analyzedRelation";
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(functions, analysis.sessionContext(), analysis.parameterContext(), new FullQualifedNameFieldProvider(currentRelationContext.sources()), null);
    ExpressionAnalysisContext expressionAnalysisContext = new ExpressionAnalysisContext();
    int numNested = 1;
    if (analysis.parameterContext().numBulkParams() > 0) {
        numNested = analysis.parameterContext().numBulkParams();
    }
    WhereClauseAnalyzer whereClauseAnalyzer = null;
    if (analyzedRelation instanceof DocTableRelation) {
        whereClauseAnalyzer = new WhereClauseAnalyzer(functions, ((DocTableRelation) analyzedRelation));
    }
    TableInfo tableInfo = ((AbstractTableRelation) analyzedRelation).tableInfo();
    List<UpdateAnalyzedStatement.NestedAnalyzedStatement> nestedAnalyzedStatements = new ArrayList<>(numNested);
    for (int i = 0; i < numNested; i++) {
        analysis.parameterContext().setBulkIdx(i);
        Symbol querySymbol = expressionAnalyzer.generateQuerySymbol(node.whereClause(), expressionAnalysisContext);
        WhereClause whereClause = new WhereClause(normalizer.normalize(querySymbol, analysis.transactionContext()));
        if (whereClauseAnalyzer != null) {
            whereClause = whereClauseAnalyzer.analyze(whereClause, analysis.transactionContext());
        }
        if (!whereClause.docKeys().isPresent() && Symbols.containsColumn(whereClause.query(), DocSysColumns.VERSION)) {
            throw VERSION_SEARCH_EX;
        }
        UpdateAnalyzedStatement.NestedAnalyzedStatement nestedAnalyzedStatement = new UpdateAnalyzedStatement.NestedAnalyzedStatement(whereClause);
        for (Assignment assignment : node.assignements()) {
            analyzeAssignment(assignment, nestedAnalyzedStatement, tableInfo, normalizer, expressionAnalyzer, columnExpressionAnalyzer, expressionAnalysisContext, analysis.transactionContext());
        }
        nestedAnalyzedStatements.add(nestedAnalyzedStatement);
    }
    statementAnalysisContext.endRelation();
    return new UpdateAnalyzedStatement(analyzedRelation, nestedAnalyzedStatements);
}
Also used : ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) Symbol(io.crate.analyze.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) ArrayList(java.util.ArrayList) Assignment(io.crate.sql.tree.Assignment) WhereClauseAnalyzer(io.crate.analyze.where.WhereClauseAnalyzer) TableInfo(io.crate.metadata.table.TableInfo)

Example 5 with Symbol

use of io.crate.analyze.symbol.Symbol in project crate by crate.

the class UpdateAnalyzer method analyzeAssignment.

private void analyzeAssignment(Assignment node, UpdateAnalyzedStatement.NestedAnalyzedStatement nestedAnalyzedStatement, TableInfo tableInfo, EvaluatingNormalizer normalizer, ExpressionAnalyzer expressionAnalyzer, ExpressionAnalyzer columnExpressionAnalyzer, ExpressionAnalysisContext expressionAnalysisContext, TransactionContext transactionContext) {
    // unknown columns in strict objects handled in here
    Reference reference = (Reference) normalizer.normalize(columnExpressionAnalyzer.convert(node.columnName(), expressionAnalysisContext), transactionContext);
    final ColumnIdent ident = reference.ident().columnIdent();
    if (hasMatchingParent(tableInfo, reference, IS_OBJECT_ARRAY)) {
        // cannot update fields of object arrays
        throw new IllegalArgumentException("Updating fields of object arrays is not supported");
    }
    Symbol value = normalizer.normalize(expressionAnalyzer.convert(node.expression(), expressionAnalysisContext), transactionContext);
    try {
        value = valueNormalizer.normalizeInputForReference(value, reference);
    } catch (IllegalArgumentException | UnsupportedOperationException e) {
        throw new ColumnValidationException(ident.sqlFqn(), e);
    }
    nestedAnalyzedStatement.addAssignment(reference, value);
}
Also used : Symbol(io.crate.analyze.symbol.Symbol) ColumnValidationException(io.crate.exceptions.ColumnValidationException)

Aggregations

Symbol (io.crate.analyze.symbol.Symbol)109 Test (org.junit.Test)51 CrateUnitTest (io.crate.test.integration.CrateUnitTest)40 Function (io.crate.analyze.symbol.Function)14 Input (io.crate.data.Input)14 Reference (io.crate.metadata.Reference)11 WhereClause (io.crate.analyze.WhereClause)10 InputColumn (io.crate.analyze.symbol.InputColumn)8 InputFactory (io.crate.operation.InputFactory)8 OrderBy (io.crate.analyze.OrderBy)7 ExpressionAnalysisContext (io.crate.analyze.expressions.ExpressionAnalysisContext)6 ExpressionAnalyzer (io.crate.analyze.expressions.ExpressionAnalyzer)6 AbstractScalarFunctionsTest (io.crate.operation.scalar.AbstractScalarFunctionsTest)6 BytesStreamOutput (org.elasticsearch.common.io.stream.BytesStreamOutput)6 StreamInput (org.elasticsearch.common.io.stream.StreamInput)6 ImmutableList (com.google.common.collect.ImmutableList)5 DocTableInfo (io.crate.metadata.doc.DocTableInfo)5 TableInfo (io.crate.metadata.table.TableInfo)5 QuerySpec (io.crate.analyze.QuerySpec)4 Literal (io.crate.analyze.symbol.Literal)4