📄 parser.java
字号:
int col = table.getColumnCount(); for (int c = 0; c < col; c++) { Expression ins = new Expression(f.getName(), table.getColumn(c)); vcolumn.add(current++, ins); // now there is one element more to parse len++; } } Trace.check(table != null, Trace.TABLE_NOT_FOUND, n); // minus the asterix element len--; vcolumn.remove(current); } else /* if (e.getType() == Expression.COLUMN) */ { if (e.getFilter() == null) { for (int f = 0; f < filters.length; f++) { e.resolveTables(filters[f]); } } } } for (int i = 0; i < len; i++) { Expression e = (Expression) (vcolumn.get(i)); e.resolveTypes(session); } select.iResultLen = len; } /** * Resolves an ORDER BY Expression, returning the column Expression object * to which it refers if it is an alias or column index. <p> * * If select is a SET QUERY, then only column indexes or names in the first * query are allowed. * * @param e search column expression * @param vcolumn list of columns * @param union is select a union * @return new or the same expression * @throws HsqlException if an ambiguous reference to an alias or * non-integer column index is encountered */ private static Expression resolveOrderByExpression(Expression e, Select select, HsqlArrayList vcolumn) throws HsqlException { int visiblecols = select.iResultLen; boolean union = select.unionSelect != null; 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) || token.equals(Token.T_RIGHT)) &&!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 : {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -