improve sql parser for db2

This commit is contained in:
wenshao
2013-08-06 09:00:31 +08:00
parent 9aa627bb21
commit eea8492bbd
6 changed files with 215 additions and 23 deletions
@@ -27,6 +27,10 @@ public class DB2SelectQueryBlock extends SQLSelectQueryBlock implements DB2Objec
private Isolation isolation;
private boolean forReadOnly;
private SQLExpr optimizeFor;
public SQLExpr getFirst() {
return first;
}
@@ -65,6 +69,22 @@ public class DB2SelectQueryBlock extends SQLSelectQueryBlock implements DB2Objec
this.isolation = isolation;
}
public boolean isForReadOnly() {
return forReadOnly;
}
public void setForReadOnly(boolean forReadOnly) {
this.forReadOnly = forReadOnly;
}
public SQLExpr getOptimizeFor() {
return optimizeFor;
}
public void setOptimizeFor(SQLExpr optimizeFor) {
this.optimizeFor = optimizeFor;
}
public static enum Isolation {
RR, RS, CS, UR
}
@@ -35,6 +35,7 @@ public class DB2Lexer extends Lexer {
map.put("FETCH", Token.FETCH);
map.put("FIRST", Token.FIRST);
map.put("ONLY", Token.ONLY);
map.put("OPTIMIZE", Token.OPTIMIZE);
DEFAULT_DB2_KEYWORDS = new Keywords(map);
}
@@ -77,31 +77,57 @@ public class DB2SelectParser extends SQLSelectParser {
parseGroupBy(queryBlock);
if (lexer.token() == Token.FETCH) {
lexer.nextToken();
accept(Token.FIRST);
SQLExpr first = this.exprParser.primary();
queryBlock.setFirst(first);
if (identifierEquals("ROW") || identifierEquals("ROWS")) {
lexer.nextToken();
}
accept(Token.ONLY);
}
if (lexer.token() == Token.WITH) {
lexer.nextToken();
if (identifierEquals("RR")) {
queryBlock.setIsolation(Isolation.RR);
} else if (identifierEquals("RS")) {
queryBlock.setIsolation(Isolation.RS);
} else if (identifierEquals("CS")) {
queryBlock.setIsolation(Isolation.CS);
} else if (identifierEquals("UR")) {
queryBlock.setIsolation(Isolation.UR);
} else {
throw new ParserException("TODO");
for (;;) {
if (lexer.token() == Token.FETCH) {
lexer.nextToken();
accept(Token.FIRST);
SQLExpr first = this.exprParser.primary();
queryBlock.setFirst(first);
if (identifierEquals("ROW") || identifierEquals("ROWS")) {
lexer.nextToken();
}
accept(Token.ONLY);
continue;
}
lexer.nextToken();
if (lexer.token() == Token.WITH) {
lexer.nextToken();
if (identifierEquals("RR")) {
queryBlock.setIsolation(Isolation.RR);
} else if (identifierEquals("RS")) {
queryBlock.setIsolation(Isolation.RS);
} else if (identifierEquals("CS")) {
queryBlock.setIsolation(Isolation.CS);
} else if (identifierEquals("UR")) {
queryBlock.setIsolation(Isolation.UR);
} else {
throw new ParserException("TODO");
}
lexer.nextToken();
continue;
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
acceptIdentifier("READ");
accept(Token.ONLY);
queryBlock.setForReadOnly(true);
}
if (lexer.token() == Token.OPTIMIZE) {
lexer.nextToken();
accept(Token.FOR);
queryBlock.setOptimizeFor(this.expr());
if (identifierEquals("ROW")) {
lexer.nextToken();
} else {
acceptIdentifier("ROWS");
}
}
break;
}
return queryRest(queryBlock);
@@ -36,12 +36,23 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit
print(" ROWS ONLY");
}
if (x.isForReadOnly()) {
println();
print("FOR READ ONLY");
}
if (x.getIsolation() != null) {
println();
print("WITH ");
print(x.getIsolation().name());
}
if (x.getOptimizeFor() != null) {
println();
print("OPTIMIZE FOR ");
x.getOptimizeFor().accept(this);
}
return false;
}