forked from opengaussexamples/examples
add update convert rules
This commit is contained in:
parent
efd9320ff6
commit
382ac95ee0
|
|
@ -4,14 +4,12 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add select convert rules">
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Document/Update statement in Oracle" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Update/UpdateEndNode.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Update/UpdateNode.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Update/UpdateObjNode.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Update/UpdateSetNode.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Update/UpdateWhereNode.java" afterDir="false" />
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add update ast class">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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" />
|
||||
|
|
@ -410,7 +408,14 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1726148093221</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="44" />
|
||||
<task id="LOCAL-00044" summary="add update ast class">
|
||||
<created>1726149015586</created>
|
||||
<option name="number" value="00044" />
|
||||
<option name="presentableId" value="LOCAL-00044" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1726149015586</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="45" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
|
|
@ -448,7 +453,8 @@
|
|||
<MESSAGE value="add join convert rule" />
|
||||
<MESSAGE value="refractor" />
|
||||
<MESSAGE value="add select convert rules" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="add select convert rules" />
|
||||
<MESSAGE value="add update ast class" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="add update ast class" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<watches-manager>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import Parser.AST.Join.JoinConditionNode;
|
|||
import Parser.AST.Join.JoinSourceTabNode;
|
||||
import Parser.AST.Select.SelectNode;
|
||||
import Parser.AST.Select.SelectObjNode;
|
||||
import Parser.AST.Update.UpdateNode;
|
||||
import Parser.AST.Update.UpdateObjNode;
|
||||
import Parser.OracleParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -43,6 +45,9 @@ public class OpenGaussGenerator {
|
|||
else if (node instanceof JoinSourceTabNode) {
|
||||
return GenJoinSQL(node);
|
||||
}
|
||||
else if (node instanceof UpdateNode) {
|
||||
return GenUpdateSQL(node);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new GenerateFailedException("Root node:" + node.getClass() + "(Unsupported node type!)");
|
||||
|
|
@ -72,7 +77,7 @@ public class OpenGaussGenerator {
|
|||
|
||||
private String GenSelectSQL(ASTNode node) {
|
||||
visitSelect(node, null);
|
||||
System.out.println(node.getASTString());
|
||||
// System.out.println(node.getASTString());
|
||||
return node.toQueryString();
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +86,12 @@ public class OpenGaussGenerator {
|
|||
return node.toQueryString();
|
||||
}
|
||||
|
||||
private String GenUpdateSQL(ASTNode node) {
|
||||
visitUpdate(node, null);
|
||||
// System.out.println(node.getASTString());
|
||||
return node.toQueryString();
|
||||
}
|
||||
|
||||
private void visitCrt(ASTNode node) {
|
||||
if (node instanceof ColumnNode) {
|
||||
ColumnTypeConvert((ColumnNode) node);
|
||||
|
|
@ -138,6 +149,24 @@ public class OpenGaussGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private void visitUpdate(ASTNode node, ASTNode parentNode) {
|
||||
if (node instanceof UpdateObjNode) {
|
||||
// check whether there exists a join statement in the select sql
|
||||
if (node.getTokens().contains(new Token(Token.TokenType.KEYWORD, "JOIN"))) {
|
||||
ASTNode joinRootNode = OracleParser.parseJoin(node.getTokens());
|
||||
visitJoin(joinRootNode);
|
||||
parentNode.replaceChild(node, joinRootNode);
|
||||
ASTNode smallestChild = joinRootNode.getDeepestChild();
|
||||
for (ASTNode child : node.getChildren()) {
|
||||
smallestChild.addChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ASTNode child : node.getChildren()) {
|
||||
visitUpdate(child, node);
|
||||
}
|
||||
}
|
||||
|
||||
private void ColumnTypeConvert(ColumnNode node) {
|
||||
// type convert
|
||||
if (node.getType().getValue().equalsIgnoreCase("NUMBER")) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public class OracleLexer {
|
|||
, "DISTINCT", "JOIN", "GROUP BY", "ORDER BY", "HAVING", "UNION", "CASE", "WHEN", "END", "AS"
|
||||
// keywords of join
|
||||
, "INNER JOIN", "LEFT JOIN", "LEFT OUTER JOIN", "RIGHT JOIN", "RIGHT OUTER JOIN", "FULL JOIN", "FULL OUTER JOIN", "CROSS JOIN", "JOIN", "ON", "USING"
|
||||
// keywords of update
|
||||
, "SET"
|
||||
};
|
||||
private static final Pattern TOKEN_PATTERN = Pattern.compile(
|
||||
"(NUMBER\\(.*?\\))|" + // NUMBER() function
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ public class Main {
|
|||
// String sql = "DROP TABLE employees CASCADE CONSTRAINTS;";
|
||||
String sql = "SELECT e.first_name, d.department_name FROM employees e JOIN departments d Using e.department_id = d.department_id;";
|
||||
// String sql = "employees e JOIN departments d ON e.department_id = d.department_id;";
|
||||
// String sql = "UPDATE employees e\n" +
|
||||
// "JOIN departments d using e.department_id = d.department_id\n" +
|
||||
// "SET e.salary = e.salary * 1.10,\n" +
|
||||
// " d.budget = d.budget * 1.10\n" +
|
||||
// "WHERE d.department_name = 'Sales';";
|
||||
OracleLexer lexer = new OracleLexer(sql);
|
||||
lexer.printTokens();
|
||||
OracleParser parser = new OracleParser(lexer);
|
||||
|
|
|
|||
|
|
@ -20,5 +20,9 @@ public class JoinEndNode extends ASTNode {
|
|||
@Override
|
||||
public void visit(ASTNode node, StringBuilder queryString) {
|
||||
queryString.append(toString());
|
||||
for (ASTNode child : getChildren())
|
||||
{
|
||||
child.visit(child, queryString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package Parser.AST;
|
||||
|
||||
import Lexer.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SelectStatementNode extends ASTNode{
|
||||
public SelectStatementNode(ASTNode node)
|
||||
{
|
||||
super(node);
|
||||
}
|
||||
|
||||
public SelectStatementNode(List<Token> tokens)
|
||||
{
|
||||
super(tokens);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ASTNode node, StringBuilder queryString)
|
||||
{
|
||||
queryString.append(toString() + " ");
|
||||
for (ASTNode child : getChildren())
|
||||
{
|
||||
child.visit(child, queryString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ import Parser.AST.Insert.InsertNode;
|
|||
import Parser.AST.Insert.InsertObjNode;
|
||||
import Parser.AST.Join.*;
|
||||
import Parser.AST.Select.*;
|
||||
import Parser.AST.Update.*;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
|
|
@ -46,6 +47,9 @@ public class OracleParser {
|
|||
else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("SELECT")) {
|
||||
return parseSelect(lexer.getTokens());
|
||||
}
|
||||
else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("UPDATE")) {
|
||||
return parseUpdate(lexer.getTokens());
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Parse failed!");
|
||||
|
|
@ -739,4 +743,79 @@ public class OracleParser {
|
|||
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update
|
||||
* For example: UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;
|
||||
*/
|
||||
private ASTNode parseUpdate(List<Token> parseTokens) {
|
||||
List<Token> tokens = new ArrayList<>();
|
||||
tokens.add(parseTokens.get(0));
|
||||
ASTNode root = new UpdateNode(tokens);
|
||||
ASTNode currentNode = root;
|
||||
for (int i = 1; i < parseTokens.size(); i++) {
|
||||
if (i == 1 && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
|
||||
// match update object
|
||||
tokens = new ArrayList<>();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("SET")) {
|
||||
i = j - 1;
|
||||
break;
|
||||
}
|
||||
tokens.add(parseTokens.get(j));
|
||||
}
|
||||
ASTNode childNode = new UpdateObjNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("SET")) {
|
||||
// match SET
|
||||
tokens = new ArrayList<>();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("WHERE")) {
|
||||
i = j - 1;
|
||||
break;
|
||||
}
|
||||
tokens.add(parseTokens.get(j));
|
||||
}
|
||||
ASTNode childNode = new UpdateSetNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHERE")) {
|
||||
// match WHERE
|
||||
tokens = new ArrayList<>();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
|
||||
i = j - 1;
|
||||
break;
|
||||
}
|
||||
tokens.add(parseTokens.get(j));
|
||||
}
|
||||
ASTNode childNode = new UpdateWhereNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equalsIgnoreCase(";")) {
|
||||
tokens = new ArrayList<>();
|
||||
tokens.add(parseTokens.get(i));
|
||||
ASTNode childNode = new UpdateEndNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Parse failed:" + parseTokens.get(i));
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue