Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ExprSubstitutionMap.java
Go to the documentation of this file.
1 package com.cloudera.impala.analysis;
2 
3 import java.util.List;
4 
5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory;
7 
8 import com.google.common.base.Joiner;
9 import com.google.common.base.Preconditions;
10 import com.google.common.collect.Lists;
11 
20 public final class ExprSubstitutionMap {
21  private final static Logger LOG = LoggerFactory.getLogger(ExprSubstitutionMap.class);
22 
23  private List<Expr> lhs_; // left-hand side
24  private List<Expr> rhs_; // right-hand side
25 
27  this(Lists.<Expr>newArrayList(), Lists.<Expr>newArrayList());
28  }
29 
30  public ExprSubstitutionMap(List<Expr> lhs, List<Expr> rhs) {
31  lhs_ = lhs;
32  rhs_ = rhs;
33  }
34 
39  public void put(Expr lhsExpr, Expr rhsExpr) {
40  Preconditions.checkState(rhsExpr.isAnalyzed_, "Rhs expr must be analyzed.");
41  lhs_.add(lhsExpr);
42  rhs_.add(rhsExpr);
43  }
44 
48  public Expr get(Expr lhsExpr) {
49  for (int i = 0; i < lhs_.size(); ++i) {
50  if (lhsExpr.equals(lhs_.get(i))) return rhs_.get(i);
51  }
52  return null;
53  }
54 
58  public boolean containsMappingFor(Expr lhsExpr) {
59  return lhs_.contains(lhsExpr);
60  }
61 
68  Analyzer analyzer) {
69  if (f == null && g == null) return new ExprSubstitutionMap();
70  if (f == null) return g;
71  if (g == null) return f;
73  // f's substitution targets need to be substituted via g
74  result.lhs_ = Expr.cloneList(f.lhs_);
75  result.rhs_ = Expr.substituteList(f.rhs_, g, analyzer, false);
76 
77  // substitution maps are cumulative: the combined map contains all
78  // substitutions from f and g.
79  for (int i = 0; i < g.lhs_.size(); i++) {
80  // If f contains expr1->fn(expr2) and g contains expr2->expr3,
81  // then result must contain expr1->fn(expr3).
82  // The check before adding to result.lhs is to ensure that cases
83  // where expr2.equals(expr1) are handled correctly.
84  // For example f: count(*) -> zeroifnull(count(*))
85  // and g: count(*) -> slotref
86  // result.lhs must only have: count(*) -> zeroifnull(slotref) from f above,
87  // and not count(*) -> slotref from g as well.
88  if (!result.lhs_.contains(g.lhs_.get(i))) {
89  result.lhs_.add(g.lhs_.get(i).clone());
90  result.rhs_.add(g.rhs_.get(i).clone());
91  }
92  }
93 
94  result.verify();
95  return result;
96  }
97 
103  if (f == null && g == null) return new ExprSubstitutionMap();
104  if (f == null) return g;
105  if (g == null) return f;
107  result.lhs_ = Lists.newArrayList(f.lhs_);
108  result.lhs_.addAll(g.lhs_);
109  result.rhs_ = Lists.newArrayList(f.rhs_);
110  result.rhs_.addAll(g.rhs_);
111  result.verify();
112  return result;
113  }
114 
115  public void substituteLhs(ExprSubstitutionMap lhsSmap, Analyzer analyzer) {
116  lhs_ = Expr.substituteList(lhs_, lhsSmap, analyzer, false);
117  }
118 
119  public List<Expr> getLhs() { return lhs_; }
120  public List<Expr> getRhs() { return rhs_; }
121 
122  public int size() { return lhs_.size(); }
123 
124  public String debugString() {
125  Preconditions.checkState(lhs_.size() == rhs_.size());
126  List<String> output = Lists.newArrayList();
127  for (int i = 0; i < lhs_.size(); ++i) {
128  output.add(lhs_.get(i).toSql() + ":" + rhs_.get(i).toSql());
129  output.add("(" + lhs_.get(i).debugString() + ":" + rhs_.get(i).debugString() + ")");
130  }
131  return "smap(" + Joiner.on(" ").join(output) + ")";
132  }
133 
138  private void verify() {
139  for (int i = 0; i < lhs_.size(); ++i) {
140  for (int j = i + 1; j < lhs_.size(); ++j) {
141  if (lhs_.get(i).equals(lhs_.get(j))) {
142  LOG.info("verify: smap=" + this.debugString());
143  Preconditions.checkState(false);
144  }
145  }
146  Preconditions.checkState(rhs_.get(i).isAnalyzed_);
147  }
148  }
149 
150  public void clear() {
151  lhs_.clear();
152  rhs_.clear();
153  }
154 }
ExprSubstitutionMap(List< Expr > lhs, List< Expr > rhs)
void substituteLhs(ExprSubstitutionMap lhsSmap, Analyzer analyzer)
static ExprSubstitutionMap combine(ExprSubstitutionMap f, ExprSubstitutionMap g)
static ExprSubstitutionMap compose(ExprSubstitutionMap f, ExprSubstitutionMap g, Analyzer analyzer)