You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/01/26 21:35:43 UTC

[4/4] calcite git commit: [CALCITE-1068] Deprecate Stacks

[CALCITE-1068] Deprecate Stacks


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/f55d10c1
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/f55d10c1
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/f55d10c1

Branch: refs/heads/master
Commit: f55d10c147746d6299fb713adc184576380a1f49
Parents: 4ec4727
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Jan 25 21:42:14 2016 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Tue Jan 26 11:53:34 2016 -0800

----------------------------------------------------------------------
 .../org/apache/calcite/jdbc/CalcitePrepare.java |  19 +--
 .../org/apache/calcite/model/ModelHandler.java  |  25 ++--
 .../apache/calcite/plan/volcano/RuleQueue.java  |  29 ++--
 .../calcite/plan/volcano/VolcanoPlanner.java    |  16 +--
 .../org/apache/calcite/rel/RelShuttleImpl.java  |  12 +-
 .../rel/rules/ReduceExpressionsRule.java        |  12 +-
 .../apache/calcite/sql/SqlIntervalLiteral.java  |   7 +-
 .../apache/calcite/sql/validate/AggChecker.java |  25 ++--
 .../sql/validate/AggregatingSelectScope.java    |   5 +-
 .../apache/calcite/sql/validate/OverScope.java  |   3 +-
 .../calcite/sql/validate/SelectScope.java       |   5 +-
 .../calcite/sql/validate/SqlValidatorImpl.java  |   5 +-
 .../calcite/sql/validate/SqlValidatorUtil.java  |  12 +-
 .../apache/calcite/sql2rel/RelDecorrelator.java |  17 +--
 .../calcite/sql2rel/SqlToRelConverter.java      |  16 +--
 .../org/apache/calcite/tools/RelBuilder.java    |  45 +++---
 .../calcite/util/PartiallyOrderedSet.java       | 141 ++++---------------
 .../org/apache/calcite/util/StackWriter.java    |  11 +-
 .../java/org/apache/calcite/util/Stacks.java    |   1 +
 .../java/org/apache/calcite/util/XmlOutput.java |  10 +-
 .../calcite/sql/test/SqlPrettyWriterTest.java   |  12 +-
 .../apache/calcite/test/MockCatalogReader.java  |   5 +-
 22 files changed, 178 insertions(+), 255 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java b/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
index 0aa47bc..31b6b70 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalcitePrepare.java
@@ -43,7 +43,6 @@ import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.util.ImmutableIntList;
-import org.apache.calcite.util.Stacks;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 
@@ -52,7 +51,8 @@ import com.google.common.collect.ImmutableList;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
-import java.util.ArrayList;
+import java.util.ArrayDeque;
+import java.util.Deque;
 import java.util.List;
 import java.util.Map;
 
@@ -66,10 +66,10 @@ public interface CalcitePrepare {
           return new CalcitePrepareImpl();
         }
       };
-  ThreadLocal<ArrayList<Context>> THREAD_CONTEXT_STACK =
-      new ThreadLocal<ArrayList<Context>>() {
-        @Override protected ArrayList<Context> initialValue() {
-          return new ArrayList<>();
+  ThreadLocal<Deque<Context>> THREAD_CONTEXT_STACK =
+      new ThreadLocal<Deque<Context>>() {
+        @Override protected Deque<Context> initialValue() {
+          return new ArrayDeque<>();
         }
       };
 
@@ -174,15 +174,16 @@ public interface CalcitePrepare {
     }
 
     public static void push(Context context) {
-      Stacks.push(THREAD_CONTEXT_STACK.get(), context);
+      THREAD_CONTEXT_STACK.get().push(context);
     }
 
     public static Context peek() {
-      return Stacks.peek(THREAD_CONTEXT_STACK.get());
+      return THREAD_CONTEXT_STACK.get().peek();
     }
 
     public static void pop(Context context) {
-      Stacks.pop(THREAD_CONTEXT_STACK.get(), context);
+      Context x = THREAD_CONTEXT_STACK.get().pop();
+      assert x == context;
     }
 
     /** Implementation of {@link SparkHandler} that either does nothing or

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/model/ModelHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/model/ModelHandler.java b/core/src/main/java/org/apache/calcite/model/ModelHandler.java
index 6b04a91..f7aa5c6 100644
--- a/core/src/main/java/org/apache/calcite/model/ModelHandler.java
+++ b/core/src/main/java/org/apache/calcite/model/ModelHandler.java
@@ -47,22 +47,19 @@ import com.google.common.collect.ImmutableMap;
 import java.io.File;
 import java.io.IOException;
 import java.sql.SQLException;
-import java.util.ArrayList;
+import java.util.ArrayDeque;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.List;
 import java.util.Map;
 import javax.sql.DataSource;
 
-import static org.apache.calcite.util.Stacks.peek;
-import static org.apache.calcite.util.Stacks.pop;
-import static org.apache.calcite.util.Stacks.push;
-
 /**
  * Reads a model and creates schema objects accordingly.
  */
 public class ModelHandler {
   private final CalciteConnection connection;
-  private final List<Pair<String, SchemaPlus>> schemaStack = new ArrayList<>();
+  private final Deque<Pair<String, SchemaPlus>> schemaStack = new ArrayDeque<>();
   private final String modelUri;
   Lattice.Builder latticeBuilder;
   Lattice.TileBuilder tileBuilder;
@@ -139,11 +136,12 @@ public class ModelHandler {
   public void visit(JsonRoot root) {
     final Pair<String, SchemaPlus> pair =
         Pair.of(null, connection.getRootSchema());
-    push(schemaStack, pair);
+    schemaStack.push(pair);
     for (JsonSchema schema : root.schemas) {
       schema.accept(this);
     }
-    pop(schemaStack, pair);
+    final Pair<String, SchemaPlus> p = schemaStack.pop();
+    assert p == pair;
     if (root.defaultSchema != null) {
       try {
         connection.setSchema(root.defaultSchema);
@@ -199,9 +197,10 @@ public class ModelHandler {
       schema.setCacheEnabled(jsonSchema.cache);
     }
     final Pair<String, SchemaPlus> pair = Pair.of(jsonSchema.name, schema);
-    push(schemaStack, pair);
+    schemaStack.push(pair);
     jsonSchema.visitChildren(this);
-    pop(schemaStack, pair);
+    final Pair<String, SchemaPlus> p = schemaStack.pop();
+    assert p == pair;
   }
 
   public void visit(JsonCustomSchema jsonSchema) {
@@ -356,15 +355,15 @@ public class ModelHandler {
   }
 
   private List<String> currentSchemaPath() {
-    return Collections.singletonList(peek(schemaStack).left);
+    return Collections.singletonList(schemaStack.peek().left);
   }
 
   private SchemaPlus currentSchema() {
-    return peek(schemaStack).right;
+    return schemaStack.peek().right;
   }
 
   private String currentSchemaName() {
-    return peek(schemaStack).left;
+    return schemaStack.peek().left;
   }
 
   private SchemaPlus currentMutableSchema(String elementType) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/plan/volcano/RuleQueue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/RuleQueue.java b/core/src/main/java/org/apache/calcite/plan/volcano/RuleQueue.java
index f14a681..9fa5b2b 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/RuleQueue.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/RuleQueue.java
@@ -22,7 +22,6 @@ import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.RelNodes;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.calcite.util.ChunkList;
-import org.apache.calcite.util.Stacks;
 import org.apache.calcite.util.Util;
 import org.apache.calcite.util.trace.CalciteTrace;
 
@@ -32,11 +31,13 @@ import com.google.common.collect.Multimap;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Deque;
 import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -68,15 +69,14 @@ class RuleQueue {
   /**
    * The importance of each subset.
    */
-  final Map<RelSubset, Double> subsetImportances =
-      new HashMap<RelSubset, Double>();
+  final Map<RelSubset, Double> subsetImportances = new HashMap<>();
 
   /**
    * The set of RelSubsets whose importance is currently in an artificially
    * raised state. Typically this only includes RelSubsets which have only
    * logical RelNodes.
    */
-  final Set<RelSubset> boostedSubsets = new HashSet<RelSubset>();
+  final Set<RelSubset> boostedSubsets = new HashSet<>();
 
   /**
    * Map of {@link VolcanoPlannerPhase} to a list of rule-matches. Initially,
@@ -87,8 +87,7 @@ class RuleQueue {
    * work.
    */
   final Map<VolcanoPlannerPhase, PhaseMatchList> matchListMap =
-      new EnumMap<VolcanoPlannerPhase, PhaseMatchList>(
-          VolcanoPlannerPhase.class);
+      new EnumMap<>(VolcanoPlannerPhase.class);
 
   /**
    * Sorts rule-matches into decreasing order of importance.
@@ -115,8 +114,7 @@ class RuleQueue {
   RuleQueue(VolcanoPlanner planner) {
     this.planner = planner;
 
-    phaseRuleMapping = new EnumMap<VolcanoPlannerPhase, Set<String>>(
-        VolcanoPlannerPhase.class);
+    phaseRuleMapping = new EnumMap<>(VolcanoPlannerPhase.class);
 
     // init empty sets for all phases
     for (VolcanoPlannerPhase phase : VolcanoPlannerPhase.values()) {
@@ -225,8 +223,8 @@ class RuleQueue {
     if (LOGGER.isLoggable(Level.FINER)) {
       LOGGER.finer("boostImportance(" + factor + ", " + subsets + ")");
     }
-    ArrayList<RelSubset> boostRemovals = new ArrayList<RelSubset>();
-    Iterator<RelSubset> iter = boostedSubsets.iterator();
+    final List<RelSubset> boostRemovals = new ArrayList<>();
+    final Iterator<RelSubset> iter = boostedSubsets.iterator();
     while (iter.hasNext()) {
       RelSubset subset = iter.next();
 
@@ -538,7 +536,7 @@ class RuleQueue {
     //   Project(A, X = X + 0 + 0)
     //   Project(A, X = X + 0 + 0 + 0)
     // also in the same subset. They are valid but useless.
-    final List<RelSubset> subsets = new ArrayList<RelSubset>();
+    final Deque<RelSubset> subsets = new ArrayDeque<>();
     try {
       checkDuplicateSubsets(subsets, match.rule.getOperand(), match.rels);
     } catch (Util.FoundOne e) {
@@ -563,18 +561,19 @@ class RuleQueue {
    *
    * @throws org.apache.calcite.util.Util.FoundOne on match
    */
-  private void checkDuplicateSubsets(List<RelSubset> subsets,
+  private void checkDuplicateSubsets(Deque<RelSubset> subsets,
       RelOptRuleOperand operand, RelNode[] rels) {
     final RelSubset subset = planner.getSubset(rels[operand.ordinalInRule]);
     if (subsets.contains(subset)) {
       throw Util.FoundOne.NULL;
     }
     if (!operand.getChildOperands().isEmpty()) {
-      Stacks.push(subsets, subset);
+      subsets.push(subset);
       for (RelOptRuleOperand childOperand : operand.getChildOperands()) {
         checkDuplicateSubsets(subsets, childOperand, rels);
       }
-      Stacks.pop(subsets, subset);
+      final RelSubset x = subsets.pop();
+      assert x == subset;
     }
   }
 
@@ -696,7 +695,7 @@ class RuleQueue {
      * A set of rule-match names contained in {@link #list}. Allows fast
      * detection of duplicate rule-matches.
      */
-    final Set<String> names = new HashSet<String>();
+    final Set<String> names = new HashSet<>();
 
     /**
      * Multi-map of RelSubset to VolcanoRuleMatches. Used to

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
index 530148c..74af6ce 100644
--- a/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
+++ b/core/src/main/java/org/apache/calcite/plan/volcano/VolcanoPlanner.java
@@ -91,11 +91,13 @@ import com.google.common.collect.Sets;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
@@ -108,10 +110,6 @@ import java.util.logging.Level;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static org.apache.calcite.util.Stacks.peek;
-import static org.apache.calcite.util.Stacks.pop;
-import static org.apache.calcite.util.Stacks.push;
-
 /**
  * VolcanoPlanner optimizes queries by transforming expressions selectively
  * according to a dynamic programming algorithm.
@@ -263,7 +261,7 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
 
   final Map<RelNode, Provenance> provenanceMap = new HashMap<>();
 
-  private final List<VolcanoRuleCall> ruleCallStack = new ArrayList<>();
+  private final Deque<VolcanoRuleCall> ruleCallStack = new ArrayDeque<>();
 
   /** Zero cost, according to {@link #costFactory}. Not necessarily a
    * {@link org.apache.calcite.plan.volcano.VolcanoCost}. */
@@ -1678,12 +1676,10 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
     rel = rel.onRegister(this);
 
     // Record its provenance. (Rule call may be null.)
-    final VolcanoRuleCall ruleCall;
     if (ruleCallStack.isEmpty()) {
-      ruleCall = null;
       provenanceMap.put(rel, Provenance.EMPTY);
     } else {
-      ruleCall = peek(ruleCallStack);
+      final VolcanoRuleCall ruleCall = ruleCallStack.peek();
       provenanceMap.put(
           rel,
           new RuleProvenance(
@@ -1957,9 +1953,9 @@ public class VolcanoPlanner extends AbstractRelOptPlanner {
       RelNode rel,
       RelNode equivRel,
       VolcanoRuleCall ruleCall) {
-    push(ruleCallStack, ruleCall);
+    ruleCallStack.push(ruleCall);
     ensureRegistered(rel, equivRel);
-    pop(ruleCallStack, ruleCall);
+    ruleCallStack.pop();
   }
 
   //~ Inner Classes ----------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/rel/RelShuttleImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/RelShuttleImpl.java b/core/src/main/java/org/apache/calcite/rel/RelShuttleImpl.java
index bd83126..a28f2b5 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelShuttleImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelShuttleImpl.java
@@ -30,9 +30,10 @@ import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.rel.logical.LogicalSort;
 import org.apache.calcite.rel.logical.LogicalUnion;
 import org.apache.calcite.rel.logical.LogicalValues;
-import org.apache.calcite.util.Stacks;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
+import java.util.Deque;
 import java.util.List;
 
 /**
@@ -42,24 +43,23 @@ import java.util.List;
  * any children change.
  */
 public class RelShuttleImpl implements RelShuttle {
-  protected final List<RelNode> stack = new ArrayList<RelNode>();
+  protected final Deque<RelNode> stack = new ArrayDeque<>();
 
   /**
    * Visits a particular child of a parent.
    */
   protected RelNode visitChild(RelNode parent, int i, RelNode child) {
-    Stacks.push(stack, parent);
+    stack.push(parent);
     try {
       RelNode child2 = child.accept(this);
       if (child2 != child) {
-        final List<RelNode> newInputs =
-            new ArrayList<RelNode>(parent.getInputs());
+        final List<RelNode> newInputs = new ArrayList<>(parent.getInputs());
         newInputs.set(i, child2);
         return parent.copy(parent.getTraitSet(), newInputs);
       }
       return parent;
     } finally {
-      Stacks.pop(stack, parent);
+      stack.pop();
     }
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index 1036ea4..1fe0218 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -58,14 +58,15 @@ import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.tools.RelBuilder;
 import org.apache.calcite.tools.RelBuilderFactory;
 import org.apache.calcite.util.Pair;
-import org.apache.calcite.util.Stacks;
 import org.apache.calcite.util.Util;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -844,7 +845,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
 
     private final List<RexNode> removableCasts;
 
-    private final List<SqlOperator> parentCallTypeStack;
+    private final Deque<SqlOperator> parentCallTypeStack = new ArrayDeque<>();
 
     ReducibleExprLocator(RelDataTypeFactory typeFactory,
         ImmutableMap<RexNode, ? extends RexNode> constants,
@@ -858,7 +859,6 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
       this.addCasts = addCasts;
       this.removableCasts = removableCasts;
       this.stack = Lists.newArrayList();
-      this.parentCallTypeStack = Lists.newArrayList();
     }
 
     public void analyze(RexNode exp) {
@@ -904,7 +904,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
       if (parentCallTypeStack.isEmpty()) {
         addCasts.add(false);
       } else {
-        addCasts.add(isUdf(Stacks.peek(parentCallTypeStack)));
+        addCasts.add(isUdf(parentCallTypeStack.peek()));
       }
     }
 
@@ -943,7 +943,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
     }
 
     private void analyzeCall(RexCall call, Constancy callConstancy) {
-      Stacks.push(parentCallTypeStack, call.getOperator());
+      parentCallTypeStack.push(call.getOperator());
 
       // visit operands, pushing their states onto stack
       super.visitCall(call);
@@ -997,7 +997,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
       operandStack.clear();
 
       // pop this parent call operator off the stack
-      Stacks.pop(parentCallTypeStack, call.getOperator());
+      parentCallTypeStack.pop();
 
       // push constancy result for this call onto stack
       stack.add(callConstancy);

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql/SqlIntervalLiteral.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlIntervalLiteral.java b/core/src/main/java/org/apache/calcite/sql/SqlIntervalLiteral.java
index 119c73e..ff47657 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlIntervalLiteral.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlIntervalLiteral.java
@@ -18,6 +18,7 @@ package org.apache.calcite.sql;
 
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.Util;
 
 /**
@@ -122,13 +123,13 @@ public class SqlIntervalLiteral extends SqlLiteral {
       IntervalValue that = (IntervalValue) obj;
       return this.intervalStr.equals(that.intervalStr)
           && (this.sign == that.sign)
-          && this.intervalQualifier.equalsDeep(that.intervalQualifier, false);
+          && this.intervalQualifier.equalsDeep(that.intervalQualifier,
+              Litmus.IGNORE);
     }
 
     public int hashCode() {
       int h = Util.hash(sign, intervalStr);
-      int i = Util.hash(h, intervalQualifier);
-      return i;
+      return Util.hash(h, intervalQualifier);
     }
 
     public SqlIntervalQualifier getIntervalQualifier() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java b/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
index 39a7f3c..ca5138a 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/AggChecker.java
@@ -24,10 +24,10 @@ import org.apache.calcite.sql.SqlNodeList;
 import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.SqlUtil;
 import org.apache.calcite.sql.util.SqlBasicVisitor;
-import org.apache.calcite.util.Stacks;
-
-import com.google.common.collect.Lists;
+import org.apache.calcite.util.Litmus;
 
+import java.util.ArrayDeque;
+import java.util.Deque;
 import java.util.List;
 
 import static org.apache.calcite.util.Static.RESOURCE;
@@ -39,7 +39,7 @@ import static org.apache.calcite.util.Static.RESOURCE;
 class AggChecker extends SqlBasicVisitor<Void> {
   //~ Instance fields --------------------------------------------------------
 
-  private final List<SqlValidatorScope> scopes = Lists.newArrayList();
+  private final Deque<SqlValidatorScope> scopes = new ArrayDeque<>();
   private final List<SqlNode> groupExprs;
   private boolean distinct;
   private SqlValidatorImpl validator;
@@ -64,14 +64,14 @@ class AggChecker extends SqlBasicVisitor<Void> {
     this.validator = validator;
     this.groupExprs = groupExprs;
     this.distinct = distinct;
-    Stacks.push(this.scopes, scope);
+    this.scopes.push(scope);
   }
 
   //~ Methods ----------------------------------------------------------------
 
   boolean isGroupExpr(SqlNode expr) {
     for (SqlNode groupExpr : groupExprs) {
-      if (groupExpr.equalsDeep(expr, false)) {
+      if (groupExpr.equalsDeep(expr, Litmus.IGNORE)) {
         return true;
       }
     }
@@ -101,7 +101,7 @@ class AggChecker extends SqlBasicVisitor<Void> {
     // it fully-qualified.
     // TODO: It would be better if we always compared fully-qualified
     // to fully-qualified.
-    final SqlQualified fqId = Stacks.peek(scopes).fullyQualify(id);
+    final SqlQualified fqId = scopes.peek().fullyQualify(id);
     if (isGroupExpr(fqId.identifier)) {
       return null;
     }
@@ -114,7 +114,7 @@ class AggChecker extends SqlBasicVisitor<Void> {
   }
 
   public Void visit(SqlCall call) {
-    final SqlValidatorScope scope = Stacks.peek(scopes);
+    final SqlValidatorScope scope = scopes.peek();
     if (call.getOperator().isAggregator()) {
       if (distinct) {
         if (scope instanceof AggregatingSelectScope) {
@@ -127,7 +127,8 @@ class AggChecker extends SqlBasicVisitor<Void> {
               sqlNode = ((SqlCall) sqlNode).operand(0);
             }
 
-            if (validator.expand(sqlNode, scope).equalsDeep(call, false)) {
+            if (validator.expand(sqlNode, scope)
+                .equalsDeep(call, Litmus.IGNORE)) {
               return null;
             }
           }
@@ -150,7 +151,7 @@ class AggChecker extends SqlBasicVisitor<Void> {
     }
     // Visit the operand in window function
     if (call.getOperator().getKind() == SqlKind.OVER) {
-      SqlCall windowFunction = (SqlCall) call.operand(0);
+      SqlCall windowFunction = call.operand(0);
       if (windowFunction.getOperandList().size() != 0) {
         windowFunction.operand(0).accept(this);
       }
@@ -167,14 +168,14 @@ class AggChecker extends SqlBasicVisitor<Void> {
 
     // Switch to new scope.
     SqlValidatorScope newScope = scope.getOperandScope(call);
-    Stacks.push(scopes, newScope);
+    scopes.push(newScope);
 
     // Visit the operands (only expressions).
     call.getOperator()
         .acceptCall(this, call, true, ArgHandlerImpl.<Void>instance());
 
     // Restore scope.
-    Stacks.pop(scopes, newScope);
+    scopes.pop();
     return null;
   }
 }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql/validate/AggregatingSelectScope.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/AggregatingSelectScope.java b/core/src/main/java/org/apache/calcite/sql/validate/AggregatingSelectScope.java
index 580e71c..cc884ee 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/AggregatingSelectScope.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/AggregatingSelectScope.java
@@ -24,6 +24,7 @@ import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.SqlNodeList;
 import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Litmus;
 
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
@@ -176,7 +177,7 @@ public class AggregatingSelectScope
   @Override public RelDataType nullifyType(SqlNode node, RelDataType type) {
     final Resolved r = this.resolved.get();
     for (Ord<SqlNode> groupExpr : Ord.zip(r.groupExprList)) {
-      if (groupExpr.e.equalsDeep(node, false)) {
+      if (groupExpr.e.equalsDeep(node, Litmus.IGNORE)) {
         if (r.isNullable(groupExpr.i)) {
           return validator.getTypeFactory().createTypeWithNullability(type,
               true);
@@ -272,7 +273,7 @@ public class AggregatingSelectScope
 
     public int lookupGroupingExpr(SqlNode operand) {
       for (Ord<SqlNode> groupExpr : Ord.zip(groupExprList)) {
-        if (operand.equalsDeep(groupExpr.e, false)) {
+        if (operand.equalsDeep(groupExpr.e, Litmus.IGNORE)) {
           return groupExpr.i;
         }
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql/validate/OverScope.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/OverScope.java b/core/src/main/java/org/apache/calcite/sql/validate/OverScope.java
index 7f980e2..9d95513 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/OverScope.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/OverScope.java
@@ -18,6 +18,7 @@ package org.apache.calcite.sql.validate;
 
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.Pair;
 
 import java.util.List;
@@ -78,7 +79,7 @@ public class OverScope extends ListScope {
       final List<Pair<SqlNode, SqlMonotonicity>> monotonicExprs =
           child.getMonotonicExprs();
       for (Pair<SqlNode, SqlMonotonicity> pair : monotonicExprs) {
-        if (expr.equalsDeep(pair.left, false)) {
+        if (expr.equalsDeep(pair.left, Litmus.IGNORE)) {
           return pair.right;
         }
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql/validate/SelectScope.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SelectScope.java b/core/src/main/java/org/apache/calcite/sql/validate/SelectScope.java
index ea6db19..c53cb99 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SelectScope.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SelectScope.java
@@ -24,6 +24,7 @@ import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.SqlWindow;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.Pair;
 
 import java.util.ArrayList;
@@ -88,7 +89,7 @@ public class SelectScope extends ListScope {
   //~ Instance fields --------------------------------------------------------
 
   private final SqlSelect select;
-  protected final List<String> windowNames = new ArrayList<String>();
+  protected final List<String> windowNames = new ArrayList<>();
 
   private List<SqlNode> expandedSelectList = null;
 
@@ -167,7 +168,7 @@ public class SelectScope extends ListScope {
         monotonicity = monotonicity.reverse();
         order0 = ((SqlCall) order0).operand(0);
       }
-      if (expr.equalsDeep(order0, false)) {
+      if (expr.equalsDeep(order0, Litmus.IGNORE)) {
         return monotonicity;
       }
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
index 00b8611..ebc7ad0 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
@@ -77,6 +77,7 @@ import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.calcite.sql.util.SqlShuttle;
 import org.apache.calcite.sql.util.SqlVisitor;
 import org.apache.calcite.util.BitString;
+import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.Pair;
 import org.apache.calcite.util.Static;
 import org.apache.calcite.util.Util;
@@ -1071,7 +1072,7 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
           SqlNode sqlNode = orderList.get(i);
           SqlNodeList selectList2 = getInnerSelect(node).getSelectList();
           for (Ord<SqlNode> sel : Ord.zip(selectList2)) {
-            if (stripAs(sel.e).equalsDeep(sqlNode, false)) {
+            if (stripAs(sel.e).equalsDeep(sqlNode, Litmus.IGNORE)) {
               orderList.set(i,
                   SqlLiteral.createExactNumeric(Integer.toString(sel.i + 1),
                       SqlParserPos.ZERO));
@@ -3163,7 +3164,7 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
       SqlNode window1 = windowList.get(i);
       for (int j = i + 1; j < windowList.size(); j++) {
         SqlNode window2 = windowList.get(j);
-        if (window1.equalsDeep(window2, false)) {
+        if (window1.equalsDeep(window2, Litmus.IGNORE)) {
           throw newValidationError(window2, RESOURCE.dupWindowSpec());
         }
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
index 3ddeed4..ac03caa 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
@@ -38,6 +38,7 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.Util;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -242,7 +243,7 @@ public class SqlValidatorUtil {
   public static List<String> uniquify(
       List<String> nameList,
       Suggester suggester) {
-    Set<String> used = new LinkedHashSet<String>();
+    final Set<String> used = new LinkedHashSet<>();
     int changeCount = 0;
     for (String name : nameList) {
       String uniqueName = uniquify(name, used, suggester);
@@ -252,7 +253,7 @@ public class SqlValidatorUtil {
     }
     return changeCount == 0
         ? nameList
-        : new ArrayList<String>(used);
+        : new ArrayList<>(used);
   }
 
   /**
@@ -329,7 +330,7 @@ public class SqlValidatorUtil {
   public static List<String> deriveNaturalJoinColumnList(
       RelDataType leftRowType,
       RelDataType rightRowType) {
-    List<String> naturalColumnNames = new ArrayList<String>();
+    final List<String> naturalColumnNames = new ArrayList<>();
     final List<String> leftNames = leftRowType.getFieldNames();
     final List<String> rightNames = rightRowType.getFieldNames();
     for (String name : leftNames) {
@@ -348,7 +349,7 @@ public class SqlValidatorUtil {
     // the resulting type will use those from type. These are presumably more
     // canonical.
     final List<RelDataTypeField> fields =
-        new ArrayList<RelDataTypeField>(columnNameList.size());
+        new ArrayList<>(columnNameList.size());
     for (String name : columnNameList) {
       RelDataTypeField field = type.getField(name, caseSensitive, elideRecord);
       fields.add(type.getFieldList().get(field.getIndex()));
@@ -516,7 +517,7 @@ public class SqlValidatorUtil {
 
   private static int lookupGroupExpr(List<SqlNode> groupExprs, SqlNode expr) {
     for (Ord<SqlNode> node : Ord.zip(groupExprs)) {
-      if (node.e.equalsDeep(expr, false)) {
+      if (node.e.equalsDeep(expr, Litmus.IGNORE)) {
         return node.i;
       }
     }
@@ -616,6 +617,7 @@ public class SqlValidatorUtil {
    * Walks over an expression, copying every node, and fully-qualifying every
    * identifier.
    */
+  @Deprecated // to be removed before 2.0
   public static class DeepCopier extends SqlScopedShuttle {
     DeepCopier(SqlValidatorScope scope) {
       super(scope);

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
index 099bb9a..5d58f3f 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
@@ -80,7 +80,6 @@ import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.Pair;
 import org.apache.calcite.util.ReflectUtil;
 import org.apache.calcite.util.ReflectiveVisitor;
-import org.apache.calcite.util.Stacks;
 import org.apache.calcite.util.Util;
 import org.apache.calcite.util.mapping.Mappings;
 import org.apache.calcite.util.trace.CalciteTrace;
@@ -99,9 +98,11 @@ import com.google.common.collect.Sets;
 import com.google.common.collect.SortedSetMultimap;
 
 import java.math.BigDecimal;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -2469,7 +2470,7 @@ public class RelDecorrelator implements ReflectiveVisitor {
     final Holder<Integer> offset = Holder.of(0);
     int corrIdGenerator = 0;
 
-    final List<RelNode> stack = new ArrayList<>();
+    final Deque<RelNode> stack = new ArrayDeque<>();
 
     /** Creates a CorelMap by iterating over a {@link RelNode} tree. */
     CorelMap build(RelNode rel) {
@@ -2480,10 +2481,10 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
     @Override public RelNode visit(LogicalJoin join) {
       try {
-        Stacks.push(stack, join);
+        stack.push(join);
         join.getCondition().accept(rexVisitor(join));
       } finally {
-        Stacks.pop(stack, join);
+        stack.pop();
       }
       return visitJoin(join);
     }
@@ -2509,22 +2510,22 @@ public class RelDecorrelator implements ReflectiveVisitor {
 
     @Override public RelNode visit(final LogicalFilter filter) {
       try {
-        Stacks.push(stack, filter);
+        stack.push(filter);
         filter.getCondition().accept(rexVisitor(filter));
       } finally {
-        Stacks.pop(stack, filter);
+        stack.pop();
       }
       return super.visit(filter);
     }
 
     @Override public RelNode visit(LogicalProject project) {
       try {
-        Stacks.push(stack, project);
+        stack.push(project);
         for (RexNode node : project.getProjects()) {
           node.accept(rexVisitor(project));
         }
       } finally {
-        Stacks.pop(stack, project);
+        stack.pop();
       }
       return super.visit(project);
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index a85c79a..a17df51 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -2792,17 +2792,15 @@ public class SqlToRelConverter {
     int ordinal = -1;
     for (SqlNode selectItem : selectScope.getExpandedSelectList()) {
       ++ordinal;
-      if (converted.equalsDeep(stripAs(selectItem), false)) {
-        return new RelFieldCollation(
-            ordinal, direction, nullDirection);
+      if (converted.equalsDeep(stripAs(selectItem), Litmus.IGNORE)) {
+        return new RelFieldCollation(ordinal, direction, nullDirection);
       }
     }
 
     for (SqlNode extraExpr : extraExprs) {
       ++ordinal;
-      if (converted.equalsDeep(extraExpr, false)) {
-        return new RelFieldCollation(
-            ordinal, direction, nullDirection);
+      if (converted.equalsDeep(extraExpr, Litmus.IGNORE)) {
+        return new RelFieldCollation(ordinal, direction, nullDirection);
       }
     }
 
@@ -4024,7 +4022,7 @@ public class SqlToRelConverter {
 
     void registerSubquery(SqlNode node, RelOptUtil.Logic logic) {
       for (SubQuery subQuery : subqueryList) {
-        if (node.equalsDeep(subQuery.node, false)) {
+        if (node.equalsDeep(subQuery.node, Litmus.IGNORE)) {
           return;
         }
       }
@@ -4033,7 +4031,7 @@ public class SqlToRelConverter {
 
     SubQuery getSubquery(SqlNode expr) {
       for (SubQuery subQuery : subqueryList) {
-        if (expr.equalsDeep(subQuery.node, false)) {
+        if (expr.equalsDeep(subQuery.node, Litmus.IGNORE)) {
           return subQuery;
         }
       }
@@ -4663,7 +4661,7 @@ public class SqlToRelConverter {
     public int lookupGroupExpr(SqlNode expr) {
       for (int i = 0; i < groupExprs.size(); i++) {
         SqlNode groupExpr = groupExprs.get(i);
-        if (expr.equalsDeep(groupExpr, false)) {
+        if (expr.equalsDeep(groupExpr, Litmus.IGNORE)) {
           return i;
         }
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
index 32d3b6b..54398a6 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -58,7 +58,6 @@ import org.apache.calcite.util.ImmutableIntList;
 import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.NlsString;
 import org.apache.calcite.util.Pair;
-import org.apache.calcite.util.Stacks;
 import org.apache.calcite.util.Static;
 import org.apache.calcite.util.Util;
 import org.apache.calcite.util.mapping.Mapping;
@@ -73,7 +72,9 @@ import com.google.common.collect.Lists;
 
 import java.math.BigDecimal;
 import java.util.AbstractList;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
+import java.util.Deque;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -118,7 +119,7 @@ public class RelBuilder {
   private final RelFactories.CorrelateFactory correlateFactory;
   private final RelFactories.ValuesFactory valuesFactory;
   private final RelFactories.TableScanFactory scanFactory;
-  private final List<Frame> stack = new ArrayList<>();
+  private final Deque<Frame> stack = new ArrayDeque<>();
 
   protected RelBuilder(Context context, RelOptCluster cluster,
       RelOptSchema relOptSchema) {
@@ -210,7 +211,7 @@ public class RelBuilder {
    * you need to use previously built expressions as inputs, call
    * {@link #build()} to pop those inputs. */
   public RelBuilder push(RelNode node) {
-    Stacks.push(stack, new Frame(node));
+    stack.push(new Frame(node));
     return this;
   }
 
@@ -227,25 +228,25 @@ public class RelBuilder {
    * <p>Throws if the stack is empty.
    */
   public RelNode build() {
-    return Stacks.pop(stack).rel;
+    return stack.pop().rel;
   }
 
   /** Returns the relational expression at the top of the stack, but does not
    * remove it. */
   public RelNode peek() {
-    return Stacks.peek(stack).rel;
+    return stack.peek().rel;
   }
 
   /** Returns the relational expression {@code n} positions from the top of the
    * stack, but does not remove it. */
   public RelNode peek(int n) {
-    return Stacks.peek(n, stack).rel;
+    return Iterables.get(stack, n).rel;
   }
 
   /** Returns the relational expression {@code n} positions from the top of the
    * stack, but does not remove it. */
   public RelNode peek(int inputCount, int inputOrdinal) {
-    return Stacks.peek(inputCount - 1 - inputOrdinal, stack).rel;
+    return peek(inputCount - 1 - inputOrdinal);
   }
 
   // Methods that return scalar expressions
@@ -333,7 +334,7 @@ public class RelBuilder {
   public RexNode field(String alias, String fieldName) {
     Preconditions.checkNotNull(alias);
     Preconditions.checkNotNull(fieldName);
-    final Frame frame = Stacks.peek(stack);
+    final Frame frame = stack.peek();
     final List<String> aliases = new ArrayList<>();
     int offset = 0;
     for (Pair<String, RelDataType> pair : frame.right) {
@@ -701,9 +702,9 @@ public class RelBuilder {
       return empty();
     }
     if (!x.isAlwaysTrue()) {
-      final Frame frame = Stacks.pop(stack);
+      final Frame frame = stack.pop();
       final RelNode filter = filterFactory.createFilter(frame.rel, x);
-      Stacks.push(stack, new Frame(filter, frame.right));
+      stack.push(new Frame(filter, frame.right));
     }
     return this;
   }
@@ -1009,8 +1010,8 @@ public class RelBuilder {
    * variables. */
   public RelBuilder join(JoinRelType joinType, RexNode condition,
       Set<CorrelationId> variablesSet) {
-    final Frame right = Stacks.pop(stack);
-    final Frame left = Stacks.pop(stack);
+    final Frame right = stack.pop();
+    final Frame left = stack.pop();
     final RelNode join;
     final boolean correlate = variablesSet.size() == 1;
     if (correlate) {
@@ -1030,7 +1031,7 @@ public class RelBuilder {
     final List<Pair<String, RelDataType>> pairs = new ArrayList<>();
     pairs.addAll(left.right);
     pairs.addAll(right.right);
-    Stacks.push(stack, new Frame(join, ImmutableList.copyOf(pairs)));
+    stack.push(new Frame(join, ImmutableList.copyOf(pairs)));
     if (correlate) {
       filter(condition);
     }
@@ -1059,11 +1060,11 @@ public class RelBuilder {
 
   /** Creates a {@link org.apache.calcite.rel.core.SemiJoin}. */
   public RelBuilder semiJoin(Iterable<? extends RexNode> conditions) {
-    final Frame right = Stacks.pop(stack);
-    final Frame left = Stacks.pop(stack);
+    final Frame right = stack.pop();
+    final Frame left = stack.pop();
     final RelNode semiJoin =
         semiJoinFactory.createSemiJoin(left.rel, right.rel, and(conditions));
-    Stacks.push(stack, new Frame(semiJoin, left.right));
+    stack.push(new Frame(semiJoin, left.right));
     return this;
   }
 
@@ -1074,8 +1075,8 @@ public class RelBuilder {
 
   /** Assigns a table alias to the top entry on the stack. */
   public RelBuilder as(String alias) {
-    final Frame pair = Stacks.pop(stack);
-    Stacks.push(stack,
+    final Frame pair = stack.pop();
+    stack.push(
         new Frame(pair.rel,
             ImmutableList.of(Pair.of(alias, pair.rel.getRowType()))));
     return this;
@@ -1172,7 +1173,7 @@ public class RelBuilder {
    * schema.
    */
   public RelBuilder empty() {
-    final Frame frame = Stacks.pop(stack);
+    final Frame frame = stack.pop();
     return values(frame.rel.getRowType());
   }
 
@@ -1309,7 +1310,7 @@ public class RelBuilder {
       if (top instanceof Sort) {
         final Sort sort2 = (Sort) top;
         if (sort2.offset == null && sort2.fetch == null) {
-          Stacks.pop(stack);
+          stack.pop();
           push(sort2.getInput());
           final RelNode sort =
               sortFactory.createSort(build(), sort2.collation,
@@ -1323,7 +1324,7 @@ public class RelBuilder {
         if (project.getInput() instanceof Sort) {
           final Sort sort2 = (Sort) project.getInput();
           if (sort2.offset == null && sort2.fetch == null) {
-            Stacks.pop(stack);
+            stack.pop();
             push(sort2.getInput());
             final RelNode sort =
                 sortFactory.createSort(build(), sort2.collation,
@@ -1421,7 +1422,7 @@ public class RelBuilder {
   }
 
   protected String getAlias() {
-    final Frame frame = Stacks.peek(stack);
+    final Frame frame = stack.peek();
     return frame.right.size() == 1
         ? frame.right.get(0).left
         : null;

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/util/PartiallyOrderedSet.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/PartiallyOrderedSet.java b/core/src/main/java/org/apache/calcite/util/PartiallyOrderedSet.java
index 200e1c9..b73a257 100644
--- a/core/src/main/java/org/apache/calcite/util/PartiallyOrderedSet.java
+++ b/core/src/main/java/org/apache/calcite/util/PartiallyOrderedSet.java
@@ -18,15 +18,16 @@ package org.apache.calcite.util;
 
 import java.util.AbstractList;
 import java.util.AbstractSet;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Set;
 
 /**
@@ -102,8 +103,8 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
   private PartiallyOrderedSet(Ordering<E> ordering, Map<E, Node<E>> map) {
     this.ordering = ordering;
     this.map = map;
-    this.topNode = new TopBottomNode<E>(true);
-    this.bottomNode = new TopBottomNode<E>(false);
+    this.topNode = new TopBottomNode<>(true);
+    this.bottomNode = new TopBottomNode<>(false);
     this.topNode.childList.add(bottomNode);
     this.bottomNode.parentList.add(topNode);
   }
@@ -186,7 +187,7 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
     Set<Node<E>> parents = findParents(e);
     Set<Node<E>> children = findChildren(e);
 
-    node = new Node<E>(e);
+    node = new Node<>(e);
 
     for (Node<E> parent : parents) {
       node.parentList.add(parent);
@@ -213,7 +214,7 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
     }
 
     // Nodes reachable from parents.
-    final Set<Node<E>> childSet = new HashSet<Node<E>>(node.childList);
+    final Set<Node<E>> childSet = new HashSet<>(node.childList);
     for (Node<E> child : children) {
       if (!isDescendantOfAny(child, childSet)) {
         node.childList.add(child);
@@ -239,8 +240,8 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
   private boolean isDescendantOfAny(
       Node<E> node,
       Set<Node<E>> nodeSet) {
-    final ArrayDeque<Node<E>> deque = new ArrayDeque<Node<E>>();
-    final Set<Node<E>> seen = new HashSet<Node<E>>();
+    final Deque<Node<E>> deque = new ArrayDeque<>();
+    final Set<Node<E>> seen = new HashSet<>();
     deque.add(node);
     while (!deque.isEmpty()) {
       final Node<E> node1 = deque.pop();
@@ -257,22 +258,22 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
   }
 
   private Set<Node<E>> findChildren(E e) {
-    ArrayDeque<Node<E>> descendants = new ArrayDeque<Node<E>>();
+    final Deque<Node<E>> descendants = new ArrayDeque<>();
     descendants.add(bottomNode);
     return findParentsChildren(e, descendants, false);
   }
 
   private Set<Node<E>> findParents(E e) {
-    ArrayDeque<Node<E>> ancestors = new ArrayDeque<Node<E>>();
+    final Deque<Node<E>> ancestors = new ArrayDeque<>();
     ancestors.add(topNode);
     return findParentsChildren(e, ancestors, true);
   }
 
   private Set<Node<E>> findParentsChildren(
       E e,
-      ArrayDeque<Node<E>> ancestors,
+      Deque<Node<E>> ancestors,
       boolean up) {
-    final Set<Node<E>> parents = new HashSet<Node<E>>();
+    final Set<Node<E>> parents = new HashSet<>();
     while (!ancestors.isEmpty()) {
       final Node<E> ancestor = ancestors.pop();
       assert ancestor.e == null
@@ -400,8 +401,7 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
         }
       }
     }
-    final Map<Node, Integer> distanceToRoot =
-        new HashMap<Node, Integer>();
+    final Map<Node, Integer> distanceToRoot = new HashMap<>();
     distanceRecurse(distanceToRoot, topNode, 0);
     for (Node<E> node : map.values()) {
       if (!distanceToRoot.containsKey(node)) {
@@ -412,15 +412,11 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
 
     // For each pair of elements, ensure that elements are related if and
     // only if they are in the ancestors or descendants lists.
-    Map<Node<E>, Set<E>> nodeAncestors = new HashMap<Node<E>, Set<E>>();
-    Map<Node<E>, Set<E>> nodeDescendants = new HashMap<Node<E>, Set<E>>();
+    final Map<Node<E>, Set<E>> nodeAncestors = new HashMap<>();
+    final Map<Node<E>, Set<E>> nodeDescendants = new HashMap<>();
     for (Node<E> node : map.values()) {
-      nodeAncestors.put(
-          node,
-          new HashSet<E>(getAncestors(node.e)));
-      nodeDescendants.put(
-          node,
-          new HashSet<E>(getDescendants(node.e)));
+      nodeAncestors.put(node, new HashSet<>(getAncestors(node.e)));
+      nodeDescendants.put(node, new HashSet<>(getDescendants(node.e)));
     }
     for (Node<E> node1 : map.values()) {
       for (Node<E> node2 : map.values()) {
@@ -504,8 +500,8 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
 
     // breadth-first search, to iterate over every element once, printing
     // those nearest the top element first
-    final HashSet<E> seen = new HashSet<E>();
-    final ArrayDeque<E> unseen = new ArrayDeque<E>();
+    final Set<E> seen = new HashSet<>();
+    final Deque<E> unseen = new ArrayDeque<>();
     unseen.addAll(getNonChildren());
     while (!unseen.isEmpty()) {
       E e = unseen.pop();
@@ -549,7 +545,7 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
       // children
       return Collections.emptyList();
     } else {
-      return new StripList<E>(node.childList);
+      return new StripList<>(node.childList);
     }
   }
 
@@ -574,7 +570,7 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
       // parents
       return Collections.emptyList();
     } else {
-      return new StripList<E>(node.parentList);
+      return new StripList<>(node.parentList);
     }
   }
 
@@ -583,7 +579,7 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
         && topNode.childList.get(0).e == null) {
       return Collections.emptyList();
     }
-    return new StripList<E>(topNode.childList);
+    return new StripList<>(topNode.childList);
   }
 
   public List<E> getNonParents() {
@@ -591,7 +587,7 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
         && bottomNode.parentList.get(0).e == null) {
       return Collections.emptyList();
     }
-    return new StripList<E>(bottomNode.parentList);
+    return new StripList<>(bottomNode.parentList);
   }
 
   @Override public void clear() {
@@ -639,10 +635,10 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
     if (c.size() == 1 && c.iterator().next().e == null) {
       return Collections.emptyList();
     }
-    ArrayDeque<Node<E>> deque = new ArrayDeque<Node<E>>(c);
+    final Deque<Node<E>> deque = new ArrayDeque<>(c);
 
-    final Set<Node<E>> seen = new HashSet<Node<E>>();
-    final List<E> list = new ArrayList<E>();
+    final Set<Node<E>> seen = new HashSet<>();
+    final List<E> list = new ArrayList<>();
     while (!deque.isEmpty()) {
       Node<E> node1 = deque.pop();
       list.add(node1.e);
@@ -670,8 +666,8 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
    * @param <E> Element type
    */
   private static class Node<E> {
-    final List<Node<E>> parentList = new ArrayList<Node<E>>();
-    final List<Node<E>> childList = new ArrayList<Node<E>>();
+    final List<Node<E>> parentList = new ArrayList<>();
+    final List<Node<E>> childList = new ArrayList<>();
     final E e;
 
     public Node(E e) {
@@ -750,87 +746,6 @@ public class PartiallyOrderedSet<E> extends AbstractSet<E> {
       return list.size();
     }
   }
-
-  /**
-   * Cut-down version of java.util.ArrayDeque, which is not available until
-   * JDK 1.6.
-   *
-   * @param <E> Element type
-   */
-  private static class ArrayDeque<E> {
-    private E[] es; // length must be multiple of 2
-    private int first;
-    private int last;
-
-    public ArrayDeque() {
-      this(16);
-    }
-
-    public ArrayDeque(Collection<E> nodes) {
-      this(nextPowerOf2(nodes.size()));
-      addAll(nodes);
-    }
-
-    private ArrayDeque(int capacity) {
-      first = last = 0;
-      //noinspection unchecked
-      es = (E[]) new Object[capacity];
-    }
-
-    private static int nextPowerOf2(int v) {
-      // Algorithm from
-      // http://graphics.stanford.edu/~seander/bithacks.html
-      v--;
-      v |= v >> 1;
-      v |= v >> 2;
-      v |= v >> 4;
-      v |= v >> 8;
-      v |= v >> 16;
-      v++;
-      return v;
-    }
-
-    @SuppressWarnings({"SuspiciousSystemArraycopy", "unchecked" })
-    private void expand() {
-      Object[] olds = es;
-      es = (E[]) new Object[es.length * 2];
-      System.arraycopy(olds, 0, es, 0, olds.length);
-      if (last <= first) {
-        final int x = last & (olds.length - 1);
-        System.arraycopy(olds, 0, es, olds.length, x);
-        last += olds.length;
-      }
-    }
-
-    public void add(E e) {
-      es[last] = e;
-      last = (last + 1) & (es.length - 1);
-      if (last == first) {
-        expand();
-      }
-    }
-
-    public boolean isEmpty() {
-      return last == first;
-    }
-
-
-    public E pop() {
-      if (last == first) {
-        throw new NoSuchElementException();
-      }
-      E e = es[first];
-      first = (first + 1) & (es.length - 1);
-      return e;
-    }
-
-
-    public void addAll(Collection<E> list) {
-      for (E e : list) {
-        add(e);
-      }
-    }
-  }
 }
 
 // End PartiallyOrderedSet.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/util/StackWriter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/StackWriter.java b/core/src/main/java/org/apache/calcite/util/StackWriter.java
index da2295c..3e42f50 100644
--- a/core/src/main/java/org/apache/calcite/util/StackWriter.java
+++ b/core/src/main/java/org/apache/calcite/util/StackWriter.java
@@ -20,8 +20,8 @@ import java.io.FilterWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.ArrayDeque;
+import java.util.Deque;
 
 /**
  * A helper class for generating formatted text. StackWriter keeps track of
@@ -106,7 +106,7 @@ public class StackWriter extends FilterWriter {
   private int indentationDepth;
   private String indentation;
   private boolean needIndent;
-  private final List<Character> quoteStack = new ArrayList<Character>();
+  private final Deque<Character> quoteStack = new ArrayDeque<>();
 
   //~ Constructors -----------------------------------------------------------
 
@@ -149,11 +149,12 @@ public class StackWriter extends FilterWriter {
 
   private void pushQuote(Character quoteChar) throws IOException {
     writeQuote(quoteChar);
-    Stacks.push(quoteStack, quoteChar);
+    quoteStack.push(quoteChar);
   }
 
   private void popQuote(Character quoteChar) throws IOException {
-    Stacks.pop(quoteStack, quoteChar);
+    final Character pop = quoteStack.pop();
+    assert pop == quoteChar;
     writeQuote(quoteChar);
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/util/Stacks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/Stacks.java b/core/src/main/java/org/apache/calcite/util/Stacks.java
index 2a41368..408747f 100644
--- a/core/src/main/java/org/apache/calcite/util/Stacks.java
+++ b/core/src/main/java/org/apache/calcite/util/Stacks.java
@@ -21,6 +21,7 @@ import java.util.List;
 /**
  * Utilities to make vanilla lists look like stacks.
  */
+@Deprecated // to be removed before 2.0
 public class Stacks {
   private Stacks() {
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/main/java/org/apache/calcite/util/XmlOutput.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/XmlOutput.java b/core/src/main/java/org/apache/calcite/util/XmlOutput.java
index 4be5669..9392b5a 100644
--- a/core/src/main/java/org/apache/calcite/util/XmlOutput.java
+++ b/core/src/main/java/org/apache/calcite/util/XmlOutput.java
@@ -23,9 +23,10 @@ import java.io.LineNumberReader;
 import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.Writer;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.List;
+import java.util.Deque;
 
 /**
  * Streaming XML output.
@@ -42,7 +43,7 @@ public class XmlOutput {
   private final PrintWriter out;
 
   // The tagStack is maintained to check that tags are balanced.
-  private final List<String> tagStack = new ArrayList<String>();
+  private final Deque<String> tagStack = new ArrayDeque<>();
 
   // The class maintains an indentation level to improve output quality.
   private int indent;
@@ -210,7 +211,7 @@ public class XmlOutput {
       out.println(">");
     }
     out.flush();
-    Stacks.push(tagStack, tagName);
+    tagStack.push(tagName);
     indent++;
     tagsWritten++;
   }
@@ -245,7 +246,8 @@ public class XmlOutput {
    */
   public void endTag(String tagName) {
     // Check that the end tag matches the corresponding start tag
-    Stacks.pop(tagStack, tagName);
+    String x = tagStack.pop();
+    assert x.equals(tagName);
 
     // Lower the indent and display the end tag
     indent--;

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java
index 26df28d..f66fd86 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlPrettyWriterTest.java
@@ -24,7 +24,9 @@ import org.apache.calcite.sql.parser.SqlParseException;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql.pretty.SqlPrettyWriter;
 import org.apache.calcite.test.DiffRepository;
+import org.apache.calcite.util.Litmus;
 
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.io.PrintWriter;
@@ -88,7 +90,7 @@ public class SqlPrettyWriterTest {
     // to the original.
     final String actual2 = actual.replaceAll("`", "\"");
     final SqlNode node2 = parseQuery(actual2);
-    assertTrue(node.equalsDeep(node2, true));
+    assertTrue(node.equalsDeep(node2, Litmus.THROW));
   }
 
   protected void assertExprPrintsTo(
@@ -111,7 +113,7 @@ public class SqlPrettyWriterTest {
     // to the original.
     final String actual2 = actual.replaceAll("`", "\"");
     final SqlNode valuesCall2 = parseQuery("VALUES (" + actual2 + ")");
-    assertTrue(valuesCall.equalsDeep(valuesCall2, true));
+    assertTrue(valuesCall.equalsDeep(valuesCall2, Litmus.THROW));
   }
 
   // ~ Tests ----------------------------------------------------------------
@@ -214,8 +216,8 @@ public class SqlPrettyWriterTest {
     checkSimple(prettyWriter, "${desc}", "${formatted}");
   }
 
-  // test disabled because default SQL parser cannot parse DDL
-  public void _testExplain() {
+  @Ignore("default SQL parser cannot parse DDL")
+  @Test public void testExplain() {
     assertPrintsTo(false, "explain select * from t", "foo");
   }
 
@@ -286,7 +288,7 @@ public class SqlPrettyWriterTest {
             + "union select * from w "
             + "order by a, b",
 
-        // todo: SELECT should not be indended from UNION, like this:
+        // todo: SELECT should not be indented from UNION, like this:
         // UNION
         //     SELECT *
         //     FROM `W`

http://git-wip-us.apache.org/repos/asf/calcite/blob/f55d10c1/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
index 529df04..f8f68d0 100644
--- a/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
+++ b/core/src/test/java/org/apache/calcite/test/MockCatalogReader.java
@@ -65,6 +65,7 @@ import org.apache.calcite.sql.validate.SqlValidatorCatalogReader;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.calcite.util.ImmutableIntList;
+import org.apache.calcite.util.Litmus;
 import org.apache.calcite.util.Pair;
 import org.apache.calcite.util.Util;
 
@@ -439,9 +440,7 @@ public class MockCatalogReader implements Prepare.CatalogReader {
   }
 
   public RelDataType getNamedType(SqlIdentifier typeName) {
-    if (typeName.equalsDeep(
-        addressType.getSqlIdentifier(),
-        false)) {
+    if (typeName.equalsDeep(addressType.getSqlIdentifier(), Litmus.IGNORE)) {
       return addressType;
     } else {
       return null;