/** * Implements a partial transaction ROLLBACK. * * @param name Name of savepoint that was marked before by savepoint() call * @throws HsqlException */ void rollbackToSavepoint(String name) throws HsqlException { int index = savepoints.getIndex(name); Trace.check(index >= 0, Trace.SAVEPOINT_NOT_FOUND, name); Integer oi = (Integer) savepoints.get(index); index = oi.intValue(); int i = tTransaction.size() - 1; for (; i >= index; i--) { Transaction t = (Transaction) tTransaction.get(i); t.rollback(this); tTransaction.remove(i); } releaseSavepoint(name); try { dDatabase.logger.writeToLog( this, Token.T_ROLLBACK + " " + Token.T_TO + " " + Token.T_SAVEPOINT + " " + name); } catch (HsqlException e) { } }
Result getResult(Session session) { boolean startTransaction = false; if (this.isExplain) { return Result.newSingleColumnStringResult("OPERATION", describe(session)); } switch (type) { // cursor case StatementTypes.ALLOCATE_CURSOR: case StatementTypes.ALLOCATE_DESCRIPTOR: return Result.updateZeroResult; // case StatementTypes.COMMIT_WORK: { try { boolean chain = parameters != null; session.commit(chain); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.DEALLOCATE_DESCRIPTOR: case StatementTypes.DEALLOCATE_PREPARE: return Result.updateZeroResult; case StatementTypes.DISCONNECT: session.close(); return Result.updateZeroResult; // case StatementTypes.DYNAMIC_CLOSE: case StatementTypes.DYNAMIC_DELETE_CURSOR: case StatementTypes.DYNAMIC_FETCH: case StatementTypes.DYNAMIC_OPEN: // case StatementTypes.FETCH: case StatementTypes.FREE_LOCATOR: case StatementTypes.GET_DESCRIPTOR: case StatementTypes.HOLD_LOCATOR: // case StatementTypes.OPEN: case StatementTypes.PREPARABLE_DYNAMIC_DELETE_CURSOR: case StatementTypes.PREPARABLE_DYNAMIC_UPDATE_CURSOR: case StatementTypes.PREPARE: return Result.updateZeroResult; case StatementTypes.TRANSACTION_LOCK_TABLE: { return Result.updateZeroResult; } case StatementTypes.RELEASE_SAVEPOINT: { String savepoint = (String) parameters[0]; try { session.releaseSavepoint(savepoint); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.ROLLBACK_WORK: { boolean chain = ((Boolean) parameters[0]).booleanValue(); session.rollback(chain); return Result.updateZeroResult; } case StatementTypes.ROLLBACK_SAVEPOINT: { String savepoint = (String) parameters[0]; try { session.rollbackToSavepoint(savepoint); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SAVEPOINT: { String savepoint = (String) parameters[0]; session.savepoint(savepoint); return Result.updateZeroResult; } case StatementTypes.SET_CATALOG: { String name; try { name = (String) expressions[0].getValue(session); name = (String) Type.SQL_VARCHAR.trim(session, name, ' ', true, true); if (session.database.getCatalogName().name.equals(name)) { return Result.updateZeroResult; } return Result.newErrorResult(Error.error(ErrorCode.X_3D000), sql); } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_CONNECTION: case StatementTypes.SET_CONSTRAINT: case StatementTypes.SET_DESCRIPTOR: return Result.updateZeroResult; case StatementTypes.SET_TIME_ZONE: { Object value = null; if (expressions[0].getType() == OpTypes.VALUE && expressions[0].getConstantValueNoCheck(session) == null) { session.timeZoneSeconds = session.sessionTimeZoneSeconds; return Result.updateZeroResult; } try { value = expressions[0].getValue(session); } catch (HsqlException e) { } if (value instanceof Result) { Result result = (Result) value; if (result.isData()) { Object[] data = (Object[]) result.getNavigator().getNext(); boolean single = !result.getNavigator().next(); if (single && data != null && data[0] != null) { value = data[0]; result.getNavigator().close(); } else { result.getNavigator().close(); return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql); } } else { return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql); } } else { if (value == null) { return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql); } } long seconds = ((IntervalSecondData) value).getSeconds(); if (-DTIType.timezoneSecondsLimit <= seconds && seconds <= DTIType.timezoneSecondsLimit) { session.timeZoneSeconds = (int) seconds; return Result.updateZeroResult; } return Result.newErrorResult(Error.error(ErrorCode.X_22009), sql); } case StatementTypes.SET_NAMES: return Result.updateZeroResult; case StatementTypes.SET_PATH: return Result.updateZeroResult; case StatementTypes.SET_ROLE: { String name; Grantee role = null; try { name = (String) expressions[0].getValue(session); if (name != null) { name = (String) Type.SQL_VARCHAR.trim(session, name, ' ', true, true); role = session.database.granteeManager.getRole(name); } } catch (HsqlException e) { return Result.newErrorResult(Error.error(ErrorCode.X_0P000), sql); } if (session.isInMidTransaction()) { return Result.newErrorResult(Error.error(ErrorCode.X_25001), sql); } if (role == null) { session.setRole(null); } if (session.getGrantee().hasRole(role)) { session.setRole(role); return Result.updateZeroResult; } else { return Result.newErrorResult(Error.error(ErrorCode.X_0P000), sql); } } case StatementTypes.SET_SCHEMA: { String name; HsqlName schema; try { if (expressions == null) { name = ((HsqlName) parameters[0]).name; } else { name = (String) expressions[0].getValue(session); } name = (String) Type.SQL_VARCHAR.trim(session, name, ' ', true, true); schema = session.database.schemaManager.getSchemaHsqlName(name); session.setSchema(schema.name); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_SESSION_AUTHORIZATION: { if (session.isInMidTransaction()) { return Result.newErrorResult(Error.error(ErrorCode.X_25001), sql); } try { String user; String password = null; user = (String) expressions[0].getValue(session); user = (String) Type.SQL_VARCHAR.trim(session, user, ' ', true, true); if (expressions[1] != null) { password = (String) expressions[1].getValue(session); } User userObject; if (password == null) { userObject = session.database.userManager.get(user); } else { userObject = session.database.getUserManager().getUser(user, password); } if (userObject == null) { throw Error.error(ErrorCode.X_28501); } sql = userObject.getConnectUserSQL(); if (userObject == session.getGrantee()) { return Result.updateZeroResult; } if (session.getGrantee().canChangeAuthorisation()) { session.setUser((User) userObject); session.setRole(null); session.resetSchema(); return Result.updateZeroResult; } /** @todo may need different error code */ throw Error.error(ErrorCode.X_28000); } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_SESSION_CHARACTERISTICS: { try { if (parameters[0] != null) { boolean readonly = ((Boolean) parameters[0]).booleanValue(); session.setReadOnlyDefault(readonly); } if (parameters[1] != null) { int level = ((Integer) parameters[1]).intValue(); session.setIsolationDefault(level); } return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_COLLATION: return Result.updateZeroResult; case StatementTypes.SET_TRANSFORM_GROUP: return Result.updateZeroResult; case StatementTypes.START_TRANSACTION: startTransaction = true; // fall through case StatementTypes.SET_TRANSACTION: { try { if (parameters[0] != null) { boolean readonly = ((Boolean) parameters[0]).booleanValue(); session.setReadOnly(readonly); } if (parameters[1] != null) { int level = ((Integer) parameters[1]).intValue(); session.setIsolation(level); } if (startTransaction) { session.startTransaction(); } return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } // case StatementTypes.SET_SESSION_AUTOCOMMIT: { boolean mode = ((Boolean) parameters[0]).booleanValue(); try { session.setAutoCommit(mode); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.DECLARE_VARIABLE: { ColumnSchema variable = (ColumnSchema) parameters[0]; try { session.sessionContext.addSessionVariable(variable); return Result.updateZeroResult; } catch (HsqlException e) { return Result.newErrorResult(e, sql); } } case StatementTypes.SET_SESSION_RESULT_MAX_ROWS: { int size = ((Integer) parameters[0]).intValue(); session.setSQLMaxRows(size); return Result.updateZeroResult; } case StatementTypes.SET_SESSION_RESULT_MEMORY_ROWS: { int size = ((Integer) parameters[0]).intValue(); session.setResultMemoryRowCount(size); return Result.updateZeroResult; } default: throw Error.runtimeError(ErrorCode.U_S0500, "CompiledStateemntCommand"); } }
/** * Executes the command encapsulated by the cmd argument. * * @param cmd the command to execute * @return the result of executing the command */ public Result execute(Result cmd) { try { if (Trace.DOASSERT) { Trace.doAssert(!isNestedTransaction); } Trace.check(!isClosed, Trace.ACCESS_IS_DENIED, "Session is closed"); } catch (Throwable t) { return new Result(t, null); } int type = cmd.iMode; synchronized (dDatabase) { if (sessionMaxRows == 0) { currentMaxRows = cmd.iUpdateCount; } DatabaseManager.gc(); switch (type) { case ResultConstants.SQLEXECUTE: { return cmd.getSize() > 1 ? sqlExecuteBatch(cmd) : sqlExecute(cmd); } case ResultConstants.SQLEXECDIRECT: { return cmd.getSize() > 0 ? sqlExecuteBatchDirect(cmd) : sqlExecuteDirectNoPreChecks(cmd.getMainString()); } case ResultConstants.SQLPREPARE: { return sqlPrepare(cmd.getMainString(), cmd.getStatementType()); } case ResultConstants.SQLFREESTMT: { return sqlFreeStatement(cmd.getStatementID()); } case ResultConstants.GETSESSIONATTR: { return getAttributes(); } case ResultConstants.SETSESSIONATTR: { return setAttributes(cmd); } case ResultConstants.SQLENDTRAN: { switch (cmd.getEndTranType()) { case ResultConstants.COMMIT: commit(); break; case ResultConstants.ROLLBACK: rollback(); break; case ResultConstants.SAVEPOINT_NAME_RELEASE: try { String name = cmd.getMainString(); releaseSavepoint(name); } catch (Throwable t) { return new Result(t, null); } break; case ResultConstants.SAVEPOINT_NAME_ROLLBACK: try { rollbackToSavepoint(cmd.getMainString()); } catch (Throwable t) { return new Result(t, null); } break; // not yet // case ResultConstants.COMMIT_AND_CHAIN : // case ResultConstants.ROLLBACK_AND_CHAIN : } return emptyUpdateCount; } case ResultConstants.SQLSETCONNECTATTR: { switch (cmd.getConnectionAttrType()) { case ResultConstants.SQL_ATTR_SAVEPOINT_NAME: try { savepoint(cmd.getMainString()); } catch (Throwable t) { return new Result(t, null); } // case ResultConstants.SQL_ATTR_AUTO_IPD // - always true // default: throw - case never happens } return emptyUpdateCount; } default: { String msg = "operation type:" + type; return new Result(msg, "s1000", Trace.OPERATION_NOT_SUPPORTED); } } } }