add trigger

This commit is contained in:
XudongXie 2024-09-18 11:01:52 +08:00
parent 8a8b13c793
commit 810e2d7608
6 changed files with 112 additions and 22 deletions

View File

@ -4,9 +4,11 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add trigger ast classes"> <list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add trigger">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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/Generator/OpenGaussGenerator.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Generator/OpenGaussGenerator.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/AST/Trigger/TriggerObjNode.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Trigger/TriggerObjNode.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" /> <change beforePath="$PROJECT_DIR$/src/main/java/Parser/OracleParser.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Parser/OracleParser.java" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@ -105,13 +107,6 @@
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1723106789329</updated> <updated>1723106789329</updated>
</task> </task>
<task id="LOCAL-00039" summary="add join">
<created>1726127728384</created>
<option name="number" value="00039" />
<option name="presentableId" value="LOCAL-00039" />
<option name="project" value="LOCAL" />
<updated>1726127728384</updated>
</task>
<task id="LOCAL-00040" summary="add join convert rule"> <task id="LOCAL-00040" summary="add join convert rule">
<created>1726129122571</created> <created>1726129122571</created>
<option name="number" value="00040" /> <option name="number" value="00040" />
@ -448,7 +443,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1726590115566</updated> <updated>1726590115566</updated>
</task> </task>
<option name="localTasksCounter" value="88" /> <task id="LOCAL-00088" summary="add trigger">
<created>1726591998690</created>
<option name="number" value="00088" />
<option name="presentableId" value="LOCAL-00088" />
<option name="project" value="LOCAL" />
<updated>1726591998690</updated>
</task>
<option name="localTasksCounter" value="89" />
<servers /> <servers />
</component> </component>
<component name="Vcs.Log.Tabs.Properties"> <component name="Vcs.Log.Tabs.Properties">
@ -463,7 +465,6 @@
</option> </option>
</component> </component>
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<MESSAGE value="add view document" />
<MESSAGE value="add keywords of view" /> <MESSAGE value="add keywords of view" />
<MESSAGE value="add ast class of view" /> <MESSAGE value="add ast class of view" />
<MESSAGE value="add view" /> <MESSAGE value="add view" />
@ -488,7 +489,8 @@
<MESSAGE value="add function" /> <MESSAGE value="add function" />
<MESSAGE value="add trigger document" /> <MESSAGE value="add trigger document" />
<MESSAGE value="add trigger ast classes" /> <MESSAGE value="add trigger ast classes" />
<option name="LAST_COMMIT_MESSAGE" value="add trigger ast classes" /> <MESSAGE value="add trigger" />
<option name="LAST_COMMIT_MESSAGE" value="add trigger" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<watches-manager> <watches-manager>

View File

