Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
<module>presto-kudu</module>
<module>presto-elasticsearch</module>
<module>presto-sql-function</module>
<module>presto-expressions</module>
</modules>

<dependencyManagement>
Expand Down Expand Up @@ -377,6 +378,12 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-expressions</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-jdbc</artifactId>
Expand Down
61 changes: 61 additions & 0 deletions presto-expressions/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-root</artifactId>
<version>0.228-SNAPSHOT</version>
</parent>

<artifactId>presto-expressions</artifactId>
<name>presto-expressions</name>

<properties>
<air.main.basedir>${project.parent.basedir}</air.main.basedir>
</properties>

<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-spi</artifactId>
</dependency>

<!-- for testing -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-main</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-main</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.expressions.translator;

import com.facebook.presto.spi.function.FunctionMetadata;
import com.facebook.presto.spi.relation.RowExpression;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import java.lang.invoke.MethodHandle;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import static java.util.Objects.requireNonNull;

public class FunctionTranslator<T>
{
private final Map<FunctionMetadata, MethodHandle> functionMapping;

public static <T> FunctionTranslator<T> buildFunctionTranslator(Set<Class<?>> translatorContainers)
{
ImmutableMap.Builder<FunctionMetadata, MethodHandle> functionMappingBuilder = new ImmutableMap.Builder<>();
translatorContainers.stream()
.map(TranslatorAnnotationParser::parseFunctionDefinitions)
.forEach(functionMappingBuilder::putAll);
return new FunctionTranslator<>(functionMappingBuilder.build());
}

public TranslatedExpression<T> translate(FunctionMetadata functionMetadata, RowExpression original, List<TranslatedExpression<T>> translatedArguments)
throws Throwable
{
if (!functionMapping.containsKey(functionMetadata)) {
return new TranslatedExpression<>(Optional.empty(), original, translatedArguments);
}
return new TranslatedExpression<>(Optional.of((T) functionMapping.get(functionMetadata).invokeWithArguments(translatedArguments)), original, translatedArguments);
}

public TranslatedExpression<T> translate(FunctionMetadata functionMetadata, RowExpression original, TranslatedExpression<T>... translatedArguments)
throws Throwable
{
return translate(functionMetadata, original, ImmutableList.copyOf(translatedArguments));
}

public TranslatedExpression<T> translate(FunctionMetadata functionMetadata, RowExpression original)
throws Throwable
{
return translate(functionMetadata, original, ImmutableList.of());
}

private FunctionTranslator(Map<FunctionMetadata, MethodHandle> functionMapping)
{
this.functionMapping = requireNonNull(functionMapping, "functionMapping is null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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.expressions.translator;

import com.facebook.presto.spi.relation.CallExpression;
import com.facebook.presto.spi.relation.ConstantExpression;
import com.facebook.presto.spi.relation.LambdaDefinitionExpression;
import com.facebook.presto.spi.relation.SpecialFormExpression;
import com.facebook.presto.spi.relation.VariableReferenceExpression;

import static com.facebook.presto.expressions.translator.TranslatedExpression.untranslated;

public class RowExpressionTranslator<T, C>
{
public TranslatedExpression<T> translateConstant(ConstantExpression literal, C context, RowExpressionTreeTranslator<T, C> rowExpressionTreeTranslator)
{
return untranslated(literal);
}

public TranslatedExpression<T> translateVariable(VariableReferenceExpression reference, C context, RowExpressionTreeTranslator<T, C> rowExpressionTreeTranslator)
{
return untranslated(reference);
}

public TranslatedExpression<T> translateLambda(LambdaDefinitionExpression reference, C context, RowExpressionTreeTranslator<T, C> rowExpressionTreeTranslator)
{
return untranslated(reference);
}

public TranslatedExpression<T> translateCall(CallExpression call, C context, RowExpressionTreeTranslator<T, C> rowExpressionTreeTranslator)
{
return untranslated(call);
}

public TranslatedExpression<T> translateSpecialForm(SpecialFormExpression specialForm, C context, RowExpressionTreeTranslator<T, C> rowExpressionTreeTranslator)
{
return untranslated(specialForm);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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.expressions.translator;

import com.facebook.presto.spi.relation.CallExpression;
import com.facebook.presto.spi.relation.ConstantExpression;
import com.facebook.presto.spi.relation.InputReferenceExpression;
import com.facebook.presto.spi.relation.LambdaDefinitionExpression;
import com.facebook.presto.spi.relation.RowExpression;
import com.facebook.presto.spi.relation.RowExpressionVisitor;
import com.facebook.presto.spi.relation.SpecialFormExpression;
import com.facebook.presto.spi.relation.VariableReferenceExpression;

import static java.util.Objects.requireNonNull;

public class RowExpressionTreeTranslator<T, C>
{
private final RowExpressionTranslator<T, C> rowExpressionTranslator;
private final RowExpressionVisitor<TranslatedExpression<T>, C> visitor;

private RowExpressionTreeTranslator(RowExpressionTranslator<T, C> rowExpressionTranslator)
{
this.rowExpressionTranslator = requireNonNull(rowExpressionTranslator, "rowExpressionTranslator is null");
this.visitor = new TranslatingVisitor();
}

public TranslatedExpression<T> rewrite(RowExpression node, C context)
{
return node.accept(this.visitor, context);
}

public static <T, C> TranslatedExpression<T> translateWith(
RowExpression expression,
RowExpressionTranslator<T, C> translator,
C context)
{
return expression.accept(new RowExpressionTreeTranslator<>(translator).visitor, context);
}

private class TranslatingVisitor
implements RowExpressionVisitor<TranslatedExpression<T>, C>
{
@Override
public TranslatedExpression<T> visitCall(CallExpression call, C context)
{
return rowExpressionTranslator.translateCall(call, context, RowExpressionTreeTranslator.this);
}

@Override
public TranslatedExpression<T> visitInputReference(InputReferenceExpression reference, C context)
{
// InputReferenceExpression should only be used by Presto engine rather than connectors
throw new UnsupportedOperationException("Cannot translate RowExpression that contains inputReferenceExpression");
}

@Override
public TranslatedExpression<T> visitConstant(ConstantExpression literal, C context)
{
return rowExpressionTranslator.translateConstant(literal, context, RowExpressionTreeTranslator.this);
}

@Override
public TranslatedExpression<T> visitLambda(LambdaDefinitionExpression lambda, C context)
{
return rowExpressionTranslator.translateLambda(lambda, context, RowExpressionTreeTranslator.this);
}

@Override
public TranslatedExpression<T> visitVariableReference(VariableReferenceExpression reference, C context)
{
return rowExpressionTranslator.translateVariable(reference, context, RowExpressionTreeTranslator.this);
}

@Override
public TranslatedExpression<T> visitSpecialForm(SpecialFormExpression specialForm, C context)
{
return rowExpressionTranslator.translateSpecialForm(specialForm, context, RowExpressionTreeTranslator.this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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.expressions.translator;

import com.facebook.presto.spi.relation.RowExpression;
import com.google.common.collect.ImmutableList;

import java.util.List;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

public class TranslatedExpression<T>
{
private final Optional<T> translated;
private final RowExpression originalExpression;
private final List<TranslatedExpression<T>> translatedArguments;

public TranslatedExpression(Optional<T> translated, RowExpression originalExpression, List<TranslatedExpression<T>> translatedArguments)
{
this.translated = requireNonNull(translated);
this.originalExpression = requireNonNull(originalExpression);
this.translatedArguments = requireNonNull(translatedArguments);
}

public Optional<T> getTranslated()
{
return translated;
}

public RowExpression getOriginalExpression()
{
return originalExpression;
}

public List<TranslatedExpression<T>> getTranslatedArguments()
{
return translatedArguments;
}

public static <T> TranslatedExpression<T> untranslated(RowExpression originalExpression)
{
return new TranslatedExpression<>(Optional.empty(), originalExpression, ImmutableList.of());
}
}
Loading