📄 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.HashMappedList;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.isError()) { session.endSchemaDefinition(); break; } if (session.getScripting()) { database.logger.writeToLog(session, tokenizer.getLastPart()); } } } catch (Throwable t) { try { if (session.isSchemaDefintion()) { HsqlName schemaName = session.getSchemaHsqlName(null); database.schemaManager.dropSchema(schemaName.name, true); database.logger.writeToLog(session, Token.T_DROP + ' ' + Token.T_SCHEMA + ' ' + schemaName.statementName + ' ' + Token.T_CASCADE); 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 : throw Trace.error(Trace.INVALID_IDENTIFIER, Trace.IN_SCHEMA_DEFINITION, new Object[]{ token }); } } switch (cmd) { case Token.OPENBRACKET : { Parser parser = new Parser(session, database, tokenizer); brackets = parser.parseOpenBracketsSelect() + 1; } 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, null); 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, null); 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, null); 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, null); 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, null); break; } case Token.SET : processSet(); break; case Token.COMMIT : processCommit(); break; case Token.ROLLBACK : processRollback(); break; case Token.SAVEPOINT : processSavepoint(); break; case Token.RELEASE : processReleaseSavepoint(); break; case Token.CREATE : processCreate(); database.setMetaDirty(false); 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; 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -