📄 databasecommandinterpreter.java
字号:
/* Copyright (c) 1995-2000, 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.
*
* Neither the name of the Hypersonic SQL 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 THE HYPERSONIC SQL GROUP,
* 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.
*
* 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-2005, 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.
*
* 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.
*
* 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 java.io.IOException;import java.io.LineNumberReader;import java.io.StringReader;import java.util.Locale;import org.hsqldb.HsqlNameManager.HsqlName;import org.hsqldb.lib.ArrayUtil;import org.hsqldb.lib.HashSet;import org.hsqldb.lib.HsqlArrayList;import org.hsqldb.lib.StringUtil;import org.hsqldb.lib.java.JavaSystem;import org.hsqldb.persist.HsqlDatabaseProperties;import org.hsqldb.scriptio.ScriptWriterBase;import org.hsqldb.scriptio.ScriptWriterText;/** * Provides SQL Interpreter services relative to a Session and * its Database. * * The core functionality of this class was inherited from Hypersonic and * extensively rewritten and extended in successive versions of HSQLDB. * * @author Thomas Mueller (Hypersonic SQL Group) * @version 1.8.0 * @since 1.7.2 */// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - various corrections// fredt@users 20020430 - patch 549741 by velichko - ALTER TABLE RENAME// fredt@users 20020405 - patch 1.7.0 - other ALTER TABLE statements// tony_lai@users 20020820 - patch 595099 - use user-defined PK name// tony_lai@users 20020820 - patch 595156 - violation of constraint name// fredt@users 20020912 - patch 1.7.1 by fredt - log alter statements// kloska@users 20021030 - patch 1.7.2 - ON UPDATE CASCADE | SET NULL | SET DEFAULT// kloska@users 20021112 - patch 1.7.2 - ON DELETE SET NULL | SET DEFAULT// boucherb@users 20020310 - disable ALTER TABLE DDL on VIEWs (avoid NPE)// fredt@users 20030314 - patch 1.7.2 by gilead@users - drop table if exists syntax// boucherb@users 20030425 - DDL methods are moved to DatabaseCommandInterpreter.java// boucherb@users 20030425 - refactoring DDL methods into smaller units// fredt@users 20030609 - support for ALTER COLUMN SET/DROP DEFAULT / RENAME TO// wondersonic@users 20031205 - IF EXISTS support for DROP INDEX// fredt@users 20031224 - support for CREATE SEQUENCE ...// fredt@users 20041209 - patch by tytar@users to set default table typeclass DatabaseCommandInterpreter { private Tokenizer tokenizer = new Tokenizer(); private Database database; private Session session; /** * Constructs a new DatabaseCommandInterpreter for the given Session * * @param s session */ DatabaseCommandInterpreter(Session s) { session = s; database = s.getDatabase(); } /** * Executes the SQL String. This method is always called from a block * synchronized on the database object. * * @param sql query * @return the result of executing the given SQL String */ Result execute(String sql) { Result result; String token; int cmd; JavaSystem.gc(); result = null; cmd = Token.UNKNOWNTOKEN; try { tokenizer.reset(sql); while (true) { tokenizer.setPartMarker(); session.setScripting(false); token = tokenizer.getSimpleToken(); if (token.length() == 0) { session.endSchemaDefinition(); break; } cmd = Token.get(token); if (cmd == Token.SEMICOLON) { session.endSchemaDefinition(); continue; } result = executePart(cmd, token); if (result.mode == ResultConstants.ERROR) { session.endSchemaDefinition(); break; } if (session.getScripting()) { database.logger.writeToLog(session, tokenizer.getLastPart()); } } } catch (Throwable t) { try { session.endSchemaDefinition(); } catch (HsqlException e) {} result = new Result(t, tokenizer.getLastPart()); } return result == null ? Session.emptyUpdateCount : result; } private Result executePart(int cmd, String token) throws Throwable { Result result = Session.emptyUpdateCount; int brackets = 0; if (session.isSchemaDefintion()) { switch (cmd) { case Token.CREATE : case Token.GRANT : break; default : String schema = session.getSchemaName(null); session.endSchemaDefinition(); database.schemaManager.dropSchema(schema, true); throw Trace.error(Trace.INVALID_IDENTIFIER, Trace.IN_SCHEMA_DEFINITION, new Object[]{ token }); } } switch (cmd) { case Token.OPENBRACKET : { brackets = Parser.parseOpenBrackets(tokenizer) + 1; tokenizer.getThis(Token.T_SELECT); } case Token.SELECT : { Parser parser = new Parser(session, database, tokenizer); CompiledStatement cStatement = parser.compileSelectStatement(brackets); if (cStatement.parameters.length != 0) { Trace.doAssert( false, Trace.getMessage( Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); } result = session.sqlExecuteCompiledNoPreChecks(cStatement); break; } case Token.INSERT : { Parser parser = new Parser(session, database, tokenizer); CompiledStatement cStatement = parser.compileInsertStatement(); if (cStatement.parameters.length != 0) { Trace.doAssert( false, Trace.getMessage( Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); } result = session.sqlExecuteCompiledNoPreChecks(cStatement); break; } case Token.UPDATE : { Parser parser = new Parser(session, database, tokenizer); CompiledStatement cStatement = parser.compileUpdateStatement(); if (cStatement.parameters.length != 0) { Trace.doAssert( false, Trace.getMessage( Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); } result = session.sqlExecuteCompiledNoPreChecks(cStatement); break; } case Token.DELETE : { Parser parser = new Parser(session, database, tokenizer); CompiledStatement cStatement = parser.compileDeleteStatement(); if (cStatement.parameters.length != 0) { Trace.doAssert( false, Trace.getMessage( Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); } result = session.sqlExecuteCompiledNoPreChecks(cStatement); break; } case Token.CALL : { Parser parser = new Parser(session, database, tokenizer); CompiledStatement cStatement = parser.compileCallStatement(); if (cStatement.parameters.length != 0) { Trace.doAssert( false, Trace.getMessage( Trace.ASSERT_DIRECT_EXEC_WITH_PARAM)); } result = session.sqlExecuteCompiledNoPreChecks(cStatement); break; } case Token.SET : processSet(); break; case Token.COMMIT : processCommit(); break; case Token.ROLLBACK : processRollback(); break; case Token.SAVEPOINT : processSavepoint(); break; case Token.CREATE : processCreate(); database.setMetaDirty(true); break; case Token.ALTER : processAlter(); database.setMetaDirty(true); break; case Token.DROP : processDrop(); database.setMetaDirty(true); break; case Token.GRANT : processGrantOrRevoke(true); database.setMetaDirty(false); break; case Token.REVOKE : processGrantOrRevoke(false); database.setMetaDirty(true); break; case Token.CONNECT : processConnect(); database.setMetaDirty(false); session.setScripting(false); break; case Token.DISCONNECT : processDisconnect(); session.setScripting(true); break; case Token.SCRIPT : result = processScript(); break; case Token.SHUTDOWN : processShutdown(); break; case Token.CHECKPOINT : processCheckpoint(); break; case Token.EXPLAIN : result = processExplainPlan(); break; case Token.RELEASE : processReleaseSavepoint(); break; default : throw Trace.error(Trace.UNEXPECTED_TOKEN, token); } return result; } /** * Responsible for parsing and executing the SCRIPT SQL statement * * @return either an empty result or one in which each row is a DDL or DML * @throws IOException * @throws HsqlException */ private Result processScript() throws IOException, HsqlException { String token = tokenizer.getString(); ScriptWriterText dsw = null; session.checkAdmin(); try { if (tokenizer.wasValue()) { if (tokenizer.getType() != Types.VARCHAR) { throw Trace.error(Trace.INVALID_IDENTIFIER); } dsw = new ScriptWriterText(database, token, true, true, true); dsw.writeAll(); return new Result(ResultConstants.UPDATECOUNT); } else { tokenizer.back(); return DatabaseScript.getScript(database, false); } } finally { if (dsw != null) { dsw.close(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -