Search in sources :

Example 1 with ColumnConstraint

use of io.crate.sql.tree.ColumnConstraint 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)1 ExpressionAnalyzer (io.crate.analyze.expressions.ExpressionAnalyzer)1 TableReferenceResolver (io.crate.analyze.expressions.TableReferenceResolver)1 FieldProvider (io.crate.analyze.relations.FieldProvider)1 Symbol (io.crate.expression.symbol.Symbol)1 CoordinatorTxnCtx (io.crate.metadata.CoordinatorTxnCtx)1 NodeContext (io.crate.metadata.NodeContext)1 RelationName (io.crate.metadata.RelationName)1 EnsureNoMatchPredicate (io.crate.planner.operators.EnsureNoMatchPredicate)1 CheckColumnConstraint (io.crate.sql.tree.CheckColumnConstraint)1 CheckConstraint (io.crate.sql.tree.CheckConstraint)1 ColumnConstraint (io.crate.sql.tree.ColumnConstraint)1 ColumnDefinition (io.crate.sql.tree.ColumnDefinition)1 CreateTable (io.crate.sql.tree.CreateTable)1 Expression (io.crate.sql.tree.Expression)1 TableElement (io.crate.sql.tree.TableElement)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1