📄 parser.java
字号:
}
if(token.equals("UNION")) {
token=tTokenizer.getString();
if(token.equals("ALL")) {
select.iUnionType=Select.UNIONALL;
} else {
select.iUnionType=Select.UNION;
tTokenizer.back();
}
tTokenizer.getThis("SELECT");
select.sUnion=parseSelect();
} else if(token.equals("INTERSECT")) {
tTokenizer.getThis("SELECT");
select.iUnionType=Select.INTERSECT;
select.sUnion=parseSelect();
} else if(token.equals("EXCEPT") || token.equals("MINUS")) {
tTokenizer.getThis("SELECT");
select.iUnionType=Select.EXCEPT;
select.sUnion=parseSelect();
} else {
tTokenizer.back();
}
return select;
}
private TableFilter parseTableFilter(boolean outerjoin) throws SQLException {
String token=tTokenizer.getString();
Table t=null;
if(token.equals("(")) {
tTokenizer.getThis("SELECT");
Select s=parseSelect();
Result r=s.getResult(0);
// it's not a problem that this table has not a unique name
t=new Table(dDatabase,false,"SYSTEM_SUBQUERY",false);
tTokenizer.getThis(")");
t.addColumns(r);
t.createPrimaryKey();
// subquery creation can't fail because of violation of primary key
t.insert(r,cChannel);
} else {
cChannel.check(token,Access.SELECT);
t=dDatabase.getTable(token,cChannel);
}
String sAlias=null;
token=tTokenizer.getString();
if(token.equals("AS")) {
sAlias=tTokenizer.getName();
} else if(tTokenizer.wasName()) {
sAlias=token;
} else {
tTokenizer.back();
}
return new TableFilter(t,sAlias,outerjoin);
}
private Expression addCondition(Expression e1,Expression e2) {
if(e1==null) {
return e2;
} else if(e2==null) {
return e1;
} else {
return new Expression(Expression.AND,e1,e2);
}
}
private Object getValue(int type) throws SQLException {
Expression r=parseExpression();
r.resolve(null);
return r.getValue(type);
}
private Expression parseExpression() throws SQLException {
read();
// todo: really this should be in readTerm
// but then grouping is much more complex
if(iToken==Expression.MIN
|| iToken==Expression.MAX
|| iToken==Expression.COUNT
|| iToken==Expression.SUM
|| iToken==Expression.AVG) {
int type=iToken;
read();
Expression r=new Expression(type,readOr(),null);
tTokenizer.back();
return r;
}
Expression r=readOr();
tTokenizer.back();
return r;
}
private Expression readOr() throws SQLException {
Expression r=readAnd();
while(iToken==Expression.OR) {
int type=iToken;
Expression a=r;
read();
r=new Expression(type,a,readAnd());
}
return r;
}
private Expression readAnd() throws SQLException {
Expression r=readCondition();
while(iToken==Expression.AND) {
int type=iToken;
Expression a=r;
read();
r=new Expression(type,a,readCondition());
}
return r;
}
private Expression readCondition() throws SQLException {
if(iToken==Expression.NOT) {
int type=iToken;
read();
return new Expression(type,readCondition(),null);
} else if(iToken==Expression.EXISTS) {
int type=iToken;
read();
readThis(Expression.OPEN);
Trace.check(iToken==Expression.SELECT,Trace.UNEXPECTED_TOKEN);
Expression s=new Expression(parseSelect());
read();
readThis(Expression.CLOSE);
return new Expression(type,s,null);
} else {
Expression a=readConcat();
boolean not=false;
if(iToken==Expression.NOT) {
not=true;
read();
}
if(iToken==Expression.LIKE) {
read();
Expression b=readConcat();
char escape=0;
if(sToken.equals("ESCAPE")) {
read();
Expression c=readTerm();
Trace.check(c.getType()==Expression.VALUE,Trace.INVALID_ESCAPE);
String s=(String)c.getValue(Column.VARCHAR);
if(s==null || s.length()<1) {
throw Trace.error(Trace.INVALID_ESCAPE,s);
}
escape=s.charAt(0);
}
a=new Expression(Expression.LIKE,a,b);
a.setLikeEscape(escape);
} else if(iToken==Expression.BETWEEN) {
read();
Expression l=new Expression(Expression.BIGGER_EQUAL,a,readConcat());
readThis(Expression.AND);
Expression h=new Expression(Expression.SMALLER_EQUAL,a,readConcat());
a=new Expression(Expression.AND,l,h);
} else if(iToken==Expression.IN) {
int type=iToken;
read();
readThis(Expression.OPEN);
Expression b=null;
if(iToken==Expression.SELECT) {
b=new Expression(parseSelect());
read();
} else if(iToken==Expression.VALUE) {
Vector v=new Vector();
while(true) {
v.addElement(Column.convertObject(oData,Column.VARCHAR));
read();
if(iToken!=Expression.COMMA) {
break;
}
read();
}
b=new Expression(v);
}
readThis(Expression.CLOSE);
a=new Expression(type,a,b);
} else {
Trace.check(!not,Trace.UNEXPECTED_TOKEN);
if(Expression.isCompare(iToken)) {
int type=iToken;
read();
return new Expression(type,a,readConcat());
}
return a;
}
if(not) {
a=new Expression(Expression.NOT,a,null);
}
return a;
}
}
private void readThis(int type) throws SQLException {
Trace.check(iToken==type,Trace.UNEXPECTED_TOKEN);
read();
}
private Expression readConcat() throws SQLException {
Expression r=readSum();
while(iToken==Expression.STRINGCONCAT) {
int type=Expression.CONCAT;
Expression a=r;
read();
r=new Expression(type,a,readSum());
}
return r;
}
private Expression readSum() throws SQLException {
Expression r=readFactor();
while(true) {
int type;
if(iToken==Expression.PLUS) {
type=Expression.ADD;
} else if(iToken==Expression.NEGATE) {
type=Expression.SUBTRACT;
} else {
break;
}
Expression a=r;
read();
r=new Expression(type,a,readFactor());
}
return r;
}
private Expression readFactor() throws SQLException {
Expression r=readTerm();
while(iToken==Expression.MULTIPLY || iToken==Expression.DIVIDE) {
int type=iToken;
Expression a=r;
read();
r=new Expression(type,a,readTerm());
}
return r;
}
private Expression readTerm() throws SQLException {
Expression r=null;
if(iToken==Expression.COLUMN) {
String name=sToken;
r=new Expression(sTable,sToken);
read();
if(iToken==Expression.OPEN) {
Function f=new Function(dDatabase.getAlias(name),cChannel);
int len=f.getArgCount();
int i=0;
read();
if(iToken!=Expression.CLOSE) {
while(true) {
f.setArgument(i++,readOr());
if(iToken!=Expression.COMMA) {
break;
}
read();
}
}
readThis(Expression.CLOSE);
r=new Expression(f);
}
} else if(iToken==Expression.NEGATE) {
int type=iToken;
read();
r=new Expression(type,readTerm(),null);
} else if(iToken==Expression.PLUS) {
read();
r=readTerm();
} else if(iToken==Expression.OPEN) {
read();
r=readOr();
if(iToken!=Expression.CLOSE) {
throw Trace.error(Trace.UNEXPECTED_TOKEN,sToken);
}
read();
} else if(iToken==Expression.VALUE) {
r=new Expression(iType,oData);
read();
} else if(iToken==Expression.SELECT) {
r=new Expression(parseSelect());
read();
} else if(iToken==Expression.MULTIPLY) {
r=new Expression(sTable,null);
read();
} else if(iToken==Expression.IFNULL
|| iToken==Expression.CONCAT) {
int type=iToken;
read();
readThis(Expression.OPEN);
r=readOr();
readThis(Expression.COMMA);
r=new Expression(type,r,readOr());
readThis(Expression.CLOSE);
} else if(iToken==Expression.CASEWHEN) {
int type=iToken;
read();
readThis(Expression.OPEN);
r=readOr();
readThis(Expression.COMMA);
Expression thenelse=readOr();
readThis(Expression.COMMA);
// thenelse part is never evaluated; only init
thenelse=new Expression(type,thenelse,readOr());
r=new Expression(type,r,thenelse);
readThis(Expression.CLOSE);
} else if(iToken==Expression.CONVERT) {
int type=iToken;
read();
readThis(Expression.OPEN);
r=readOr();
readThis(Expression.COMMA);
int t=Column.getTypeNr(sToken);
r=new Expression(type,r,null);
r.setDataType(t);
read();
readThis(Expression.CLOSE);
} else if(iToken==Expression.CAST) {
read();
readThis(Expression.OPEN);
r=readOr();
Trace.check(sToken.equals("AS"),Trace.UNEXPECTED_TOKEN,sToken);
read();
int t=Column.getTypeNr(sToken);
r=new Expression(Expression.CONVERT,r,null);
r.setDataType(t);
read();
readThis(Expression.CLOSE);
} else {
throw Trace.error(Trace.UNEXPECTED_TOKEN,sToken);
}
return r;
}
private void read() throws SQLException {
sToken=tTokenizer.getString();
if(tTokenizer.wasValue()) {
iToken=Expression.VALUE;
oData=tTokenizer.getAsValue();
iType=tTokenizer.getType();
} else if(tTokenizer.wasName()) {
iToken=Expression.COLUMN;
sTable=null;
} else if(tTokenizer.wasLongName()) {
sTable=tTokenizer.getLongNameFirst();
sToken=tTokenizer.getLongNameLast();
if(sToken.equals("*")) {
iToken=Expression.MULTIPLY;
} else {
iToken=Expression.COLUMN;
}
} else if(sToken.equals("")) {
iToken=Expression.END;
} else if(sToken.equals("AND")) {
iToken=Expression.AND;
} else if(sToken.equals("OR")) {
iToken=Expression.OR;
} else if(sToken.equals("NOT")) {
iToken=Expression.NOT;
} else if(sToken.equals("IN")) {
iToken=Expression.IN;
} else if(sToken.equals("EXISTS")) {
iToken=Expression.EXISTS;
} else if(sToken.equals("BETWEEN")) {
iToken=Expression.BETWEEN;
} else if(sToken.equals("+")) {
iToken=Expression.PLUS;
} else if(sToken.equals("-")) {
iToken=Expression.NEGATE;
} else if(sToken.equals("*")) {
iToken=Expression.MULTIPLY;
sTable=null; // in case of ASTERIX
} else if(sToken.equals("/")) {
iToken=Expression.DIVIDE;
} else if(sToken.equals("||")) {
iToken=Expression.STRINGCONCAT;
} else if(sToken.equals("(")) {
iToken=Expression.OPEN;
} else if(sToken.equals(")")) {
iToken=Expression.CLOSE;
} else if(sToken.equals("SELECT")) {
iToken=Expression.SELECT;
} else if(sToken.equals("<")) {
iToken=Expression.SMALLER;
} else if(sToken.equals("<=")) {
iToken=Expression.SMALLER_EQUAL;
} else if(sToken.equals(">=")) {
iToken=Expression.BIGGER_EQUAL;
} else if(sToken.equals(">")) {
iToken=Expression.BIGGER;
} else if(sToken.equals("=")) {
iToken=Expression.EQUAL;
} else if(sToken.equals("IS")) {
sToken=tTokenizer.getString();
if(sToken.equals("NOT")) {
iToken=Expression.NOT_EQUAL;
} else {
iToken=Expression.EQUAL;
tTokenizer.back();
}
} else if(sToken.equals("<>") || sToken.equals("!=")) {
iToken=Expression.NOT_EQUAL;
} else if(sToken.equals("LIKE")) {
iToken=Expression.LIKE;
} else if(sToken.equals("COUNT")) {
iToken=Expression.COUNT;
} else if(sToken.equals("SUM")) {
iToken=Expression.SUM;
} else if(sToken.equals("MIN")) {
iToken=Expression.MIN;
} else if(sToken.equals("MAX")) {
iToken=Expression.MAX;
} else if(sToken.equals("AVG")) {
iToken=Expression.AVG;
} else if(sToken.equals("IFNULL")) {
iToken=Expression.IFNULL;
} else if(sToken.equals("CONVERT")) {
iToken=Expression.CONVERT;
} else if(sToken.equals("CAST")) {
iToken=Expression.CAST;
} else if(sToken.equals("CASEWHEN")) {
iToken=Expression.CASEWHEN;
} else if(sToken.equals(",")) {
iToken=Expression.COMMA;
} else {
iToken=Expression.END;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -