有四个必须条件需要同时满足。
- 根节点的类型是一个 query,或者 explain,或者 create table as select,或者 materializedView。
- 操作类型的判断条件:根节点的类型是 query,或者 create table as select,或者 materializedView;或者操作是 insert,或者多路 insert。
- 不包含以下关键字:
- canHandleQbForCbo 返回 null。
boolean canCBOHandleAst(ASTNode ast, QB qb, PreCboCtx cboCtx) {
int root = ast.getToken().getType();
boolean needToLogMessage = STATIC_LOG.isInfoEnabled();
boolean isSupportedRoot = root == HiveParser.TOK_QUERY || root == HiveParser.TOK_EXPLAIN
|| qb.isCTAS() || qb.isMaterializedView();
// Queries without a source table currently are not supported by CBO
boolean isSupportedType = (qb.getIsQuery())
|| qb.isCTAS() || qb.isMaterializedView() || cboCtx.type == PreCboCtx.Type.INSERT
|| cboCtx.type == PreCboCtx.Type.MULTI_INSERT;
boolean noBadTokens = HiveCalciteUtil.validateASTForUnsupportedTokens(ast);
boolean result = isSupportedRoot && isSupportedType && noBadTokens;
if (!result) {
if (needToLogMessage) {
String msg = "";
if (!isSupportedRoot) {
msg += "doesn't have QUERY or EXPLAIN as root and not a CTAS; ";
}
if (!isSupportedType) {
msg += "is not a query with at least one source table "
+ " or there is a subquery without a source table, or CTAS, or insert; ";
}
if (!noBadTokens) {
msg += "has unsupported tokens; ";
}
if (msg.isEmpty()) {
msg += "has some unspecified limitations; ";
}
STATIC_LOG.info("Not invoking CBO because the statement "
+ msg.substring(0, msg.length() - 2));
}
return false;
}
// Now check QB in more detail. canHandleQbForCbo returns null if query can
// be handled.
String msg = CalcitePlanner.canHandleQbForCbo(queryProperties, conf, true, needToLogMessage, qb);
if (msg == null) {
return true;
}
if (needToLogMessage) {
STATIC_LOG.info("Not invoking CBO because the statement "
+ msg.substring(0, msg.length() - 2));
}
return false;
validateASTForUnsupportedTokens
public static boolean validateASTForUnsupportedTokens(ASTNode ast) {
if (ParseUtils.containsTokenOfType(ast, HiveParser.TOK_CHARSETLITERAL, HiveParser.TOK_TABLESPLITSAMPLE)) {
return false;
} else {
return true;
}
}
canHandleQbForCbo
static String canHandleQbForCbo(QueryProperties queryProperties, HiveConf conf,
boolean topLevelQB, boolean verbose, QB qb) {
if (!queryProperties.hasClusterBy() && !queryProperties.hasDistributeBy()
&& !queryProperties.hasSortBy() && !queryProperties.hasPTF() && !queryProperties.usesscript()
&& queryProperties.isCBOSupportedLateralViews()) {
// Ok to run CBO.
return null;
}
// Not ok to run CBO, build error message.
String msg = "";
if (verbose) {
if (queryProperties.hasClusterBy())
msg += "has cluster by; ";
if (queryProperties.hasDistributeBy())
msg += "has distribute by; ";
if (queryProperties.hasSortBy())
msg += "has sort by; ";
if (queryProperties.hasPTF())
msg += "has PTF; ";
if (queryProperties.usesscript())
msg += "uses scripts; ";
if (queryProperties.hasLateralViews())
msg += "has lateral views; ";
if (msg.isEmpty())
msg += "has some unspecified limitations; ";
}
return msg;
}



