forked from opengaussexamples/examples
add view
This commit is contained in:
parent
c10d92fae6
commit
c4cec7795c
|
|
@ -4,7 +4,14 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add view document" />
|
||||
<list default="true" id="d8d12963-4777-48e3-9669-309cf5e41d60" name="更改" comment="add ast class of view">
|
||||
<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/View/ViewEndNode.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/View/ViewEndNode.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/main/java/Parser/AST/View/ViewNode.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/Parser/AST/View/ViewCreateNode.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" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
|
|
@ -13,8 +20,8 @@
|
|||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Class" />
|
||||
<option value="Interface" />
|
||||
<option value="Class" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
|
|
@ -101,20 +108,6 @@
|
|||
<option name="presentableId" value="Default" />
|
||||
<updated>1723106789329</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00010" summary="add parser function">
|
||||
<created>1724166047929</created>
|
||||
<option name="number" value="00010" />
|
||||
<option name="presentableId" value="LOCAL-00010" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1724166047929</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00011" summary="add function">
|
||||
<created>1724338301831</created>
|
||||
<option name="number" value="00011" />
|
||||
<option name="presentableId" value="LOCAL-00011" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1724338301831</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00012" summary="add function">
|
||||
<created>1724419179050</created>
|
||||
<option name="number" value="00012" />
|
||||
|
|
@ -444,7 +437,21 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1726214965146</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="59" />
|
||||
<task id="LOCAL-00059" summary="add keywords of view">
|
||||
<created>1726215246855</created>
|
||||
<option name="number" value="00059" />
|
||||
<option name="presentableId" value="LOCAL-00059" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1726215246856</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00060" summary="add ast class of view">
|
||||
<created>1726215657277</created>
|
||||
<option name="number" value="00060" />
|
||||
<option name="presentableId" value="LOCAL-00060" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1726215657277</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="61" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
|
|
@ -459,8 +466,6 @@
|
|||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="add insert sql" />
|
||||
<MESSAGE value="add todolist" />
|
||||
<MESSAGE value="add select" />
|
||||
<MESSAGE value="add case when" />
|
||||
<MESSAGE value="add pattern of functions in select" />
|
||||
|
|
@ -484,7 +489,9 @@
|
|||
<MESSAGE value="add alter" />
|
||||
<MESSAGE value="fix some bugs" />
|
||||
<MESSAGE value="add view document" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="add view document" />
|
||||
<MESSAGE value="add keywords of view" />
|
||||
<MESSAGE value="add ast class of view" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="add ast class of view" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<watches-manager>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class OracleLexer {
|
|||
// keywords of drop table
|
||||
, "DROP", "CASCADE"
|
||||
// keywords of select
|
||||
, "DISTINCT", "JOIN", "GROUP BY", "ORDER BY", "HAVING", "UNION", "CASE", "WHEN", "END", "AS"
|
||||
, "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 case when
|
||||
|
|
@ -45,6 +45,7 @@ public class OracleLexer {
|
|||
"(AVG\\(.*?\\))|" + // AVG() function
|
||||
"(MAX\\(.*?\\))|" + // MAX() function
|
||||
"(MIN\\(.*?\\))|" + // MIN() function
|
||||
"(\\|\\|\\s*'.*?'\\s*\\|\\|)|" + // || '*' ||
|
||||
|
||||
"(NOT NULL)|" +
|
||||
"(PRIMARY KEY)|" +
|
||||
|
|
@ -66,6 +67,7 @@ public class OracleLexer {
|
|||
"(FULL JOIN)|" +
|
||||
"(FULL OUTER JOIN)|" +
|
||||
"(CROSS JOIN)|" +
|
||||
"(\\|\\|)|" +
|
||||
|
||||
|
||||
"(\\b[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*\\b)|" + // Keywords and identifiers
|
||||
|
|
@ -122,40 +124,43 @@ public class OracleLexer {
|
|||
else if (tokenValue.matches("(?i)NUMBER\\(.*?\\)")) {
|
||||
// NUMBER() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)DECIMAL\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)DECIMAL\\(.*?\\)")) {
|
||||
// DECIMAL() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)FLOAT\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)FLOAT\\(.*?\\)")) {
|
||||
// FLOAT() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)CHAR\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)CHAR\\(.*?\\)")) {
|
||||
// CHAR() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)VARCHAR2\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)VARCHAR2\\(.*?\\)")) {
|
||||
// VARCHAR2() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)NCHAR\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)NCHAR\\(.*?\\)")) {
|
||||
// NCHAR() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)NVARCHAR2\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)NVARCHAR2\\(.*?\\)")) {
|
||||
// NVARCHAR2() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)RAW\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)RAW\\(.*?\\)")) {
|
||||
// RAW() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)COUNT\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)COUNT\\(.*?\\)")) {
|
||||
// RAW() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)SUM\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)SUM\\(.*?\\)")) {
|
||||
// RAW() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)AVG\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)AVG\\(.*?\\)")) {
|
||||
// RAW() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)MAX\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)MAX\\(.*?\\)")) {
|
||||
// RAW() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}else if (tokenValue.matches("(?i)MIN\\(.*?\\)")) {
|
||||
} else if (tokenValue.matches("(?i)MIN\\(.*?\\)")) {
|
||||
// RAW() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
} else if (tokenValue.matches("\\|\\|\\s*'.*?'\\s*\\|\\|")) {
|
||||
// RAW() function, CASE_INSENSITIVE
|
||||
return new Token(Token.TokenType.KEYWORD, tokenValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,9 @@ public class Main {
|
|||
// " FROM departments d\n" +
|
||||
// " WHERE d.department_name = 'Sales'\n" +
|
||||
// ");";
|
||||
String sql = "ALTER TABLE employees ADD email VARCHAR2(100) Check (email != '12813@163.com');";
|
||||
// String sql = "ALTER TABLE employees ADD email VARCHAR2(100) Check (email != '12813@163.com');";
|
||||
// String sql = "CASE WHEN column2 > 0 THEN 'Positive' ELSE 'Non-positive' END";
|
||||
String sql = "CREATE OR REPLACE VIEW emp_dept_info AS SELECT e.first_name, e.last_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id;";
|
||||
OracleLexer lexer = new OracleLexer(sql);
|
||||
lexer.printTokens();
|
||||
OracleParser parser = new OracleParser(lexer);
|
||||
|
|
|
|||
|
|
@ -5,12 +5,17 @@ import Parser.AST.ASTNode;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public class ViewNode extends ASTNode {
|
||||
public ViewNode(ASTNode node) {
|
||||
public class ViewCreateNode extends ASTNode {
|
||||
|
||||
public ViewCreateNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ViewCreateNode(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public ViewNode(List<Token> tokens) {
|
||||
public ViewCreateNode(List<Token> tokens) {
|
||||
super(tokens);
|
||||
}
|
||||
|
||||
|
|
@ -6,6 +6,10 @@ import Parser.AST.ASTNode;
|
|||
import java.util.List;
|
||||
|
||||
public class ViewEndNode extends ASTNode {
|
||||
public ViewEndNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ViewEndNode(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ import Parser.AST.Insert.InsertObjNode;
|
|||
import Parser.AST.Join.*;
|
||||
import Parser.AST.Select.*;
|
||||
import Parser.AST.Update.*;
|
||||
import Parser.AST.View.ViewCreateNode;
|
||||
import Parser.AST.View.ViewEndNode;
|
||||
import Parser.AST.View.ViewNameNode;
|
||||
import Parser.AST.View.ViewTargetNode;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
|
|
@ -38,38 +42,41 @@ public class OracleParser {
|
|||
}
|
||||
public ASTNode parse()
|
||||
{
|
||||
// check if the input is a create table statement
|
||||
if ((lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("TABLE")) ||
|
||||
(lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("TEMPORARY") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("TABLE")) ) {
|
||||
return parseCreateTab(lexer.getTokens());
|
||||
}
|
||||
else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("INSERT")) {
|
||||
return parseInsert(lexer.getTokens());
|
||||
}
|
||||
else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("DROP")) {
|
||||
return parseDrop(lexer.getTokens());
|
||||
}
|
||||
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 if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("DELETE")) {
|
||||
return parseDelete(lexer.getTokens());
|
||||
}
|
||||
else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("ALTER")) {
|
||||
return parseAlterTable(lexer.getTokens());
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Parse failed!--Unsupport SQL:" + lexer.getTokens().get(0).getValue());
|
||||
try {
|
||||
// check if the input is a create table statement
|
||||
if ((lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("TABLE")) ||
|
||||
(lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("TEMPORARY") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("TABLE"))) {
|
||||
return parseCreateTab(lexer.getTokens());
|
||||
} else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("INSERT")) {
|
||||
return parseInsert(lexer.getTokens());
|
||||
} else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("DROP")) {
|
||||
return parseDrop(lexer.getTokens());
|
||||
} 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 if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("DELETE")) {
|
||||
return parseDelete(lexer.getTokens());
|
||||
} else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("ALTER")) {
|
||||
return parseAlterTable(lexer.getTokens());
|
||||
} else if (
|
||||
(lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("OR") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("REPLACE") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("VIEW"))
|
||||
|| (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("VIEW"))
|
||||
) {
|
||||
return parseCreateView(lexer.getTokens());
|
||||
} else {
|
||||
try {
|
||||
throw new ParseFailedException("Parse failed!--Unsupport SQL:" + lexer.getTokens().get(0).getValue());
|
||||
} catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1210,5 +1217,68 @@ public class OracleParser {
|
|||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create view
|
||||
* Grammar: CREATE [OR REPLACE] VIEW view_name [(column_name [, column_name]...)] AS SELECT_statement;
|
||||
* Example: CREATE OR REPLACE VIEW employee_details (full_name, pay)
|
||||
* AS SELECT first_name, last_name, salary FROM employees;
|
||||
*/
|
||||
private ASTNode parseCreateView(List<Token> parseTokens) {
|
||||
List<Token> tokens = new ArrayList<>();
|
||||
ASTNode root = new ViewCreateNode();
|
||||
ASTNode currentNode = root;
|
||||
for (int i = 0; i < parseTokens.size(); i++) {
|
||||
if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("CREATE")) {
|
||||
tokens.add(parseTokens.get(i));
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("OR")) {
|
||||
tokens.add(parseTokens.get(i));
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("REPLACE")) {
|
||||
tokens.add(parseTokens.get(i));
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("VIEW")) {
|
||||
tokens.add(parseTokens.get(i));
|
||||
root.setTokens(tokens);
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER) && currentNode instanceof ViewCreateNode) {
|
||||
tokens = new ArrayList<>();
|
||||
for (int j = i; j < parseTokens.size(); j++) {
|
||||
if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("AS")) {
|
||||
i = j - 1;
|
||||
break;
|
||||
}
|
||||
tokens.add(parseTokens.get(j));
|
||||
}
|
||||
ASTNode childNode = new ViewNameNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
}
|
||||
else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("AS")) {
|
||||
tokens = new ArrayList<>();
|
||||
tokens.add(parseTokens.get(i));
|
||||
ASTNode childNode = new ViewTargetNode(tokens);
|
||||
currentNode.addChild(childNode);
|
||||
currentNode = childNode;
|
||||
tokens = parseTokens.subList(i + 1, parseTokens.size());
|
||||
ASTNode selectRootNode = parseSelect(tokens);
|
||||
currentNode.addChild(selectRootNode);
|
||||
currentNode = selectRootNode.getDeepestChild();
|
||||
ASTNode viewEndNode = new ViewEndNode();
|
||||
currentNode.addChild(viewEndNode);
|
||||
currentNode = viewEndNode;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
throw new ParseFailedException("Failed to parse:" + parseTokens.get(i));
|
||||
}
|
||||
catch (ParseFailedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue