Search in sources :

Example 1 with TableReferenceResolver

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

the class DocIndexMetaData method initializeGeneratedExpressions.

private void initializeGeneratedExpressions() {
    if (generatedColumnReferences.isEmpty()) {
        return;
    }
    Collection<Reference> references = this.references.values();
    TableReferenceResolver tableReferenceResolver = new TableReferenceResolver(references);
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(functions, SessionContext.SYSTEM_SESSION, ParamTypeHints.EMPTY, tableReferenceResolver, null);
    ExpressionAnalysisContext context = new ExpressionAnalysisContext();
    for (Reference reference : generatedColumnReferences) {
        GeneratedReference generatedReference = (GeneratedReference) reference;
        Expression expression = SqlParser.createExpression(generatedReference.formattedGeneratedExpression());
        generatedReference.generatedExpression(expressionAnalyzer.convert(expression, context));
        generatedReference.referencedReferences(ImmutableList.copyOf(tableReferenceResolver.references()));
        tableReferenceResolver.references().clear();
    }
}
Also used : ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) Expression(io.crate.sql.tree.Expression) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver)

Example 2 with TableReferenceResolver

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

the class AlterTableAddColumnAnalyzer method analyze.

public AnalyzedAlterTableAddColumn analyze(AlterTableAddColumn<Expression> alterTable, ParamTypeHints paramTypeHints, CoordinatorTxnCtx txnCtx) {
    if (!alterTable.table().partitionProperties().isEmpty()) {
        throw new UnsupportedOperationException("Adding a column to a single partition is not supported");
    }
    DocTableInfo tableInfo = (DocTableInfo) schemas.resolveTableInfo(alterTable.table().getName(), Operation.ALTER, txnCtx.sessionContext().sessionUser(), txnCtx.sessionContext().searchPath());
    TableReferenceResolver referenceResolver = new TableReferenceResolver(tableInfo.columns(), tableInfo.ident());
    var exprAnalyzerWithReferenceResolver = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, referenceResolver, null);
    var exprAnalyzerWithFieldsAsString = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, FieldProvider.FIELDS_AS_LITERAL, null);
    var exprCtx = new ExpressionAnalysisContext(txnCtx.sessionContext());
    AddColumnDefinition<Expression> tableElement = alterTable.tableElement();
    // convert and validate the column name
    ExpressionToColumnIdentVisitor.convert(tableElement.name());
    // 1st phase, exclude check constraints (their expressions contain column references) and generated expressions
    AddColumnDefinition<Symbol> addColumnDefinition = new AddColumnDefinition<>(exprAnalyzerWithFieldsAsString.convert(tableElement.name(), exprCtx), // expression must be mapped later on using mapExpressions()
    null, tableElement.type() == null ? null : tableElement.type().map(y -> exprAnalyzerWithFieldsAsString.convert(y, exprCtx)), tableElement.constraints().stream().filter(c -> false == c instanceof CheckColumnConstraint).map(x -> x.map(y -> exprAnalyzerWithFieldsAsString.convert(y, exprCtx))).collect(Collectors.toList()), false, tableElement.generatedExpression() != null);
    AnalyzedTableElements<Symbol> analyzedTableElements = TableElementsAnalyzer.analyze(singletonList(addColumnDefinition), tableInfo.ident(), tableInfo);
    // 2nd phase, analyze possible generated expressions
    AddColumnDefinition<Symbol> addColumnDefinitionWithExpression = (AddColumnDefinition<Symbol>) tableElement.mapExpressions(addColumnDefinition, x -> exprAnalyzerWithReferenceResolver.convert(x, exprCtx));
    AnalyzedTableElements<Symbol> analyzedTableElementsWithExpressions = TableElementsAnalyzer.analyze(singletonList(addColumnDefinitionWithExpression), tableInfo.ident(), tableInfo);
    // now analyze possible check expressions
    var checkColumnConstraintsAnalyzer = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, new SelfReferenceFieldProvider(tableInfo.ident(), referenceResolver, analyzedTableElements.columns()), null);
    tableElement.constraints().stream().filter(CheckColumnConstraint.class::isInstance).map(x -> x.map(y -> checkColumnConstraintsAnalyzer.convert(y, exprCtx))).forEach(c -> {
        CheckColumnConstraint<Symbol> check = (CheckColumnConstraint<Symbol>) c;
        analyzedTableElements.addCheckColumnConstraint(tableInfo.ident(), check);
        analyzedTableElementsWithExpressions.addCheckColumnConstraint(tableInfo.ident(), check);
    });
    return new AnalyzedAlterTableAddColumn(tableInfo, analyzedTableElements, analyzedTableElementsWithExpressions);
}
Also used : ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) AlterTableAddColumn(io.crate.sql.tree.AlterTableAddColumn) RelationName(io.crate.metadata.RelationName) FieldProvider(io.crate.analyze.relations.FieldProvider) Operation(io.crate.metadata.table.Operation) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver) Collections.singletonList(java.util.Collections.singletonList) Locale(java.util.Locale) ExpressionToColumnIdentVisitor(io.crate.analyze.expressions.ExpressionToColumnIdentVisitor) QualifiedName(io.crate.sql.tree.QualifiedName) Nullable(javax.annotation.Nullable) DocTableInfo(io.crate.metadata.doc.DocTableInfo) NodeContext(io.crate.metadata.NodeContext) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) ColumnIdent(io.crate.metadata.ColumnIdent) Reference(io.crate.metadata.Reference) CheckColumnConstraint(io.crate.sql.tree.CheckColumnConstraint) Collectors(java.util.stream.Collectors) List(java.util.List) RowGranularity(io.crate.metadata.RowGranularity) Symbol(io.crate.expression.symbol.Symbol) ColumnUnknownException(io.crate.exceptions.ColumnUnknownException) Schemas(io.crate.metadata.Schemas) ReferenceIdent(io.crate.metadata.ReferenceIdent) AddColumnDefinition(io.crate.sql.tree.AddColumnDefinition) Expression(io.crate.sql.tree.Expression) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) DocTableInfo(io.crate.metadata.doc.DocTableInfo) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) Symbol(io.crate.expression.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) AddColumnDefinition(io.crate.sql.tree.AddColumnDefinition) Expression(io.crate.sql.tree.Expression) CheckColumnConstraint(io.crate.sql.tree.CheckColumnConstraint) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver)

