From 810e2d76089f8e45454d816c56a58c43e4e8664a Mon Sep 17 00:00:00 2001 From: XudongXie Date: Wed, 18 Sep 2024 11:01:52 +0800 Subject: [PATCH] add trigger --- sqlTranslate/.idea/workspace.xml | 26 +++++------ .../java/Generator/OpenGaussGenerator.java | 43 +++++++++++++++++++ sqlTranslate/src/main/java/Main.java | 20 ++++++--- .../AST/Trigger/TriggerConditionNode.java | 10 ++++- .../Parser/AST/Trigger/TriggerObjNode.java | 1 + .../src/main/java/Parser/OracleParser.java | 34 ++++++++++++++- 6 files changed, 112 insertions(+), 22 deletions(-) diff --git a/sqlTranslate/.idea/workspace.xml b/sqlTranslate/.idea/workspace.xml index 167475143..424a9e5c8 100644 --- a/sqlTranslate/.idea/workspace.xml +++ b/sqlTranslate/.idea/workspace.xml @@ -4,9 +4,11 @@ - @@ -488,7 +489,8 @@ - diff --git a/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java b/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java index 764d557f1..1812a3d3a 100644 --- a/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java +++ b/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java @@ -31,6 +31,7 @@ import Parser.AST.Procedure.ProcedureEndNode; import Parser.AST.Procedure.ProcedureNode; import Parser.AST.Procedure.ProcedureRetDefNode; import Parser.AST.Select.SelectNode; +import Parser.AST.Trigger.*; import Parser.AST.Update.UpdateNode; import Parser.AST.View.ViewCreateNode; @@ -89,6 +90,9 @@ public class OpenGaussGenerator { else if (node instanceof FunctionNode) { return GenFunctionSQL(node); } + else if (node instanceof TriggerNode) { + return GenTriggerSQL(node); + } else { try { throw new GenerateFailedException("Root node:" + node.getClass() + "(Unsupported node type!)"); @@ -170,6 +174,11 @@ public class OpenGaussGenerator { return node.toQueryString(); } + private String GenTriggerSQL(ASTNode node) { + visitTrigger(node); + return node.toQueryString(); + } + private void visitCrt(ASTNode node) { if (node instanceof ColumnNode) { 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) { if (node.checkExistsByRegex("(?i)DBMS_OUTPUT.PUT_LINE\\(.*?\\)")) { String printObj = ""; @@ -416,6 +440,25 @@ public class OpenGaussGenerator { } 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(); + } + } + } } diff --git a/sqlTranslate/src/main/java/Main.java b/sqlTranslate/src/main/java/Main.java index 5952be8f8..fa8a3dfa0 100644 --- a/sqlTranslate/src/main/java/Main.java +++ b/sqlTranslate/src/main/java/Main.java @@ -87,13 +87,19 @@ public class Main { // " DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);\n" + // " END update_salary;\n" + // " /"; - String sql = "CREATE OR REPLACE FUNCTION string_length (\n" + - " input_string VARCHAR2\n" + - ") RETURN NUMBER IS\n" + - "BEGIN\n" + - " RETURN LENGTH(input_string);\n" + - "END;\n" + - "/"; +// String sql = "CREATE OR REPLACE FUNCTION string_length (\n" + +// " input_string VARCHAR2\n" + +// ") RETURN NUMBER IS\n" + +// "BEGIN\n" + +// " RETURN LENGTH(input_string);\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); lexer.printTokens(); OracleParser parser = new OracleParser(lexer); diff --git a/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerConditionNode.java b/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerConditionNode.java index da2ef316f..4d83c66b5 100644 --- a/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerConditionNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerConditionNode.java @@ -11,6 +11,7 @@ public class TriggerConditionNode extends ASTNode { private Token action; public TriggerConditionNode() { super(); + setTokens(new ArrayList<>()); } public TriggerConditionNode(List tokens) { @@ -39,9 +40,16 @@ public class TriggerConditionNode extends ASTNode { @Override public void visit(ASTNode node, StringBuilder queryString) { - queryString.append(getCondition().getValue() + getAction().getValue() + " "); + queryString.append(getCondition().getValue() + " " + getAction().getValue() + " "); for (ASTNode child : getChildren()) { child.visit(child, queryString); } } + + @Override + public String toString() { + String str = ""; + str = getCondition().getValue() + " " + getAction().getValue(); + return str; + } } diff --git a/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerObjNode.java b/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerObjNode.java index 118903a08..fdee8395d 100644 --- a/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerObjNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/Trigger/TriggerObjNode.java @@ -9,6 +9,7 @@ import java.util.List; public class TriggerObjNode extends ASTNode { public TriggerObjNode() { super(); + setTokens(new ArrayList<>()); } public TriggerObjNode(List tokens) { diff --git a/sqlTranslate/src/main/java/Parser/OracleParser.java b/sqlTranslate/src/main/java/Parser/OracleParser.java index b946b9e3e..092d0d654 100644 --- a/sqlTranslate/src/main/java/Parser/OracleParser.java +++ b/sqlTranslate/src/main/java/Parser/OracleParser.java @@ -2202,6 +2202,9 @@ public class OracleParser { TriggerConditionNode childNode = new TriggerConditionNode(); childNode.setCondition(parseTokens.get(i)); childNode.setAction(parseTokens.get(i + 1)); + i++; + currentNode.addChild(childNode); + currentNode = childNode; } else { try { @@ -2252,6 +2255,7 @@ public class OracleParser { childNode.addToken(parseTokens.get(i + 2)); currentNode.addChild(childNode); currentNode = childNode; + i += 2; } else { try { @@ -2282,8 +2286,34 @@ public class OracleParser { currentNode = childNode; } // match trigger body - else if (currentNode instanceof TriggerBeginNode) { - //TODO: parse trigger body + else if ( ((currentNode instanceof TriggerBeginNode) || (currentNode instanceof TriggerBodyNode)) && !(parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END"))) { + 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)) { break;