Skip to content

Commit

Permalink
Refactor SymbolAliases to ExpressionAliases
Browse files Browse the repository at this point in the history
Storing expression aliases is much more convenient as it enable to store
symbols (as SymbolReference) as well as any other expression.

For example alias C may point to some symbol c as well as to expression
which was projected to symbol c.
  • Loading branch information
kokosing authored and martint committed Aug 26, 2016
1 parent df1582d commit d2940f4
Show file tree
Hide file tree
Showing 15 changed files with 111 additions and 119 deletions.
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* 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.assertions;

import com.facebook.presto.sql.planner.Symbol;
import com.facebook.presto.sql.tree.Expression;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;

import java.util.Map;

import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;

public final class ExpressionAliases
{
private final Multimap<String, Expression> map;

public ExpressionAliases()
{
this.map = ArrayListMultimap.create();
}

public ExpressionAliases(ExpressionAliases expressionAliases)
{
requireNonNull(expressionAliases, "symbolAliases are null");
this.map = ArrayListMultimap.create(expressionAliases.map);
}

public void put(String alias, Expression expression)
{
alias = alias(alias);
if (map.containsKey(alias)) {
checkState(map.get(alias).contains(expression), "Alias '%s' points to different expression '%s' and '%s'", alias, expression, map.get(alias));
}
else {
checkState(!map.values().contains(expression), "Expression '%s' is already pointed by different alias than '%s', check mapping for '%s'", expression, alias, map);
map.put(alias, expression);
}
}

private String alias(String alias)
{
return alias.toLowerCase().replace("(", "").replace(")", "").replace("\"", "");
}

public void updateAssignments(Map<Symbol, Expression> assignments)
{
ImmutableMultimap.Builder<String, Expression> mapUpdate = ImmutableMultimap.builder();
for (Map.Entry<Symbol, Expression> assignment : assignments.entrySet()) {
for (String alias : map.keys()) {
if (map.get(alias).contains(assignment.getKey().toSymbolReference())) {
mapUpdate.put(alias, assignment.getValue());
}
}
}
map.putAll(mapUpdate.build());
}
}
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@
*/ */
package com.facebook.presto.sql.planner.assertions; package com.facebook.presto.sql.planner.assertions;


import com.facebook.presto.sql.planner.Symbol;
import com.facebook.presto.sql.tree.AstVisitor; import com.facebook.presto.sql.tree.AstVisitor;
import com.facebook.presto.sql.tree.ComparisonExpression; import com.facebook.presto.sql.tree.ComparisonExpression;
import com.facebook.presto.sql.tree.DereferenceExpression;
import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.Expression;
import com.facebook.presto.sql.tree.LogicalBinaryExpression; import com.facebook.presto.sql.tree.LogicalBinaryExpression;
import com.facebook.presto.sql.tree.LongLiteral; import com.facebook.presto.sql.tree.LongLiteral;
import com.facebook.presto.sql.tree.Node; import com.facebook.presto.sql.tree.Node;
import com.facebook.presto.sql.tree.NotExpression; import com.facebook.presto.sql.tree.NotExpression;
import com.facebook.presto.sql.tree.QualifiedName;
import com.facebook.presto.sql.tree.QualifiedNameReference; import com.facebook.presto.sql.tree.QualifiedNameReference;
import com.facebook.presto.sql.tree.StringLiteral; import com.facebook.presto.sql.tree.StringLiteral;
import com.facebook.presto.sql.tree.SymbolReference; import com.facebook.presto.sql.tree.SymbolReference;
Expand Down Expand Up @@ -57,11 +54,11 @@
final class ExpressionVerifier final class ExpressionVerifier
extends AstVisitor<Boolean, Expression> extends AstVisitor<Boolean, Expression>
{ {
private final SymbolAliases symbolAliases; private final ExpressionAliases expressionAliases;


ExpressionVerifier(SymbolAliases symbolAliases) ExpressionVerifier(ExpressionAliases expressionAliases)
{ {
this.symbolAliases = requireNonNull(symbolAliases, "symbolAliases is null"); this.expressionAliases = requireNonNull(expressionAliases, "expressionAliases is null");
} }


@Override @Override
Expand Down Expand Up @@ -126,41 +123,14 @@ protected Boolean visitNotExpression(NotExpression actual, Expression expected)
@Override @Override
protected Boolean visitQualifiedNameReference(QualifiedNameReference actual, Expression expected) protected Boolean visitQualifiedNameReference(QualifiedNameReference actual, Expression expected)
{ {
if (isReference(expected)) { expressionAliases.put(expected.toString(), actual);
symbolAliases.put(asQualifiedName(expected).toString(), Symbol.from(actual)); return true;
return true;
}
return false;
} }


@Override @Override
protected Boolean visitSymbolReference(SymbolReference actual, Expression expected) protected Boolean visitSymbolReference(SymbolReference actual, Expression expected)
{ {
if (isReference(expected)) { expressionAliases.put(expected.toString(), actual);
symbolAliases.put(asQualifiedName(expected).toString(), Symbol.from(actual)); return true;
return true;
}
return false;
}

private boolean isReference(Expression expression)
{
return expression instanceof DereferenceExpression || expression instanceof QualifiedNameReference || expression instanceof SymbolReference;
}

private QualifiedName asQualifiedName(Expression expression)
{
if (expression instanceof DereferenceExpression) {
return DereferenceExpression.getQualifiedName((DereferenceExpression) expression);
}
else if (expression instanceof QualifiedNameReference) {
return ((QualifiedNameReference) expression).getName();
}
else if (expression instanceof SymbolReference) {
return QualifiedName.of(((SymbolReference) expression).getName());
}
else {
throw new IllegalArgumentException("Expression is not a DereferenceExpression or QualifiedNameReference");
}
} }
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ final class FilterMatcher
} }


