use of io.crate.metadata.GeneratedReference in project crate by crate.
the class AnalyzedInsertStatement method symbolsFromTargetColumnPositionOrGeneratedExpression.
private List<Symbol> symbolsFromTargetColumnPositionOrGeneratedExpression(Map<ColumnIdent, Integer> targetColumnMap, List<Reference> targetColumns, List<ColumnIdent> columns, Map<ColumnIdent, GeneratedReference> generatedColumns, Map<ColumnIdent, Reference> defaultExpressionColumns, boolean alwaysRequireColumn) {
if (columns.isEmpty()) {
return Collections.emptyList();
}
List<Symbol> symbols = new ArrayList<>(columns.size());
InputColumns.SourceSymbols sourceSymbols = new InputColumns.SourceSymbols(targetColumns);
for (ColumnIdent column : columns) {
Integer position = targetColumnMap.get(column);
if (position == null) {
final Symbol symbol;
Reference reference = defaultExpressionColumns.get(column);
if (reference != null) {
symbol = InputColumns.create(requireNonNull(reference.defaultExpression(), "Column " + column + " must contain a default expression"), sourceSymbols);
} else {
GeneratedReference generatedRef = generatedColumns.get(column);
if (generatedRef == null) {
Reference columnRef = requireNonNull(targetTable.getReference(column), "Column " + column + " must exist in table " + targetTable.ident());
symbol = InputColumns.create(columnRef, sourceSymbols);
} else {
symbol = InputColumns.create(generatedRef.generatedExpression(), sourceSymbols);
}
}
if (SymbolVisitors.any(Symbols.IS_COLUMN, symbol)) {
if (alwaysRequireColumn) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH, "Column \"%s\" is required but is missing from the insert statement", column.sqlFqn()));
} else {
symbols.add(Literal.NULL);
}
} else {
symbols.add(symbol);
}
} else {
symbols.add(new InputColumn(position, targetColumns.get(position).valueType()));
}
}
return symbols;
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class DocIndexMetadata method add.
private void add(int position, ColumnIdent column, DataType type, @Nullable String defaultExpression, ColumnPolicy columnPolicy, Reference.IndexType indexType, boolean isNotNull, boolean hasDocValues) {
Reference ref;
boolean partitionByColumn = partitionedBy.contains(column);
String generatedExpression = generatedColumns.get(column.fqn());
if (partitionByColumn) {
indexType = Reference.IndexType.PLAIN;
}
if (generatedExpression == null) {
ref = newInfo(position, column, type, defaultExpression, columnPolicy, indexType, isNotNull, hasDocValues);
} else {
ref = new GeneratedReference(position, refIdent(column), granularity(column), type, columnPolicy, indexType, generatedExpression, isNotNull, hasDocValues);
}
if (column.isTopLevel()) {
columns.add(ref);
} else {
nestedColumns.add(ref);
}
if (ref instanceof GeneratedReference) {
generatedColumnReferencesBuilder.add((GeneratedReference) ref);
}
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class DocIndexMetadata method build.
public DocIndexMetadata build() {
notNullColumns = getNotNullColumns();
columnPolicy = getColumnPolicy();
createColumnDefinitions();
indices = createIndexDefinitions();
references = new LinkedHashMap<>();
DocSysColumns.forTable(ident, references::put);
columns.sort(SORT_REFS_BY_POSTITON_THEN_NAME);
nestedColumns.sort(SORT_REFS_BY_POSTITON_THEN_NAME);
for (Reference ref : columns) {
references.put(ref.column(), ref);
for (Reference nestedColumn : nestedColumns) {
if (nestedColumn.column().getRoot().equals(ref.column())) {
references.put(nestedColumn.column(), nestedColumn);
}
}
}
// Order of the partitionedByColumns is important; Must be the same order as `partitionedBy` is in.
partitionedByColumns = Lists2.map(partitionedBy, references::get);
generatedColumnReferences = List.copyOf(generatedColumnReferencesBuilder);
primaryKey = getPrimaryKey();
routingCol = getRoutingCol();
Collection<Reference> references = this.references.values();
TableReferenceResolver tableReferenceResolver = new TableReferenceResolver(references, ident);
CoordinatorTxnCtx txnCtx = CoordinatorTxnCtx.systemTransactionContext();
ExpressionAnalyzer exprAnalyzer = new ExpressionAnalyzer(txnCtx, nodeCtx, ParamTypeHints.EMPTY, tableReferenceResolver, null);
ExpressionAnalysisContext analysisCtx = new ExpressionAnalysisContext(txnCtx.sessionContext());
ArrayList<CheckConstraint<Symbol>> checkConstraintsBuilder = null;
Map<String, Object> metaMap = Maps.get(mappingMap, "_meta");
if (metaMap != null) {
Map<String, String> checkConstraintsMap = Maps.get(metaMap, "check_constraints");
if (checkConstraintsMap != null) {
checkConstraintsBuilder = new ArrayList<>();
for (Map.Entry<String, String> entry : checkConstraintsMap.entrySet()) {
String name = entry.getKey();
String expressionStr = entry.getValue();
Expression expr = SqlParser.createExpression(expressionStr);
Symbol analyzedExpr = exprAnalyzer.convert(expr, analysisCtx);
checkConstraintsBuilder.add(new CheckConstraint<>(name, null, analyzedExpr, expressionStr));
}
}
}
checkConstraints = checkConstraintsBuilder != null ? List.copyOf(checkConstraintsBuilder) : List.of();
for (Reference reference : generatedColumnReferences) {
GeneratedReference generatedReference = (GeneratedReference) reference;
Expression expression = SqlParser.createExpression(generatedReference.formattedGeneratedExpression());
generatedReference.generatedExpression(exprAnalyzer.convert(expression, analysisCtx));
generatedReference.referencedReferences(List.copyOf(tableReferenceResolver.references()));
tableReferenceResolver.references().clear();
}
return this;
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class DocIndexMetadataTest method testSchemaWithNotNullGeneratedColumn.
@Test
public void testSchemaWithNotNullGeneratedColumn() throws Exception {
XContentBuilder builder = XContentFactory.jsonBuilder().startObject().startObject("_meta").startObject("generated_columns").field("week", "date_trunc('week', ts)").endObject().startObject("constraints").array("not_null", "week").endObject().endObject().startObject("properties").startObject("ts").field("type", "date").endObject().startObject("week").field("type", "long").endObject().endObject().endObject();
IndexMetadata metadata = getIndexMetadata("test1", builder);
DocIndexMetadata md = newMeta(metadata, "test1");
assertThat(md.columns().size(), is(2));
Reference week = md.references().get(new ColumnIdent("week"));
assertThat(week, Matchers.notNullValue());
assertThat(week.isNullable(), is(false));
assertThat(week, instanceOf(GeneratedReference.class));
assertThat(((GeneratedReference) week).formattedGeneratedExpression(), is("date_trunc('week', ts)"));
assertThat(((GeneratedReference) week).generatedExpression(), isFunction("date_trunc", isLiteral("week"), isReference("ts")));
assertThat(((GeneratedReference) week).referencedReferences(), contains(isReference("ts")));
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class TableReferenceResolver method resolveField.
@Override
public Reference resolveField(QualifiedName qualifiedName, @Nullable List<String> path, Operation operation) {
List<String> parts = qualifiedName.getParts();
ColumnIdent columnIdent = new ColumnIdent(parts.get(parts.size() - 1), path);
if (parts.size() != 1) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH, "Column reference \"%s\" has too many parts. " + "A column must not have a schema or a table here.", qualifiedName));
}
for (Reference reference : tableReferences) {
if (reference.ident().columnIdent().equals(columnIdent)) {
if (reference instanceof GeneratedReference) {
throw new IllegalArgumentException("A generated column cannot be based on a generated column");
}
references.add(reference);
return reference;
}
}
throw new ColumnUnknownException(columnIdent.sqlFqn());
}
Aggregations