forked from opengaussexamples/examples
add exception
This commit is contained in:
parent
565851cb6c
commit
a4c7aa2acf
|
|
@ -4,9 +4,12 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add exception classes">
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="revise">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/Document/Exception in Oracle" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Document/Exception in Oracle" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/Generator/OpenGaussGenerator.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Generator/OpenGaussGenerator.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/Lexer/OracleLexer.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Lexer/OracleLexer.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/Main.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Main.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/Parser/OracleParser.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Parser/OracleParser.java" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
|
@ -104,13 +107,6 @@
|
|||
<option name="presentableId" value="Default" />
|
||||
<updated>1723106789329</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00028" summary="revise">
|
||||
<created>1725958136981</created>
|
||||
<option name="number" value="00028" />
|
||||
<option name="presentableId" value="LOCAL-00028" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1725958136981</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00029" summary="revise">
|
||||
<created>1725978582486</created>
|
||||
<option name="number" value="00029" />
|
||||
|
|
@ -447,7 +443,14 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1726471382852</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="77" />
|
||||
<task id="LOCAL-00077" summary="revise">
|
||||
<created>1726472321577</created>
|
||||
<option name="number" value="00077" />
|
||||
<option name="presentableId" value="LOCAL-00077" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1726472321577</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="78" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
|
|
@ -485,9 +488,9 @@
|
|||
<MESSAGE value="add Loop ast classes" />
|
||||
<MESSAGE value="add Loop" />
|
||||
<MESSAGE value="add Exception document" />
|
||||
<MESSAGE value="revise" />
|
||||
<MESSAGE value="add exception classes" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="add exception classes" />
|
||||
<MESSAGE value="revise" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="revise" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<watches-manager>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import Exception.GenerateFailedException;
|
|||
import Parser.AST.Delete.DeleteNode;
|
||||
import Parser.AST.Drop.DropNode;
|
||||
import Parser.AST.Drop.DropOptionNode;
|
||||
import Parser.AST.Exception.ExceptionActionNode;
|
||||
import Parser.AST.Exception.ExceptionNode;
|
||||
import Parser.AST.Insert.InsertNode;
|
||||
import Parser.AST.Join.JoinConditionNode;
|
||||
import Parser.AST.Join.JoinSourceTabNode;
|
||||
|
|
@ -70,6 +72,9 @@ public class OpenGaussGenerator {
|
|||
else if (node instanceof LoopNode || node instanceof WhileNode || node instanceof ForNode) {
|
||||
return GenLoopSQL(node);
|
||||
}
|
||||
else if (node instanceof ExceptionNode) {
|
||||
return GenExceptionSQL(node);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new GenerateFailedException("Root node:" + node.getClass() + "(Unsupported node type!)");
|
||||
|
|
@ -135,6 +140,11 @@ public class OpenGaussGenerator {
|
|||
return node.toQueryString();
|
||||
}
|
||||
|
||||
private String GenExceptionSQL(ASTNode node) {
|
||||
visitException(node);
|
||||
return node.toQueryString();
|
||||
}
|
||||
|
||||
private void visitCrt(ASTNode node) {
|
||||
if (node instanceof ColumnNode) {
|
||||
ColumnTypeConvert((ColumnNode) node);
|
||||
|
|
@ -183,6 +193,15 @@ public class OpenGaussGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private void visitException(ASTNode node) {
|
||||
if (node instanceof ExceptionActionNode) {
|
||||
PLConvert(node);
|
||||
}
|
||||
for (ASTNode child : node.getChildren()) {
|
||||
visitException(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitSelect(ASTNode node) {
|
||||
if (node instanceof JoinSourceTabNode) {
|
||||
visitJoin(node);
|
||||
|
|
@ -252,7 +271,7 @@ public class OpenGaussGenerator {
|
|||
if (token.hasType(Token.TokenType.STRING)) {
|
||||
output += token.getValue().replace("'", "");
|
||||
}
|
||||
else if (token.hasType(Token.TokenType.IDENTIFIER)) {
|
||||
else if (token.hasType(Token.TokenType.IDENTIFIER) || token.hasType(Token.TokenType.KEYWORD)) {
|
||||
output += "%";
|
||||
outputObj.add(token);
|
||||
}
|
||||
|
|
@ -260,16 +279,29 @@ public class OpenGaussGenerator {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
List<Token> tokens = new ArrayList<>();
|
||||
tokens.add(new Token(Token.TokenType.KEYWORD, "RAISE"));
|
||||
tokens.add(new Token(Token.TokenType.KEYWORD, "NOTICE"));
|
||||
tokens.add(new Token(Token.TokenType.STRING, "'" + output + "'"));
|
||||
for (Token token: outputObj) {
|
||||
tokens.add(new Token(Token.TokenType.SYMBOL, ","));
|
||||
tokens.add(token);
|
||||
if (!outputObj.isEmpty()) {
|
||||
List<Token> tokens = new ArrayList<>();
|
||||
tokens.add(new Token(Token.TokenType.KEYWORD, "RAISE"));
|
||||
tokens.add(new Token(Token.TokenType.KEYWORD, "NOTICE"));
|
||||
tokens.add(new Token(Token.TokenType.STRING, "'" + output + "'"));
|
||||
for (Token token: outputObj) {
|
||||
tokens.add(new Token(Token.TokenType.SYMBOL, ","));
|
||||
tokens.add(token);
|
||||
}
|
||||
tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
|
||||
node.setTokens(tokens);
|
||||
}
|
||||
tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
|
||||
node.setTokens(tokens);
|
||||
else {
|
||||
List<Token> tokens = new ArrayList<>();
|
||||
tokens.add(new Token(Token.TokenType.KEYWORD, "RAISE"));
|
||||
tokens.add(new Token(Token.TokenType.KEYWORD, "NOTICE"));
|
||||
tokens.add(new Token(Token.TokenType.STRING, "'%'"));
|
||||
tokens.add(new Token(Token.TokenType.SYMBOL, ","));
|
||||
tokens.add(new Token(Token.TokenType.STRING, "'" + output + "'"));
|
||||
tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
|
||||
node.setTokens(tokens);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public class OracleLexer {
|
|||
// Loop
|
||||
, "LOOP", "EXIT", "WHILE", "FOR", "IN", "CONTINUE"
|
||||
// Exception
|
||||
, "EXCEPTION", "SQLERRM", "ZERO_DIVIDE", "INVALID_NUMBER"
|
||||
, "EXCEPTION", "SQLERRM", "ZERO_DIVIDE", "INVALID_NUMBER", "OTHERS"
|
||||
};
|
||||
private static final Pattern TOKEN_PATTERN = Pattern.compile(
|
||||
"(NUMBER\\(.*?\\))|" + // NUMBER() function
|
||||
|
|
|
|||
|
|
@ -45,17 +45,27 @@ public class Main {
|
|||
// " ELSE\n" +
|
||||
// " v_bonus := v_salary * 0.03;\n" +
|
||||
// " END IF;";
|
||||
String sql = "LOOP\n" +
|
||||
" DBMS_OUTPUT.PUT_LINE(v_counter);\n" +
|
||||
" Continue;\n" +
|
||||
" v_counter := v_counter + 1;\n" +
|
||||
" EXIT WHEN v_counter > 10;\n" +
|
||||
" END LOOP;";
|
||||
// String sql = "LOOP\n" +
|
||||
// " DBMS_OUTPUT.PUT_LINE(v_counter);\n" +
|
||||
// " Continue;\n" +
|
||||
// " v_counter := v_counter + 1;\n" +
|
||||
// " EXIT WHEN v_counter > 10;\n" +
|
||||
// " END LOOP;";
|
||||
String sql = "EXCEPTION\n" +
|
||||
" WHEN e_custom_exception THEN\n" +
|
||||
" DBMS_OUTPUT.PUT_LINE('Caught an exception: Custom exception raised');\n" +
|
||||
" WHEN ZERO_DIVIDE THEN\n" +
|
||||
" DBMS_OUTPUT.PUT_LINE('Caught an exception: Division by zero');\n" +
|
||||
" WHEN INVALID_NUMBER THEN\n" +
|
||||
" DBMS_OUTPUT.PUT_LINE('Caught an exception: Invalid number');\n" +
|
||||
" WHEN OTHERS THEN\n" +
|
||||
" DBMS_OUTPUT.PUT_LINE('Caught an exception: ' || SQLERRM);";
|
||||
OracleLexer lexer = new OracleLexer(sql);
|
||||
lexer.printTokens();
|
||||
// OracleParser parser = new OracleParser(lexer);
|
||||
// ASTNode root = parser.parse();
|
||||
ASTNode root = OracleParser.parseLoop(lexer.getTokens());
|
||||
ASTNode root = OracleParser.parseException(lexer.getTokens());
|
||||
// ASTNode root = OracleParser.parseLoop(lexer.getTokens());
|
||||
// ASTNode root = OracleParser.parseIFELSE(lexer.getTokens());
|
||||
// ASTNode root = OracleParser.parseCaseWhen(lexer.getTokens());
|
||||
// ASTNode root = OracleParser.parseJoin(lexer.getTokens());
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import Parser.AST.Drop.DropEndNode;
|
|||
import Parser.AST.Drop.DropObjNameNode;
|
||||
import Parser.AST.Drop.DropNode;
|
||||
import Parser.AST.Drop.DropOptionNode;
|
||||
import Parser.AST.Exception.*;
|
||||
import Parser.AST.IFELSIF.*;
|
||||
import Parser.AST.Insert.InsertDataNode;
|
||||
import Parser.AST.Insert.InsertEndNode;
|
||||
|
|
@ -849,6 +850,122 @@ public class OracleParser {
|
|||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception
|
||||
* For example: EXCEPTION
|
||||
* -- custom exception
|
||||
* WHEN e_custom_exception THEN
|
||||
* DBMS_OUTPUT.PUT_LINE('Caught an exception: Custom exception raised');
|
||||
* -- divide by zero
|
||||
* WHEN ZERO_DIVIDE THEN
|
||||
* DBMS_OUTPUT.PUT_LINE('Caught an exception: Division by zero');
|
||||
* -- invalid number
|
||||
* WHEN INVALID_NUMBER THEN
|
||||
* DBMS_OUTPUT.PUT_LINE('Caught an exception: Invalid number');
|
||||
* -- other exceptions
|
||||
* WHEN OTHERS THEN
|
||||
* DBMS_OUTPUT.PUT_LINE('Caught an exception: ' || SQLERRM);
|
||||
* @param parseTokens should start with Exception keyword
|
||||
* @return ASTNode will not contain 'END'
|
||||
*/
|
||||
public static ASTNode parseException(List<Token> parseTokens) {
|
||||
ASTNode root = new ExceptionNode();
|
||||
root.addToken(parseTokens.get(0));
|
||||
ASTNode currentNode = root;
|
||||
for (int i = 1; i < parseTokens.size(); i++) {
|
||||
// match exception type
|
||||
if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHEN")) {
|
||||
if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.IDENTIFIER)) {
|
||||
ASTNode childNode = new CustomExceptionNode();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
childNode.addToken(parseTokens.get(j));
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("ZERO_DIVIDE")) {
|
||||
ASTNode childNode = new Zero_divideNode();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
childNode.addToken(parseTokens.get(j));
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("INVALID_NUMBER")) {
|
||||
ASTNode childNode = new Invalid_numberNode();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
childNode.addToken(parseTokens.get(j));
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("OTHERS")) {
|
||||
ASTNode childNode = new OtherExceptionNode();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
childNode.addToken(parseTokens.get(j));
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Parse failed:There exists syntex error in the input sql!");
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
|
||||
ASTNode childNode = new ExceptionEndNode();
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
break;
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
|
||||
if (!(currentNode instanceof ExceptionEndNode)) {
|
||||
ASTNode childNode = new ExceptionEndNode();
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// match exception action
|
||||
else {
|
||||
ASTNode childNode = new ExceptionActionNode();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
childNode.addToken(parseTokens.get(j));
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* JOIN clause
|
||||
* For example: table1 t1 JOIN table2 t2 ON|USING t1.id = t2.id
|
||||
|
|
|
|||
Loading…
Reference in New Issue