Search in sources :

Example 1 with CheckColumnConstraint

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

the class AstBuilder method visitColumnCheckConstraint.

@Override
public Node visitColumnCheckConstraint(SqlBaseParser.ColumnCheckConstraintContext context) {
    SqlBaseParser.CheckConstraintContext ctx = context.checkConstraint();
    String name = ctx.CONSTRAINT() != null ? getIdentText(ctx.name) : null;
    Expression expression = (Expression) visit(ctx.expression);
    String expressionStr = ExpressionFormatter.formatStandaloneExpression(expression);
    // column name is obtained during analysis
    return new CheckColumnConstraint<>(name, null, expression, expressionStr);
}
Also used : SqlBaseParser(io.crate.sql.parser.antlr.v4.SqlBaseParser) SubscriptExpression(io.crate.sql.tree.SubscriptExpression) IfExpression(io.crate.sql.tree.IfExpression) NotExpression(io.crate.sql.tree.NotExpression) SearchedCaseExpression(io.crate.sql.tree.SearchedCaseExpression) LogicalBinaryExpression(io.crate.sql.tree.LogicalBinaryExpression) ArraySliceExpression(io.crate.sql.tree.ArraySliceExpression) ArraySubQueryExpression(io.crate.sql.tree.ArraySubQueryExpression) SimpleCaseExpression(io.crate.sql.tree.SimpleCaseExpression) SubqueryExpression(io.crate.sql.tree.SubqueryExpression) InListExpression(io.crate.sql.tree.InListExpression) ParameterExpression(io.crate.sql.tree.ParameterExpression) ArrayComparisonExpression(io.crate.sql.tree.ArrayComparisonExpression) Expression(io.crate.sql.tree.Expression) ComparisonExpression(io.crate.sql.tree.ComparisonExpression) ArithmeticExpression(io.crate.sql.tree.ArithmeticExpression) NegativeExpression(io.crate.sql.tree.NegativeExpression) CheckColumnConstraint(io.crate.sql.tree.CheckColumnConstraint) BitString(io.crate.sql.tree.BitString)

Example 2 with CheckColumnConstraint

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

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

CheckColumnConstraint (io.crate.sql.tree.CheckColumnConstraint)3 Expression (io.crate.sql.tree.Expression)3 ExpressionAnalysisContext (io.crate.analyze.expressions.ExpressionAnalysisContext)2 ExpressionAnalyzer (io.crate.analyze.expressions.ExpressionAnalyzer)2 TableReferenceResolver (io.crate.analyze.expressions.TableReferenceResolver)2 FieldProvider (io.crate.analyze.relations.FieldProvider)2 Symbol (io.crate.expression.symbol.Symbol)2 CoordinatorTxnCtx (io.crate.metadata.CoordinatorTxnCtx)2 NodeContext (io.crate.metadata.NodeContext)2 RelationName (io.crate.metadata.RelationName)2 ExpressionToColumnIdentVisitor (io.crate.analyze.expressions.ExpressionToColumnIdentVisitor)1 ColumnUnknownException (io.crate.exceptions.ColumnUnknownException)1 ColumnIdent (io.crate.metadata.ColumnIdent)1 Reference (io.crate.metadata.Reference)1 ReferenceIdent (io.crate.metadata.ReferenceIdent)1 RowGranularity (io.crate.metadata.RowGranularity)1 Schemas (io.crate.metadata.Schemas)1 DocTableInfo (io.crate.metadata.doc.DocTableInfo)1 Operation (io.crate.metadata.table.Operation)1 EnsureNoMatchPredicate (io.crate.planner.operators.EnsureNoMatchPredicate)1