@ -31,6 +31,7 @@ import Parser.AST.Procedure.ProcedureEndNode;
import Parser.AST.Procedure.ProcedureNode; import Parser.AST.Procedure.ProcedureNode;
import Parser.AST.Procedure.ProcedureRetDefNode; import Parser.AST.Procedure.ProcedureRetDefNode;
import Parser.AST.Select.SelectNode; import Parser.AST.Select.SelectNode;
import Parser.AST.Trigger.*;
import Parser.AST.Update.UpdateNode; import Parser.AST.Update.UpdateNode;
import Parser.AST.View.ViewCreateNode; import Parser.AST.View.ViewCreateNode;
@ -89,6 +90,9 @@ public class OpenGaussGenerator {
else if (node instanceof FunctionNode) { else if (node instanceof FunctionNode) {
return GenFunctionSQL(node); return GenFunctionSQL(node);
} }
else if (node instanceof TriggerNode) {
return GenTriggerSQL(node);
}
else { else {
try { try {
throw new GenerateFailedException("Root node:" + node.getClass() + "(Unsupported node type!)"); throw new GenerateFailedException("Root node:" + node.getClass() + "(Unsupported node type!)");
@ -170,6 +174,11 @@ public class OpenGaussGenerator {
return node.toQueryString(); return node.toQueryString();
} }
private String GenTriggerSQL(ASTNode node) {
visitTrigger(node);
return node.toQueryString();
}
private void visitCrt(ASTNode node) { private void visitCrt(ASTNode node) {
if (node instanceof ColumnNode) { if (node instanceof ColumnNode) {
ColumnTypeConvert((ColumnNode) node); ColumnTypeConvert((ColumnNode) node);
@ -302,6 +311,21 @@ public class OpenGaussGenerator {
} }
} }
private void visitTrigger(ASTNode node) {
if (node instanceof TriggerBodyNode) {
PLConvert(node);
}
else if (node instanceof TriggerConditionNode) {
PLConvert(node);
}
else if (node instanceof TriggerOptionNode) {
PLConvert(node);
}
for (ASTNode child : node.getChildren()) {
visitTrigger(child);
}
}
private void PLConvert(ASTNode node) { private void PLConvert(ASTNode node) {
if (node.checkExistsByRegex("(?i)DBMS_OUTPUT.PUT_LINE\\(.*?\\)")) { if (node.checkExistsByRegex("(?i)DBMS_OUTPUT.PUT_LINE\\(.*?\\)")) {
String printObj = ""; String printObj = "";
@ -416,6 +440,25 @@ public class OpenGaussGenerator {
} }
node.setTokens(tokens); node.setTokens(tokens);
} }
if (node instanceof TriggerOptionNode) {
try {
throw new GenerateFailedException("Unsupported type:" + node.toString() + "(OpenGauss doesn't support the keyword -- " + node.toString() + " or have any expression that keeps the same semantic!)");
}
catch (GenerateFailedException e) {
e.printStackTrace();
}
}
if (node instanceof TriggerConditionNode) {
if (((TriggerConditionNode) node).getCondition().hasType(Token.TokenType.KEYWORD) &&
((TriggerConditionNode) node).getCondition().getValue().equalsIgnoreCase("INSTEAD OF")) {
try {
throw new GenerateFailedException("Unsupported type:" + node.toString() + "(OpenGauss doesn't support the keyword -- " + node.toString() + " or have any expression that keeps the same semantic!)");
}
catch (GenerateFailedException e) {
e.printStackTrace();
}
}
}
} }

View File

@ -87,13 +87,19 @@ public class Main {
// " DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);\n" + // " DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);\n" +
// " END update_salary;\n" + // " END update_salary;\n" +
// " /"; // " /";
String sql = "CREATE OR REPLACE FUNCTION string_length (\n" + // String sql = "CREATE OR REPLACE FUNCTION string_length (\n" +
" input_string VARCHAR2\n" + // " input_string VARCHAR2\n" +
") RETURN NUMBER IS\n" + // ") RETURN NUMBER IS\n" +
"BEGIN\n" + // "BEGIN\n" +
" RETURN LENGTH(input_string);\n" + // " RETURN LENGTH(input_string);\n" +
"END;\n" + // "END;\n" +
"/"; // "/";
String sql = "CREATE OR REPLACE TRIGGER log_insert\n" +
" BEFORE INSERT ON employees\n" +
" FOR EACH ROW\n" +
" BEGIN\n" +
" INSERT INTO audit_log (action, employee_id) VALUES ('INSERT', :NEW.id);\n" +
" END;";
OracleLexer lexer = new OracleLexer(sql); OracleLexer lexer = new OracleLexer(sql);
lexer.printTokens(); lexer.printTokens();
OracleParser parser = new OracleParser(lexer); OracleParser parser = new OracleParser(lexer);

View File

@ -11,6 +11,7 @@ public class TriggerConditionNode extends ASTNode {
private Token action; private Token action;
public TriggerConditionNode() { public TriggerConditionNode() {
super(); super();
setTokens(new ArrayList<>());
} }
public TriggerConditionNode(List<Token> tokens) { public TriggerConditionNode(List<Token> tokens) {
@ -39,9 +40,16 @@ public class TriggerConditionNode extends ASTNode {
@Override @Override
public void visit(ASTNode node, StringBuilder queryString) { public void visit(ASTNode node, StringBuilder queryString) {
queryString.append(getCondition().getValue() + getAction().getValue() + " "); queryString.append(getCondition().getValue() + " " + getAction().getValue() + " ");
for (ASTNode child : getChildren()) { for (ASTNode child : getChildren()) {
child.visit(child, queryString); child.visit(child, queryString);
} }
} }
@Override
public String toString() {
String str = "";
str = getCondition().getValue() + " " + getAction().getValue();
return str;
}
} }

View File

@ -9,6 +9,7 @@ import java.util.List;
public class TriggerObjNode extends ASTNode { public class TriggerObjNode extends ASTNode {
public TriggerObjNode() { public TriggerObjNode() {
super(); super();
setTokens(new ArrayList<>());
} }
public TriggerObjNode(List<Token> tokens) { public TriggerObjNode(List<Token> tokens) {

View File

@ -2202,6 +2202,9 @@ public class OracleParser {
TriggerConditionNode childNode = new TriggerConditionNode(); TriggerConditionNode childNode = new TriggerConditionNode();
childNode.setCondition(parseTokens.get(i)); childNode.setCondition(parseTokens.get(i));
childNode.setAction(parseTokens.get(i + 1)); childNode.setAction(parseTokens.get(i + 1));
i++;
currentNode.addChild(childNode);
currentNode = childNode;
} }
else { else {
try { try {
@ -2252,6 +2255,7 @@ public class OracleParser {
childNode.addToken(parseTokens.get(i + 2)); childNode.addToken(parseTokens.get(i + 2));
currentNode.addChild(childNode); currentNode.addChild(childNode);
currentNode = childNode; currentNode = childNode;
i += 2;
} }
else { else {
try { try {
@ -2282,8 +2286,34 @@ public class OracleParser {
currentNode = childNode; currentNode = childNode;
} }
// match trigger body // match trigger body
else if (currentNode instanceof TriggerBeginNode) { else if ( ((currentNode instanceof TriggerBeginNode) || (currentNode instanceof TriggerBodyNode)) && !(parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END"))) {
//TODO: parse trigger body ASTNode childNode = new TriggerBodyNode();
for (int j = i; j < parseTokens.size(); j++) {
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")) {
i = j - 1;
break;
}
else if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
i = j;
childNode.addToken(parseTokens.get(j));
break;
}
childNode.addToken(parseTokens.get(j));
}
currentNode.addChild(childNode);
currentNode = childNode;
}
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
ASTNode childNode = new TriggerEndNode();
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;
} }
else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) { else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
break; break;