Skip to content

Commit

Permalink
Factor out Symbol to ColumnHandle translation from DomainTranslator
Browse files Browse the repository at this point in the history
It now operates on Symbols. Callers that need TupleDomains to be translated
in terms of ColumnHandle should call TupleDomain::transform
  • Loading branch information
martint committed Apr 15, 2015
1 parent b852ef5 commit 74f1f17
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 199 deletions.
Expand Up @@ -14,7 +14,6 @@
package com.facebook.presto.sql.planner;

import com.facebook.presto.Session;
import com.facebook.presto.spi.ColumnHandle;
import com.facebook.presto.metadata.Metadata;
import com.facebook.presto.spi.ConnectorSession;
import com.facebook.presto.spi.Domain;
Expand Down Expand Up @@ -83,16 +82,14 @@ private DomainTranslator()
{
}

public static Expression toPredicate(TupleDomain<ColumnHandle> tupleDomain, Map<ColumnHandle, Symbol> symbolTranslationMap, Map<Symbol, Type> symbolTypes)
public static Expression toPredicate(TupleDomain<Symbol> tupleDomain, Map<Symbol, Type> symbolTypes)
{
if (tupleDomain.isNone()) {
return FALSE_LITERAL;
}
ImmutableList.Builder<Expression> conjunctBuilder = ImmutableList.builder();
for (Map.Entry<ColumnHandle, Domain> entry : tupleDomain.getDomains().entrySet()) {
ColumnHandle columnHandle = entry.getKey();
checkArgument(symbolTranslationMap.containsKey(columnHandle), "Unable to convert TupleDomain to Expression b/c don't know Symbol for ColumnHandle %s", columnHandle);
Symbol symbol = symbolTranslationMap.get(columnHandle);
for (Map.Entry<Symbol, Domain> entry : tupleDomain.getDomains().entrySet()) {
Symbol symbol = entry.getKey();
QualifiedNameReference reference = new QualifiedNameReference(symbol.toQualifiedName());
Type type = symbolTypes.get(symbol);
conjunctBuilder.add(toPredicate(entry.getValue(), reference, type));
Expand Down Expand Up @@ -191,10 +188,9 @@ public static ExtractionResult fromPredicate(
Metadata metadata,
Session session,
Expression predicate,
Map<Symbol, Type> types,
Map<Symbol, ColumnHandle> columnHandleTranslationMap)
Map<Symbol, Type> types)
{
return new Visitor(metadata, session, types, columnHandleTranslationMap).process(predicate, false);
return new Visitor(metadata, session, types).process(predicate, false);
}

private static class Visitor
Expand All @@ -203,14 +199,12 @@ private static class Visitor
private final Metadata metadata;
private final ConnectorSession session;
private final Map<Symbol, Type> types;
private final Map<Symbol, ColumnHandle> columnHandles;

private Visitor(Metadata metadata, Session session, Map<Symbol, Type> types, Map<Symbol, ColumnHandle> columnHandles)
private Visitor(Metadata metadata, Session session, Map<Symbol, Type> types)
{
this.metadata = checkNotNull(metadata, "metadata is null");
this.session = checkNotNull(session, "session is null").toConnectorSession();
this.types = ImmutableMap.copyOf(checkNotNull(types, "types is null"));
this.columnHandles = ImmutableMap.copyOf(checkNotNull(columnHandles, "columnHandles is null"));
}

private Type checkedTypeLookup(Symbol symbol)
Expand All @@ -220,13 +214,6 @@ private Type checkedTypeLookup(Symbol symbol)
return type;
}

private ColumnHandle checkedColumnHandleLookup(Symbol symbol)
{
ColumnHandle columnHandle = columnHandles.get(symbol);
checkArgument(columnHandle != null, "ColumnHandles is missing info for symbol: %s", symbol);
return columnHandle;
}

private static SortedRangeSet complementIfNecessary(SortedRangeSet range, boolean complement)
{
return complement ? range.complement() : range;
Expand All @@ -246,7 +233,7 @@ private static Expression complementIfNecessary(Expression expression, boolean c
protected ExtractionResult visitExpression(Expression node, Boolean complement)
{
// If we don't know how to process this node, the default response is to say that the TupleDomain is "all"
return new ExtractionResult(TupleDomain.<ColumnHandle>all(), complementIfNecessary(node, complement));
return new ExtractionResult(TupleDomain.all(), complementIfNecessary(node, complement));
}

@Override
Expand All @@ -263,7 +250,7 @@ protected ExtractionResult visitLogicalBinaryExpression(LogicalBinaryExpression
combineConjuncts(leftResult.getRemainingExpression(), rightResult.getRemainingExpression()));

case OR:
TupleDomain<ColumnHandle> columnUnionedTupleDomain = TupleDomain.columnWiseUnion(leftResult.getTupleDomain(), rightResult.getTupleDomain());
TupleDomain<Symbol> columnUnionedTupleDomain = TupleDomain.columnWiseUnion(leftResult.getTupleDomain(), rightResult.getTupleDomain());

// In most cases, the columnUnionedTupleDomain is only a superset of the actual strict union
// and so we can return the current node as the remainingExpression so that all bounds will be double checked again at execution time.
Expand Down Expand Up @@ -331,7 +318,6 @@ else if (isSimpleComparison(node)) {

Symbol symbol = Symbol.fromQualifiedName(((QualifiedNameReference) node.getLeft()).getName());
Type columnType = checkedTypeLookup(symbol);
ColumnHandle columnHandle = checkedColumnHandleLookup(symbol);
Object value = LiteralInterpreter.evaluate(metadata, session, node.getRight());

// Handle the cases where implicit coercions can happen in comparisons
Expand All @@ -343,10 +329,10 @@ else if (isSimpleComparison(node)) {
value = ((Long) value).doubleValue();
}
verifyType(columnType, value);
return createComparisonExtractionResult(node.getType(), columnHandle, columnType, objectToComparable(value), complement);
return createComparisonExtractionResult(node.getType(), symbol, columnType, objectToComparable(value), complement);
}

private ExtractionResult createComparisonExtractionResult(ComparisonExpression.Type comparisonType, ColumnHandle columnHandle, Type columnType, Comparable<?> value, boolean complement)
private ExtractionResult createComparisonExtractionResult(ComparisonExpression.Type comparisonType, Symbol column, Type columnType, Comparable<?> value, boolean complement)
{
if (value == null) {
switch (comparisonType) {
Expand All @@ -356,12 +342,12 @@ private ExtractionResult createComparisonExtractionResult(ComparisonExpression.T
case LESS_THAN:
case LESS_THAN_OR_EQUAL:
case NOT_EQUAL:
return new ExtractionResult(TupleDomain.<ColumnHandle>none(), TRUE_LITERAL);
return new ExtractionResult(TupleDomain.none(), TRUE_LITERAL);

case IS_DISTINCT_FROM:
Domain domain = complementIfNecessary(Domain.notNull(wrap(columnType.getJavaType())), complement);
return new ExtractionResult(
TupleDomain.withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(columnHandle, domain)),
TupleDomain.withColumnDomains(ImmutableMap.of(column, domain)),
TRUE_LITERAL);

default:
Expand Down Expand Up @@ -398,7 +384,7 @@ private ExtractionResult createComparisonExtractionResult(ComparisonExpression.T
}

return new ExtractionResult(
TupleDomain.withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(columnHandle, domain)),
TupleDomain.withColumnDomains(ImmutableMap.of(column, domain)),
TRUE_LITERAL);
}

Expand Down Expand Up @@ -447,11 +433,9 @@ protected ExtractionResult visitIsNullPredicate(IsNullPredicate node, Boolean co

Symbol symbol = Symbol.fromQualifiedName(((QualifiedNameReference) node.getValue()).getName());
Type columnType = checkedTypeLookup(symbol);
ColumnHandle columnHandle = checkedColumnHandleLookup(symbol);

Domain domain = complementIfNecessary(Domain.onlyNull(wrap(columnType.getJavaType())), complement);
return new ExtractionResult(
TupleDomain.withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(columnHandle, domain)),
TupleDomain.withColumnDomains(ImmutableMap.of(symbol, domain)),
TRUE_LITERAL);
}

Expand All @@ -464,25 +448,24 @@ protected ExtractionResult visitIsNotNullPredicate(IsNotNullPredicate node, Bool

Symbol symbol = Symbol.fromQualifiedName(((QualifiedNameReference) node.getValue()).getName());
Type columnType = checkedTypeLookup(symbol);
ColumnHandle columnHandle = checkedColumnHandleLookup(symbol);

Domain domain = complementIfNecessary(Domain.notNull(wrap(columnType.getJavaType())), complement);
return new ExtractionResult(
TupleDomain.withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of(columnHandle, domain)),
TupleDomain.withColumnDomains(ImmutableMap.of(symbol, domain)),
TRUE_LITERAL);
}

@Override
protected ExtractionResult visitBooleanLiteral(BooleanLiteral node, Boolean complement)
{
boolean value = complement ? !node.getValue() : node.getValue();
return new ExtractionResult(value ? TupleDomain.<ColumnHandle>all() : TupleDomain.<ColumnHandle>none(), TRUE_LITERAL);
return new ExtractionResult(value ? TupleDomain.all() : TupleDomain.none(), TRUE_LITERAL);
}

@Override
protected ExtractionResult visitNullLiteral(NullLiteral node, Boolean complement)
{
return new ExtractionResult(TupleDomain.<ColumnHandle>none(), TRUE_LITERAL);
return new ExtractionResult(TupleDomain.none(), TRUE_LITERAL);
}
}

Expand Down Expand Up @@ -574,16 +557,16 @@ private static Expression coerceDoubleToLongComparison(ComparisonExpression comp

public static class ExtractionResult
{
private final TupleDomain<ColumnHandle> tupleDomain;
private final TupleDomain<Symbol> tupleDomain;
private final Expression remainingExpression;

public ExtractionResult(TupleDomain<ColumnHandle> tupleDomain, Expression remainingExpression)
public ExtractionResult(TupleDomain<Symbol> tupleDomain, Expression remainingExpression)
{
this.tupleDomain = checkNotNull(tupleDomain, "tupleDomain is null");
this.remainingExpression = checkNotNull(remainingExpression, "remainingExpression is null");
}

public TupleDomain<ColumnHandle> getTupleDomain()
public TupleDomain<Symbol> getTupleDomain()
{
return tupleDomain;
}
Expand Down
Expand Up @@ -163,9 +163,9 @@ public Expression visitDistinctLimit(DistinctLimitNode node, Void context)
@Override
public Expression visitTableScan(TableScanNode node, Void context)
{
Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
return DomainTranslator.toPredicate(
spanTupleDomain(node.getCurrentConstraint()),
ImmutableBiMap.copyOf(node.getAssignments()).inverse(),
spanTupleDomain(node.getCurrentConstraint()).transform(assignments::get),
symbolTypes);
}

Expand Down
Expand Up @@ -458,10 +458,11 @@ private PlanWithProperties planTableScan(TableScanNode node, Expression predicat
metadata,
session,
deterministicPredicate,
symbolAllocator.getTypes(),
node.getAssignments());
symbolAllocator.getTypes());

TupleDomain<ColumnHandle> simplifiedConstraint = decomposedPredicate.getTupleDomain().intersect(node.getCurrentConstraint());
TupleDomain<ColumnHandle> simplifiedConstraint = decomposedPredicate.getTupleDomain()
.transform(node.getAssignments()::get)
.intersect(node.getCurrentConstraint());

List<TableLayoutResult> layouts = metadata.getLayouts(
node.getTable(),
Expand Down Expand Up @@ -495,8 +496,7 @@ private PlanWithProperties planTableScan(TableScanNode node, Expression predicat
Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
Expression resultingPredicate = combineConjuncts(
DomainTranslator.toPredicate(
layout.getUnenforcedConstraint(),
assignments,
layout.getUnenforcedConstraint().transform(assignments::get),
symbolAllocator.getTypes()),
stripDeterministicConjuncts(predicate),
decomposedPredicate.getRemainingExpression());
Expand Down
Expand Up @@ -246,13 +246,10 @@ public PlanNode visitTableScan(TableScanNode node, RewriteContext<Context> conte
@NotNull
private PlanNode planTableScan(TableScanNode node, Expression predicate, Context context)
{
TupleDomain<ColumnHandle> constraint = node.getCurrentConstraint().intersect(
DomainTranslator.fromPredicate(
metadata,
session,
predicate,
symbolAllocator.getTypes(),
node.getAssignments()).getTupleDomain());
TupleDomain<ColumnHandle> constraint = DomainTranslator.fromPredicate(metadata, session, predicate, symbolAllocator.getTypes())
.getTupleDomain()
.transform(node.getAssignments()::get)
.intersect(node.getCurrentConstraint());

checkState(node.getOutputSymbols().containsAll(context.getLookupSymbols()));

Expand All @@ -268,7 +265,7 @@ private PlanNode planTableScan(TableScanNode node, Expression predicate, Context
ResolvedIndex resolvedIndex = optionalResolvedIndex.get();

Map<ColumnHandle, Symbol> inverseAssignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
Expression unresolvedExpression = DomainTranslator.toPredicate(resolvedIndex.getUnresolvedTupleDomain(), inverseAssignments, symbolAllocator.getTypes());
Expression unresolvedExpression = DomainTranslator.toPredicate(resolvedIndex.getUnresolvedTupleDomain().transform(inverseAssignments::get), symbolAllocator.getTypes());

PlanNode source = new IndexSourceNode(
idAllocator.getNextId(),
Expand Down
Expand Up @@ -110,10 +110,12 @@ private PlanNode planTableScan(TableScanNode node, Expression predicate)
metadata,
session,
predicate,
symbolAllocator.getTypes(),
node.getAssignments());
symbolAllocator.getTypes());

TupleDomain<ColumnHandle> simplifiedConstraint = decomposedPredicate.getTupleDomain()
.transform(node.getAssignments()::get)
.intersect(node.getCurrentConstraint());

TupleDomain<ColumnHandle> simplifiedConstraint = decomposedPredicate.getTupleDomain().intersect(node.getCurrentConstraint());
List<TableLayoutResult> layouts = metadata.getLayouts(node.getTable(), Optional.empty(), new Constraint<>(simplifiedConstraint, bindings -> true));

if (layouts.isEmpty()) {
Expand All @@ -131,11 +133,11 @@ private PlanNode planTableScan(TableScanNode node, Expression predicate)
simplifiedConstraint.intersect(layout.getLayout().getPredicate()),
Optional.ofNullable(node.getOriginalConstraint()).orElse(predicate));

Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
Expression resultingPredicate = combineConjuncts(
decomposedPredicate.getRemainingExpression(),
DomainTranslator.toPredicate(
layout.getUnenforcedConstraint(),
ImmutableBiMap.copyOf(node.getAssignments()).inverse(),
layout.getUnenforcedConstraint().transform(assignments::get),
symbolAllocator.getTypes()));

if (!BooleanLiteral.TRUE_LITERAL.equals(resultingPredicate)) {
Expand Down

0 comments on commit 74f1f17

Please sign in to comment.