diff --git a/sqlTranslate/.idea/workspace.xml b/sqlTranslate/.idea/workspace.xml
index 05e23705..2fc6ac4d 100644
--- a/sqlTranslate/.idea/workspace.xml
+++ b/sqlTranslate/.idea/workspace.xml
@@ -4,12 +4,10 @@
-
+
-
-
@@ -339,7 +337,14 @@
1726041355829
-
+
+ 1726059547456
+
+
+
+ 1726059547457
+
+
@@ -367,11 +372,11 @@
-
-
+
+
diff --git a/sqlTranslate/src/main/java/Lexer/OracleLexer.java b/sqlTranslate/src/main/java/Lexer/OracleLexer.java
index 3e01431d..87deec53 100644
--- a/sqlTranslate/src/main/java/Lexer/OracleLexer.java
+++ b/sqlTranslate/src/main/java/Lexer/OracleLexer.java
@@ -48,6 +48,8 @@ public class OracleLexer {
"(INTERVAL YEAR TO MONTH)|" +
"(INTERVAL DAY TO SECOND)|" +
"(REF CURSOR)|" +
+ "(GROUP BY)|" +
+ "(ORDER BY)|" +
"(\\b[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*\\b)|" + // Keywords and identifiers
diff --git a/sqlTranslate/src/main/java/Main.java b/sqlTranslate/src/main/java/Main.java
index 470998c8..4cdf9d9f 100644
--- a/sqlTranslate/src/main/java/Main.java
+++ b/sqlTranslate/src/main/java/Main.java
@@ -16,7 +16,7 @@ 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 = "SELECT column1, COUNT(column2) FROM table_name GROUP BY column1 HAVING COUNT(column2) > 10;";
OracleLexer lexer = new OracleLexer(sql);
lexer.printTokens();
OracleParser parser = new OracleParser(lexer);
diff --git a/sqlTranslate/src/main/java/Parser/OracleParser.java b/sqlTranslate/src/main/java/Parser/OracleParser.java
index 425b6333..d0c442a8 100644
--- a/sqlTranslate/src/main/java/Parser/OracleParser.java
+++ b/sqlTranslate/src/main/java/Parser/OracleParser.java
@@ -405,14 +405,14 @@ public class OracleParser {
currentNode.addChild(childNode);
currentNode = childNode;
}
- // match select_tab (possible last token: ; | GROUP | ORDER | HAVING | WHERE | UNION)
+ // match select_tab (possible last token: ; | GROUP BY | ORDER BY | HAVING | WHERE | UNION)
else if (currentNode instanceof SelectObjNode) {
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"))
- || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP"))
- || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER BY"))
|| (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("HAVING"))
|| (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("UNION"))
|| (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";"))
@@ -431,8 +431,8 @@ public class OracleParser {
tokens = new ArrayList<>();
for (int j = i; j < parseTokens.size(); j++) {
if (
- (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP"))
- || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER"))
+ (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER BY"))
|| (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("HAVING"))
|| (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("UNION"))
|| (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";"))
@@ -448,15 +448,20 @@ public class OracleParser {
}
// match select_option
else if (
- (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("GROUP"))
- || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ORDER"))
+ (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ORDER BY"))
|| (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("HAVING"))
) {
tokens = new ArrayList<>();
+ String optionName = parseTokens.get(i).getValue();
for (int j = i; j < parseTokens.size(); j++) {
if (
- (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("UNION"))
+ j != i && !parseTokens.get(j).getValue().equalsIgnoreCase(optionName) &&
+ ((parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("UNION"))
|| (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("HAVING")))
) {
i = j - 1;
break;
@@ -493,7 +498,7 @@ public class OracleParser {
}
else {
try {
- throw new ParseFailedException("Parse failed!");
+ throw new ParseFailedException("Parse failed!--" + parseTokens.get(i).getValue());
}
catch (ParseFailedException e) {
e.printStackTrace();