private void assertCommonSuperType(Type firstType, Type secondType, Type expected) { TypeRegistry typeManager = new TypeRegistry(); assertEquals( typeManager.getCommonSuperType(firstType, secondType), Optional.ofNullable(expected)); assertEquals( typeManager.getCommonSuperType(secondType, firstType), Optional.ofNullable(expected)); }
private void assertCommonSuperType(String firstType, String secondType, String expected) { assertEquals( typeRegistry.getCommonSuperType(createType(firstType), createType(secondType)), Optional.ofNullable(expected).map(this::createType)); assertEquals( typeRegistry.getCommonSuperType(createType(secondType), createType(firstType)), Optional.ofNullable(expected).map(this::createType)); }
@Test public void testCoerceTypeBase() throws Exception { assertEquals( typeRegistry.coerceTypeBase(createDecimalType(21, 1), "decimal"), Optional.of(createDecimalType(21, 1))); assertEquals( typeRegistry.coerceTypeBase(BIGINT, "decimal"), Optional.of(createDecimalType(19, 0))); assertEquals( typeRegistry.coerceTypeBase(INTEGER, "decimal"), Optional.of(createDecimalType(10, 0))); assertEquals( typeRegistry.coerceTypeBase(TINYINT, "decimal"), Optional.of(createDecimalType(3, 0))); assertEquals( typeRegistry.coerceTypeBase(SMALLINT, "decimal"), Optional.of(createDecimalType(5, 0))); }
@Test public void testIsTypeOnlyCoercion() { assertTrue(typeRegistry.isTypeOnlyCoercion(BIGINT, BIGINT)); assertTrue(isTypeOnlyCoercion("varchar(42)", "varchar(44)")); assertFalse(isTypeOnlyCoercion("varchar(44)", "varchar(42)")); assertTrue(isTypeOnlyCoercion("array(varchar(42))", "array(varchar(44))")); assertFalse(isTypeOnlyCoercion("array(varchar(44))", "array(varchar(42))")); assertTrue(isTypeOnlyCoercion("decimal(22,1)", "decimal(23,1)")); assertTrue(isTypeOnlyCoercion("decimal(2,1)", "decimal(3,1)")); assertFalse(isTypeOnlyCoercion("decimal(23,1)", "decimal(22,1)")); assertFalse(isTypeOnlyCoercion("decimal(3,1)", "decimal(2,1)")); assertFalse(isTypeOnlyCoercion("decimal(3,1)", "decimal(22,1)")); assertTrue(isTypeOnlyCoercion("array(decimal(22,1))", "array(decimal(23,1))")); assertTrue(isTypeOnlyCoercion("array(decimal(2,1))", "array(decimal(3,1))")); assertFalse(isTypeOnlyCoercion("array(decimal(23,1))", "array(decimal(22,1))")); assertFalse(isTypeOnlyCoercion("array(decimal(3,1))", "array(decimal(2,1))")); assertTrue( isTypeOnlyCoercion("map(decimal(2,1), decimal(2,1))", "map(decimal(2,1), decimal(3,1))")); assertFalse( isTypeOnlyCoercion("map(decimal(2,1), decimal(2,1))", "map(decimal(2,1), decimal(23,1))")); assertFalse( isTypeOnlyCoercion("map(decimal(2,1), decimal(2,1))", "map(decimal(2,1), decimal(3,2))")); assertTrue( isTypeOnlyCoercion("map(decimal(22,1), decimal(2,1))", "map(decimal(23,1), decimal(3,1))")); assertFalse( isTypeOnlyCoercion("map(decimal(23,1), decimal(3,1))", "map(decimal(22,1), decimal(2,1))")); }
@Test public void testCanCoerceIsTransitive() throws Exception { Set<Type> types = getStandardPrimitiveTypes(); for (Type transitiveType : types) { for (Type resultType : types) { if (typeRegistry.canCoerce(transitiveType, resultType)) { for (Type sourceType : types) { if (typeRegistry.canCoerce(sourceType, transitiveType)) { if (!typeRegistry.canCoerce(sourceType, resultType)) { fail( format( "'%s' -> '%s' coercion is missing when transitive coercion is possible: '%s' -> '%s' -> '%s'", sourceType, resultType, sourceType, transitiveType, resultType)); } } } } } } }
private Set<Type> getStandardPrimitiveTypes() { ImmutableSet.Builder<Type> builder = ImmutableSet.builder(); // add unparametrized types builder.addAll(typeRegistry.getTypes()); // add corner cases for parametrized types builder.add(createDecimalType(1, 0)); builder.add(createDecimalType(17, 0)); builder.add(createDecimalType(38, 0)); builder.add(createDecimalType(17, 17)); builder.add(createDecimalType(38, 38)); builder.add(createVarcharType(0)); builder.add(createUnboundedVarcharType()); return builder.build(); }
@Test public void testCastOperatorsExistForCoercions() { FunctionRegistry functionRegistry = new FunctionRegistry( typeRegistry, new BlockEncodingManager(typeRegistry), new FeaturesConfig().setExperimentalSyntaxEnabled(true)); Set<Type> types = getStandardPrimitiveTypes(); for (Type sourceType : types) { for (Type resultType : types) { if (typeRegistry.canCoerce(sourceType, resultType) && sourceType != UNKNOWN && resultType != UNKNOWN) { assertTrue( functionRegistry.canResolveOperator( OperatorType.CAST, resultType, ImmutableList.of(sourceType)), format( "'%s' -> '%s' coercion exists but there is no cast operator", sourceType, resultType)); } } } }
@Test public void testCanCoerce() { assertTrue(typeRegistry.canCoerce(BIGINT, BIGINT)); assertTrue(typeRegistry.canCoerce(UNKNOWN, BIGINT)); assertFalse(typeRegistry.canCoerce(BIGINT, UNKNOWN)); assertTrue(typeRegistry.canCoerce(BIGINT, DOUBLE)); assertTrue(typeRegistry.canCoerce(DATE, TIMESTAMP)); assertTrue(typeRegistry.canCoerce(DATE, TIMESTAMP_WITH_TIME_ZONE)); assertTrue(typeRegistry.canCoerce(TIME, TIME_WITH_TIME_ZONE)); assertTrue(typeRegistry.canCoerce(TIMESTAMP, TIMESTAMP_WITH_TIME_ZONE)); assertTrue(typeRegistry.canCoerce(VARCHAR, JONI_REGEXP)); assertTrue(typeRegistry.canCoerce(VARCHAR, RE2J_REGEXP)); assertTrue(typeRegistry.canCoerce(VARCHAR, LIKE_PATTERN)); assertTrue(typeRegistry.canCoerce(VARCHAR, JSON_PATH)); assertTrue(typeRegistry.canCoerce(FLOAT, DOUBLE)); assertTrue(typeRegistry.canCoerce(TINYINT, FLOAT)); assertTrue(typeRegistry.canCoerce(SMALLINT, FLOAT)); assertTrue(typeRegistry.canCoerce(INTEGER, FLOAT)); assertTrue(typeRegistry.canCoerce(BIGINT, FLOAT)); assertFalse(typeRegistry.canCoerce(DOUBLE, BIGINT)); assertFalse(typeRegistry.canCoerce(TIMESTAMP, TIME_WITH_TIME_ZONE)); assertFalse(typeRegistry.canCoerce(TIMESTAMP_WITH_TIME_ZONE, TIMESTAMP)); assertFalse(typeRegistry.canCoerce(VARBINARY, VARCHAR)); assertFalse(canCoerce("float", "decimal(37,1)")); assertFalse(canCoerce("float", "decimal(37,37)")); assertFalse(canCoerce("double", "decimal(37,1)")); assertFalse(canCoerce("double", "decimal(37,37)")); assertTrue(canCoerce("unknown", "array(bigint)")); assertFalse(canCoerce("array(bigint)", "unknown")); assertTrue(canCoerce("array(bigint)", "array(double)")); assertFalse(canCoerce("array(double)", "array(bigint)")); assertTrue(canCoerce("map(bigint,double)", "map(bigint,double)")); assertTrue(canCoerce("map(bigint,double)", "map(double,double)")); assertTrue(canCoerce("row(a bigint,b double,c varchar)", "row(a bigint,b double,c varchar)")); assertTrue(canCoerce("varchar(42)", "varchar(42)")); assertTrue(canCoerce("varchar(42)", "varchar(44)")); assertFalse(canCoerce("varchar(44)", "varchar(42)")); assertTrue(canCoerce("decimal(22,1)", "decimal(23,1)")); assertFalse(canCoerce("decimal(23,1)", "decimal(22,1)")); assertFalse(canCoerce("bigint", "decimal(18,0)")); assertTrue(canCoerce("bigint", "decimal(19,0)")); assertTrue(canCoerce("bigint", "decimal(37,1)")); assertTrue(canCoerce("array(bigint)", "array(decimal(20,1))")); assertFalse(canCoerce("array(bigint)", "array(decimal(2,1))")); assertTrue(canCoerce("decimal(3,2)", "double")); assertTrue(canCoerce("decimal(22,1)", "double")); assertTrue(canCoerce("decimal(3,2)", "float")); assertTrue(canCoerce("decimal(22,1)", "float")); assertFalse(canCoerce("integer", "decimal(9,0)")); assertTrue(canCoerce("integer", "decimal(10,0)")); assertTrue(canCoerce("integer", "decimal(37,1)")); assertFalse(canCoerce("tinyint", "decimal(2,0)")); assertTrue(canCoerce("tinyint", "decimal(3,0)")); assertTrue(canCoerce("tinyint", "decimal(37,1)")); assertFalse(canCoerce("smallint", "decimal(4,0)")); assertTrue(canCoerce("smallint", "decimal(5,0)")); assertTrue(canCoerce("smallint", "decimal(37,1)")); }
private Type createType(String signature) { return typeRegistry.getType(TypeSignature.parseTypeSignature(signature)); }
private boolean isTypeOnlyCoercion(String actual, String expected) { return typeRegistry.isTypeOnlyCoercion(createType(actual), createType(expected)); }
private boolean canCoerce(String actual, String expected) { return typeRegistry.canCoerce(createType(actual), createType(expected)); }