📄 parser.java
字号:
* @return a conjunction, possibly degenerate * @throws HsqlException */ private Expression readAnd() throws HsqlException { 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 a predicate, possibly composite * @throws HsqlException */ private Expression readCondition() throws HsqlException { switch (iToken) { case Expression.NOT : { int type = iToken; read(); return new Expression(type, readCondition(), null); } case Expression.EXISTS : { int type = iToken; read(); readThis(Expression.OPEN); int brackets = 0; if (iToken == Expression.OPEN) { brackets += parseOpenBrackets() + 1; read(); } Trace.check(iToken == Expression.SELECT, Trace.UNEXPECTED_TOKEN); SubQuery sq = parseSubquery(brackets, null, false, Expression.EXISTS); Expression s = new Expression(sq); read(); readThis(Expression.CLOSE); return new Expression(type, s, null); } default : { Expression a = readConcat(); if (iToken == Expression.IS) { read(); boolean not; if (iToken == Expression.NOT) { not = true; read(); } else { not = false; } Trace.check(iToken == Expression.VALUE && oData == null, Trace.UNEXPECTED_TOKEN); read(); // TODO: the TableFilter needs a right hand side to avoid null pointer exceptions... a = new Expression(Expression.IS_NULL, a, new Expression(Types.NULL, null)); if (not) { a = new Expression(Expression.NOT, a, null); } return a; } boolean not = false; if (iToken == Expression.NOT) { not = true; read(); } switch (iToken) { case Expression.LIKE : { a = parseLikePredicate(a); break; } case Expression.BETWEEN : { a = parseBetweenPredicate(a); break; } case Expression.IN : { a = this.parseInPredicate(a); break; } default : { 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 Expression parseLikePredicate(Expression a) throws HsqlException { read(); Expression b = readConcat(); Character escape = null; if (sToken.equals(Token.T_ESCAPE)) { read(); Expression c = readTerm(); Trace.check(c.getType() == Expression.VALUE, Trace.INVALID_ESCAPE); String s = (String) c.getValue(session, Types.VARCHAR); // boucherb@users 2003-09-25 // CHECKME: // Assert s.length() == 1 for xxxchar comparisons? // TODO: // SQL200n says binary escape can be 1 or more octets. // Maybe we need to retain s and check this in // Expression.resolve()? if (s == null || s.length() < 1) { throw Trace.error(Trace.INVALID_ESCAPE, s); } escape = new Character(s.charAt(0)); } boolean hasCollation = database.collation.name != null; a = new Expression(a, b, escape, hasCollation); return a; } private Expression parseBetweenPredicate(Expression a) throws HsqlException { read(); Expression l = new Expression(Expression.BIGGER_EQUAL, a, readConcat()); readThis(Expression.AND); Expression h = new Expression(Expression.SMALLER_EQUAL, a, readConcat()); if (l.getArg().isParam() && l.getArg2().isParam()) { throw Trace.error(Trace.UNRESOLVED_PARAMETER_TYPE, Trace.Parser_ambiguous_between1); } if (h.getArg().isParam() && h.getArg2().isParam()) { throw Trace.error(Trace.UNRESOLVED_PARAMETER_TYPE, Trace.Parser_ambiguous_between1); } return new Expression(Expression.AND, l, h); } private Expression parseInPredicate(Expression a) throws HsqlException { int type = iToken; read(); readThis(Expression.OPEN); Expression b = null; int brackets = 0; if (iToken == Expression.OPEN) { brackets += parseOpenBrackets() + 1; read(); } if (iToken == Expression.SELECT) { SubQuery sq = parseSubquery(brackets, null, false, Expression.IN); // until we support rows in IN predicates Trace.check(sq.select.iResultLen == 1, Trace.SINGLE_COLUMN_EXPECTED); b = new Expression(sq); read(); } else { tokenizer.back(); HsqlArrayList v = new HsqlArrayList(); while (true) { Expression value = parseExpression(); if (value.exprType == Expression.VALUE && value.valueData == null && !value.isParam()) { throw Trace.error(Trace.NULL_IN_VALUE_LIST); } v.add(value); read(); if (iToken != Expression.COMMA) { break; } } Expression[] valueList; valueList = (Expression[]) v.toArray(new Expression[v.size()]); b = new Expression(valueList); } readThis(Expression.CLOSE); return new Expression(type, a, b); } private Expression parseAllAnyPredicate() throws HsqlException { int type = iToken; read(); readThis(Expression.OPEN); Expression b = null; int brackets = 0; if (iToken == Expression.OPEN) { brackets += parseOpenBrackets() + 1; read(); } if (iToken != Expression.SELECT) { throw Trace.error(Trace.INVALID_IDENTIFIER); } SubQuery sq = parseSubquery(brackets, null, false, type); Select select = sq.select; // until we support rows Trace.check(sq.select.iResultLen == 1, Trace.SINGLE_COLUMN_EXPECTED); b = new Expression(sq); read(); readThis(Expression.CLOSE); return new Expression(type, b, null); } /** * Method declaration * * @param type * @throws HsqlException */ private void readThis(int type) throws HsqlException { Trace.check(iToken == type, Trace.UNEXPECTED_TOKEN); read(); } /** * Method declaration * * @return a concatenation, possibly degenerate * @throws HsqlException */ private Expression readConcat() throws HsqlException { Expression r = readSum(); while (iToken == Expression.CONCAT) { int type = Expression.CONCAT; Expression a = r; read(); r = new Expression(type, a, readSum()); } return r; } static HashMap simpleFunctions = new HashMap(); static { simpleFunctions.put(Token.T_CURRENT_DATE, "org.hsqldb.Library.curdate"); simpleFunctions.put(Token.T_CURRENT_TIME, "org.hsqldb.Library.curtime"); simpleFunctions.put(Token.T_CURRENT_TIMESTAMP, "org.hsqldb.Library.now"); simpleFunctions.put(Token.T_CURRENT_USER, "org.hsqldb.Library.user"); simpleFunctions.put(Token.T_SYSDATE, "org.hsqldb.Library.curdate"); simpleFunctions.put(Token.T_NOW, "org.hsqldb.Library.now"); simpleFunctions.put(Token.T_TODAY, "org.hsqldb.Library.curdate"); } /** * Method declaration * * @return a summation, possibly degenerate * @throws HsqlException */ private Expression readSum() throws HsqlException { 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 a product, possibly degenerate * @throws HsqlException */ private Expression readFactor() throws HsqlException { 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 a term, possibly composite * @throws HsqlException */ private Expression readTerm() throws HsqlException { Expression r = null; switch (iToken) { case Expression.COLUMN : { r = readColumnExpression(); break; } case Expression.NEGATE : { int type = iToken; read(); r = new Expression(type, readTerm(), null); Trace.check(!r.getArg().isParam(), Trace.Expression_resolveTypes1); break; } case Expression.PLUS : { read(); r = readTerm(); Trace.check(!r.isParam(), Trace.UNRESOLVED_PARAMETER_TYPE, Trace.getMessage(Trace.Expression_resolveTypes1)); break; } case Expression.OPEN : { read();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -