mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Oracle支持Flashback Clause
git-svn-id: http://code.alibabatech.com/svn/druid/trunk@152 b9813039-fb51-4c41-a8b9-e21c2acb5095
This commit is contained in:
+7
-3
@@ -6,7 +6,9 @@ import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
|
||||
|
||||
public abstract class FlashbackQueryClause extends OracleSQLObject {
|
||||
|
||||
private Type type;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Type type;
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
@@ -21,7 +23,8 @@ public abstract class FlashbackQueryClause extends OracleSQLObject {
|
||||
}
|
||||
|
||||
public static class VersionsFlashbackQueryClause extends FlashbackQueryClause {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private SQLExpr begin;
|
||||
private SQLExpr end;
|
||||
|
||||
@@ -52,7 +55,8 @@ public abstract class FlashbackQueryClause extends OracleSQLObject {
|
||||
}
|
||||
|
||||
public static class AsOfFlashbackQueryClause extends FlashbackQueryClause {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private SQLExpr expr;
|
||||
|
||||
public SQLExpr getExpr() {
|
||||
|
||||
+7
-1
@@ -744,6 +744,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
if (x.getFlashback() != null) {
|
||||
println();
|
||||
x.getFlashback().accept(this);
|
||||
}
|
||||
|
||||
printAlias(x.getAlias());
|
||||
|
||||
@@ -1545,8 +1550,9 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
public boolean visit(AsOfFlashbackQueryClause x) {
|
||||
print("AS OF ");
|
||||
print(x.getType().name());
|
||||
print(" ");
|
||||
print(" (");
|
||||
x.getExpr().accept(this);
|
||||
print(")");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalytic;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAnalyticWindowing;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleIntervalType;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectOrderByItem;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
@@ -252,4 +253,24 @@ public class OracleExprParser extends SQLExprParser {
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
protected SQLExpr parseInterval() {
|
||||
accept(Token.INTERVAL);
|
||||
|
||||
OracleIntervalExpr interval = new OracleIntervalExpr();
|
||||
if (lexer.token() != Token.LITERAL_CHARS) {
|
||||
throw new ParserException("syntax error : " + lexer.token());
|
||||
}
|
||||
interval.setValue(lexer.stringVal());
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() != Token.IDENTIFIER) {
|
||||
throw new ParserException("syntax error : " + lexer.token());
|
||||
}
|
||||
OracleIntervalType type = OracleIntervalType.valueOf(lexer.stringVal());
|
||||
interval.setType(type);
|
||||
lexer.nextToken();
|
||||
|
||||
return interval;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.alibaba.druid.sql.dialect.oracle.parser;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
@@ -23,6 +25,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.AsOfFlashbackQueryClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.FlashbackQueryClause.VersionsFlashbackQueryClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.PartitionExtensionClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
|
||||
@@ -380,6 +383,34 @@ public class OracleSelectParser extends SQLSelectParser {
|
||||
clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP);
|
||||
}
|
||||
clause.setExpr(createExprParser().primary());
|
||||
|
||||
tableReference.setFlashback(clause);
|
||||
} else {
|
||||
throw new SQLParseException("TODO");
|
||||
}
|
||||
} else if (identifierEquals("VERSIONS")) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.BETWEEN) {
|
||||
lexer.nextToken();
|
||||
|
||||
VersionsFlashbackQueryClause clause = new VersionsFlashbackQueryClause();
|
||||
if (identifierEquals("SCN")) {
|
||||
clause.setType(AsOfFlashbackQueryClause.Type.SCN);
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
acceptIdentifier("TIMESTAMP");
|
||||
clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP);
|
||||
}
|
||||
|
||||
SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) createExprParser().expr();
|
||||
if (binaryExpr.getOperator() != SQLBinaryOperator.BooleanAnd) {
|
||||
throw new SQLParseException("syntax error : " + binaryExpr.getOperator());
|
||||
}
|
||||
|
||||
clause.setBegin(binaryExpr.getLeft());
|
||||
clause.setEnd(binaryExpr.getRight());
|
||||
|
||||
tableReference.setFlashback(clause);
|
||||
} else {
|
||||
throw new SQLParseException("TODO");
|
||||
|
||||
@@ -16,20 +16,22 @@ import com.alibaba.druid.util.JdbcUtils;
|
||||
public class OracleSQLParserResourceTest extends TestCase {
|
||||
|
||||
public void test_0() throws Exception {
|
||||
// exec_test("bvt/parser/oracle-0.txt");
|
||||
// exec_test("bvt/parser/oracle-1.txt");
|
||||
// exec_test("bvt/parser/oracle-2.txt");
|
||||
// exec_test("bvt/parser/oracle-3.txt");
|
||||
// exec_test("bvt/parser/oracle-4.txt");
|
||||
// exec_test("bvt/parser/oracle-5.txt");
|
||||
// exec_test("bvt/parser/oracle-6.txt"); // PARTITION
|
||||
// exec_test("bvt/parser/oracle-7.txt");
|
||||
// exec_test("bvt/parser/oracle-8.txt");
|
||||
exec_test("bvt/parser/oracle-0.txt");
|
||||
exec_test("bvt/parser/oracle-1.txt");
|
||||
exec_test("bvt/parser/oracle-2.txt");
|
||||
exec_test("bvt/parser/oracle-3.txt");
|
||||
exec_test("bvt/parser/oracle-4.txt");
|
||||
exec_test("bvt/parser/oracle-5.txt");
|
||||
exec_test("bvt/parser/oracle-6.txt"); // PARTITION
|
||||
exec_test("bvt/parser/oracle-7.txt");
|
||||
exec_test("bvt/parser/oracle-8.txt");
|
||||
exec_test("bvt/parser/oracle-9.txt");
|
||||
exec_test("bvt/parser/oracle-10.txt");
|
||||
}
|
||||
|
||||
|
||||
public void exec_test(String resource) throws Exception {
|
||||
System.out.println(resource);
|
||||
InputStream is = null;
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
SELECT salary FROM employees
|
||||
VERSIONS BETWEEN TIMESTAMP
|
||||
SYSTIMESTAMP - INTERVAL '10' MINUTE AND
|
||||
SYSTIMESTAMP - INTERVAL '1' MINUTE
|
||||
WHERE last_name = 'Chung';
|
||||
---------------------------
|
||||
SELECT salary
|
||||
FROM employees
|
||||
VERSIONS BETWEEN TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE AND SYSTIMESTAMP - INTERVAL '1' MINUTE
|
||||
WHERE last_name = 'Chung';
|
||||
@@ -9,9 +9,9 @@ FROM
|
||||
FROM employees) b
|
||||
ORDER BY a.department_id;
|
||||
---------------------------
|
||||
SELECT a.department_id AS 'department_id', a.num_emp / b.total_count AS 'total_count', a.sal_sum / b.total_sal AS 'total_sal'
|
||||
FROM (SELECT department_id, COUNT(*) AS 'num_emp', SUM(salary) AS 'sal_sum'
|
||||
SELECT a.department_id AS department_id, a.num_emp / b.total_count AS total_count, a.sal_sum / b.total_sal AS total_sal
|
||||
FROM (SELECT department_id, COUNT(*) AS num_emp, SUM(salary) AS sal_sum
|
||||
FROM employees
|
||||
GROUP BY department_id) 'a' , (SELECT COUNT(*) AS 'total_count', SUM(salary) AS 'total_sal'
|
||||
FROM employees) 'b'
|
||||
GROUP BY department_id) a , (SELECT COUNT(*) AS total_count, SUM(salary) AS total_sal
|
||||
FROM employees) b
|
||||
ORDER BY a.department_id;
|
||||
@@ -2,6 +2,7 @@ SELECT salary FROM employees
|
||||
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' MINUTE)
|
||||
WHERE last_name = 'Chung';
|
||||
---------------------------
|
||||
SELECT salary FROM employees
|
||||
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' MINUTE)
|
||||
WHERE last_name = 'Chung';
|
||||
SELECT salary
|
||||
FROM employees
|
||||
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' MINUTE)
|
||||
WHERE last_name = 'Chung';
|
||||
Reference in New Issue
Block a user