Example 3 with TableReferenceResolver

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

the class DocIndexMetadata method build.

public DocIndexMetadata build() {
    notNullColumns = getNotNullColumns();
    columnPolicy = getColumnPolicy();
    createColumnDefinitions();
    indices = createIndexDefinitions();
    references = new LinkedHashMap<>();
    DocSysColumns.forTable(ident, references::put);
    columns.sort(SORT_REFS_BY_POSTITON_THEN_NAME);
    nestedColumns.sort(SORT_REFS_BY_POSTITON_THEN_NAME);
    for (Reference ref : columns) {
        references.put(ref.column(), ref);
        for (Reference nestedColumn : nestedColumns) {
            if (nestedColumn.column().getRoot().equals(ref.column())) {
                references.put(nestedColumn.column(), nestedColumn);
            }
        }
    }
    // Order of the partitionedByColumns is important; Must be the same order as `partitionedBy` is in.
    partitionedByColumns = Lists2.map(partitionedBy, references::get);
    generatedColumnReferences = List.copyOf(generatedColumnReferencesBuilder);
    primaryKey = getPrimaryKey();
    routingCol = getRoutingCol();
    Collection<Reference> references = this.references.values();
    TableReferenceResolver tableReferenceResolver = new TableReferenceResolver(references, ident);
    CoordinatorTxnCtx txnCtx = CoordinatorTxnCtx.systemTransactionContext();
    ExpressionAnalyzer exprAnalyzer = new ExpressionAnalyzer(txnCtx, nodeCtx, ParamTypeHints.EMPTY, tableReferenceResolver, null);
    ExpressionAnalysisContext analysisCtx = new ExpressionAnalysisContext(txnCtx.sessionContext());
    ArrayList<CheckConstraint<Symbol>> checkConstraintsBuilder = null;
    Map<String, Object> metaMap = Maps.get(mappingMap, "_meta");
    if (metaMap != null) {
        Map<String, String> checkConstraintsMap = Maps.get(metaMap, "check_constraints");
        if (checkConstraintsMap != null) {
            checkConstraintsBuilder = new ArrayList<>();
            for (Map.Entry<String, String> entry : checkConstraintsMap.entrySet()) {
                String name = entry.getKey();
                String expressionStr = entry.getValue();
                Expression expr = SqlParser.createExpression(expressionStr);
                Symbol analyzedExpr = exprAnalyzer.convert(expr, analysisCtx);
                checkConstraintsBuilder.add(new CheckConstraint<>(name, null, analyzedExpr, expressionStr));
            }
        }
    }
    checkConstraints = checkConstraintsBuilder != null ? List.copyOf(checkConstraintsBuilder) : List.of();
    for (Reference reference : generatedColumnReferences) {
        GeneratedReference generatedReference = (GeneratedReference) reference;
        Expression expression = SqlParser.createExpression(generatedReference.formattedGeneratedExpression());
        generatedReference.generatedExpression(exprAnalyzer.convert(expression, analysisCtx));
        generatedReference.referencedReferences(List.copyOf(tableReferenceResolver.references()));
        tableReferenceResolver.references().clear();
    }
    return this;
}
Also used : CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) GeneratedReference(io.crate.metadata.GeneratedReference) GeneratedReference(io.crate.metadata.GeneratedReference) GeoReference(io.crate.metadata.GeoReference) IndexReference(io.crate.metadata.IndexReference) Reference(io.crate.metadata.Reference) Symbol(io.crate.expression.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) Expression(io.crate.sql.tree.Expression) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) CheckConstraint(io.crate.sql.tree.CheckConstraint)

Example 4 with TableReferenceResolver

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

the class AnalyzedTableElements method validateGeneratedColumns.

private void validateGeneratedColumns(TableIdent tableIdent, Collection<? extends Reference> existingColumns, Functions functions, ParameterContext parameterContext, SessionContext sessionContext) {
    List<Reference> tableReferences = new ArrayList<>();
    for (AnalyzedColumnDefinition columnDefinition : columns) {
        buildReference(tableIdent, columnDefinition, tableReferences);
    }
    tableReferences.addAll(existingColumns);
    TableReferenceResolver tableReferenceResolver = new TableReferenceResolver(tableReferences);
    ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(functions, sessionContext, parameterContext, tableReferenceResolver, null);
    SymbolPrinter printer = new SymbolPrinter(functions);
    ExpressionAnalysisContext expressionAnalysisContext = new ExpressionAnalysisContext();
    for (AnalyzedColumnDefinition columnDefinition : columns) {
        if (columnDefinition.generatedExpression() != null) {
            processGeneratedExpression(expressionAnalyzer, printer, columnDefinition, expressionAnalysisContext);
        }
    }
}
Also used : SymbolPrinter(io.crate.analyze.symbol.format.SymbolPrinter) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver)

Example 5 with TableReferenceResolver

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

the class UserDefinedFunctionService method validateFunctionIsNotInUseByGeneratedColumn.

