use of io.crate.metadata.GeneratedReference in project crate by crate.
the class DocTableRelation method ensureColumnCanBeUpdated.
/**
* @throws io.crate.exceptions.ColumnValidationException if the column cannot be updated
*/
@VisibleForTesting
void ensureColumnCanBeUpdated(ColumnIdent ci) {
if (ci.isSystemColumn()) {
throw new ColumnValidationException(ci.toString(), tableInfo.ident(), "Updating a system column is not supported");
}
for (ColumnIdent pkIdent : tableInfo.primaryKey()) {
ensureNotUpdated(ci, pkIdent, "Updating a primary key is not supported");
}
if (tableInfo.clusteredBy() != null) {
ensureNotUpdated(ci, tableInfo.clusteredBy(), "Updating a clustered-by column is not supported");
}
List<GeneratedReference> generatedReferences = tableInfo.generatedColumns();
for (Reference partitionRef : tableInfo.partitionedByColumns()) {
ensureNotUpdated(ci, partitionRef.column(), "Updating a partitioned-by column is not supported");
if (!(partitionRef instanceof GeneratedReference)) {
continue;
}
int idx = generatedReferences.indexOf(partitionRef);
if (idx >= 0) {
GeneratedReference generatedReference = generatedReferences.get(idx);
for (Reference reference : generatedReference.referencedReferences()) {
ensureNotUpdated(ci, reference.column(), "Updating a column which is referenced in a partitioned by generated column expression is not supported");
}
}
}
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class CopyToPlan method bind.
@VisibleForTesting
public static BoundCopyTo bind(AnalyzedCopyTo copyTo, CoordinatorTxnCtx txnCtx, NodeContext nodeCtx, Row parameters, SubQueryResults subQueryResults) {
Function<? super Symbol, Object> eval = x -> SymbolEvaluator.evaluate(txnCtx, nodeCtx, x, parameters, subQueryResults);
DocTableInfo table = (DocTableInfo) copyTo.tableInfo();
List<String> partitions = resolvePartitions(Lists2.map(copyTo.table().partitionProperties(), x -> x.map(eval)), table);
List<Symbol> outputs = new ArrayList<>();
Map<ColumnIdent, Symbol> overwrites = null;
boolean columnsDefined = false;
final List<String> outputNames = new ArrayList<>(copyTo.columns().size());
if (!copyTo.columns().isEmpty()) {
// TODO: remove outputNames?
for (Symbol symbol : copyTo.columns()) {
assert symbol instanceof Reference : "Only references are expected here";
RefVisitor.visitRefs(symbol, r -> outputNames.add(r.column().sqlFqn()));
outputs.add(DocReferences.toSourceLookup(symbol));
}
columnsDefined = true;
} else {
Reference sourceRef;
if (table.isPartitioned() && partitions.isEmpty()) {
// table is partitioned, insert partitioned columns into the output
overwrites = new HashMap<>();
for (Reference reference : table.partitionedByColumns()) {
if (!(reference instanceof GeneratedReference)) {
overwrites.put(reference.column(), reference);
}
}
if (overwrites.size() > 0) {
sourceRef = table.getReference(DocSysColumns.DOC);
} else {
sourceRef = table.getReference(DocSysColumns.RAW);
}
} else {
sourceRef = table.getReference(DocSysColumns.RAW);
}
outputs = List.of(sourceRef);
}
Settings settings = genericPropertiesToSettings(copyTo.properties().map(eval));
WriterProjection.CompressionType compressionType = settingAsEnum(WriterProjection.CompressionType.class, COMPRESSION_SETTING.get(settings));
WriterProjection.OutputFormat outputFormat = settingAsEnum(WriterProjection.OutputFormat.class, OUTPUT_FORMAT_SETTING.get(settings));
if (!columnsDefined && outputFormat == WriterProjection.OutputFormat.JSON_ARRAY) {
throw new UnsupportedFeatureException("Output format not supported without specifying columns.");
}
WhereClause whereClause = new WhereClause(copyTo.whereClause(), partitions, Collections.emptySet());
return new BoundCopyTo(outputs, table, whereClause, Literal.of(DataTypes.STRING.sanitizeValue(eval.apply(copyTo.uri()))), compressionType, outputFormat, outputNames.isEmpty() ? null : outputNames, columnsDefined, overwrites, settings);
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class CopyFromPlan method rewriteToCollectToUsePartitionValues.
private static void rewriteToCollectToUsePartitionValues(List<Reference> partitionedByColumns, List<String> partitionValues, List<Symbol> toCollect) {
for (int i = 0; i < partitionValues.size(); i++) {
Reference partitionedByColumn = partitionedByColumns.get(i);
int idx;
if (partitionedByColumn instanceof GeneratedReference) {
idx = toCollect.indexOf(((GeneratedReference) partitionedByColumn).generatedExpression());
} else {
idx = toCollect.indexOf(partitionedByColumn);
}
if (idx > -1) {
toCollect.set(idx, Literal.of(partitionValues.get(i)));
}
}
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class GeneratedColumns method validateValues.
void validateValues(HashMap<String, Object> source) {
for (var entry : toValidate.entrySet()) {
Reference ref = entry.getKey();
Object providedValue = ValueExtractors.fromMap(source, ref.column());
if (providedValue == null && !ref.column().isTopLevel()) {
// If they're null here we can assume that they'll be generated after the validation
continue;
}
Object generatedValue = entry.getValue().value();
// noinspection unchecked
DataType<Object> dataType = (DataType<Object>) ref.valueType();
if (Comparator.nullsFirst(dataType).compare(dataType.sanitizeValue(generatedValue), dataType.sanitizeValue(providedValue)) != 0) {
throw new IllegalArgumentException("Given value " + providedValue + " for generated column " + ref.column() + " does not match calculation " + ((GeneratedReference) ref).formattedGeneratedExpression() + " = " + generatedValue);
}
}
}
use of io.crate.metadata.GeneratedReference in project crate by crate.
the class AnalyzedTableElements method buildReference.
private static <T> void buildReference(RelationName relationName, AnalyzedColumnDefinition<T> columnDefinition, List<Reference> references) {
Reference reference;
DataType<?> type = columnDefinition.dataType() == null ? DataTypes.UNDEFINED : columnDefinition.dataType();
DataType<?> realType = ArrayType.NAME.equals(columnDefinition.collectionType()) ? new ArrayType<>(type) : type;
if (columnDefinition.isGenerated() == false) {
reference = new Reference(new ReferenceIdent(relationName, columnDefinition.ident()), RowGranularity.DOC, realType, columnDefinition.position, // not required in this context
null);
} else {
reference = new GeneratedReference(columnDefinition.position, new ReferenceIdent(relationName, columnDefinition.ident()), RowGranularity.DOC, realType, "dummy expression, real one not needed here");
}
references.add(reference);
for (AnalyzedColumnDefinition<T> childDefinition : columnDefinition.children()) {
buildReference(relationName, childDefinition, references);
}
}
Aggregations