📄 parser.java
字号:
e = ec;
break;
}
}
}
token = tTokenizer.getString();
if (token.equals("DESC")) {
e.setDescending();
token = tTokenizer.getString();
} else if (token.equals("ASC")) {
token = tTokenizer.getString();
}
vcolumn.addElement(e);
len++;
} while (token.equals(","));
select.iOrderLen = len;
}
len = vcolumn.size();
select.eColumn = new Expression[len];
vcolumn.copyInto(select.eColumn);
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;
}
/**
* Method declaration
*
*
* @param outerjoin
*
* @return
*
* @throws SQLException
*/
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);
}
/**
* Method declaration
*
*
* @param e1
* @param e2
*
* @return
*/
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);
}
}
/**
* Method declaration
*
*
* @param type
*
* @return
*
* @throws SQLException
*/
private Object getValue(int type) throws SQLException {
Expression r = parseExpression();
r.resolve(null);
return r.getValue(type);
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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;
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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;
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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;
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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 {
tTokenizer.back();
Vector v = new Vector();
while (true) {
v.addElement(getValue(Column.VARCHAR));
read();
if (iToken != Expression.COMMA) {
break;
}
}
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;
}
}
/**
* Method declaration
*
*
* @param type
*
* @throws SQLException
*/
private void readThis(int type) throws SQLException {
Trace.check(iToken == type, Trace.UNEXPECTED_TOKEN);
read();
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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;
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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;
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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;
}
/**
* Method declaration
*
*
* @return
*
* @throws SQLException
*/
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;
}
/**
* Method declaration
*
*
* @throws SQLException
*/
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 + -