/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.spi.type;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.testng.annotations.Test;
import java.util.List;
import java.util.Set;
import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature;
import static com.facebook.presto.spi.type.VarcharType.VARCHAR;
import static com.facebook.presto.spi.type.VarcharType.createUnboundedVarcharType;
import static com.facebook.presto.spi.type.VarcharType.createVarcharType;
import static com.google.common.collect.Lists.transform;
import static java.util.Arrays.asList;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
public class TestTypeSignature
{
@Test
public void parseSignatureWithLiterals()
throws Exception
{
TypeSignature result = parseTypeSignature("decimal(X,42)", ImmutableSet.of("X"));
assertEquals(result.getParameters().size(), 2);
assertEquals(result.getParameters().get(0).isVariable(), true);
assertEquals(result.getParameters().get(1).isLongLiteral(), true);
}
@Test
public void parseRowSignature()
throws Exception
{
assertRowSignature(
"row(a bigint,b varchar)",
rowSignature(namedParameter("a", signature("bigint")), namedParameter("b", varchar())));
assertEquals(parseTypeSignature("row(col iNt)"), parseTypeSignature("row(col integer)"));
assertRowSignature(
"ROW(a bigint,b varchar)",
"ROW",
ImmutableList.of("a bigint", "b varchar"),
"row(a bigint,b varchar)");
assertRowSignature(
"row(a bigint,b array(bigint),c row(a bigint))",
rowSignature(
namedParameter("a", signature("bigint")),
namedParameter("b", array(signature("bigint"))),
namedParameter("c", rowSignature(namedParameter("a", signature("bigint"))))));
assertRowSignature(
"row(a varchar(10),b row(a bigint))",
rowSignature(
namedParameter("a", varchar(10)),
namedParameter("b", rowSignature(namedParameter("a", signature("bigint"))))));
assertRowSignature(
"array(row(col0 bigint,col1 double))",
array(rowSignature(namedParameter("col0", signature("bigint")), namedParameter("col1", signature("double")))));
assertRowSignature(
"row(col0 array(row(col0 bigint,col1 double)))",
rowSignature(namedParameter("col0", array(
rowSignature(namedParameter("col0", signature("bigint")), namedParameter("col1", signature("double")))))));
assertRowSignature(
"row(a decimal(p1,s1),b decimal(p2,s2))",
ImmutableSet.of("p1", "s1", "p2", "s2"),
rowSignature(namedParameter("a", decimal("p1", "s1")), namedParameter("b", decimal("p2", "s2"))));
assertEquals(parseTypeSignature("row(a Int(p1))"), parseTypeSignature("row(a integer(p1))"));
// TODO: remove the following tests when the old style row type has been completely dropped
assertOldRowSignature(
"row<bigint,varchar>('a','b')",
rowSignature(namedParameter("a", signature("bigint")), namedParameter("b", varchar())));
assertOldRowSignature(
"row<bigint,array(bigint),row<bigint>('a')>('a','b','c')",
rowSignature(
namedParameter("a", signature("bigint")),
namedParameter("b", array(signature("bigint"))),
namedParameter("c", rowSignature(namedParameter("a", signature("bigint"))))));
assertOldRowSignature(
"row<varchar(10),row<bigint>('a')>('a','b')",
rowSignature(
namedParameter("a", varchar(10)),
namedParameter("b", rowSignature(namedParameter("a", signature("bigint"))))));
assertOldRowSignature(
"array(row<bigint,double>('col0','col1'))",
array(rowSignature(namedParameter("col0", signature("bigint")), namedParameter("col1", signature("double")))));
assertEquals(parseTypeSignature("array(row<inT>('col'))"), parseTypeSignature("array(row<integer>('col'))"));
assertOldRowSignature(
"row<array(row<bigint,double>('col0','col1'))>('col0')",
rowSignature(namedParameter("col0", array(
rowSignature(namedParameter("col0", signature("bigint")), namedParameter("col1", signature("double")))))));
assertOldRowSignature(
"row<decimal(p1,s1),decimal(p2,s2)>('a','b')",
ImmutableSet.of("p1", "s1", "p2", "s2"),
rowSignature(namedParameter("a", decimal("p1", "s1")), namedParameter("b", decimal("p2", "s2"))));
}
private TypeSignature varchar()
{
return new TypeSignature(StandardTypes.VARCHAR, TypeSignatureParameter.of(VarcharType.UNBOUNDED_LENGTH));
}
private TypeSignature varchar(long length)
{
return new TypeSignature(StandardTypes.VARCHAR, TypeSignatureParameter.of(length));
}
private TypeSignature decimal(String precisionVariable, String scaleVariable)
{
return new TypeSignature(StandardTypes.DECIMAL, ImmutableList.of(
TypeSignatureParameter.of(precisionVariable), TypeSignatureParameter.of(scaleVariable)));
}
private static TypeSignature rowSignature(NamedTypeSignature... columns)
{
return new TypeSignature("row", transform(asList(columns), TypeSignatureParameter::of));
}
private static NamedTypeSignature namedParameter(String name, TypeSignature value)
{
return new NamedTypeSignature(name, value);
}
private static TypeSignature array(TypeSignature type)
{
return new TypeSignature(StandardTypes.ARRAY, TypeSignatureParameter.of(type));
}
private TypeSignature signature(String name)
{
return new TypeSignature(name);
}
@Test
public void parseSignature()
throws Exception
{
assertSignature("bigint", "bigint", ImmutableList.of());
assertSignature("boolean", "boolean", ImmutableList.of());
assertSignature("varchar", "varchar", ImmutableList.of(Integer.toString(VarcharType.UNBOUNDED_LENGTH)));
assertEquals(parseTypeSignature("int"), parseTypeSignature("integer"));
assertSignature("array(bigint)", "array", ImmutableList.of("bigint"));
assertEquals(parseTypeSignature("array(int)"), parseTypeSignature("array(integer)"));
assertSignature("array(array(bigint))", "array", ImmutableList.of("array(bigint)"));
assertEquals(parseTypeSignature("array(array(int))"), parseTypeSignature("array(array(integer))"));
assertSignature(
"array(timestamp with time zone)",
"array",
ImmutableList.of("timestamp with time zone"));
assertSignature(
"map(bigint,bigint)",
"map",
ImmutableList.of("bigint", "bigint"));
assertSignature(
"map(bigint,array(bigint))",
"map", ImmutableList.of("bigint", "array(bigint)"));
assertSignature(
"map(bigint,map(bigint,map(varchar,bigint)))",
"map",
ImmutableList.of("bigint", "map(bigint,map(varchar,bigint))"));
assertSignatureFail("blah()");
assertSignatureFail("array()");
assertSignatureFail("map()");
assertSignatureFail("x", ImmutableSet.of("x"));
// ensure this is not treated as a row type
assertSignature("rowxxx<a>", "rowxxx", ImmutableList.of("a"));
}
@Test
public void parseWithLiteralParameters()
{
assertSignature("foo(42)", "foo", ImmutableList.of("42"));
assertSignature("varchar(10)", "varchar", ImmutableList.of("10"));
}
@Test
public void testVarchar()
throws Exception
{
assertEquals(VARCHAR.getTypeSignature().toString(), "varchar");
assertEquals(createVarcharType(42).getTypeSignature().toString(), "varchar(42)");
assertEquals(parseTypeSignature("varchar"), createUnboundedVarcharType().getTypeSignature());
assertEquals(createUnboundedVarcharType().getTypeSignature(), parseTypeSignature("varchar"));
assertEquals(parseTypeSignature("varchar").hashCode(), createUnboundedVarcharType().getTypeSignature().hashCode());
assertNotEquals(createUnboundedVarcharType().getTypeSignature(), parseTypeSignature("varchar(10)"));
}
@Test
public void testIsCalculated()
throws Exception
{
assertFalse(parseTypeSignature("bigint").isCalculated());
assertTrue(parseTypeSignature("decimal(p, s)", ImmutableSet.of("p", "s")).isCalculated());
assertFalse(parseTypeSignature("decimal(2, 1)").isCalculated());
assertTrue(parseTypeSignature("array(decimal(p, s))", ImmutableSet.of("p", "s")).isCalculated());
assertFalse(parseTypeSignature("array(decimal(2, 1))").isCalculated());
assertTrue(parseTypeSignature("map(decimal(p1, s1),decimal(p2, s2))", ImmutableSet.of("p1", "s1", "p2", "s2")).isCalculated());
assertFalse(parseTypeSignature("map(decimal(2, 1),decimal(3, 1))").isCalculated());
assertTrue(parseTypeSignature("row(a decimal(p1,s1),b decimal(p2,s2))", ImmutableSet.of("p1", "s1", "p2", "s2")).isCalculated());
assertFalse(parseTypeSignature("row(a decimal(2,1),b decimal(3,2))").isCalculated());
}
private static void assertRowSignature(
String typeName,
Set<String> literalParameters,
TypeSignature expectedSignature)
{
TypeSignature signature = parseTypeSignature(typeName, literalParameters);
assertEquals(signature, expectedSignature);
assertEquals(signature.toString(), typeName);
}
private static void assertRowSignature(
String typeName,
TypeSignature expectedSignature)
{
assertRowSignature(typeName, ImmutableSet.of(), expectedSignature);
}
private static void assertSignature(String typeName, String base, List<String> parameters)
{
assertSignature(typeName, base, parameters, typeName.replace("<", "(").replace(">", ")"));
}
private static void assertRowSignature(
String typeName,
String base,
List<String> parameters,
String expected)
{
assertSignature(typeName, base, parameters, expected);
}
// TODO: remove this when old style row type is removed
@Deprecated
private static void assertOldRowSignature(
String typeName,
Set<String> literalParameters,
TypeSignature expectedSignature)
{
TypeSignature signature = parseTypeSignature(typeName, literalParameters);
assertEquals(signature, expectedSignature);
}
// TODO: remove this when old style row type is removed
@Deprecated
private static void assertOldRowSignature(
String typeName,
TypeSignature expectedSignature)
{
assertOldRowSignature(typeName, ImmutableSet.of(), expectedSignature);
}
private static void assertSignature(
String typeName,
String base,
List<String> parameters,
String expectedTypeName)
{
TypeSignature signature = parseTypeSignature(typeName);
assertEquals(signature.getBase(), base);
assertEquals(signature.getParameters().size(), parameters.size());
for (int i = 0; i < signature.getParameters().size(); i++) {
assertEquals(signature.getParameters().get(i).toString(), parameters.get(i));
}
assertEquals(signature.toString(), expectedTypeName);
}
private void assertSignatureFail(String typeName)
{
try {
parseTypeSignature(typeName);
fail("Type signatures with zero parameters should fail to parse");
}
catch (RuntimeException e) {
// Expected
}
}
private void assertSignatureFail(String typeName, Set<String> literalCalculationParameters)
{
try {
parseTypeSignature(typeName, literalCalculationParameters);
fail("Type signatures with zero parameters should fail to parse");
}
catch (RuntimeException e) {
// Expected
}
}
}