📄 parser.java
字号:
vcolumn.add(e); len++; } while (token.equals(Token.T_COMMA)); tokenizer.back(); select.iOrderLen = len; } private void resolveSelectTableFilter(Select select, HsqlArrayList vcolumn, HsqlArrayList vfilter) throws HsqlException { int colcount; TableFilter[] filters = new TableFilter[vfilter.size()]; vfilter.toArray(filters); select.tFilter = filters; // expand [table.]* columns colcount = vcolumn.size(); for (int pos = 0; pos < colcount; ) { Expression e = (Expression) (vcolumn.get(pos)); if (e.getType() == Expression.ASTERISK) { vcolumn.remove(pos); colcount = vcolumn.size(); String tablename = e.getTableName(); int oldPos = pos; if (tablename == null) { for (int i = 0; i < filters.length; i++) { pos = addFilterColumns(filters[i], vcolumn, pos); colcount = vcolumn.size(); } } else { TableFilter f = e.findTableFilter(filters); if (f == null) { throw Trace.error(Trace.TABLE_NOT_FOUND, tablename); } pos = addFilterColumns(f, vcolumn, pos); colcount = vcolumn.size(); } if (isCompilingView()) { // find this expression's position in the Select's asterisk list boolean foundAsteriskPos = false; Iterator expSearch = select.asteriskPositions.keySet().iterator(); while (expSearch.hasNext()) { int expPos = expSearch.nextInt(); if (e == select.asteriskPositions.get(expPos)) { // compile the complete column list which later is to replace the asterisk StringBuffer completeColList = new StringBuffer(); for (int col = oldPos; col < pos; ++col) { Expression resolvedColExpr = (Expression) (vcolumn.get(col)); completeColList.append( resolvedColExpr.getColumnDDL()); if (col < pos - 1) { completeColList.append(","); } } select.asteriskPositions.put( expPos, completeColList.toString()); foundAsteriskPos = true; break; } } Trace.doAssert(foundAsteriskPos); } } else { if (e.getFilter() == null) { for (int i = 0; i < filters.length; i++) { e.resolveTables(filters[i]); } } pos++; } } for (int i = 0; i < colcount; i++) { Expression e = (Expression) (vcolumn.get(i)); e.resolveTypes(session); } select.iResultLen = colcount; } /** * Add all columns of a table filter to list of columns */ int addFilterColumns(TableFilter filter, HsqlArrayList columnList, int position) throws HsqlException { Table table = filter.getTable(); int count = table.getColumnCount(); for (int i = 0; i < count; i++) { Expression e = new Expression(filter, table.getColumn(i)); if (isCompilingView()) { e.resolveTables(filter); } columnList.add(position++, e); } return position; } /** * 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, null, 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 = null; String sAlias = null; HashMappedList columnList = null; if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { int brackets = parseOpenBrackets(); 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(); if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { tokenizer.back(); columnList = parseColumnList(); } } else if (tokenizer.wasSimpleName()) { sAlias = token; if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { tokenizer.back(); columnList = parseColumnList(); } } else { tokenizer.back(); } if (columnList != null && t.getColumnCount() != columnList.size()) { throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH); } return new TableFilter(t, sAlias, columnList, outerjoin); } /** * 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 *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -