TestBlockAndPositionNullConvention.java
/*
* 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.operator.scalar;
import com.facebook.presto.common.block.Block;
import com.facebook.presto.common.type.StandardTypes;
import com.facebook.presto.common.type.Type;
import com.facebook.presto.spi.function.BlockIndex;
import com.facebook.presto.spi.function.BlockPosition;
import com.facebook.presto.spi.function.ScalarFunction;
import com.facebook.presto.spi.function.SqlNullable;
import com.facebook.presto.spi.function.SqlType;
import com.facebook.presto.spi.function.TypeParameter;
import io.airlift.slice.Slice;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.facebook.presto.common.type.BigintType.BIGINT;
import static com.facebook.presto.common.type.BooleanType.BOOLEAN;
import static com.facebook.presto.common.type.DoubleType.DOUBLE;
import static com.facebook.presto.common.type.TypeUtils.readNativeValue;
import static com.facebook.presto.common.type.VarcharType.VARCHAR;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
public class TestBlockAndPositionNullConvention
extends AbstractTestFunctions
{
@BeforeClass
public void setUp()
{
registerParametricScalar(FunctionWithBlockAndPositionConvention.class);
}
@Test
public void testBlockPosition()
{
assertFunction("test_block_position(9876543210)", BIGINT, 9876543210L);
assertFalse(FunctionWithBlockAndPositionConvention.hitBlockPositionBigint.get());
assertFunction("test_block_position(bound_long)", BIGINT, 1234L);
assertTrue(FunctionWithBlockAndPositionConvention.hitBlockPositionBigint.get());
assertFunction("test_block_position(3.0E0)", DOUBLE, 3.0);
assertFalse(FunctionWithBlockAndPositionConvention.hitBlockPositionDouble.get());
assertFunction("test_block_position(bound_double)", DOUBLE, 12.34);
assertTrue(FunctionWithBlockAndPositionConvention.hitBlockPositionDouble.get());
assertFunction("test_block_position(bound_string)", VARCHAR, "hello");
assertTrue(FunctionWithBlockAndPositionConvention.hitBlockPositionSlice.get());
// TODO: add adaptations so these will pass
//assertFunction("test_block_position(null)", UNKNOWN, null);
//assertFalse(FunctionWithBlockAndPositionConvention.hitBlockPositionObject.get());
assertFunction("test_block_position(false)", BOOLEAN, false);
assertFalse(FunctionWithBlockAndPositionConvention.hitBlockPositionBoolean.get());
assertFunction("test_block_position(bound_boolean)", BOOLEAN, true);
assertTrue(FunctionWithBlockAndPositionConvention.hitBlockPositionBoolean.get());
}
@ScalarFunction(value = "test_block_position", calledOnNullInput = true)
public static class FunctionWithBlockAndPositionConvention
{
private static final AtomicBoolean hitBlockPositionBigint = new AtomicBoolean();
private static final AtomicBoolean hitBlockPositionDouble = new AtomicBoolean();
private static final AtomicBoolean hitBlockPositionSlice = new AtomicBoolean();
private static final AtomicBoolean hitBlockPositionBoolean = new AtomicBoolean();
private static final AtomicBoolean hitBlockPositionObject = new AtomicBoolean();
// generic implementations
// these will not work right now because MethodHandle is not properly adapted
@TypeParameter("E")
@SqlNullable
@SqlType("E")
public static Object generic(@TypeParameter("E") Type type, @SqlNullable @SqlType("E") Object object)
{
return object;
}
@TypeParameter("E")
@SqlNullable
@SqlType("E")
public static Object generic(@TypeParameter("E") Type type, @BlockPosition @SqlType("E") Block block, @BlockIndex int position)
{
hitBlockPositionObject.set(true);
return readNativeValue(type, block, position);
}
// specialized
@TypeParameter("E")
@SqlNullable
@SqlType("E")
public static Slice specializedSlice(@TypeParameter("E") Type type, @SqlNullable @SqlType("E") Slice slice)
{
return slice;
}
@TypeParameter("E")
@SqlType("E")
public static Slice specializedSlice(@TypeParameter("E") Type type, @BlockPosition @SqlType(value = "E", nativeContainerType = Slice.class) Block block, @BlockIndex int position)
{
hitBlockPositionSlice.set(true);
return type.getSlice(block, position);
}
@TypeParameter("E")
@SqlNullable
@SqlType("E")
public static Boolean specializedBoolean(@TypeParameter("E") Type type, @SqlNullable @SqlType("E") Boolean bool)
{
return bool;
}
@TypeParameter("E")
@SqlNullable
@SqlType("E")
public static Boolean specializedBoolean(@TypeParameter("E") Type type, @BlockPosition @SqlType(value = "E", nativeContainerType = boolean.class) Block block, @BlockIndex int position)
{
hitBlockPositionBoolean.set(true);
return type.getBoolean(block, position);
}
// exact
@SqlType(StandardTypes.BIGINT)
public static long getLong(@SqlNullable @SqlType(StandardTypes.BIGINT) Long number)
{
return number;
}
@SqlType(StandardTypes.BIGINT)
public static long getBlockPosition(@BlockPosition @SqlType(value = StandardTypes.BIGINT, nativeContainerType = long.class) Block block, @BlockIndex int position)
{
hitBlockPositionBigint.set(true);
return BIGINT.getLong(block, position);
}
@SqlType(StandardTypes.DOUBLE)
@SqlNullable
public static Double getDouble(@SqlNullable @SqlType(StandardTypes.DOUBLE) Double number)
{
return number;
}
@SqlType(StandardTypes.DOUBLE)
@SqlNullable
public static Double getDouble(@BlockPosition @SqlType(value = StandardTypes.DOUBLE, nativeContainerType = double.class) Block block, @BlockIndex int position)
{
hitBlockPositionDouble.set(true);
return DOUBLE.getDouble(block, position);
}
}
}