📄 parser.java
字号:
token = tokenizer.getString(); } vcolumn.add(e); } while (tokenizer.wasThis(Token.T_COMMA)); if (token.equals(Token.T_INTO)) { boolean getname = true; token = tokenizer.getString(); select.intoType = database.getDefaultTableType(); if (tokenizer.wasSimpleToken()) { switch (Token.get(token)) { case Token.CACHED : select.intoType = Table.CACHED_TABLE; break; case Token.TEMP : select.intoType = Table.TEMP_TABLE; break; case Token.TEXT : select.intoType = Table.TEXT_TABLE; break; case Token.MEMORY : select.intoType = Table.MEMORY_TABLE; break; default : getname = false; break; } if (getname) { token = tokenizer.getName(); } } if (!tokenizer.wasName()) { tokenizer.throwUnexpected(); } select.sIntoTable = database.nameManager.newHsqlName(token, tokenizer.wasQuotedIdentifier()); select.sIntoTable.schema = session.getSchemaHsqlName(tokenizer.getLongNameFirst()); token = tokenizer.getString(); } tokenizer.matchThis(Token.T_FROM); Expression condition = null; // parse table list HsqlArrayList vfilter = new HsqlArrayList(); vfilter.add(parseTableFilter(false)); while (true) { token = tokenizer.getString(); boolean cross = false; if (tokenizer.wasThis(Token.T_INNER)) { tokenizer.getThis(Token.T_JOIN); token = Token.T_JOIN; } else if (tokenizer.wasThis(Token.T_CROSS)) { tokenizer.getThis(Token.T_JOIN); token = Token.T_JOIN; cross = true; } if (token.equals(Token.T_LEFT) && !tokenizer.wasQuotedIdentifier()) { tokenizer.isGetThis(Token.T_OUTER); tokenizer.getThis(Token.T_JOIN); TableFilter tf = parseTableFilter(true); vfilter.add(tf); tokenizer.getThis(Token.T_ON); Expression newcondition = parseExpression(); newcondition.checkTables(vfilter); condition = addJoinCondition(condition, newcondition, tf, true); // MarcH HuugO RIGHT JOIN SUPPORT } else if (token.equals(Token.T_RIGHT) && !tokenizer.wasQuotedIdentifier()) { tokenizer.isGetThis(Token.T_OUTER); tokenizer.getThis(Token.T_JOIN); // this object is not an outerjoin, the next object is an outerjoin TableFilter tf = parseTableFilter(false); // insert new condition as first element in a new vfilter (nvfilter), copy the content of vfilter and rename nvfilter back to vfilter. HsqlArrayList nvfilter = new HsqlArrayList(); nvfilter.add(tf); nvfilter.addAll(vfilter); vfilter = nvfilter; // set isOuterJoin correct ((TableFilter) vfilter.get(1)).isOuterJoin = true; tokenizer.getThis(Token.T_ON); Expression newcondition = parseExpression(); newcondition.checkTables(vfilter); condition = addJoinCondition(condition, newcondition, ((TableFilter) vfilter.get(1)), true); } else if (tokenizer.wasThis(Token.T_JOIN)) { vfilter.add(parseTableFilter(false)); if (!cross) { tokenizer.getThis(Token.T_ON); Expression newcondition = parseExpression(); newcondition.checkTables(vfilter); condition = addJoinCondition(condition, newcondition, null, false); } } else if (tokenizer.wasThis(Token.T_COMMA)) { vfilter.add(parseTableFilter(false)); } else { tokenizer.back(); break; } } resolveSelectTableFilter(select, vcolumn, vfilter); // where token = tokenizer.getString(); if (tokenizer.wasThis(Token.T_WHERE)) { Expression newcondition = parseExpression(); condition = addCondition(condition, newcondition); token = tokenizer.getString(); } select.queryCondition = condition; // group by if (tokenizer.wasThis(Token.T_GROUP)) { tokenizer.getThis(Token.T_BY); int len = 0; do { Expression e = parseExpression(); vcolumn.add(e); token = tokenizer.getString(); len++; } while (tokenizer.wasThis(Token.T_COMMA)); select.iGroupLen = len; } // having if (tokenizer.wasThis(Token.T_HAVING)) { select.iHavingLen = 1; select.havingCondition = parseExpression(); token = tokenizer.getString(); vcolumn.add(select.havingCondition); } if (isMain || limitWithOrder) { if (tokenizer.wasThis(Token.T_ORDER)) { tokenizer.getThis(Token.T_BY); parseOrderBy(select, vcolumn); token = tokenizer.getString(); } if (tokenizer.wasThis(Token.T_LIMIT)) { parseLimit(token, select, true); token = tokenizer.getString(); } } boolean closebrackets = false; if (brackets > 0 && token.equals(Token.T_CLOSEBRACKET)) { closebrackets = true; brackets -= parseCloseBrackets(brackets - 1) + 1; token = tokenizer.getString(); } select.unionDepth = brackets; // checks for ORDER and LIMIT if (!(isMain || closebrackets)) { limitWithOrder = false; } boolean hasOrder = select.iOrderLen != 0; boolean hasLimit = select.limitCondition != null; if (limitWithOrder) { if (hasLimit && !hasOrder) { throw Trace.error(Trace.ORDER_LIMIT_REQUIRED); } } else { if (hasOrder && !canHaveOrder) { throw Trace.error(Trace.INVALID_ORDER_BY); } if (hasLimit && !canHaveLimit) { throw Trace.error(Trace.INVALID_LIMIT); } } int unionType = parseUnion(token); if (unionType != Select.NOUNION) { boolean openbracket = false; select.unionType = unionType; if (tokenizer.isGetThis(Token.T_OPENBRACKET)) { openbracket = true; brackets += parseOpenBrackets() + 1; } tokenizer.getThis(Token.T_SELECT); // accept ORDRY BY with LIMIT when in brackets select.unionSelect = parseSelect(brackets, false, false, openbracket, false); token = tokenizer.getString(); } if (isMain && (canHaveOrder || limitWithOrder) && select.iOrderLen == 0) { if (tokenizer.wasThis(Token.T_ORDER)) { tokenizer.getThis(Token.T_BY); parseOrderBy(select, vcolumn); token = tokenizer.getString(); select.sortUnion = true; } if (tokenizer.wasThis(Token.T_LIMIT)) { parseLimit(token, select, true); token = tokenizer.getString(); } } tokenizer.back(); if (isMain) { select.prepareUnions(); } int len = vcolumn.size(); select.exprColumns = new Expression[len]; vcolumn.toArray(select.exprColumns); return select; } /** * Parses the given token and any further tokens in tokenizer to return * any UNION or other set operation ID. */ int parseUnion(String token) throws HsqlException { int unionType = Select.NOUNION; if (tokenizer.wasSimpleToken()) { switch (Token.get(token)) { case Token.UNION : token = tokenizer.getSimpleToken(); if (token.equals(Token.T_ALL)) { unionType = Select.UNIONALL; } else if (token.equals(Token.T_DISTINCT)) { unionType = Select.UNION; } else { unionType = Select.UNION; tokenizer.back(); } break; case Token.INTERSECT : tokenizer.isGetThis(Token.T_DISTINCT); unionType = Select.INTERSECT; break; case Token.EXCEPT : case Token.MINUS : tokenizer.isGetThis(Token.T_DISTINCT); unionType = Select.EXCEPT; break; default : break; } } return unionType; }// fredt@users 20011010 - patch 471710 by fredt - LIMIT rewritten// SELECT LIMIT n m DISTINCT ... queries and error message// "SELECT LIMIT n m ..." creates the result set for the SELECT statement then// discards the first n rows and returns m rows of the remaining result set// "SELECT LIMIT 0 m" is equivalent to "SELECT TOP m" or "SELECT FIRST m"// in other RDBMS's// "SELECT LIMIT n 0" discards the first n rows and returns the remaining rows// fredt@users 20020225 - patch 456679 by hiep256 - TOP keyword private void parseLimit(String token, Select select, boolean isEnd) throws HsqlException { if (select.limitCondition != null) { return; } Expression e1 = null; Expression e2; boolean islimit = false; if (isEnd) { if (token.equals(Token.T_LIMIT)) { islimit = true; read(); e2 = readTerm(); if (sToken.equals(Token.T_OFFSET)) { read(); e1 = readTerm(); } tokenizer.back(); } else { return; } } else if (token.equals(Token.T_LIMIT)) { read(); e1 = readTerm(); e2 = readTerm(); islimit = true; tokenizer.back(); } else if (token.equals(Token.T_TOP)) { read(); e2 = readTerm(); tokenizer.back(); } else { return; } if (e1 == null) { e1 = new Expression(Types.INTEGER, ValuePool.getInt(0)); } if (e1.isParam() || (e1.getType() == Expression.VALUE && e1.getDataType() == Types.INTEGER && e1.getValue(null) != null && ((Integer) e1.getValue(null)).intValue() >= 0)) { if (e2.isParam() || (e2.getType() == Expression.VALUE && e2.getDataType() == Types.INTEGER && e2.getValue(null) != null && ((Integer) e2.getValue(null)).intValue() >= 0)) { // necessary for params e1.setDataType(Types.INTEGER); e2.setDataType(Types.INTEGER); select.limitCondition = new Expression(Expression.LIMIT, e1, e2); return; } } int messageid = islimit ? Trace.INVALID_LIMIT_EXPRESSION : Trace.INVALID_TOP_EXPRESSION; throw Trace.error(Trace.WRONG_DATA_TYPE, messageid); } private void parseOrderBy(Select select, HsqlArrayList vcolumn) throws HsqlException { String token; int len = 0; do { Expression e = parseExpression(); e = resolveOrderByExpression(e, select, vcolumn); token = tokenizer.getString(); if (token.equals(Token.T_DESC)) { e.setDescending(); token = tokenizer.getString(); } else if (token.equals(Token.T_ASC)) { token = tokenizer.getString(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -