use of io.crate.types.ArrayType in project crate by crate.
the class AnalyzedTableElements method validateAndFormatExpression.
private static void validateAndFormatExpression(Symbol function, AnalyzedColumnDefinition<Symbol> columnDefinitionWithExpressionSymbols, AnalyzedColumnDefinition<Object> columnDefinitionEvaluated, Consumer<String> formattedExpressionConsumer) {
String formattedExpression;
DataType<?> valueType = function.valueType();
DataType<?> definedType = columnDefinitionWithExpressionSymbols.dataType();
if (SymbolVisitors.any(Symbols::isAggregate, function)) {
throw new UnsupportedOperationException("Aggregation functions are not allowed in generated columns: " + function);
}
// check for optional defined type and add `cast` to expression if possible
if (definedType != null && !definedType.equals(valueType)) {
final DataType<?> columnDataType;
if (ArrayType.NAME.equals(columnDefinitionWithExpressionSymbols.collectionType())) {
columnDataType = new ArrayType<>(definedType);
} else {
columnDataType = definedType;
}
if (!valueType.isConvertableTo(columnDataType, false)) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH, "expression value type '%s' not supported for conversion to '%s'", valueType, columnDataType.getName()));
}
Symbol castFunction = CastFunctionResolver.generateCastFunction(function, columnDataType);
formattedExpression = castFunction.toString(Style.UNQUALIFIED);
} else {
if (valueType instanceof ArrayType) {
columnDefinitionEvaluated.collectionType(ArrayType.NAME);
columnDefinitionEvaluated.dataType(ArrayType.unnest(valueType).getName());
} else {
columnDefinitionEvaluated.dataType(valueType.getName());
}
formattedExpression = function.toString(Style.UNQUALIFIED);
}
formattedExpressionConsumer.accept(formattedExpression);
}
use of io.crate.types.ArrayType in project crate by crate.
the class ArrayDifferenceFunction method compile.
@Override
public Scalar<List<Object>, List<Object>> compile(List<Symbol> arguments) {
Symbol symbol = arguments.get(1);
if (!symbol.symbolType().isValueSymbol()) {
// arguments are no values, we can't compile
return this;
}
Input<?> input = (Input<?>) symbol;
Object inputValue = input.value();
DataType<?> innerType = ((ArrayType<?>) this.boundSignature.getReturnType().createType()).innerType();
List<Object> values = (List<Object>) inputValue;
Set<Object> subtractSet;
if (values == null) {
subtractSet = Collections.emptySet();
} else {
subtractSet = new HashSet<>();
for (Object element : values) {
subtractSet.add(innerType.sanitizeValue(element));
}
}
return new ArrayDifferenceFunction(signature, boundSignature, subtractSet);
}
use of io.crate.types.ArrayType in project crate by crate.
the class ArrayMinFunctionTest method test_array_returns_min_element.
@Test
public void test_array_returns_min_element() {
List<DataType> typesToTest = new ArrayList(DataTypes.PRIMITIVE_TYPES);
typesToTest.add(DataTypes.NUMERIC);
for (DataType type : typesToTest) {
var valuesToTest = TestingHelpers.getRandomsOfType(2, 10, type);
var optional = valuesToTest.stream().filter(o -> o != null).min((o1, o2) -> type.compare(o1, o2));
var expected = optional.orElse(null);
String expression = String.format(Locale.ENGLISH, "array_min(?::%s[])", type.getName());
assertEvaluate(expression, expected, Literal.of(valuesToTest, new ArrayType<>(type)));
}
}
use of io.crate.types.ArrayType in project crate by crate.
the class ArraySumFunctionTest method test_array_returns_sum_of_elements.
@Test
public void test_array_returns_sum_of_elements() {
// This test picks up random numbers but controls that overflow will not happen (overflow case is checked in another test).
List<DataType> typesToTest = new ArrayList(DataTypes.NUMERIC_PRIMITIVE_TYPES);
typesToTest.add(DataTypes.NUMERIC);
for (DataType type : typesToTest) {
var valuesToTest = TestingHelpers.getRandomsOfType(1, 10, type);
DataType inputDependantOutputType = DataTypes.LONG;
if (type == DataTypes.FLOAT || type == DataTypes.DOUBLE || type == DataTypes.NUMERIC) {
inputDependantOutputType = type;
} else {
// check potential overflow and get rid of numbers causing overflow
long sum = 0;
for (int i = 0; i < valuesToTest.size(); i++) {
if (valuesToTest.get(i) != null) {
long nextNum = ((Number) valuesToTest.get(i)).longValue();
try {
sum = Math.addExact(sum, nextNum);
} catch (ArithmeticException e) {
// excluding i
valuesToTest = valuesToTest.subList(0, i);
break;
}
}
}
}
KahanSummationForDouble kahanSummationForDouble = new KahanSummationForDouble();
var optional = valuesToTest.stream().filter(Objects::nonNull).reduce((o1, o2) -> {
if (o1 instanceof BigDecimal) {
return ((BigDecimal) o1).add((BigDecimal) o2);
} else if (o1 instanceof Double || o1 instanceof Float) {
return kahanSummationForDouble.sum(((Number) o1).doubleValue(), ((Number) o2).doubleValue());
} else {
return DataTypes.LONG.implicitCast(o1) + DataTypes.LONG.implicitCast(o2);
}
});
var expected = inputDependantOutputType.implicitCast(optional.orElse(null));
String expression = String.format(Locale.ENGLISH, "array_sum(?::%s[])", type.getName());
assertEvaluate(expression, expected, Literal.of(valuesToTest, new ArrayType<>(type)));
}
}
use of io.crate.types.ArrayType in project crate by crate.
the class DocIndexMetadataTest method testArrayAsGeneratedColumn.
@Test
public void testArrayAsGeneratedColumn() throws Exception {
DocIndexMetadata md = getDocIndexMetadataFromStatement("create table t1 (x as ([10, 20]))");
GeneratedReference generatedReference = md.generatedColumnReferences().get(0);
assertThat(generatedReference.valueType(), is(new ArrayType<>(DataTypes.INTEGER)));
}
Aggregations