Oracle支持Sample Clause

git-svn-id: http://code.alibabatech.com/svn/druid/trunk@148 b9813039-fb51-4c41-a8b9-e21c2acb5095
This commit is contained in:
wenshao
2011-05-19 15:44:50 +00:00
parent 55010d5bec
commit e13df989bb
7 changed files with 145 additions and 2 deletions
@@ -0,0 +1,49 @@
package com.alibaba.druid.sql.dialect.oracle.ast.clause;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
public class SampleClause extends OracleSQLObject {
private static final long serialVersionUID = 1L;
private boolean block = false;
private int percent;
private SQLExpr seedValue;
public boolean isBlock() {
return block;
}
public void setBlock(boolean block) {
this.block = block;
}
public int getPercent() {
return percent;
}
public void setPercent(int percent) {
this.percent = percent;
}
public SQLExpr getSeedValue() {
return seedValue;
}
public void setSeedValue(SQLExpr seedValue) {
this.seedValue = seedValue;
}
@Override
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, seedValue);
}
visitor.endVisit(this);
}
}
@@ -16,6 +16,7 @@
package com.alibaba.druid.sql.dialect.oracle.ast.stmt;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.visitor.OracleASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -26,6 +27,8 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
private boolean only = false;
protected OracleSelectPivotBase pivot;
protected SampleClause sampleClause;
public OracleSelectTableReference(){
}
@@ -38,6 +41,14 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
this.only = only;
}
public SampleClause getSampleClause() {
return sampleClause;
}
public void setSampleClause(SampleClause sampleClause) {
this.sampleClause = sampleClause;
}
public OracleSelectPivotBase getPivot() {
return pivot;
}
@@ -54,6 +65,7 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
protected void accept0(OracleASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.expr);
acceptChild(visitor, this.sampleClause);
acceptChild(visitor, this.pivot);
}
visitor.endVisit(this);
@@ -73,6 +85,8 @@ public class OracleSelectTableReference extends SQLExprTableSource implements Or
this.pivot.output(buf);
}
if ((this.alias != null) && (this.alias.length() != 0)) buf.append(this.alias);
if ((this.alias != null) && (this.alias.length() != 0)) {
buf.append(this.alias);
}
}
}
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeInterval;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause;
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;
@@ -51,6 +52,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectOrderByItem;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectRestriction;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectSubqueryTableSource;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectUnPivot;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableColumn;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleTableExpr;
@@ -304,4 +306,11 @@ public interface OracleASTVisitor extends SQLASTVisitor {
boolean visit(OracleUpdateStatement x);
boolean visit(SampleClause x);
void endVisit(SampleClause x);
boolean visit(OracleSelectTableReference x);
void endVisit(OracleSelectTableReference x);
}
@@ -31,6 +31,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleDataTypeInterval;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleHint;
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
import com.alibaba.druid.sql.dialect.oracle.ast.clause.SampleClause;
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;
@@ -715,6 +716,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
} else {
x.getExpr().accept(this);
}
if (x.getSampleClause() != null) {
print(" ");
x.getSampleClause().accept(this);
}
if (x.getPivot() != null) {
incrementIndent();
@@ -1449,4 +1455,34 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
}
@Override
public boolean visit(SampleClause x) {
print("SAMPLE ");
if (x.isBlock()) {
print("BLOCK ");
}
print("(");
print(x.getPercent());
print(")");
if (x.getSeedValue() != null) {
print(" SEED ");
x.getSeedValue().accept(this);
}
return false;
}
@Override
public void endVisit(SampleClause x) {
}
@Override
public void endVisit(OracleSelectTableReference x) {
}
}
@@ -22,6 +22,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
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.SampleClause;
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelect;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectForUpdate;
@@ -294,6 +295,35 @@ public class OracleSelectParser extends SQLSelectParser {
private void parseTableSourceQueryTableExpr(OracleSelectTableReference tableReference) {
tableReference.setExpr(this.createExprParser().expr());
if (identifierEquals("SAMPLE")) {
lexer.nextToken();
SampleClause sample = new SampleClause();
if (identifierEquals("BLOCK")) {
sample.setBlock(true);
}
accept(Token.LPAREN);
if (lexer.token() != Token.LITERAL_INT) {
throw new ParserException("syntax error : " + lexer.token());
}
sample.setPercent(lexer.integerValue().intValue());
lexer.nextToken();
accept(Token.RPAREN);
if (identifierEquals("SEED")) {
lexer.nextToken();
accept(Token.LPAREN);
sample.setSeedValue(expr());
accept(Token.RPAREN);
}
tableReference.setSampleClause(sample);
}
if (identifierEquals("PARTITION")) {
lexer.nextToken();
@@ -22,7 +22,8 @@ public class OracleSQLParserResourceTest extends TestCase {
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-6.txt"); PARTITION
exec_test("bvt/parser/oracle-7.txt");
}
@@ -0,0 +1,4 @@
SELECT COUNT(*) * 10 FROM orders SAMPLE (10);
---------------------------
SELECT COUNT(*) * 10
FROM orders SAMPLE (10);