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);
}
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);
}
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);
}
Aggregations