[fix](Nereids) should not fallback to legacy planner when execution failed (#18847)
This commit is contained in:
@ -436,11 +436,13 @@ public class StmtExecutor implements ProfileWriter {
|
||||
executeByNereids(queryId);
|
||||
} catch (NereidsException e) {
|
||||
// try to fall back to legacy planner
|
||||
LOG.warn("nereids cannot process statement\n" + originStmt.originStmt
|
||||
+ "\n because of " + e.getMessage(), e);
|
||||
if (!context.getSessionVariable().enableFallbackToOriginalPlanner) {
|
||||
LOG.warn("Analyze failed. {}", context.getQueryIdentifier(), e);
|
||||
throw e.getException();
|
||||
}
|
||||
LOG.warn("fall back to legacy planner, because: {}", e.getMessage(), e);
|
||||
LOG.info("fall back to legacy planner");
|
||||
parsedStmt = null;
|
||||
context.getState().setNereids(false);
|
||||
executeByLegacy(queryId);
|
||||
@ -483,77 +485,83 @@ public class StmtExecutor implements ProfileWriter {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void executeByNereids(TUniqueId queryId) {
|
||||
private void executeByNereids(TUniqueId queryId) throws Exception {
|
||||
LOG.info("Nereids start to execute query:\n {}", originStmt.originStmt);
|
||||
context.setQueryId(queryId);
|
||||
context.setStartTime();
|
||||
plannerProfile.setQueryBeginTime();
|
||||
context.setStmtId(STMT_ID_GENERATOR.incrementAndGet());
|
||||
try {
|
||||
parseByNereids();
|
||||
Preconditions.checkState(parsedStmt instanceof LogicalPlanAdapter,
|
||||
"Nereids only process LogicalPlanAdapter, but parsedStmt is " + parsedStmt.getClass().getName());
|
||||
context.getState().setNereids(true);
|
||||
LogicalPlan logicalPlan = ((LogicalPlanAdapter) parsedStmt).getLogicalPlan();
|
||||
if (logicalPlan instanceof Command) {
|
||||
if (logicalPlan instanceof Forward) {
|
||||
redirectStatus = ((Forward) logicalPlan).toRedirectStatus();
|
||||
if (isForwardToMaster()) {
|
||||
if (isProxy) {
|
||||
// This is already a stmt forwarded from other FE.
|
||||
// If goes here, which means we can't find a valid Master FE(some error happens).
|
||||
// To avoid endless forward, throw exception here.
|
||||
throw new UserException("The statement has been forwarded to master FE("
|
||||
+ Env.getCurrentEnv().getSelfNode().getIp() + ") and failed to execute"
|
||||
+ " because Master FE is not ready. You may need to check FE's status");
|
||||
}
|
||||
forwardToMaster();
|
||||
if (masterOpExecutor != null && masterOpExecutor.getQueryId() != null) {
|
||||
context.setQueryId(masterOpExecutor.getQueryId());
|
||||
}
|
||||
return;
|
||||
parseByNereids();
|
||||
Preconditions.checkState(parsedStmt instanceof LogicalPlanAdapter,
|
||||
"Nereids only process LogicalPlanAdapter, but parsedStmt is " + parsedStmt.getClass().getName());
|
||||
context.getState().setNereids(true);
|
||||
LogicalPlan logicalPlan = ((LogicalPlanAdapter) parsedStmt).getLogicalPlan();
|
||||
if (logicalPlan instanceof Command) {
|
||||
if (logicalPlan instanceof Forward) {
|
||||
redirectStatus = ((Forward) logicalPlan).toRedirectStatus();
|
||||
if (isForwardToMaster()) {
|
||||
if (isProxy) {
|
||||
// This is already a stmt forwarded from other FE.
|
||||
// If goes here, which means we can't find a valid Master FE(some error happens).
|
||||
// To avoid endless forward, throw exception here.
|
||||
throw new NereidsException(new UserException("The statement has been forwarded to master FE("
|
||||
+ Env.getCurrentEnv().getSelfNode().getIp() + ") and failed to execute"
|
||||
+ " because Master FE is not ready. You may need to check FE's status"));
|
||||
}
|
||||
forwardToMaster();
|
||||
if (masterOpExecutor != null && masterOpExecutor.getQueryId() != null) {
|
||||
context.setQueryId(masterOpExecutor.getQueryId());
|
||||
}
|
||||
}
|
||||
try {
|
||||
((Command) logicalPlan).run(context, this);
|
||||
} catch (QueryStateException e) {
|
||||
LOG.warn("", e);
|
||||
context.setState(e.getQueryState());
|
||||
} catch (UserException e) {
|
||||
// Return message to info client what happened.
|
||||
LOG.warn("DDL statement({}) process failed.", originStmt.originStmt, e);
|
||||
context.getState().setError(e.getMysqlErrorCode(), e.getMessage());
|
||||
} catch (Exception e) {
|
||||
// Maybe our bug
|
||||
LOG.warn("DDL statement(" + originStmt.originStmt + ") process failed.", e);
|
||||
context.getState().setError(ErrorCode.ERR_UNKNOWN_ERROR, "Unexpected exception: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
context.getState().setIsQuery(true);
|
||||
if (context.getSessionVariable().enableProfile) {
|
||||
ConnectContext.get().setStatsErrorEstimator(new StatsErrorEstimator());
|
||||
}
|
||||
// create plan
|
||||
planner = new NereidsPlanner(statementContext);
|
||||
planner.plan(parsedStmt, context.getSessionVariable().toThrift());
|
||||
if (checkBlockRules()) {
|
||||
return;
|
||||
}
|
||||
plannerProfile.setQueryPlanFinishTime();
|
||||
handleQueryWithRetry(queryId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NereidsException(new AnalysisException("Unexpected exception: " + e.getMessage(), e));
|
||||
try {
|
||||
((Command) logicalPlan).run(context, this);
|
||||
} catch (QueryStateException e) {
|
||||
LOG.warn("", e);
|
||||
context.setState(e.getQueryState());
|
||||
throw new NereidsException(e);
|
||||
} catch (UserException e) {
|
||||
// Return message to info client what happened.
|
||||
LOG.warn("DDL statement({}) process failed.", originStmt.originStmt, e);
|
||||
context.getState().setError(e.getMysqlErrorCode(), e.getMessage());
|
||||
throw new NereidsException("DDL statement(" + originStmt.originStmt + ") process failed", e);
|
||||
} catch (Exception e) {
|
||||
// Maybe our bug
|
||||
LOG.warn("DDL statement(" + originStmt.originStmt + ") process failed.", e);
|
||||
context.getState().setError(ErrorCode.ERR_UNKNOWN_ERROR, "Unexpected exception: " + e.getMessage());
|
||||
throw new NereidsException("DDL statement(" + originStmt.originStmt + ") process failed.", e);
|
||||
}
|
||||
} else {
|
||||
context.getState().setIsQuery(true);
|
||||
if (context.getSessionVariable().enableProfile) {
|
||||
ConnectContext.get().setStatsErrorEstimator(new StatsErrorEstimator());
|
||||
}
|
||||
// create plan
|
||||
planner = new NereidsPlanner(statementContext);
|
||||
try {
|
||||
planner.plan(parsedStmt, context.getSessionVariable().toThrift());
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Nereids plan query failed:\n{}", originStmt.originStmt);
|
||||
throw new NereidsException(new AnalysisException("Unexpected exception: " + e.getMessage(), e));
|
||||
}
|
||||
if (checkBlockRules()) {
|
||||
return;
|
||||
}
|
||||
plannerProfile.setQueryPlanFinishTime();
|
||||
handleQueryWithRetry(queryId);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseByNereids() throws AnalysisException {
|
||||
private void parseByNereids() {
|
||||
if (parsedStmt != null) {
|
||||
return;
|
||||
}
|
||||
List<StatementBase> statements = new NereidsParser().parseSQL(originStmt.originStmt);
|
||||
if (statements.size() <= originStmt.idx) {
|
||||
throw new AnalysisException("Nereids parse failed. Parser get " + statements.size() + " statements,"
|
||||
+ " but we need at least " + originStmt.idx + " statements.");
|
||||
throw new NereidsException(
|
||||
new AnalysisException("Nereids parse failed. Parser get " + statements.size() + " statements,"
|
||||
+ " but we need at least " + originStmt.idx + " statements."));
|
||||
}
|
||||
parsedStmt = statements.get(originStmt.idx);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user