/*
* 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.sql.planner.plan;
import com.facebook.presto.metadata.FunctionKind;
import com.facebook.presto.metadata.Signature;
import com.facebook.presto.server.SliceDeserializer;
import com.facebook.presto.server.SliceSerializer;
import com.facebook.presto.spi.block.SortOrder;
import com.facebook.presto.sql.Serialization;
import com.facebook.presto.sql.parser.SqlParser;
import com.facebook.presto.sql.planner.Symbol;
import com.facebook.presto.sql.planner.SymbolAllocator;
import com.facebook.presto.sql.tree.Expression;
import com.facebook.presto.sql.tree.FrameBound;
import com.facebook.presto.sql.tree.FunctionCall;
import com.facebook.presto.sql.tree.QualifiedName;
import com.facebook.presto.sql.tree.WindowFrame;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import io.airlift.json.ObjectMapperProvider;
import io.airlift.slice.Slice;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import static com.facebook.presto.spi.type.BigintType.BIGINT;
import static org.testng.Assert.assertEquals;
public class TestWindowNode
{
private SymbolAllocator symbolAllocator;
private ValuesNode sourceNode;
private Symbol columnA;
private Symbol columnB;
private Symbol columnC;
private final ObjectMapper objectMapper;
public TestWindowNode()
{
// dependencies copied from ServerMainModule.java to avoid depending on whole ServerMainModule here
SqlParser sqlParser = new SqlParser();
ObjectMapperProvider provider = new ObjectMapperProvider();
provider.setJsonSerializers(ImmutableMap.of(
Slice.class, new SliceSerializer(),
Expression.class, new Serialization.ExpressionSerializer()));
provider.setJsonDeserializers(ImmutableMap.of(
Slice.class, new SliceDeserializer(),
Expression.class, new Serialization.ExpressionDeserializer(sqlParser),
FunctionCall.class, new Serialization.FunctionCallDeserializer(sqlParser)));
objectMapper = provider.get();
}
@BeforeMethod
public void setUp()
{
symbolAllocator = new SymbolAllocator();
columnA = symbolAllocator.newSymbol("a", BIGINT);
columnB = symbolAllocator.newSymbol("b", BIGINT);
columnC = symbolAllocator.newSymbol("c", BIGINT);
sourceNode = new ValuesNode(
newId(),
ImmutableList.of(columnA, columnB, columnC),
ImmutableList.of());
}
@Test
public void testSerializationRoundtrip()
throws Exception
{
Symbol windowSymbol = symbolAllocator.newSymbol("sum", BIGINT);
Signature signature = new Signature(
"sum",
FunctionKind.WINDOW,
ImmutableList.of(),
ImmutableList.of(),
BIGINT.getTypeSignature(),
ImmutableList.of(BIGINT.getTypeSignature()),
false);
FunctionCall functionCall = new FunctionCall(QualifiedName.of("sum"), ImmutableList.of(columnC.toSymbolReference()));
WindowNode.Frame frame = new WindowNode.Frame(
WindowFrame.Type.RANGE,
FrameBound.Type.UNBOUNDED_PRECEDING,
Optional.empty(),
FrameBound.Type.UNBOUNDED_FOLLOWING,
Optional.empty());
PlanNodeId id = newId();
WindowNode.Specification specification = new WindowNode.Specification(
ImmutableList.of(columnA),
ImmutableList.of(columnB),
ImmutableMap.of(columnB, SortOrder.ASC_NULLS_FIRST));
Map<Symbol, WindowNode.Function> functions = ImmutableMap.of(windowSymbol, new WindowNode.Function(functionCall, signature, frame));
Optional<Symbol> hashSymbol = Optional.of(columnB);
Set<Symbol> prePartitionedInputs = ImmutableSet.of(columnA);
WindowNode windowNode = new WindowNode(
id,
sourceNode,
specification,
functions,
hashSymbol,
prePartitionedInputs,
0);
String json = objectMapper.writeValueAsString(windowNode);
WindowNode actualNode = objectMapper.readValue(json, WindowNode.class);
assertEquals(actualNode.getId(), windowNode.getId());
assertEquals(actualNode.getSpecification(), windowNode.getSpecification());
assertEquals(actualNode.getWindowFunctions(), windowNode.getWindowFunctions());
assertEquals(actualNode.getFrames(), windowNode.getFrames());
assertEquals(actualNode.getHashSymbol(), windowNode.getHashSymbol());
assertEquals(actualNode.getPrePartitionedInputs(), windowNode.getPrePartitionedInputs());
assertEquals(actualNode.getPreSortedOrderPrefix(), windowNode.getPreSortedOrderPrefix());
}
private static PlanNodeId newId()
{
return new PlanNodeId(UUID.randomUUID().toString());
}
}