📄 parser.java
字号:
/* Copyrights and Licenses * * This product includes Hypersonic SQL. * Originally developed by Thomas Mueller and the Hypersonic SQL Group. * * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * - Redistributions of source code must retain the above copyright notice, this list of conditions * and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * - All advertising materials mentioning features or use of this software must display the * following acknowledgment: "This product includes Hypersonic SQL." * - Products derived from this software may not be called "Hypersonic SQL" nor may * "Hypersonic SQL" appear in their names without prior written permission of the * Hypersonic SQL Group. * - Redistributions of any form whatsoever must retain the following acknowledgment: "This * product includes Hypersonic SQL." * This software is provided "as is" and any expressed or implied warranties, including, but * not limited to, the implied warranties of merchantability and fitness for a particular purpose are * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any * direct, indirect, incidental, special, exemplary, or consequential damages (including, but * not limited to, procurement of substitute goods or services; loss of use, data, or profits; * or business interruption). However caused any on any theory of liability, whether in contract, * strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this * software, even if advised of the possibility of such damage. * This software consists of voluntary contributions made by many individuals on behalf of the * Hypersonic SQL Group. * * * For work added by the HSQL Development Group: * * Copyright (c) 2001-2002, The HSQL Development Group * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer, including earlier * license statements (above) and comply with all above license conditions. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution, including earlier * license statements (above) and comply with all above license conditions. * * Neither the name of the HSQL Development Group nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */package org.hsqldb;import org.hsqldb.lib.StringUtil;import java.sql.SQLException;import java.sql.Types;import java.util.Vector;// fredt@users 20020130 - patch 491987 by jimbag@users - made optional// changes applied to different parts of this method// fredt@users 20020215 - patch 1.7.0 by fredt - quoted identifiers// support for sql standard quoted identifiers for column and table names// fredt@users 20020218 - patch 1.7.0 by fredt - DEFAULT keyword// support for default values for table columns// fredt@users 20020425 - patch 548182 by skitt@users - DEFAULT enhancement// thertz@users 20020320 - patch 473613 by thertz - outer join condition bug// fredt@users 20020420 - patch 523880 by leptipre@users - VIEW support// fredt@users 20020525 - patch 559914 by fredt@users - SELECT INTO logging/** * Class declaration * * @version 1.7.0 */class Parser { private Database dDatabase; private Tokenizer tTokenizer; private Session cSession; private String sTable; private String sToken; private Object oData; private int iType; private int iToken; private static boolean sql_enforce_size; /** * Constructor declaration * * @param db * @param t * @param session */ Parser(Database db, Tokenizer t, Session session) { dDatabase = db; tTokenizer = t; cSession = session; } /** * Sets the enforceSize attribute of the Parser class * * @param value The new enforceSize value */ static void setEnforceSize(boolean value) { sql_enforce_size = value; } /** * Method declaration * * @return * @throws SQLException */ Result processSelect() throws SQLException { Select select = parseSelect(); if (select.sIntoTable == null) { return select.getResult(cSession.getMaxRows()); } else {// fredt@users 20020215 - patch 497872 by Nitin Chauhan// to require column labels in SELECT INTO TABLE for (int i = 0; i < select.eColumn.length; i++) { if (select.eColumn[i].getAlias().length() == 0) { throw Trace.error(Trace.LABEL_REQUIRED); } } if (dDatabase.findUserTable(select.sIntoTable.name, cSession) != null) { throw Trace.error(Trace.TABLE_ALREADY_EXISTS, select.sIntoTable.name); } Result r = select.getResult(0);// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) Table t; if (select.intoType == Table.TEXT_TABLE) { t = new TextTable(dDatabase, select.sIntoTable, select.intoType, cSession); } else { t = new Table(dDatabase, select.sIntoTable, select.intoType, cSession); } t.addColumns(r); t.createPrimaryKey(); dDatabase.linkTable(t);// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) if (select.intoType == Table.TEXT_TABLE) { try { // Use default lowercase name "<table>.csv" (with invalid // char's converted to underscores): String src = StringUtil.toLowerSubset(select.sIntoTable.name, '_') + ".csv"; t.setDataSource(src, false, cSession); logTableDDL(t); t.insert(r, cSession); } catch (SQLException e) { dDatabase.dropTable(select.sIntoTable.name, false, false, cSession); throw (e); } } else { logTableDDL(t); // SELECT .. INTO can't fail because of constraint violation t.insert(r, cSession); } int i = r.getSize(); r = new Result(); r.iUpdateCount = i; return r; } } /** * Logs the DDL for a table created with INTO. * Uses three dummy arguments for getTableDDL() as the new table has no * FK constraints. * * @throws SQLException */ void logTableDDL(Table t) throws SQLException { if (t.isTemp()) { return; } StringBuffer tableDDL = new StringBuffer(); DatabaseScript.getTableDDL(dDatabase, t, 0, null, null, tableDDL); String sourceDDL = DatabaseScript.getDataSource(t); dDatabase.logger.writeToLog(cSession, tableDDL.toString()); if (sourceDDL != null) { dDatabase.logger.writeToLog(cSession, sourceDDL); } } /** * Method declaration * * @return * @throws SQLException */ Result processCall() throws SQLException { Expression e = parseExpression(); e.resolve(null); int type = e.getDataType(); Object o = e.getValue(); Result r = new Result(1); r.sTable[0] = ""; r.colType[0] = type; r.sLabel[0] = ""; r.sName[0] = ""; Object row[] = new Object[1]; row[0] = o; r.add(row); return r; } /** * Method declaration * * @return * @throws SQLException */ Result processUpdate() throws SQLException { String token = tTokenizer.getString(); cSession.checkReadWrite(); cSession.check(token, UserManager.UPDATE); Table table = dDatabase.getTable(token, cSession); TableFilter filter = new TableFilter(table, null, false); if (table.isView()) { throw Trace.error(Trace.NOT_A_TABLE, token); } tTokenizer.getThis("SET"); Vector vColumn = new Vector(); Vector eColumn = new Vector(); int len = 0; token = null; do { len++; int i = table.getColumnNr(tTokenizer.getString()); vColumn.addElement(new Integer(i)); tTokenizer.getThis("="); Expression e = parseExpression(); e.resolve(filter); eColumn.addElement(e); token = tTokenizer.getString(); } while (token.equals(",")); Expression eCondition = null; if (token.equals("WHERE")) { eCondition = parseExpression(); eCondition.resolve(filter); filter.setCondition(eCondition); } else { tTokenizer.back(); } // do the update table.fireAll(TriggerDef.UPDATE_BEFORE); Expression exp[] = new Expression[len]; eColumn.copyInto(exp); int col[] = new int[len]; int type[] = new int[len]; int csize[] = new int[len]; for (int i = 0; i < len; i++) { col[i] = ((Integer) vColumn.elementAt(i)).intValue(); Column column = table.getColumn(col[i]); type[i] = column.getType(); csize[i] = column.getSize(); } int count = 0; if (filter.findFirst()) { Result del = new Result(); // don't need column count and so on Result ins = new Result(); int size = table.getColumnCount(); do { if (eCondition == null || eCondition.test()) { Object nd[] = filter.oCurrentData; del.add(nd); Object ni[] = table.getNewRow();// fredt@users 20020130 - patch 1.7.0 by fredt System.arraycopy(nd, 0, ni, 0, size); /* for (int i = 0; i < size; i++) { ni[i] = nd[i]; } */// fredt@users 20020130 - patch 491987 by jimbag@users - made optional if (sql_enforce_size) { for (int i = 0; i < len; i++) { ni[col[i]] = enforceSize(exp[i].getValue(type[i]), type[i], csize[i], true); } } else { for (int i = 0; i < len; i++) { ni[col[i]] = exp[i].getValue(type[i]); } } ins.add(ni); } } while (filter.next()); cSession.beginNestedTransaction(); try { Record nd = del.rRoot; while (nd != null) { table.fireAll(TriggerDef.UPDATE_BEFORE_ROW, nd.data); table.deleteNoCheck(nd.data, cSession, true); nd = nd.next; } Record ni = ins.rRoot; while (ni != null) { table.insertNoCheck(ni.data, cSession, true); ni = ni.next; count++; } table.checkUpdate(col, del, ins); ni = ins.rRoot; while (ni != null) { // fire triggers now that update has been checked table.fireAll(TriggerDef.UPDATE_AFTER_ROW, ni.data); ni = ni.next; } cSession.endNestedTransaction(false); } catch (SQLException e) { // update failed (constraint violation) cSession.endNestedTransaction(true); throw e; } } table.fireAll(TriggerDef.UPDATE_AFTER); Result r = new Result(); r.iUpdateCount = count; return r; } /** * Method declaration * * @return * @throws SQLException */ Result processDelete() throws SQLException { tTokenizer.getThis("FROM"); String token = tTokenizer.getString(); cSession.checkReadWrite(); cSession.check(token, UserManager.DELETE); Table table = dDatabase.getTable(token, cSession); TableFilter filter = new TableFilter(table, null, false); if (table.isView()) { throw Trace.error(Trace.NOT_A_TABLE, token); } token = tTokenizer.getString(); Expression eCondition = null; if (token.equals("WHERE")) { eCondition = parseExpression(); eCondition.resolve(filter); filter.setCondition(eCondition); } else { tTokenizer.back(); }// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) Trace.check(!table.isDataReadOnly(), Trace.DATA_IS_READONLY); table.fireAll(TriggerDef.DELETE_BEFORE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -