/* Copyright (c) 2001-2009, 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 org.hsqldb.HsqlNameManager.HsqlName; import org.hsqldb.persist.HsqlDatabaseProperties; import org.hsqldb.result.Result; import org.hsqldb.rights.User; import org.hsqldb.scriptio.ScriptWriterText; /** * Implementation of Statement for SQL commands.<p> * * @author Fred Toussi (fredt@users dot sourceforge.net) * @version 1.9.0 * @since 1.9.0 */ public class StatementCommand extends Statement { Expression[] expressions; Object[] parameters; StatementCommand(int type, Object[] args, HsqlName readName, HsqlName writeName) { super(type); this.isTransactionStatement = true; this.parameters = args; if (readName != null) { this.readTableNames = new HsqlName[]{ readName }; } if (writeName != null) { this.writeTableNames = new HsqlName[]{ writeName }; } switch (type) { case StatementTypes.DATABASE_BACKUP : case StatementTypes.DATABASE_CHECKPOINT : case StatementTypes.DATABASE_SCRIPT : group = StatementTypes.X_HSQLDB_OPERATION; isLogged = false; break; case StatementTypes.SET_DATABASE_FILES_WRITE_DELAY : this.isTransactionStatement = false; group = StatementTypes.X_HSQLDB_SETTING; break; // case StatementTypes.SET_DATABASE_DEFAULT_INITIAL_SCHEMA : case StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE : case StatementTypes.SET_DATABASE_FILES_CACHE_FILE_SCALE : case StatementTypes.SET_DATABASE_FILES_CACHE_SIZE : case StatementTypes.SET_DATABASE_FILES_DEFRAG : case StatementTypes.SET_DATABASE_FILES_EVENT_LOG : case StatementTypes.SET_DATABASE_FILES_LOCK : case StatementTypes.SET_DATABASE_FILES_LOG_SIZE : case StatementTypes.SET_DATABASE_FILES_NIO : case StatementTypes.SET_DATABASE_FILES_SCRIPT_FORMAT : case StatementTypes.SET_DATABASE_PROPERTY : case StatementTypes.SET_DATABASE_RESULT_MEMORY_ROWS : case StatementTypes.SET_DATABASE_SQL_IGNORECASE : case StatementTypes.SET_DATABASE_SQL_REFERENTIAL_INTEGRITY : case StatementTypes.SET_DATABASE_SQL_STRICT_KEYWORDS : case StatementTypes.SET_DATABASE_SQL_STRICT_SIZE : case StatementTypes.SET_DATABASE_FILES_READ_ONLY : case StatementTypes.SET_DATABASE_FILES_READ_ONLY_FILES : case StatementTypes.SET_DATABASE_TRANSACTION_CONTROL : // case StatementTypes.SET_DATABASE_SQL_COLLATION : case StatementTypes.SET_DATABASE_FILES_BACKUP_INCREMENT : case StatementTypes.SET_DATABASE_SCRIPT_FORMAT : group = StatementTypes.X_HSQLDB_SETTING; this.isTransactionStatement = true; break; case StatementTypes.SET_TABLE_SOURCE : metaDataImpact = Statement.META_RESET_VIEWS; group = StatementTypes.X_HSQLDB_OPERATION; this.isTransactionStatement = true; break; case StatementTypes.SET_TABLE_READONLY : metaDataImpact = Statement.META_RESET_VIEWS; group = StatementTypes.X_HSQLDB_SETTING; this.isTransactionStatement = true; break; case StatementTypes.DATABASE_SHUTDOWN : isLogged = false; group = StatementTypes.X_HSQLDB_OPERATION; this.isTransactionStatement = false; break; case StatementTypes.SET_TABLE_TYPE : group = StatementTypes.X_HSQLDB_OPERATION; this.isTransactionStatement = true; break; case StatementTypes.SET_TABLE_INDEX : group = StatementTypes.X_HSQLDB_SETTING; this.isTransactionStatement = false; isLogged = false; break; case StatementTypes.SET_USER_INITIAL_SCHEMA : case StatementTypes.SET_USER_PASSWORD : group = StatementTypes.X_HSQLDB_SETTING; this.isTransactionStatement = false; break; default : throw Error.runtimeError(ErrorCode.U_S0500, "StatementCommand"); } } public Result execute(Session session) { Result result = getResult(session); if (result.isError()) { result.getException().setStatementType(group, type); return result; } try { if (isLogged) { session.database.logger.writeToLog(session, sql); } } catch (HsqlException e) { return Result.newErrorResult(e, sql); } return result; } Result getResult(Session session) { if (this.isExplain) { return Result.newSingleColumnStringResult("OPERATION", describe(session)); } switch (type) { case StatementTypes.DATABASE_BACKUP : { String path = ((String) parameters[0]); boolean blocking = ((Boolean) parameters[1]).booleanValue(); boolean script = ((Boolean) parameters[2]).booleanValue(); boolean compressed = ((Boolean) parameters[3]).booleanValue(); if (!blocking) { // SHOULD NEVER GET HERE. Parser requires this option // for v. 1.9. return Result.newErrorResult( Error.error(ErrorCode.X_0A000), "'BLOCKING' required in: " + sql); } if (script) { // Dev assertion // SHOULD NEVER GET HERE. Parser prohibits this option // for v. 1.9. return Result.newErrorResult( Error.error(ErrorCode.X_0A000), "'SCRIPT' unsupported in: " + sql); } try { session.checkAdmin(); if (!session.database.getType().equals( DatabaseURL.S_FILE)) { // Do not enforce this constraint for SCRIPT type // backup. return Result.newErrorResult( Error.error(ErrorCode.DATABASE_IS_NON_FILE)); // If we were to back up res: type DB's, could use // DatabasURL.isFileBasedDataType(), but I see no // point to back up one of these. } if (session.database.isReadOnly()) { // Do not enforce this constraint for SCRIPT type // backup. return Result.newErrorResult( Error.error(ErrorCode.DATABASE_IS_MEMORY_ONLY), null); } session.database.logger.backup(path, session.database.getPath(), script, blocking, compressed); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.DATABASE_CHECKPOINT : { boolean defrag = ((Boolean) parameters[0]).booleanValue(); try { session.database.logger.checkpoint(defrag); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_FILES_BACKUP_INCREMENT : { try { boolean mode = ((Boolean) parameters[0]).booleanValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.logger.setIncrementalBackup(mode); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_FILES_CACHE_SIZE : case StatementTypes.SET_DATABASE_FILES_CACHE_FILE_SCALE : { // todo } case StatementTypes.SET_DATABASE_FILES_DEFRAG : { try { int value = ((Integer) parameters[0]).intValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.getProperties().setProperty( HsqlDatabaseProperties.hsqldb_defrag_limit, value); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_FILES_EVENT_LOG : { try { int value = ((Integer) parameters[0]).intValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.getProperties().setProperty( HsqlDatabaseProperties.hsqldb_applog, value); session.database.logger.appLog.setLevel(value); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_FILES_LOCK : { // todo } case StatementTypes.SET_DATABASE_FILES_NIO : { // todo } case StatementTypes.SET_DATABASE_FILES_READ_ONLY : case StatementTypes.SET_DATABASE_FILES_READ_ONLY_FILES : { // todo } case StatementTypes.SET_DATABASE_FILES_LOG_SIZE : { try { int value = ((Integer) parameters[0]).intValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.logger.setLogSize(value); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_FILES_WRITE_DELAY : { try { int value = ((Integer) parameters[0]).intValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.setMetaDirty(false); session.database.logger.setWriteDelay(value); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_SQL_COLLATION : { try { String name = (String) parameters[0]; /** @todo 1.9.0 - ensure no data in character columns */ session.checkAdmin(); session.checkDDLWrite(); session.database.collation.setCollation(name); session.database.setMetaDirty(false); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_SQL_IGNORECASE : { try { boolean mode = ((Boolean) parameters[0]).booleanValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.setIgnoreCase(mode); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_SCRIPT_FORMAT : { try { int value = ((Integer) parameters[0]).intValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.logger.setScriptType(value); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_SQL_REFERENTIAL_INTEGRITY : { boolean mode = ((Boolean) parameters[0]).booleanValue(); session.database.setReferentialIntegrity(mode); return Result.updateZeroResult; } case StatementTypes.SET_DATABASE_DEFAULT_INITIAL_SCHEMA : { HsqlName schema = (HsqlName) parameters[0]; // session.database.schemaManager.setDefaultSchemaHsqlName( schema); session.database.setMetaDirty(true); // return Result.updateZeroResult; } case StatementTypes.SET_DATABASE_DEFAULT_TABLE_TYPE : { Integer type = (Integer) parameters[0]; // session.database.schemaManager.setDefaultTableType( type.intValue()); // return Result.updateZeroResult; } case StatementTypes.SET_DATABASE_TRANSACTION_CONTROL : { try { boolean mvcc = ((Boolean) parameters[0]).booleanValue(); session.checkAdmin(); session.checkDDLWrite(); session.database.txManager.setMVCC(mvcc); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_USER_INITIAL_SCHEMA : { try { User user = (User) parameters[0]; HsqlName schema = (HsqlName) parameters[1]; session.checkDDLWrite(); if (user == null) { user = session.getUser(); } else { session.checkAdmin(); session.checkDDLWrite(); user = session.database.userManager.get( user.getNameString()); } if (schema != null) { schema = session.database.schemaManager.getSchemaHsqlName( schema.name); } // user.setInitialSchema(schema); session.database.setMetaDirty(false); // return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_USER_PASSWORD : { try { User user = parameters[0] == null ? session.getUser() : (User) parameters[0]; String password = (String) parameters[1]; session.checkDDLWrite(); session.setScripting(true); user.setPassword(password); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_PROPERTY : { try { String property = (String) parameters[0]; Object value = parameters[1]; // session.checkAdmin(); session.checkDDLWrite(); // if (HsqlDatabaseProperties.hsqldb_cache_file_scale.equals( property)) { if (session.database.logger.hasCache() || ((Integer) value).intValue() != 8) { HsqlException e = Error.error(ErrorCode.X_42513, property); return Result.newErrorResult(e, sql); } } HsqlDatabaseProperties p = session.database.getProperties(); p.setDatabaseProperty(property, value.toString().toLowerCase()); p.setDatabaseVariables(); p.save(); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_DATABASE_RESULT_MEMORY_ROWS : { int size = ((Integer) parameters[0]).intValue(); session.database.getProperties().setProperty( HsqlDatabaseProperties.hsqldb_result_max_memory_rows, size); return Result.updateZeroResult; } case StatementTypes.SET_TABLE_INDEX : { try { HsqlName name = (HsqlName) parameters[0]; String value = (String) parameters[1]; Table table = session.database.schemaManager.getTable(session, name.name, name.schema.name); table.setIndexRoots(session, value); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_TABLE_READONLY : { try { HsqlName name = (HsqlName) parameters[0]; Table table = session.database.schemaManager.getTable(session, name.name, name.schema.name); boolean mode = ((Boolean) parameters[1]).booleanValue(); session.checkAdmin(); session.checkDDLWrite(); table.setDataReadOnly(mode); session.database.setMetaDirty(false); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_TABLE_SOURCE : { try { HsqlName name = (HsqlName) parameters[0]; Table table = session.database.schemaManager.getTable(session, name.name, name.schema.name); if (!table.isText()) { Exception e = Error.error(ErrorCode.X_S0522); return Result.newErrorResult(e, sql); } if (parameters[1] != null) { boolean mode = ((Boolean) parameters[1]).booleanValue(); if (mode) { ((TextTable) table).connect(session); } else { ((TextTable) table).disconnect(); } session.database.setMetaDirty(false); return Result.updateZeroResult; } String source = (String) parameters[2]; boolean isDesc = ((Boolean) parameters[3]).booleanValue(); boolean isHeader = ((Boolean) parameters[4]).booleanValue(); if (isHeader) { ((TextTable) table).setHeader(source); } else { ((TextTable) table).setDataSource(session, source, isDesc, false); } return Result.updateZeroResult; } catch (Throwable e) { if (!(e instanceof HsqlException)) { e = Error.error(ErrorCode.GENERAL_IO_ERROR, e.getMessage()); } if (session.isProcessingLog() || session.isProcessingScript()) { session.addWarning((HsqlException) e); //* @todo - add an entry to applog too */ return Result.updateZeroResult; } else { return Result.newErrorResult(e, sql); } } } case StatementTypes.SET_TABLE_TYPE : { try { HsqlName name = (HsqlName) parameters[0]; int type = ((Integer) parameters[1]).intValue(); // session.checkAdmin(); session.checkDDLWrite(); Table table = session.database.schemaManager.getUserTable(session, name.name, name.schema.name); session.setScripting(true); TableWorks tw = new TableWorks(session, table); tw.setTableType(session, type); session.database.setMetaDirty(false); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.DATABASE_SCRIPT : { ScriptWriterText dsw = null; String name = (String) parameters[0]; if (name == null) { return session.database.getScript(false); } else { try { dsw = new ScriptWriterText(session.database, name, true, true, true); dsw.writeAll(); dsw.close(); } catch (HsqlException e) { return Result.newErrorResult(e, sql); } return Result.updateZeroResult; } } case StatementTypes.DATABASE_SHUTDOWN : { try { int mode = ((Integer) parameters[0]).intValue(); session.database.close(mode); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } default : throw Error.runtimeError(ErrorCode.U_S0500, "CompiledStateemntCommand"); } } public boolean isAutoCommitStatement() { return isTransactionStatement; } public String describe(Session session) { return sql; } }