diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index fb43e7d..5d727c0 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -387,8 +387,9 @@ boolean canCBOHandleAst(ASTNode ast, QB qb, PreCboCtx cboCtx) { boolean needToLogMessage = STATIC_LOG.isInfoEnabled(); boolean isSupportedRoot = root == HiveParser.TOK_QUERY || root == HiveParser.TOK_EXPLAIN || qb.isCTAS(); - boolean isSupportedType = qb.getIsQuery() || qb.isCTAS() - || cboCtx.type == PreCboCtx.Type.INSERT; + // Queries without a source table currently are not supported by CBO + boolean isSupportedType = (qb.getIsQuery() && !qb.containsQueryWithoutSourceTable()) + || qb.isCTAS() || cboCtx.type == PreCboCtx.Type.INSERT; boolean noBadTokens = HiveCalciteUtil.validateASTForUnsupportedTokens(ast); boolean result = isSupportedRoot && isSupportedType && getCreateViewDesc() == null && noBadTokens; @@ -400,7 +401,7 @@ boolean canCBOHandleAst(ASTNode ast, QB qb, PreCboCtx cboCtx) { msg += "doesn't have QUERY or EXPLAIN as root and not a CTAS; "; } if (!isSupportedType) { - msg += "is not a query, CTAS, or insert; "; + msg += "is not a query with at least one source table os subquery, CTAS, or insert; "; } if (getCreateViewDesc() != null) { msg += "has create view; "; diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/QB.java ql/src/java/org/apache/hadoop/hive/ql/parse/QB.java index de7b151..7e732f3 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/QB.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/QB.java @@ -437,4 +437,17 @@ public void setInsideView(boolean insideView) { return aliasInsideView; } + /** + * returns true, if the query block contains any query, or subquery without a source table + * Like select current_user(), select current_database() + * @return true, if the query block contains any query without a source table + */ + public boolean containsQueryWithoutSourceTable() { + for (QBExpr qbexpr : aliasToSubq.values()) { + if (qbexpr.containsQueryWithoutSourceTable()) { + return true; + } + } + return aliasToTabs.size()==0 && aliasToSubq.size()==0; + } } diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/QBExpr.java ql/src/java/org/apache/hadoop/hive/ql/parse/QBExpr.java index 32aee48..cccf0f6 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/QBExpr.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/QBExpr.java @@ -120,4 +120,17 @@ public boolean isSimpleSelectQuery() { } return qbexpr1.isSimpleSelectQuery() && qbexpr2.isSimpleSelectQuery(); } + + /** + * returns true, if the query block contains any query, or subquery without a source table + * Like select current_user(), select current_database() + * @return true, if the query block contains any query without a source table + */ + public boolean containsQueryWithoutSourceTable() { + if (qb != null) { + return qb.containsQueryWithoutSourceTable(); + } else { + return qbexpr1.containsQueryWithoutSourceTable() || qbexpr2.containsQueryWithoutSourceTable(); + } + } }