📄 parser.java
字号:
int count = 0; if (filter.findFirst()) { Result del = new Result(); // don't need column count and so on do { if (eCondition == null || eCondition.test()) { del.add(filter.oCurrentData); } } while (filter.next()); Record n = del.rRoot; while (n != null) { table.delete(n.data, cSession); count++; n = n.next; } } table.fireAll(TriggerDef.DELETE_AFTER); Result r = new Result(); r.iUpdateCount = count; return r; } /** * Method declaration * * @return * @throws SQLException */ Result processInsert() throws SQLException { tTokenizer.getThis("INTO"); String token = tTokenizer.getString(); cSession.checkReadWrite(); cSession.check(token, UserManager.INSERT); Table t = dDatabase.getTable(token, cSession); if (t.isView()) { throw Trace.error(Trace.NOT_A_TABLE, token); } token = tTokenizer.getString(); Vector vcolumns = null; if (token.equals("(")) { vcolumns = new Vector(); int i = 0; while (true) { vcolumns.addElement(tTokenizer.getString()); i++; token = tTokenizer.getString(); if (token.equals(")")) { break; } if (!token.equals(",")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } } token = tTokenizer.getString(); } int count = 0; int len; if (vcolumns == null) { len = t.getColumnCount(); } else { len = vcolumns.size(); }// fredt@users 20020218 - patch 1.7.0 by fredt - DEFAULT keyword if (token.equals("VALUES")) { tTokenizer.getThis("("); Object row[] = t.getNewRow(); boolean check[] = (vcolumns == null) ? null : new boolean[row.length]; int i = 0; while (true) { int colindex; if (vcolumns == null) { colindex = i; if (i == len) { // fredt will be caught in Trace.check below break; } } else { colindex = t.getColumnNr((String) vcolumns.elementAt(i)); check[colindex] = true; } Column column = t.getColumn(colindex);// fredt@users 20020130 - patch 491987 by jimbag@users - made optional if (sql_enforce_size) { row[colindex] = enforceSize(getValue(column.getType()), column.getType(), column.getSize(), true); } else { row[colindex] = getValue(column.getType()); } i++; token = tTokenizer.getString(); if (token.equals(")")) { break; } if (!token.equals(",")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } } Trace.check(len == i, Trace.COLUMN_COUNT_DOES_NOT_MATCH); if (vcolumns != null) { for (i = 0; i < check.length; i++) { if (check[i] == false) { String def = t.getColumn(i).getDefaultString(); if (def != null) { row[i] = Column.convertObject( def, t.getColumn(i).getType()); } } } } t.insert(row, cSession); count = 1; } else if (token.equals("SELECT")) { Result result = processSelect(); Record r = result.rRoot; Trace.check(len == result.getColumnCount(), Trace.COLUMN_COUNT_DOES_NOT_MATCH); int col[] = new int[len]; int type[] = new int[len]; for (int i = 0; i < len; i++) { int j; if (vcolumns == null) { j = i; } else { j = t.getColumnNr((String) vcolumns.elementAt(i)); } col[i] = j; type[i] = t.getColumn(j).getType(); } cSession.beginNestedTransaction(); try { while (r != null) { Object row[] = t.getNewRow(); boolean check[] = new boolean[row.length]; for (int i = 0; i < len; i++) { check[col[i]] = true; if (type[i] != result.colType[i]) { row[col[i]] = Column.convertObject(r.data[i], type[i]); } else { row[col[i]] = r.data[i]; } } // skitt@users - this is exactly the same loop as the // above - it probably should be in a separate method for (int i = 0; i < check.length; i++) { if (check[i] == false) { String def = t.getColumn(i).getDefaultString(); if (def != null) { row[i] = Column.convertObject( def, t.getColumn(i).getType()); } } } t.insert(row, cSession); count++; r = r.next; } cSession.endNestedTransaction(false); } catch (SQLException e) { // insert failed (violation of primary key) cSession.endNestedTransaction(true); throw e; } } else { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } Result r = new Result(); r.iUpdateCount = count; return r; }// fredt@users 20020130 - patch 491987 by jimbag@users - modified /** * Check an object for type CHAR and VARCHAR and truncate/pad based on * the size * * @param obj object to check * @param type the object type * @param size size to enforce * @param pad pad strings * @return the altered object if the right type, else the object * passed in unaltered */ static Object enforceSize(Object obj, int type, int size, boolean pad) { // todo: need to handle BINARY like this as well if (size == 0 || obj == null) { return obj; } switch (type) { case Types.CHAR : return padOrTrunc((String) obj, size, pad); case Types.VARCHAR : if (((String) obj).length() > size) { // Just truncate for VARCHAR type return ((String) obj).substring(0, size); } default : return obj; } } /** * Pad or truncate a string to len size * * @param s the string to pad to truncate * @param len the len to make the string * @param pad pad the string * @return the string of size len */ static String padOrTrunc(String s, int len, boolean pad) { if (s.length() >= len) { return s.substring(0, len); } StringBuffer b = new StringBuffer(len); b.append(s); if (pad) { for (int i = s.length(); i < len; i++) { b.append(' '); } } return b.toString(); } /** * Method declaration * * @return * @throws SQLException */ Select parseSelect() throws SQLException { Select select = new Select();// 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 String token = tTokenizer.getString(); if (token.equals("LIMIT")) { String limStart = tTokenizer.getString(); String limEnd = tTokenizer.getString(); try { select.limitStart = new Integer(limStart).intValue(); select.limitCount = new Integer(limEnd).intValue(); } catch (NumberFormatException ex) { // todo: add appropriate error type and message to Trace.java throw Trace.error(Trace.WRONG_DATA_TYPE, "LIMIT n m"); } token = tTokenizer.getString(); } else if (token.equals("TOP")) { String limEnd = tTokenizer.getString(); try { select.limitStart = 0; select.limitCount = new Integer(limEnd).intValue(); } catch (NumberFormatException ex) { // todo: add appropriate error type and message to Trace.java throw Trace.error(Trace.WRONG_DATA_TYPE, "TOP m"); } token = tTokenizer.getString(); } if (token.equals("DISTINCT")) { select.isDistinctSelect = true; } else { tTokenizer.back(); } // parse column list Vector vcolumn = new Vector(); do { Expression e = parseExpression(); token = tTokenizer.getString(); if (token.equals("AS")) { e.setAlias(tTokenizer.getName(), tTokenizer.wasQuotedIdentifier()); token = tTokenizer.getString(); } else if (tTokenizer.wasName()) { e.setAlias(token, tTokenizer.wasQuotedIdentifier()); token = tTokenizer.getString(); } vcolumn.addElement(e); } while (token.equals(",")); if (token.equals("INTO")) {// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) token = tTokenizer.getString(); if (token.equals("CACHED")) { select.intoType = Table.CACHED_TABLE; select.sIntoTable = new HsqlName(tTokenizer.getString(), tTokenizer.wasQuotedIdentifier()); } else if (token.equals("TEMP")) { select.intoType = Table.TEMP_TABLE; select.sIntoTable = new HsqlName(tTokenizer.getString(), tTokenizer.wasQuotedIdentifier()); } else if (token.equals("TEXT")) { select.intoType = Table.TEXT_TABLE; select.sIntoTable = new HsqlName(tTokenizer.getString(), tTokenizer.wasQuotedIdentifier()); } else { select.sIntoTable = new HsqlName(token, tTokenizer.wasQuotedIdentifier()); } token = tTokenizer.getString(); } if (!token.equals("FROM")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } Expression condition = null; // parse table list Vector vfilter = new Vector(); vfilter.addElement(parseTableFilter(false)); while (true) { token = tTokenizer.getString(); if (token.equals("LEFT")) { token = tTokenizer.getString(); if (token.equals("OUTER")) { token = tTokenizer.getString(); } Trace.check(token.equals("JOIN"), Trace.UNEXPECTED_TOKEN, token); vfilter.addElement(parseTableFilter(true)); tTokenizer.getThis("ON");// thertz@users 20020320 - patch 473613 - outer join condition bug// we now call parseJoinCondition() because a limitation of HSQLDB results// in incorrect results for OUTER JOINS that have anything other than// tableA.colA=tableB.colB type expressions //condition = addCondition(condition, parseExpression()); condition = addCondition(condition, parseOuterJoinCondition()); } else if (token.equals("INNER")) { tTokenizer.getThis("JOIN"); vfilter.addElement(parseTableFilter(false)); tTokenizer.getThis("ON"); condition = addCondition(condition, parseExpression()); } else if (token.equals(",")) { vfilter.addElement(parseTableFilter(false)); } else { break; } } tTokenizer.back(); int len = vfilter.size(); TableFilter filter[] = new TableFilter[len]; vfilter.copyInto(filter); select.tFilter = filter; // expand [table.]* columns len = vcolumn.size(); for (int i = 0; i < len; i++) { Expression e = (Expression) (vcolumn.elementAt(i)); if (e.getType() == Expression.ASTERIX) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -