Search in sources :

Example 6 with TableReferenceResolver

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

the class CreateTableStatementAnalyzer method analyze.

public AnalyzedCreateTable analyze(CreateTable<Expression> createTable, ParamTypeHints paramTypeHints, CoordinatorTxnCtx txnCtx) {
    RelationName relationName = RelationName.of(createTable.name().getName(), txnCtx.sessionContext().searchPath().currentSchema());
    relationName.ensureValidForRelationCreation();
    var exprAnalyzerWithoutFields = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, FieldProvider.UNSUPPORTED, null);
    var exprAnalyzerWithFieldsAsString = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, FieldProvider.FIELDS_AS_LITERAL, null);
    var exprCtx = new ExpressionAnalysisContext(txnCtx.sessionContext());
    Function<Expression, Symbol> exprMapper = y -> exprAnalyzerWithFieldsAsString.convert(y, exprCtx);
    // 1st phase, map and analyze everything EXCEPT:
    // - check constraints defined at any level (table or column)
    // - generated expressions
    // - default expressions
    Map<TableElement<Symbol>, TableElement<Expression>> analyzed = new LinkedHashMap<>();
    List<CheckConstraint<Expression>> checkConstraints = new ArrayList<>();
    for (int i = 0; i < createTable.tableElements().size(); i++) {
        TableElement<Expression> te = createTable.tableElements().get(i);
        if (te instanceof CheckConstraint) {
            checkConstraints.add((CheckConstraint<Expression>) te);
            continue;
        }
        TableElement<Symbol> analyzedTe = null;
        if (te instanceof ColumnDefinition) {
            ColumnDefinition<Expression> def = (ColumnDefinition<Expression>) te;
            List<ColumnConstraint<Symbol>> analyzedColumnConstraints = new ArrayList<>();
            for (int j = 0; j < def.constraints().size(); j++) {
                ColumnConstraint<Expression> cc = def.constraints().get(j);
                if (cc instanceof CheckColumnConstraint) {
                    // Re-frame the column check constraint as a table check constraint
                    CheckColumnConstraint<Expression> columnCheck = (CheckColumnConstraint<Expression>) cc;
                    checkConstraints.add(new CheckConstraint<>(columnCheck.name(), def.ident(), columnCheck.expression(), columnCheck.expressionStr()));
                    continue;
                }
                analyzedColumnConstraints.add(cc.map(exprMapper));
            }
            analyzedTe = new ColumnDefinition<>(def.ident(), null, null, def.type() == null ? null : def.type().map(exprMapper), analyzedColumnConstraints, false, def.isGenerated());
        }
        analyzed.put(analyzedTe == null ? te.map(exprMapper) : analyzedTe, te);
    }
    CreateTable<Symbol> analyzedCreateTable = new CreateTable<>(createTable.name().map(exprMapper), new ArrayList<>(analyzed.keySet()), createTable.partitionedBy().map(x -> x.map(exprMapper)), createTable.clusteredBy().map(x -> x.map(exprMapper)), createTable.properties().map(x -> exprAnalyzerWithoutFields.convert(x, exprCtx)), createTable.ifNotExists());
    AnalyzedTableElements<Symbol> analyzedTableElements = TableElementsAnalyzer.analyze(analyzedCreateTable.tableElements(), relationName, null);
    // 2nd phase, analyze and map with a reference resolver:
    // - generated/default expressions
    // - check constraints
    TableReferenceResolver referenceResolver = analyzedTableElements.referenceResolver(relationName);
    var exprAnalyzerWithReferences = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, referenceResolver, null);
    List<TableElement<Symbol>> tableElementsWithExpressions = new ArrayList<>();
    for (int i = 0; i < analyzedCreateTable.tableElements().size(); i++) {
        TableElement<Symbol> elementSymbol = analyzedCreateTable.tableElements().get(i);
        TableElement<Expression> elementExpression = analyzed.get(elementSymbol);
        tableElementsWithExpressions.add(elementExpression.mapExpressions(elementSymbol, x -> {
            Symbol symbol = exprAnalyzerWithReferences.convert(x, exprCtx);
            EnsureNoMatchPredicate.ensureNoMatchPredicate(symbol, "Cannot use MATCH in CREATE TABLE statements");
            return symbol;
        }));
    }
    checkConstraints.stream().map(x -> x.map(y -> exprAnalyzerWithReferences.convert(y, exprCtx))).forEach(te -> {
        analyzedCreateTable.tableElements().add(te);
        tableElementsWithExpressions.add(te);
        analyzedTableElements.addCheckConstraint(relationName, (CheckConstraint<Symbol>) te);
    });
    AnalyzedTableElements<Symbol> analyzedTableElementsWithExpressions = TableElementsAnalyzer.analyze(tableElementsWithExpressions, relationName, null, false);
    return new AnalyzedCreateTable(relationName, analyzedCreateTable, analyzedTableElements, analyzedTableElementsWithExpressions);
}
Also used : ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) CreateTable(io.crate.sql.tree.CreateTable) NodeContext(io.crate.metadata.NodeContext) TableElement(io.crate.sql.tree.TableElement) ColumnConstraint(io.crate.sql.tree.ColumnConstraint) RelationName(io.crate.metadata.RelationName) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) FieldProvider(io.crate.analyze.relations.FieldProvider) CheckColumnConstraint(io.crate.sql.tree.CheckColumnConstraint) Function(java.util.function.Function) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver) CheckConstraint(io.crate.sql.tree.CheckConstraint) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) ColumnDefinition(io.crate.sql.tree.ColumnDefinition) List(java.util.List) Symbol(io.crate.expression.symbol.Symbol) Map(java.util.Map) EnsureNoMatchPredicate(io.crate.planner.operators.EnsureNoMatchPredicate) Expression(io.crate.sql.tree.Expression) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) Symbol(io.crate.expression.symbol.Symbol) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) ArrayList(java.util.ArrayList) CreateTable(io.crate.sql.tree.CreateTable) TableElement(io.crate.sql.tree.TableElement) LinkedHashMap(java.util.LinkedHashMap) CheckColumnConstraint(io.crate.sql.tree.CheckColumnConstraint) ColumnConstraint(io.crate.sql.tree.ColumnConstraint) CheckColumnConstraint(io.crate.sql.tree.CheckColumnConstraint) RelationName(io.crate.metadata.RelationName) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver) CheckConstraint(io.crate.sql.tree.CheckConstraint) ColumnConstraint(io.crate.sql.tree.ColumnConstraint) CheckColumnConstraint(io.crate.sql.tree.CheckColumnConstraint) CheckConstraint(io.crate.sql.tree.CheckConstraint) ColumnDefinition(io.crate.sql.tree.ColumnDefinition) Expression(io.crate.sql.tree.Expression)

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