This is an automated email from the ASF dual-hosted git repository. lihaopeng pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 5515a4aac06 [opt](plsql) Fix plsql exception and doris exception compatibility (#31647) 5515a4aac06 is described below commit 5515a4aac06a72de79d76ec16bf158d599eb97a0 Author: Xinyi Zou <zouxiny...@gmail.com> AuthorDate: Fri Mar 1 18:44:23 2024 +0800 [opt](plsql) Fix plsql exception and doris exception compatibility (#31647) --- .../main/java/org/apache/doris/plsql/Console.java | 8 +++- .../src/main/java/org/apache/doris/plsql/Exec.java | 44 +++++++++++++-------- .../src/main/java/org/apache/doris/plsql/Stmt.java | 8 ++-- .../doris/plsql/executor/PlSqlOperation.java | 46 ++++++++++++---------- .../apache/doris/plsql/executor/PlsqlResult.java | 35 +++++++++------- .../org/apache/doris/qe/MysqlConnectProcessor.java | 2 +- 6 files changed, 84 insertions(+), 59 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/plsql/Console.java b/fe/fe-core/src/main/java/org/apache/doris/plsql/Console.java index 024ea356759..91cc0988652 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/plsql/Console.java +++ b/fe/fe-core/src/main/java/org/apache/doris/plsql/Console.java @@ -20,6 +20,8 @@ package org.apache.doris.plsql; +import org.apache.doris.common.ErrorCode; + public interface Console { void print(String msg); @@ -27,7 +29,7 @@ public interface Console { void printError(String msg); - void flushConsole(); + void printError(ErrorCode errorCode, String msg); Console STANDARD = new Console() { @Override @@ -46,6 +48,8 @@ public interface Console { } @Override - public void flushConsole() {} + public void printError(ErrorCode errorCode, String msg) { + System.err.println(errorCode.toString() + ", " + msg); + } }; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/plsql/Exec.java b/fe/fe-core/src/main/java/org/apache/doris/plsql/Exec.java index 34e84ab4097..3caf8181ff0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/plsql/Exec.java +++ b/fe/fe-core/src/main/java/org/apache/doris/plsql/Exec.java @@ -20,6 +20,7 @@ package org.apache.doris.plsql; +import org.apache.doris.common.ErrorCode; import org.apache.doris.nereids.PLLexer; import org.apache.doris.nereids.PLParser; import org.apache.doris.nereids.PLParser.Allocate_cursor_stmtContext; @@ -150,6 +151,8 @@ import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.io.ByteArrayInputStream; import java.io.Closeable; @@ -176,6 +179,7 @@ import java.util.stream.Collectors; * PL/SQL script executor */ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> implements Closeable { + private static final Logger LOG = LogManager.getLogger(Exec.class); public static final String VERSION = "PL/SQL 0.1"; public static final String ERRORCODE = "ERRORCODE"; @@ -839,6 +843,8 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> init(); try { parseAndEval(arguments); + } catch (Exception e) { + exec.signal(e); } finally { close(); } @@ -901,8 +907,6 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> */ public void init() { enterGlobalScope(); - // specify the default log4j2 properties file. - System.setProperty("log4j.configurationFile", "hive-log4j2.properties"); if (conf == null) { conf = new Conf(); } @@ -944,7 +948,7 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> PLParser parser = newParser(tokens); ParseTree tree = parser.program(); if (trace) { - console.printError("Parser tree: " + tree.toStringTree(parser)); + console.printLine("Parser tree: " + tree.toStringTree(parser)); } return tree; } @@ -978,7 +982,7 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> boolean parseArguments(String[] args) { boolean parsed = arguments.parse(args); if (parsed && arguments.hasVersionOption()) { - console.printError(VERSION); + console.printLine(VERSION); return false; } if (!parsed || arguments.hasHelpOption() @@ -1092,13 +1096,24 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> if (sig.type == Signal.Type.VALIDATION) { error(((PlValidationException) sig.exception).getCtx(), sig.exception.getMessage()); } else if (sig.type == Signal.Type.SQLEXCEPTION) { - console.printError("Unhandled exception in PL/SQL. " + ExceptionUtils.getStackTrace(sig.exception)); + LOG.warn(ExceptionUtils.getStackTrace(sig.exception)); + console.printError(ErrorCode.ERR_SP_BAD_SQLSTATE, + "Unhandled exception in PL/SQL. " + sig.exception.toString()); } else if (sig.type == Signal.Type.UNSUPPORTED_OPERATION) { - console.printError(sig.value == null ? "Unsupported operation" : sig.value); + console.printError(ErrorCode.ERR_SP_BAD_SQLSTATE, + sig.value == null ? "Unsupported operation" : sig.value); + } else if (sig.type == Signal.Type.TOO_MANY_ROWS) { + console.printError(ErrorCode.ERR_SP_BAD_SQLSTATE, + sig.value == null ? "Too many rows exception" : sig.value); + } else if (sig.type == Signal.Type.NOTFOUND) { + console.printError(ErrorCode.ERR_SP_FETCH_NO_DATA, + sig.value == null ? "Not found data exception" : sig.value); } else if (sig.exception != null) { - console.printError("HPL/SQL error: " + ExceptionUtils.getStackTrace(sig.exception)); + LOG.warn(ExceptionUtils.getStackTrace(sig.exception)); + console.printError(ErrorCode.ERR_SP_BAD_SQLSTATE, + "PL/SQL error: " + sig.exception.toString()); } else if (sig.value != null) { - console.printError(sig.value); + console.printError(ErrorCode.ERR_SP_BAD_SQLSTATE, sig.value); } else { trace(null, "Signal: " + sig.type); } @@ -1156,14 +1171,9 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> @Override public Integer visitDoris_statement(Doris_statementContext ctx) { Integer rc = exec.stmt.statement(ctx); - if (rc != 0) { - printExceptions(); - throw new RuntimeException(exec.signalPeek().getValue()); - } // Sometimes the query results are not returned to the mysql client, - // such as declare result; select … into result; + // such as `declare result; select … into result;`, not need finalize. resultListener.onFinalize(); - console.flushConsole(); // if running from plsql.sh return rc; } @@ -1793,6 +1803,8 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> } else if (ctx.multipartIdentifier() != null) { functionCall(ctx, ctx.multipartIdentifier(), null); } + } catch (Exception e) { + exec.signal(e); } finally { exec.inCallStmt = false; } @@ -2379,9 +2391,9 @@ public class Exec extends org.apache.doris.nereids.PLParserBaseVisitor<Integer> return; } if (ctx != null) { - console.printError("Ln:" + ctx.getStart().getLine() + " " + message); + console.printLine("Ln:" + ctx.getStart().getLine() + " " + message); } else { - console.printError(message); + console.printLine(message); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/plsql/Stmt.java b/fe/fe-core/src/main/java/org/apache/doris/plsql/Stmt.java index 1567f020701..d86a648b99a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/plsql/Stmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/plsql/Stmt.java @@ -134,11 +134,11 @@ public class Stmt { exec.setSqlSuccess(); if (query.next()) { exec.setSqlCode(SqlCodes.TOO_MANY_ROWS); - exec.signal(Signal.Type.TOO_MANY_ROWS); + exec.signal(Signal.Type.TOO_MANY_ROWS, "too many rows into variables"); } } else { exec.setSqlCode(SqlCodes.NO_DATA_FOUND); - exec.signal(Signal.Type.NOTFOUND); + exec.signal(Signal.Type.NOTFOUND, "no rows into variables"); } } else if (ctx instanceof Doris_statementContext) { // only from visitStatement // Print all results for standalone Statement. @@ -406,7 +406,7 @@ public class Stmt { return 1; } else if (exec.getOffline()) { exec.setSqlCode(SqlCodes.NO_DATA_FOUND); - exec.signal(Signal.Type.NOTFOUND); + exec.signal(Signal.Type.NOTFOUND, "fetch not found data"); return 0; } // Assign values from the row to local variables @@ -590,7 +590,7 @@ public class Stmt { exec.setSqlSuccess(); } else { exec.setSqlCode(SqlCodes.NO_DATA_FOUND); - exec.signal(Signal.Type.NOTFOUND); + exec.signal(Signal.Type.NOTFOUND, "assign from select not found data"); } } catch (QueryException | AnalysisException e) { exec.signal(query); diff --git a/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlSqlOperation.java b/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlSqlOperation.java index b98507c1a41..8c5baf23764 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlSqlOperation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlSqlOperation.java @@ -44,30 +44,34 @@ public class PlSqlOperation { } public void execute(ConnectContext ctx, String statement) { - ctx.setRunProcedure(true); - ctx.setProcedureExec(exec); - result.reset(); try { - Arguments args = new Arguments(); - args.parse(new String[] { "-e", statement }); - exec.parseAndEval(args); - // Exception is not thrown after catch. - // For example, select a not exist table will return empty results, exception - // will put into signals. - exec.printExceptions(); - String error = result.getError(); - String msg = result.getMsg(); - if (!error.isEmpty()) { - ctx.getState().setError("plsql exec error, " + error); - } else if (!msg.isEmpty()) { - ctx.getState().setOk(0, 0, msg); + ctx.setRunProcedure(true); + ctx.setProcedureExec(exec); + result.reset(); + try { + Arguments args = new Arguments(); + args.parse(new String[] {"-e", statement}); + exec.parseAndEval(args); + } catch (Exception e) { + exec.signal(e); + } finally { + // Exception is not thrown after catch. + // For example, select a not exist table will return empty results, exception + // will put into signals. + exec.printExceptions(); + String error = result.getError(); + String msg = result.getMsg(); + if (!error.isEmpty()) { + ctx.getState().setError(result.getLastErrorCode(), error); + } else if (!msg.isEmpty()) { + ctx.getState().setOk(0, 0, msg); + } + ctx.getMysqlChannel().reset(); + ctx.setRunProcedure(false); + ctx.setProcedureExec(null); } - ctx.getMysqlChannel().reset(); - ctx.setRunProcedure(false); - ctx.setProcedureExec(null); } catch (Exception e) { - exec.printExceptions(); - ctx.getState().setError(ErrorCode.ERR_UNKNOWN_ERROR, result.getError() + " " + e.getMessage()); + ctx.getState().setError(ErrorCode.ERR_UNKNOWN_ERROR, e.getMessage()); LOG.warn(e); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlsqlResult.java b/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlsqlResult.java index c632b930a8a..76e600e7fcc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlsqlResult.java +++ b/fe/fe-core/src/main/java/org/apache/doris/plsql/executor/PlsqlResult.java @@ -17,6 +17,7 @@ package org.apache.doris.plsql.executor; +import org.apache.doris.common.ErrorCode; import org.apache.doris.mysql.MysqlEofPacket; import org.apache.doris.mysql.MysqlSerializer; import org.apache.doris.mysql.MysqlServerStatusFlag; @@ -27,11 +28,13 @@ import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ConnectProcessor; import org.apache.doris.qe.QueryState; +import com.google.common.collect.Lists; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.List; // If running from mysql client, first send schema column, // and then send the ByteBuffer through the mysql channel. @@ -44,12 +47,14 @@ public class PlsqlResult implements ResultListener, Console { private Metadata metadata = null; private StringBuilder msg; private StringBuilder error; + private List<ErrorCode> errorCodes; private boolean isSendFields; public PlsqlResult() { this.msg = new StringBuilder(); this.error = new StringBuilder(); this.isSendFields = false; + this.errorCodes = Lists.newArrayList(); } public void reset() { @@ -58,6 +63,7 @@ public class PlsqlResult implements ResultListener, Console { isSendFields = false; error.delete(0, error.length()); msg.delete(0, msg.length()); + errorCodes.clear(); } public void setProcessor(ConnectProcessor processor) { @@ -72,6 +78,14 @@ public class PlsqlResult implements ResultListener, Console { return error.toString(); } + public List<ErrorCode> getErrorCodes() { + return errorCodes; + } + + public ErrorCode getLastErrorCode() { + return errorCodes.isEmpty() ? ErrorCode.ERR_UNKNOWN_ERROR : errorCodes.get(errorCodes.size() - 1); + } + @Override public void onMysqlRow(ByteBuffer rows) { ConnectContext ctx = processor != null ? processor.getConnectContext() : ConnectContext.get(); @@ -106,6 +120,7 @@ public class PlsqlResult implements ResultListener, Console { @Override public void onFinalize() { + // If metadata not null, it means that mysql channel sent query results. if (metadata == null) { return; } @@ -166,24 +181,14 @@ public class PlsqlResult implements ResultListener, Console { @Override public void printError(String msg) { - this.error.append(msg); + errorCodes.add(ErrorCode.ERR_UNKNOWN_ERROR); + this.error.append("\n" + errorCodes.size() + ". " + getLastErrorCode().toString() + ", " + msg); } @Override - public void flushConsole() { - ConnectContext ctx = processor != null ? processor.getConnectContext() : ConnectContext.get(); - boolean needSend = false; - if (error.length() > 0) { - ctx.getState().setError("hplsql exec error, " + error.toString()); - needSend = true; - } else if (msg.length() > 0) { - ctx.getState().setOk(0, 0, msg.toString()); - needSend = true; - } - if (needSend) { - finalizeCommand(); - reset(); - } + public void printError(ErrorCode errorCode, String msg) { + errorCodes.add(errorCode != null ? errorCode : ErrorCode.ERR_UNKNOWN_ERROR); + this.error.append("\n" + errorCodes.size() + ". " + getLastErrorCode().toString() + ", " + msg); } private void finalizeCommand() { diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java index 7e9ec551861..61c93adbf96 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/MysqlConnectProcessor.java @@ -153,7 +153,7 @@ public class MysqlConnectProcessor extends ConnectProcessor { } } catch (Throwable e) { // Catch all throwable. - // If reach here, maybe palo bug. + // If reach here, maybe doris bug. LOG.warn("Process one query failed because unknown reason: ", e); ctx.getState().setError(ErrorCode.ERR_UNKNOWN_ERROR, e.getClass().getSimpleName() + ", msg: " + e.getMessage()); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org