Search in sources :

Example 1 with TableElement

use of io.crate.sql.tree.TableElement 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)

Example 2 with TableElement

use of io.crate.sql.tree.TableElement in project crate by crate.

the class CreateTableAsAnalyzer method analyze.

public AnalyzedCreateTableAs analyze(CreateTableAs createTableAs, ParamTypeHints paramTypeHints, CoordinatorTxnCtx txnCtx) {
    RelationName relationName = RelationName.of(createTableAs.name().getName(), txnCtx.sessionContext().searchPath().currentSchema());
    relationName.ensureValidForRelationCreation();
    AnalyzedRelation analyzedSourceQuery = relationAnalyzer.analyze(createTableAs.query(), new StatementAnalysisContext(paramTypeHints, Operation.READ, txnCtx));
    List<TableElement<Expression>> tableElements = Lists2.map(analyzedSourceQuery.outputs(), Symbols::toColumnDefinition);
    CreateTable<Expression> createTable = new CreateTable<Expression>(createTableAs.name(), tableElements, Optional.empty(), Optional.empty(), GenericProperties.empty(), false);
    // This is only a preliminary analysis to to have the source available for privilege checks.
    // It will be analyzed again with the target columns from the target table once
    // the table has been created.
    AnalyzedRelation sourceRelation = relationAnalyzer.analyze(createTableAs.query(), new StatementAnalysisContext(paramTypeHints, Operation.READ, txnCtx));
    // postponing the analysis of the insert statement, since the table has not been created yet.
    Supplier<AnalyzedInsertStatement> postponedInsertAnalysis = () -> {
        Insert<Expression> insert = new Insert<Expression>(createTableAs.name(), createTableAs.query(), Collections.emptyList(), Collections.emptyList(), Insert.DuplicateKeyContext.none());
        return insertAnalyzer.analyze(insert, paramTypeHints, txnCtx);
    };
    return new AnalyzedCreateTableAs(createTableStatementAnalyzer.analyze(createTable, paramTypeHints, txnCtx), sourceRelation, postponedInsertAnalysis);
}
Also used : CreateTable(io.crate.sql.tree.CreateTable) AnalyzedRelation(io.crate.analyze.relations.AnalyzedRelation) Insert(io.crate.sql.tree.Insert) TableElement(io.crate.sql.tree.TableElement) StatementAnalysisContext(io.crate.analyze.relations.StatementAnalysisContext) Expression(io.crate.sql.tree.Expression) Symbols(io.crate.expression.symbol.Symbols) RelationName(io.crate.metadata.RelationName)

Aggregations

RelationName (io.crate.metadata.RelationName)2 CreateTable (io.crate.sql.tree.CreateTable)2 Expression (io.crate.sql.tree.Expression)2 TableElement (io.crate.sql.tree.TableElement)2 ExpressionAnalysisContext (io.crate.analyze.expressions.ExpressionAnalysisContext)1 ExpressionAnalyzer (io.crate.analyze.expressions.ExpressionAnalyzer)1 TableReferenceResolver (io.crate.analyze.expressions.TableReferenceResolver)1 AnalyzedRelation (io.crate.analyze.relations.AnalyzedRelation)1 FieldProvider (io.crate.analyze.relations.FieldProvider)1 StatementAnalysisContext (io.crate.analyze.relations.StatementAnalysisContext)1 Symbol (io.crate.expression.symbol.Symbol)1 Symbols (io.crate.expression.symbol.Symbols)1 CoordinatorTxnCtx (io.crate.metadata.CoordinatorTxnCtx)1 NodeContext (io.crate.metadata.NodeContext)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 Insert (io.crate.sql.tree.Insert)1