📄 parser.java
字号:
if (e.getType() == Expression.VALUE) { return resolveOrderByColumnIndex(e, vcolumn, visiblecols); } if (e.getType() != Expression.COLUMN) { if (union) { throw Trace.error(Trace.INVALID_ORDER_BY); } return e; } String ecolname = e.getColumnName(); String etablename = e.getTableName(); for (int i = 0, size = visiblecols; i < size; i++) { Expression colexpr = (Expression) vcolumn.get(i); String colalias = colexpr.getDefinedAlias(); String colname = colexpr.getColumnName(); String tablename = colexpr.getTableName(); String filtername = colexpr.getFilterTableName(); if ((ecolname.equals(colalias) || ecolname.equals(colname)) && (etablename == null || etablename.equals(tablename) || etablename.equals(filtername))) { colexpr.joinedTableColumnIndex = i; return colexpr; } } if (union) { throw Trace.error(Trace.INVALID_ORDER_BY, ecolname); } return e; } private static Expression resolveOrderByColumnIndex(Expression e, HsqlArrayList vcolumn, int visiblecols) throws HsqlException { // order by 1,2,3 if (e.getDataType() == Types.INTEGER) { int i = ((Integer) e.getValue(null)).intValue(); if (0 < i && i <= visiblecols) { Expression colexpr = (Expression) vcolumn.get(i - 1); colexpr.joinedTableColumnIndex = i - 1; return colexpr; } } throw Trace.error(Trace.INVALID_ORDER_BY); } private TableFilter parseSimpleTableFilter(int type) throws HsqlException { String alias = null; String token = tokenizer.getName(); String schema = session.getSchemaName(tokenizer.getLongNameFirst()); Table table = database.schemaManager.getTable(session, token, schema); checkTableWriteAccess(table, type);// token = tokenizer.getString(); if (token.equals(Token.T_AS)) { alias = tokenizer.getSimpleName(); } else if (tokenizer.wasSimpleName()) { alias = token; } else { tokenizer.back(); } return new TableFilter(table, alias, false); } /** * Retrieves a TableFilter object newly constructed from the current * parse context. <p> * * @param outerjoin if the filter is to back an outer join * @return a newly constructed TableFilter object * @throws HsqlException if a parsing error occurs */ private TableFilter parseTableFilter(boolean outerjoin) throws HsqlException { Table t = null; SubQuery sq; TableFilter tf; String sAlias = null; if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { int brackets = Parser.parseOpenBrackets(tokenizer); tokenizer.getThis(Token.T_SELECT); // fredt - not correlated - a joined subquery table must resolve fully sq = parseSubquery(brackets, null, true, Expression.QUERY); tokenizer.getThis(Token.T_CLOSEBRACKET); t = sq.table; } else { String token = tokenizer.getName(); String schema = session.getSchemaName(tokenizer.getLongNameFirst()); t = database.schemaManager.getTable(session, token, schema); session.check(t.getName(), UserManager.SELECT); if (t.isView()) { sq = getViewSubquery((View) t); sq.select = ((View) t).viewSelect; t = sq.table; sAlias = token; } } // fredt - we removed LEFT from the list of reserved words in Tokenizer // to allow LEFT() to work. Thus wasName() will return true for LEFT // and we check separately for this token String token = tokenizer.getString(); if (tokenizer.wasLongName()) { tokenizer.throwUnexpected(); } if (token.equals(Token.T_LEFT) &&!tokenizer.wasQuotedIdentifier()) { tokenizer.back(); } else if (token.equals(Token.T_AS) &&!tokenizer.wasQuotedIdentifier()) { sAlias = tokenizer.getSimpleName(); } else if (tokenizer.wasSimpleName()) { sAlias = token; } else { tokenizer.back(); } tf = new TableFilter(t, sAlias, outerjoin); return tf; } /** * Add a condition from the WHERE clause. * * @param e1 * @param e2 * @return */ private static 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); } } /** * Conjuntively adds a condition from the JOIN table ON clause. * * @param e1 an existing condition with which e2 is to be combined * in order to form a new conjunction * @param e2 the new condition * @param tf the table filter that should become e2's join * table filter * @param outer true if join is outer * @throws HsqlException if e2 responds that it cannot participate * in the join * @return a new Expression object; the conjunction of e1 and e2 */ private static Expression addJoinCondition(Expression e1, Expression e2, TableFilter tf, boolean outer) throws HsqlException { if (!e2.setForJoin(tf, outer)) { throw Trace.error(Trace.OUTER_JOIN_CONDITION); } return addCondition(e1, e2); } /** * Method declaration * * @return the Expression resulting from the parse * @throws HsqlException */ Expression parseExpression() throws HsqlException { read(); Expression r = readOr(); tokenizer.back(); return r; } private Expression readAggregate() throws HsqlException { boolean distinct = false; boolean all = false; int type = iToken; read(); String token = tokenizer.getString(); if (token.equals(Token.T_DISTINCT)) { distinct = true; } else if (token.equals(Token.T_ALL)) { all = true; } else { tokenizer.back(); } readThis(Expression.OPEN); Expression s = readOr(); readThis(Expression.CLOSE); if ((all || distinct) && (type == Expression.STDDEV_POP || type == Expression.STDDEV_SAMP || type == Expression.VAR_POP || type == Expression.VAR_SAMP)) { throw Trace.error(Trace.INVALID_FUNCTION_ARGUMENT); } Expression aggregateExp = new Expression(type, s, null); aggregateExp.setDistinctAggregate(distinct); return aggregateExp; } /** * Method declaration * * @return a disjuntion, possibly degenerate * @throws HsqlException */ private Expression readOr() throws HsqlException { 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 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 += Parser.parseOpenBrackets(tokenizer) + 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 = readTerm(); 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -