use of io.crate.exceptions.ColumnValidationException in project crate by crate.
the class ValueNormalizer method normalizeInputForReference.
/**
* normalize and validate given value according to the corresponding {@link io.crate.metadata.Reference}
*
* @param valueSymbol the value to normalize, might be anything from {@link Scalar} to {@link io.crate.expression.symbol.Literal}
* @param reference the reference to which the value has to comply in terms of type-compatibility
* @return the normalized Symbol, should be a literal
* @throws io.crate.exceptions.ColumnValidationException
*/
public static Symbol normalizeInputForReference(Symbol valueSymbol, Reference reference, TableInfo tableInfo, Function<Symbol, Symbol> normalizer) {
assert valueSymbol != null : "valueSymbol must not be null";
DataType<?> targetType = getTargetType(valueSymbol, reference);
try {
valueSymbol = normalizer.apply(valueSymbol.cast(reference.valueType()));
} catch (PgArrayParsingException | ConversionException e) {
throw new ColumnValidationException(reference.column().name(), tableInfo.ident(), String.format(Locale.ENGLISH, "Cannot cast expression `%s` of type `%s` to `%s`", valueSymbol, valueSymbol.valueType().getName(), reference.valueType().getName()));
}
if (!(valueSymbol instanceof Literal)) {
return valueSymbol.cast(targetType);
}
Object value = ((Literal<?>) valueSymbol).value();
if (value == null) {
return valueSymbol;
}
try {
if (targetType.id() == ObjectType.ID) {
// noinspection unchecked
normalizeObjectValue((Map) value, reference, tableInfo);
} else if (isObjectArray(targetType)) {
normalizeObjectArrayValue((List<Map<String, Object>>) value, reference, tableInfo);
}
} catch (PgArrayParsingException | ConversionException e) {
throw new ColumnValidationException(reference.column().name(), tableInfo.ident(), Symbols.format("\"%s\" has a type that can't be implicitly cast to that of \"%s\" (" + reference.valueType().getName() + ")", valueSymbol, reference));
}
return valueSymbol;
}
use of io.crate.exceptions.ColumnValidationException in project crate by crate.
the class ValueNormalizer method normalizeObjectValue.
@SuppressWarnings("unchecked")
private static void normalizeObjectValue(Map<String, Object> value, Reference info, TableInfo tableInfo) {
for (Map.Entry<String, Object> entry : value.entrySet()) {
ColumnIdent nestedIdent = ColumnIdent.getChildSafe(info.column(), entry.getKey());
Reference nestedInfo = tableInfo.getReference(nestedIdent);
if (nestedInfo == null) {
if (info.columnPolicy() == ColumnPolicy.IGNORED) {
continue;
}
DynamicReference dynamicReference = null;
if (tableInfo instanceof DocTableInfo) {
dynamicReference = ((DocTableInfo) tableInfo).getDynamic(nestedIdent, true, true);
}
if (dynamicReference == null) {
throw new ColumnUnknownException(nestedIdent.sqlFqn(), tableInfo.ident());
}
DataType type = DataTypes.guessType(entry.getValue());
if (type == null) {
throw new ColumnValidationException(info.column().sqlFqn(), tableInfo.ident(), "Invalid value");
}
dynamicReference.valueType(type);
nestedInfo = dynamicReference;
} else {
if (entry.getValue() == null) {
continue;
}
}
if (nestedInfo.valueType().id() == ObjectType.ID && entry.getValue() instanceof Map) {
normalizeObjectValue((Map<String, Object>) entry.getValue(), nestedInfo, tableInfo);
} else if (isObjectArray(nestedInfo.valueType()) && entry.getValue() instanceof List) {
normalizeObjectArrayValue((List<Map<String, Object>>) entry.getValue(), nestedInfo, tableInfo);
} else {
entry.setValue(normalizePrimitiveValue(entry.getValue(), nestedInfo));
}
}
}
use of io.crate.exceptions.ColumnValidationException in project crate by crate.
the class ValueNormalizer method normalizeInputForReference.
/**
* normalize and validate given value according to the corresponding {@link io.crate.metadata.Reference}
*
* @param valueSymbol the value to normalize, might be anything from {@link io.crate.metadata.Scalar} to {@link io.crate.analyze.symbol.Literal}
* @param reference the reference to which the value has to comply in terms of type-compatibility
* @return the normalized Symbol, should be a literal
* @throws io.crate.exceptions.ColumnValidationException
*/
public Symbol normalizeInputForReference(Symbol valueSymbol, Reference reference) {
assert valueSymbol != null : "valueSymbol must not be null";
DataType<?> targetType = getTargetType(valueSymbol, reference);
if (!(valueSymbol instanceof Literal)) {
return ExpressionAnalyzer.castIfNeededOrFail(valueSymbol, targetType);
}
Literal literal = (Literal) valueSymbol;
try {
literal = Literal.convert(literal, reference.valueType());
} catch (ConversionException e) {
throw new ColumnValidationException(reference.ident().columnIdent().name(), String.format(Locale.ENGLISH, "%s cannot be cast to type %s", SymbolPrinter.INSTANCE.printSimple(valueSymbol), reference.valueType().getName()));
}
Object value = literal.value();
if (value == null) {
return literal;
}
try {
if (targetType == DataTypes.OBJECT) {
//noinspection unchecked
normalizeObjectValue((Map) value, reference);
} else if (isObjectArray(targetType)) {
normalizeObjectArrayValue((Object[]) value, reference);
}
} catch (ConversionException e) {
throw new ColumnValidationException(reference.ident().columnIdent().name(), SymbolFormatter.format("\"%s\" has a type that can't be implicitly cast to that of \"%s\" (" + reference.valueType().getName() + ")", literal, reference));
}
return literal;
}
Aggregations