Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package com.facebook.presto.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.SpecialFormExpression;
import com.facebook.presto.spi.relation.VariableReferenceExpression;
import com.facebook.presto.spi.translator.ExpressionTranslator;
import com.facebook.presto.spi.translator.TargetExpression;
import com.facebook.presto.translator.registry.ConstantTypeRegistry;
import com.facebook.presto.translator.registry.FunctionRegistry;

import java.util.Map;

public abstract class AbstractExpressionTranslator<T>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User will extend this class when writing their translator. It will be populated with default implementations.

implements ExpressionTranslator
{
private final FunctionRegistry functionRegistry;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be protected/ have protected accessors.

private final ConstantTypeRegistry constantTypeRegistry;

public AbstractExpressionTranslator(FunctionRegistry functionRegistry, ConstantTypeRegistry constantTypeRegistry)
{
this.functionRegistry = functionRegistry;
this.constantTypeRegistry = constantTypeRegistry;
}

@Override
public TargetExpression<T> translateCallExpression(CallExpression callExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateInputReferenceExpression(InputReferenceExpression inputReferenceExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateConstantExpression(ConstantExpression constantExpression, Map context)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mocked functions, will implement once we get consensus on how this interface should look.

{
return null;
}

@Override
public TargetExpression<T> translateLambdaDefinitionExpression(LambdaDefinitionExpression lambdaDefinitionExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateVariableReferenceExpression(VariableReferenceExpression variableReferenceExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateIf(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateNullIf(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateSwitch(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateWhen(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateIsNull(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateCoalesce(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateIn(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateAnd(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateOr(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateDereference(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateRowConstructor(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}

@Override
public TargetExpression<T> translateBind(SpecialFormExpression specialFormExpression, Map context)
{
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.facebook.presto.translator;

import com.facebook.presto.spi.ColumnHandle;
import com.facebook.presto.spi.function.FunctionMetadataManager;
import com.facebook.presto.spi.function.StandardFunctionResolution;
import com.facebook.presto.spi.relation.DeterminismEvaluator;
import com.facebook.presto.spi.relation.LogicalRowExpressions;
import com.facebook.presto.spi.relation.RowExpression;
import com.facebook.presto.spi.relation.VariableReferenceExpression;
import com.facebook.presto.spi.translator.ExpressionTranslator;
import com.facebook.presto.spi.translator.TargetExpression;

import java.util.Map;

public class RowExpressionTranslator<T>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User uses this class in their ComputePushdown class (see JdbcComputePushdown.java) and calls .translate on it.

{
private final RowExpressionTranslatorVisitor<T> visitor;
private final LogicalRowExpressions logicalRowExpressions;

public RowExpressionTranslator(
ExpressionTranslator<T> expressionTranslator, FunctionMetadataManager functionMetadataManager, StandardFunctionResolution functionResolution, DeterminismEvaluator determinismEvaluator)
{
this.visitor = new RowExpressionTranslatorVisitor<>(expressionTranslator);
this.logicalRowExpressions = new LogicalRowExpressions(determinismEvaluator, functionResolution, functionMetadataManager);
}

public TargetExpression translate(
RowExpression expression,
Map<VariableReferenceExpression, ColumnHandle> assignments)
{
return logicalRowExpressions.convertToConjunctiveNormalForm(expression).accept(visitor, assignments);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.facebook.presto.translator;

import com.facebook.presto.spi.ColumnHandle;
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.RowExpressionVisitor;
import com.facebook.presto.spi.relation.SpecialFormExpression;
import com.facebook.presto.spi.relation.VariableReferenceExpression;
import com.facebook.presto.spi.translator.ExpressionTranslator;
import com.facebook.presto.spi.translator.TargetExpression;

import java.util.Map;

import static java.util.Objects.requireNonNull;

class RowExpressionTranslatorVisitor<T>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Underlying adapter for RowExpression visitor. This calls functions on the ExpressionTranslator interface. This class allows to hide internals from the user (i.e. they don't have to care about the visitor, only have to implement functions that are pertinent to their use case)

implements RowExpressionVisitor<TargetExpression<T>, Map<VariableReferenceExpression, ColumnHandle>>
{
private final ExpressionTranslator<T> expressionTranslator;

public RowExpressionTranslatorVisitor(ExpressionTranslator<T> expressionTranslator)
{
this.expressionTranslator = requireNonNull(expressionTranslator);
}

@Override
public TargetExpression<T> visitCall(CallExpression call, Map<VariableReferenceExpression, ColumnHandle> context)
{
return expressionTranslator.translateCallExpression(call, context);
}

@Override
public TargetExpression<T> visitInputReference(InputReferenceExpression reference, Map<VariableReferenceExpression, ColumnHandle> context)
{
return expressionTranslator.translateInputReferenceExpression(reference, context);
}

@Override
public TargetExpression<T> visitConstant(ConstantExpression literal, Map<VariableReferenceExpression, ColumnHandle> context)
{
return expressionTranslator.translateConstantExpression(literal, context);
}

@Override
public TargetExpression<T> visitLambda(LambdaDefinitionExpression lambda, Map<VariableReferenceExpression, ColumnHandle> context)
{
return expressionTranslator.translateLambdaDefinitionExpression(lambda, context);
}

@Override
public TargetExpression<T> visitVariableReference(VariableReferenceExpression reference, Map<VariableReferenceExpression, ColumnHandle> context)
{
return expressionTranslator.translateVariableReferenceExpression(reference, context);
}

@Override
public TargetExpression<T> visitSpecialForm(SpecialFormExpression specialForm, Map<VariableReferenceExpression, ColumnHandle> context)
{
switch (specialForm.getForm()) {
case IF:
return expressionTranslator.translateIf(specialForm, context);
case NULL_IF:
return expressionTranslator.translateNullIf(specialForm, context);
case SWITCH:
return expressionTranslator.translateSwitch(specialForm, context);
case WHEN:
return expressionTranslator.translateWhen(specialForm, context);
case IS_NULL:
return expressionTranslator.translateIsNull(specialForm, context);
case COALESCE:
return expressionTranslator.translateCoalesce(specialForm, context);
case IN:
return expressionTranslator.translateIn(specialForm, context);
case AND:
return expressionTranslator.translateAnd(specialForm, context);
case OR:
return expressionTranslator.translateOr(specialForm, context);
case DEREFERENCE:
return expressionTranslator.translateDereference(specialForm, context);
case ROW_CONSTRUCTOR:
return expressionTranslator.translateRowConstructor(specialForm, context);
case BIND:
return expressionTranslator.translateBind(specialForm, context);
default:
throw new IllegalStateException("Unexpected value: " + specialForm.getForm());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.facebook.presto.translator.registry;

import com.facebook.presto.spi.type.Type;
import com.facebook.presto.spi.type.TypeSignature;
import com.google.common.collect.ImmutableSet;

import java.util.Arrays;
import java.util.Set;

import static com.facebook.presto.translator.registry.ScalarFromAnnotationsParser.removeTypeParameters;

public class ConstantTypeRegistry
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For registering constant types. May consider combining Constant and Function registries. Lmk if a better way to do this.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not need this.

{
private final Set<TypeSignature> constantTypes;

public ConstantTypeRegistry(Type... types)
{
ImmutableSet.Builder<TypeSignature> constantTypes = ImmutableSet.builder();
Arrays.stream(types).forEach(type -> {
constantTypes.add(removeTypeParameters(type.getTypeSignature()));
});
this.constantTypes = constantTypes.build();
}

public Set<TypeSignature> getConstantTypes()
{
return constantTypes;
}

public boolean constantTypesContains(TypeSignature typeSignature)
{
return constantTypes.contains(typeSignature);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.facebook.presto.translator.registry;

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

import java.lang.invoke.MethodHandle;
import java.util.Arrays;

import static com.facebook.presto.translator.registry.ScalarFromAnnotationsParser.parseFunctionDefinitions;

public class FunctionRegistry
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check my example code

{
private final ImmutableMap<FunctionMetadata, MethodHandle> translators;

public FunctionRegistry(Class<?>... classes)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For registering MethodHandles to their corresponding function metadata so that they can be invoked via reflection.

Copy link
Contributor Author

@sachdevs sachdevs Sep 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AbstractExpressionTranslator will use this class and ConstantTypeRegistry for it's default implementations of translate functions.

{
ImmutableMap.Builder<FunctionMetadata, MethodHandle> functions = ImmutableMap.builder();
Arrays.stream(classes).forEach(functionDefinition -> {
functions.putAll(parseFunctionDefinitions(functionDefinition));
});

this.translators = functions.build();
}

public ImmutableMap<FunctionMetadata, MethodHandle> getTranslators()
{
return translators;
}

public MethodHandle getTranslatorForFunction(FunctionMetadata function)
{
return translators.get(function);
}
}
Loading