@Override @Override
public boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) public boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
if (node instanceof FilterNode) { if (node instanceof FilterNode) {
FilterNode filterNode = (FilterNode) node; FilterNode filterNode = (FilterNode) node;
if (new ExpressionVerifier(symbolAliases).process(filterNode.getPredicate(), predicate)) { if (new ExpressionVerifier(expressionAliases).process(filterNode.getPredicate(), predicate)) {
return true; return true;
} }
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class JoinMatcher
} }


@Override @Override
public boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) public boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
if (node instanceof JoinNode) { if (node instanceof JoinNode) {
JoinNode joinNode = (JoinNode) node; JoinNode joinNode = (JoinNode) node;
Expand All @@ -48,8 +48,8 @@ public boolean matches(PlanNode node, Session session, Metadata metadata, Symbol
int i = 0; int i = 0;
for (JoinNode.EquiJoinClause equiJoinClause : joinNode.getCriteria()) { for (JoinNode.EquiJoinClause equiJoinClause : joinNode.getCriteria()) {
AliasPair expectedEquiClause = equiCriteria.get(i++); AliasPair expectedEquiClause = equiCriteria.get(i++);
symbolAliases.put(expectedEquiClause.left, equiJoinClause.getLeft()); expressionAliases.put(expectedEquiClause.left, equiJoinClause.getLeft().toSymbolReference());
symbolAliases.put(expectedEquiClause.right, equiJoinClause.getRight()); expressionAliases.put(expectedEquiClause.right, equiJoinClause.getRight().toSymbolReference());
} }
return true; return true;
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@


public interface Matcher public interface Matcher
{ {
boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases); boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases);
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class NotPlanNodeMatcher implements Matcher
} }


@Override @Override
public boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) public boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
return (!node.getClass().equals(excludedNodeClass)); return (!node.getClass().equals(excludedNodeClass));
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -121,20 +121,20 @@ public PlanMatchPattern(List<PlanMatchPattern> sourcePatterns)
this.sourcePatterns = ImmutableList.copyOf(sourcePatterns); this.sourcePatterns = ImmutableList.copyOf(sourcePatterns);
} }


List<PlanMatchingState> matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) List<PlanMatchingState> matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
ImmutableList.Builder<PlanMatchingState> states = ImmutableList.builder(); ImmutableList.Builder<PlanMatchingState> states = ImmutableList.builder();
if (anyTree) { if (anyTree) {
int sourcesCount = node.getSources().size(); int sourcesCount = node.getSources().size();
if (sourcesCount > 1) { if (sourcesCount > 1) {
states.add(new PlanMatchingState(nCopies(sourcesCount, this), symbolAliases)); states.add(new PlanMatchingState(nCopies(sourcesCount, this), expressionAliases));
} }
else { else {
states.add(new PlanMatchingState(ImmutableList.of(this), symbolAliases)); states.add(new PlanMatchingState(ImmutableList.of(this), expressionAliases));
} }
} }
if (node.getSources().size() == sourcePatterns.size() && matchers.stream().allMatch(it -> it.matches(node, session, metadata, symbolAliases))) { if (node.getSources().size() == sourcePatterns.size() && matchers.stream().allMatch(it -> it.matches(node, session, metadata, expressionAliases))) {
states.add(new PlanMatchingState(sourcePatterns, symbolAliases)); states.add(new PlanMatchingState(sourcePatterns, expressionAliases));
} }
return states.build(); return states.build();
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@


final class PlanMatchingContext final class PlanMatchingContext
{ {
private final SymbolAliases symbolAliases; private final ExpressionAliases expressionAliases;
private final PlanMatchPattern pattern; private final PlanMatchPattern pattern;


PlanMatchingContext(PlanMatchPattern pattern) PlanMatchingContext(PlanMatchPattern pattern)
{ {
this(new SymbolAliases(), pattern); this(new ExpressionAliases(), pattern);
} }


PlanMatchingContext(SymbolAliases symbolAliases, PlanMatchPattern pattern) PlanMatchingContext(ExpressionAliases expressionAliases, PlanMatchPattern pattern)
{ {
requireNonNull(symbolAliases, "symbolAliases is null"); requireNonNull(expressionAliases, "expressionAliases is null");
requireNonNull(pattern, "pattern is null"); requireNonNull(pattern, "pattern is null");
this.symbolAliases = new SymbolAliases(symbolAliases); this.expressionAliases = new ExpressionAliases(expressionAliases);
this.pattern = pattern; this.pattern = pattern;
} }


Expand All @@ -38,8 +38,8 @@ PlanMatchPattern getPattern()
return pattern; return pattern;
} }


SymbolAliases getSymbolAliases() ExpressionAliases getExpressionAliases()
{ {
return symbolAliases; return expressionAliases;
} }
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
final class PlanMatchingState final class PlanMatchingState
{ {
private final List<PlanMatchPattern> patterns; private final List<PlanMatchPattern> patterns;
private final SymbolAliases symbolAliases; private final ExpressionAliases expressionAliases;


PlanMatchingState(List<PlanMatchPattern> patterns, SymbolAliases symbolAliases) PlanMatchingState(List<PlanMatchPattern> patterns, ExpressionAliases expressionAliases)
{ {
requireNonNull(symbolAliases, "symbolAliases is null"); requireNonNull(expressionAliases, "expressionAliases is null");
requireNonNull(patterns, "matchers is null"); requireNonNull(patterns, "matchers is null");
this.symbolAliases = new SymbolAliases(symbolAliases); this.expressionAliases = new ExpressionAliases(expressionAliases);
this.patterns = ImmutableList.copyOf(patterns); this.patterns = ImmutableList.copyOf(patterns);
} }


Expand All @@ -41,7 +41,7 @@ boolean isTerminated()
PlanMatchingContext createContext(int matcherId) PlanMatchingContext createContext(int matcherId)
{ {
checkArgument(matcherId < patterns.size(), "mactcherId out of scope"); checkArgument(matcherId < patterns.size(), "mactcherId out of scope");
return new PlanMatchingContext(symbolAliases, patterns.get(matcherId)); return new PlanMatchingContext(expressionAliases, patterns.get(matcherId));
} }


List<PlanMatchPattern> getPatterns() List<PlanMatchPattern> getPatterns()
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public PlanNodeMatcher(Class<? extends PlanNode> nodeClass)
} }


@Override @Override
public boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) public boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
return node.getClass().equals(nodeClass); return node.getClass().equals(nodeClass);
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ final class SemiJoinMatcher
} }


@Override @Override
public boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) public boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
if (node instanceof SemiJoinNode) { if (node instanceof SemiJoinNode) {
SemiJoinNode semiJoinNode = (SemiJoinNode) node; SemiJoinNode semiJoinNode = (SemiJoinNode) node;
symbolAliases.put(sourceSymbolAlias, semiJoinNode.getSourceJoinSymbol()); expressionAliases.put(sourceSymbolAlias, semiJoinNode.getSourceJoinSymbol().toSymbolReference());
symbolAliases.put(filteringSymbolAlias, semiJoinNode.getFilteringSourceJoinSymbol()); expressionAliases.put(filteringSymbolAlias, semiJoinNode.getFilteringSourceJoinSymbol().toSymbolReference());
symbolAliases.put(outputAlias, semiJoinNode.getSemiJoinOutput()); expressionAliases.put(outputAlias, semiJoinNode.getSemiJoinOutput().toSymbolReference());
return true; return true;
} }
return false; return false;
Expand Down

This file was deleted.

Original file line number Original file line Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ final class SymbolMatcher
} }


@Override @Override
public boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) public boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
Symbol symbol = null; Symbol symbol = null;
for (Symbol outputSymbol : node.getOutputSymbols()) { for (Symbol outputSymbol : node.getOutputSymbols()) {
Expand All @@ -46,7 +46,7 @@ public boolean matches(PlanNode node, Session session, Metadata metadata, Symbol
} }
} }
if (symbol != null) { if (symbol != null) {
symbolAliases.put(alias, symbol); expressionAliases.put(alias, symbol.toSymbolReference());
return true; return true;
} }
return false; return false;
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public TableScanMatcher(String expectedTableName, Map<String, Domain> expectedCo
} }


@Override @Override
public boolean matches(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) public boolean matches(PlanNode node, Session session, Metadata metadata, ExpressionAliases expressionAliases)
{ {
if (node instanceof TableScanNode) { if (node instanceof TableScanNode) {
TableScanNode tableScanNode = (TableScanNode) node; TableScanNode tableScanNode = (TableScanNode) node;
Expand Down
Loading

0 comments on commit d2940f4

Please sign in to comment.