forked from opengaussexamples/examples
add join
This commit is contained in:
parent
34023bc8e8
commit
6fcb0541d0
|
|
@ -4,12 +4,13 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add join pattern">
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Join/JoinColumnNode.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Join/JoinSourceTabNode.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Join/JoinTargetTabNode.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Join/JoinTypeNode.java" afterDir="false" />
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add join class">
|
||||
<change afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Join/JoinEndNode.java" 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/Main.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Main.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/Parser/AST/Join/JoinColumnNode.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/Join/JoinConditionNode.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" />
|
||||
|
|
@ -366,7 +367,14 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1726068883795</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="38" />
|
||||
<task id="LOCAL-00038" summary="add join class">
|
||||
<created>1726112198383</created>
|
||||
<option name="number" value="00038" />
|
||||
<option name="presentableId" value="LOCAL-00038" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1726112198384</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="39" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
|
|
@ -399,7 +407,8 @@
|
|||
<MESSAGE value="add parseSelect" />
|
||||
<MESSAGE value="revise" />
|
||||
<MESSAGE value="add join pattern" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="add join pattern" />
|
||||
<MESSAGE value="add join class" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="add join class" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<watches-manager>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public class OracleLexer {
|
|||
// keywords of select
|
||||
, "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"
|
||||
, "INNER JOIN", "LEFT JOIN", "LEFT OUTER JOIN", "RIGHT JOIN", "RIGHT OUTER JOIN", "FULL JOIN", "FULL OUTER JOIN", "CROSS JOIN", "JOIN", "ON", "USING"
|
||||
};
|
||||
private static final Pattern TOKEN_PATTERN = Pattern.compile(
|
||||
"(NUMBER\\(.*?\\))|" + // NUMBER() function
|
||||
|
|
|
|||
|
|
@ -17,10 +17,13 @@ public class Main {
|
|||
// String sql = "INSERT INTO employees (first_name, last_name, email) VALUES ('Jane', 'Smith', 'janesm@example.com');";
|
||||
// String sql = "DROP TABLE employees CASCADE CONSTRAINTS;";
|
||||
String sql = "SELECT e.first_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id;";
|
||||
// String sql = "Customers\n" +
|
||||
// "LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID where";
|
||||
OracleLexer lexer = new OracleLexer(sql);
|
||||
lexer.printTokens();
|
||||
OracleParser parser = new OracleParser(lexer);
|
||||
ASTNode root = parser.parse();
|
||||
// ASTNode root = OracleParser.parseJoin(lexer.getTokens());
|
||||
System.out.println(root.toQueryString());
|
||||
System.out.println(root.getASTString());
|
||||
OpenGaussGenerator generator = new OpenGaussGenerator(root);
|
||||
|
|
|
|||
|
|
@ -123,11 +123,13 @@ public abstract class ASTNode {
|
|||
@Override
|
||||
public String toString() {
|
||||
String str = "";
|
||||
for (int i = 0; i < tokens.size(); i++) {
|
||||
if (i < tokens.size() - 1)
|
||||
str += tokens.get(i).getValue() + " ";
|
||||
else
|
||||
str += tokens.get(i).getValue();
|
||||
if (tokens != null) {
|
||||
for (int i = 0; i < tokens.size(); i++) {
|
||||
if (i < tokens.size() - 1)
|
||||
str += tokens.get(i).getValue() + " ";
|
||||
else
|
||||
str += tokens.get(i).getValue();
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,20 +4,24 @@ import Lexer.Token;
|
|||
import Parser.AST.ASTNode;
|
||||
import java.util.List;
|
||||
|
||||
public class JoinColumnNode extends ASTNode {
|
||||
public class JoinConditionNode extends ASTNode {
|
||||
private String keyword;
|
||||
public JoinColumnNode(List<Token> tokens)
|
||||
public JoinConditionNode(List<Token> tokens)
|
||||
{
|
||||
super(tokens);
|
||||
this.keyword = "";
|
||||
}
|
||||
|
||||
public JoinColumnNode(ASTNode node)
|
||||
public JoinConditionNode(ASTNode node)
|
||||
{
|
||||
super(node);
|
||||
this.keyword = "";
|
||||
}
|
||||
|
||||
public JoinConditionNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setKeyword(String keyword) {
|
||||
this.keyword = keyword + " ";
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package Parser.AST.Join;
|
||||
|
||||
import Lexer.Token;
|
||||
import Parser.AST.ASTNode;
|
||||
import java.util.List;
|
||||
|
||||
public class JoinEndNode extends ASTNode {
|
||||
public JoinEndNode(List<Token> tokens) {
|
||||
super(tokens);
|
||||
}
|
||||
|
||||
public JoinEndNode(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public JoinEndNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ASTNode node, StringBuilder queryString) {
|
||||
queryString.append(toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -17,12 +17,12 @@ import Parser.AST.Insert.InsertDataNode;
|
|||
import Parser.AST.Insert.InsertEndNode;
|
||||
import Parser.AST.Insert.InsertNode;
|
||||
import Parser.AST.Insert.InsertObjNode;
|
||||
import Parser.AST.Join.*;
|
||||
import Parser.AST.Select.*;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class OracleParser {
|
||||
|
|
@ -581,5 +581,168 @@ public class OracleParser {
|
|||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* JOIN clause
|
||||
* For example: table1 t1 JOIN table2 t2 ON|USING t1.id = t2.id (parseTokens should start with table)
|
||||
*/
|
||||
public static ASTNode parseJoin(List<Token> parseTokens) {
|
||||
List <Token> tokens = new ArrayList<>();
|
||||
int index = 0;
|
||||
boolean parseState = false;
|
||||
ASTNode currentNode = null;
|
||||
ASTNode root = null;
|
||||
// match table 1
|
||||
for (int i = index; i < parseTokens.size(); i++) {
|
||||
if (
|
||||
(parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("INNER JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("LEFT JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("RIGHT JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("FULL JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("LEFT OUTER JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("RIGHT OUTER JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("FULL OUTER JOIN"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("CROSS JOIN"))
|
||||
) {
|
||||
index = i;
|
||||
parseState = true;
|
||||
break;
|
||||
}
|
||||
tokens.add(parseTokens.get(i));
|
||||
}
|
||||
if (parseState) {
|
||||
root = new JoinSourceTabNode(tokens);
|
||||
currentNode = root;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Fail to parse:" + parseTokens.get(index));
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// match join type
|
||||
if (parseState) {
|
||||
tokens = new ArrayList<>();
|
||||
tokens.add(parseTokens.get(index));
|
||||
index++;
|
||||
ASTNode childNode = new JoinTypeNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Fail to parse:" + parseTokens.get(index));
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// match table 2
|
||||
tokens = new ArrayList<>();
|
||||
parseState = false;
|
||||
for (int i = index; i < parseTokens.size(); i++) {
|
||||
if (
|
||||
(parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ON"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("USING"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equalsIgnoreCase(";"))
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD))
|
||||
) {
|
||||
index = i;
|
||||
parseState = true;
|
||||
break;
|
||||
}
|
||||
tokens.add(parseTokens.get(i));
|
||||
}
|
||||
if (parseState) {
|
||||
ASTNode childNode = new JoinTargetTabNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Fail to parse:" + parseTokens.get(index));
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// match join condition
|
||||
if (parseState) {
|
||||
// match end
|
||||
if (parseTokens.get(index).hasType(Token.TokenType.SYMBOL) && parseTokens.get(index).getValue().equalsIgnoreCase(";")) {
|
||||
tokens = new ArrayList<>();
|
||||
tokens.add(parseTokens.get(index));
|
||||
ASTNode childNode = new JoinEndNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
// match end with keyword
|
||||
else if (parseTokens.get(index).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(index).getValue().equalsIgnoreCase("ON") && !parseTokens.get(index).getValue().equalsIgnoreCase("USING")) {
|
||||
ASTNode childNode = new JoinEndNode();
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else {
|
||||
parseState = false;
|
||||
JoinConditionNode joinConditionNode = new JoinConditionNode();
|
||||
joinConditionNode.setKeyword(parseTokens.get(index).getValue());
|
||||
index++;
|
||||
tokens = new ArrayList<>();
|
||||
for (int i = index; i < parseTokens.size(); i++) {
|
||||
if (
|
||||
parseTokens.get(i).hasType(Token.TokenType.KEYWORD)
|
||||
|| (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equalsIgnoreCase(";"))
|
||||
)
|
||||
{
|
||||
index = i;
|
||||
parseState = true;
|
||||
break;
|
||||
}
|
||||
tokens.add(parseTokens.get(i));
|
||||
}
|
||||
if (parseState) {
|
||||
joinConditionNode.setTokens(tokens);
|
||||
currentNode.addChild(joinConditionNode);
|
||||
currentNode = joinConditionNode;
|
||||
// match end
|
||||
if (parseTokens.get(index).hasType(Token.TokenType.SYMBOL) && parseTokens.get(index).getValue().equalsIgnoreCase(";")) {
|
||||
tokens = new ArrayList<>();
|
||||
tokens.add(parseTokens.get(index));
|
||||
ASTNode childNode = new JoinEndNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
// match end with keyword
|
||||
else if (parseTokens.get(index).hasType(Token.TokenType.KEYWORD)) {
|
||||
ASTNode childNode = new JoinEndNode();
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Fail to parse:" + parseTokens.get(index));
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Fail to parse:" + parseTokens.get(index));
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue