diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/HiveCalciteUtil.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/HiveCalciteUtil.java index a3b1790c10b2da6070e70d94a31000a35609da92..8458be4d56fb3a4520e152ed1d7715565a61ea06 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/HiveCalciteUtil.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/HiveCalciteUtil.java @@ -17,13 +17,15 @@ */ package org.apache.hadoop.hive.ql.optimizer.calcite; +import java.util.List; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Queue; +import java.util.Set; import java.util.HashSet; -import java.util.List; import java.util.Map; +import java.util.HashMap; + import java.util.Map.Entry; -import java.util.Set; import org.apache.calcite.plan.RelOptUtil; import org.apache.calcite.plan.RelOptUtil.InputReferencedVisitor; @@ -50,6 +52,7 @@ import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.Pair; import org.apache.calcite.util.Util; +import org.apache.hadoop.hive.ql.lib.Node; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveJoin; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveProject; import org.apache.hadoop.hive.ql.parse.ASTNode; @@ -59,6 +62,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import org.eclipse.jetty.util.ArrayQueue; /** * Generic utility functions needed for Calcite based Hive CBO. @@ -87,14 +91,29 @@ } public static boolean validateASTForUnsupportedTokens(ASTNode ast) { - String astTree = ast.toStringTree(); - // if any of following tokens are present in AST, bail out - String[] tokens = { "TOK_CHARSETLITERAL", "TOK_TABLESPLITSAMPLE" }; - for (String token : tokens) { - if (astTree.contains(token)) { + Queue fringe = new ArrayQueue(); + Set unsupportedTokens = new HashSet() { + { + add("TOK_CHARSETLITERAL"); + add("TOK_TABLESPLITSAMPLE"); + } + }; + + // Flat-DFS. + fringe.add(ast); + while (!fringe.isEmpty()) { + ASTNode current = fringe.remove(); + if (current.getChildCount() > 0) { + for (Node child : current.getChildren()) { + fringe.add((ASTNode) child); + } + } + + if (unsupportedTokens.contains(current.getText())) { return false; } } + return true; }