void validateFunctionIsNotInUseByGeneratedColumn(String schema, String functionName, UserDefinedFunctionsMetadata functionsMetadata, ClusterState currentState) {
    // The iteration of schemas/tables must happen on the node context WITHOUT the UDF already removed.
    // Otherwise the lazy table factories will already fail while evaluating generated functionsMetadata.
    // To avoid that, a copy of the node context with the removed UDF function is used on concrete expression evaluation.
    var nodeCtxWithRemovedFunction = new NodeContext(nodeCtx.functions().copyOf());
    updateImplementations(schema, functionsMetadata.functionsMetadata().stream(), nodeCtxWithRemovedFunction);
    var metadata = currentState.metadata();
    var indices = Stream.of(metadata.getConcreteAllIndices()).filter(NO_BLOB_NOR_DANGLING).map(IndexParts::new).filter(indexParts -> !indexParts.isPartitioned()).collect(Collectors.toList());
    var templates = metadata.getTemplates().keysIt();
    while (templates.hasNext()) {
        var indexParts = new IndexParts(templates.next());
        if (indexParts.isPartitioned()) {
            indices.add(indexParts);
        }
    }
    var indexNameExpressionResolver = new IndexNameExpressionResolver();
    for (var indexParts : indices) {
        var tableInfo = new DocTableInfoBuilder(nodeCtx, indexParts.toRelationName(), currentState, indexNameExpressionResolver).build();
        TableReferenceResolver tableReferenceResolver = new TableReferenceResolver(tableInfo.columns(), tableInfo.ident());
        CoordinatorTxnCtx coordinatorTxnCtx = CoordinatorTxnCtx.systemTransactionContext();
        ExpressionAnalyzer exprAnalyzer = new ExpressionAnalyzer(coordinatorTxnCtx, nodeCtxWithRemovedFunction, ParamTypeHints.EMPTY, tableReferenceResolver, null);
        for (var ref : tableInfo.columns()) {
            if (ref instanceof GeneratedReference) {
                var genRef = (GeneratedReference) ref;
                Expression expression = SqlParser.createExpression(genRef.formattedGeneratedExpression());
                try {
                    exprAnalyzer.convert(expression, new ExpressionAnalysisContext(coordinatorTxnCtx.sessionContext()));
                } catch (UnsupportedOperationException e) {
                    throw new IllegalArgumentException("Cannot drop function '" + functionName + "', it is still in use by '" + tableInfo + "." + genRef + "'");
                }
            }
        }
    }
}
Also used : ParamTypeHints(io.crate.analyze.ParamTypeHints) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) IndexParts(io.crate.metadata.IndexParts) UserDefinedFunctionAlreadyExistsException(io.crate.exceptions.UserDefinedFunctionAlreadyExistsException) FunctionName(io.crate.metadata.FunctionName) ClusterService(org.elasticsearch.cluster.service.ClusterService) FunctionProvider(io.crate.metadata.FunctionProvider) HashMap(java.util.HashMap) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver) Inject(org.elasticsearch.common.inject.Inject) ArrayList(java.util.ArrayList) ClusterState(org.elasticsearch.cluster.ClusterState) Metadata(org.elasticsearch.cluster.metadata.Metadata) ClusterStateUpdateTask(org.elasticsearch.cluster.ClusterStateUpdateTask) Locale(java.util.Locale) Map(java.util.Map) SqlParser(io.crate.sql.parser.SqlParser) Nullable(javax.annotation.Nullable) ScriptException(javax.script.ScriptException) NO_BLOB_NOR_DANGLING(io.crate.metadata.doc.DocSchemaInfo.NO_BLOB_NOR_DANGLING) NodeContext(io.crate.metadata.NodeContext) Iterator(java.util.Iterator) GeneratedReference(io.crate.metadata.GeneratedReference) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) DataType(io.crate.types.DataType) Signature(io.crate.metadata.functions.Signature) AcknowledgedResponse(org.elasticsearch.action.support.master.AcknowledgedResponse) Collectors(java.util.stream.Collectors) Lists2(io.crate.common.collections.Lists2) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Stream(java.util.stream.Stream) UserDefinedFunctionUnknownException(io.crate.exceptions.UserDefinedFunctionUnknownException) FunctionType(io.crate.metadata.FunctionType) Singleton(org.elasticsearch.common.inject.Singleton) TimeValue(io.crate.common.unit.TimeValue) VisibleForTesting(io.crate.common.annotations.VisibleForTesting) Scalar(io.crate.metadata.Scalar) IndexNameExpressionResolver(org.elasticsearch.cluster.metadata.IndexNameExpressionResolver) LogManager(org.apache.logging.log4j.LogManager) Expression(io.crate.sql.tree.Expression) ActionListener(org.elasticsearch.action.ActionListener) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) DocTableInfoBuilder(io.crate.metadata.doc.DocTableInfoBuilder) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) GeneratedReference(io.crate.metadata.GeneratedReference) NodeContext(io.crate.metadata.NodeContext) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) IndexParts(io.crate.metadata.IndexParts) Expression(io.crate.sql.tree.Expression) DocTableInfoBuilder(io.crate.metadata.doc.DocTableInfoBuilder) IndexNameExpressionResolver(org.elasticsearch.cluster.metadata.IndexNameExpressionResolver) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver)

Aggregations

ExpressionAnalysisContext (io.crate.analyze.expressions.ExpressionAnalysisContext)6 ExpressionAnalyzer (io.crate.analyze.expressions.ExpressionAnalyzer)6 TableReferenceResolver (io.crate.analyze.expressions.TableReferenceResolver)6 Expression (io.crate.sql.tree.Expression)5 CoordinatorTxnCtx (io.crate.metadata.CoordinatorTxnCtx)4 Symbol (io.crate.expression.symbol.Symbol)3 NodeContext (io.crate.metadata.NodeContext)3 List (java.util.List)3 Map (java.util.Map)3 FieldProvider (io.crate.analyze.relations.FieldProvider)2 GeneratedReference (io.crate.metadata.GeneratedReference)2 Reference (io.crate.metadata.Reference)2 RelationName (io.crate.metadata.RelationName)2 CheckColumnConstraint (io.crate.sql.tree.CheckColumnConstraint)2 CheckConstraint (io.crate.sql.tree.CheckConstraint)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 ParamTypeHints (io.crate.analyze.ParamTypeHints)1 ExpressionToColumnIdentVisitor (io.crate.analyze.expressions.ExpressionToColumnIdentVisitor)1