/**
   * Drops the index with the specified name from this database.
   *
   * @param indexname the name of the index to drop
   * @param ifExists if true and if the Index to drop does not exist, fail silently, else throw
   * @param session the execution context
   * @throws HsqlException if the index does not exist, the session lacks the permission or the
   *     operation violates database integrity
   */
  void dropIndex(Session session, String indexname, String tableName, boolean ifExists)
      throws HsqlException {

    Table t = findUserTableForIndex(session, indexname);

    if (t == null) {
      if (ifExists) {
        return;
      } else {
        throw Trace.error(Trace.INDEX_NOT_FOUND, indexname);
      }
    }

    if (tableName != null && !t.getName().name.equals(tableName)) {
      throw Trace.error(Trace.INDEX_NOT_FOUND, indexname);
    }

    t.checkDropIndex(indexname, null);

    // fredt@users 20020405 - patch 1.7.0 by fredt - drop index bug
    // see Table.moveDefinition();
    session.commit();
    session.setScripting(!t.isTemp());

    TableWorks tw = new TableWorks(session, t);

    tw.dropIndex(indexname);
  }
  /**
   * Setter for the autocommit attribute.
   *
   * @param autocommit the new value
   * @throws HsqlException
   */
  public void setAutoCommit(boolean autocommit) {

    if (autocommit != isAutoCommit) {
      commit();

      isAutoCommit = autocommit;
    }
  }
  /**
   * Drops the specified user-defined view or table from this Database object.
   *
   * <p>The process of dropping a table or view includes:
   *
   * <OL>
   *   <LI>checking that the specified Session's currently connected User has the right to perform
   *       this operation and refusing to proceed if not by throwing.
   *   <LI>checking for referential constraints that conflict with this operation and refusing to
   *       proceed if they exist by throwing.
   *   <LI>removing the specified Table from this Database object.
   *   <LI>removing any exported foreign keys Constraint objects held by any tables referenced by
   *       the table to be dropped. This is especially important so that the dropped Table ceases to
   *       be referenced, eventually allowing its full garbage collection.
   *   <LI>
   * </OL>
   *
   * <p>
   *
   * @param name of the table or view to drop
   * @param ifExists if true and if the Table to drop does not exist, fail silently, else throw
   * @param isView true if the name argument refers to a View
   * @param session the connected context in which to perform this operation
   * @throws HsqlException if any of the checks listed above fail
   */
  void dropTable(Session session, String name, boolean ifExists, boolean isView)
      throws HsqlException {

    Table toDrop = null;
    int dropIndex = -1;

    for (int i = 0; i < tTable.size(); i++) {
      toDrop = (Table) tTable.get(i);

      if (toDrop.equals(session, name) && isView == toDrop.isView()) {
        dropIndex = i;

        break;
      } else {
        toDrop = null;
      }
    }

    if (dropIndex == -1) {
      if (ifExists) {
        return;
      } else {
        throw Trace.error(isView ? Trace.VIEW_NOT_FOUND : Trace.TABLE_NOT_FOUND, name);
      }
    }

    if (!toDrop.isTemp()) {
      session.checkDDLWrite();
    }

    if (isView) {
      checkViewIsInView((View) toDrop);
    } else {
      checkTableIsReferenced(toDrop);
      checkTableIsInView(toDrop.tableName.name);
    }

    tTable.remove(dropIndex);
    removeExportedKeys(toDrop);
    userManager.removeDbObject(toDrop.getName());
    triggerNameList.removeOwner(toDrop.tableName);
    indexNameList.removeOwner(toDrop.tableName);
    constraintNameList.removeOwner(toDrop.tableName);
    toDrop.dropTriggers();
    toDrop.drop();
    session.setScripting(!toDrop.isTemp());
    session.commit();
  }
Esempio n. 4
0
    public void run() {

      try {
        Session sysSession = sessionManager.newSysSession();
        Statement checkpoint = ParserCommand.getAutoCheckpointStatement(Database.this);

        sysSession.executeCompiledStatement(checkpoint, ValuePool.emptyObjectArray, 0);
        sysSession.commit(false);
        sysSession.close();

        waiting = false;
      } catch (Throwable e) {

        // ignore exceptions
        // may be InterruptedException or IOException
      }
    }
  /**
   * Drops the index with the specified name from this database.
   *
   * @param indexname the name of the index to drop
   * @param session the execution context
   * @throws SQLException if the index does not exist, the session lacks the permission or the
   *     operation violates database integrity
   */
  void dropIndex(String indexname, Session session) throws SQLException {

    Table t = findUserTableForIndex(indexname, session);

    if (t == null) {
      throw Trace.error(Trace.INDEX_NOT_FOUND, indexname);
    }

    t.checkDropIndex(indexname, null);

    // fredt@users 20020405 - patch 1.7.0 by fredt - drop index bug
    // see Table.moveDefinition();
    session.commit();
    session.setScripting(!t.isTemp());

    TableWorks tw = new TableWorks(t);

    tw.dropIndex(indexname);
  }
  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");
    }
  }
  /**
   * Drops the specified user-defined view or table from this Database object.
   *
   * <p>The process of dropping a table or view includes:
   *
   * <OL>
   *   <LI>checking that the specified Session's currently connected User has the right to perform
   *       this operation and refusing to proceed if not by throwing.
   *   <LI>checking for referential constraints that conflict with this operation and refusing to
   *       proceed if they exist by throwing.
   *   <LI>removing the specified Table from this Database object.
   *   <LI>removing any exported foreign keys Constraint objects held by any tables referenced by
   *       the table to be dropped. This is especially important so that the dropped Table ceases to
   *       be referenced, eventually allowing its full garbage collection.
   *   <LI>
   * </OL>
   *
   * <p>
   *
   * @param name of the table or view to drop
   * @param ifExists if true and if the Table to drop does not exist, fail silently, else throw
   * @param isView true if the name argument refers to a View
   * @param session the connected context in which to perform this operation
   * @throws SQLException if any of the checks listed above fail
   */
  void dropTable(String name, boolean ifExists, boolean isView, Session session)
      throws SQLException {

    Table toDrop = null;
    int dropIndex = -1;
    int refererIndex = -1;
    Enumeration constraints = null;
    Constraint currentConstraint = null;
    Table refTable = null;
    boolean isRef = false;
    boolean isSelfRef = false;

    for (int i = 0; i < tTable.size(); i++) {
      toDrop = (Table) tTable.get(i);

      if (toDrop.equals(name, session) && isView == toDrop.isView()) {
        dropIndex = i;

        break;
      } else {
        toDrop = null;
      }
    }

    if (dropIndex == -1) {
      if (ifExists) {
        return;
      } else {
        throw Trace.error(isView ? Trace.VIEW_NOT_FOUND : Trace.TABLE_NOT_FOUND, name);
      }
    }

    constraints = toDrop.getConstraints().elements();

    while (constraints.hasMoreElements()) {
      currentConstraint = (Constraint) constraints.nextElement();

      if (currentConstraint.getType() != Constraint.MAIN) {
        continue;
      }

      refTable = currentConstraint.getRef();
      isRef = (refTable != null);
      isSelfRef = (isRef && toDrop.equals(refTable));

      if (isRef && !isSelfRef) {

        // cover the case where the referencing table
        // may have already been dropped
        for (int k = 0; k < tTable.size(); k++) {
          if (refTable.equals(tTable.get(k))) {
            refererIndex = k;

            break;
          }
        }

        if (refererIndex != -1) {

          // tony_lai@users 20020820 - patch 595156
          throw Trace.error(
              Trace.INTEGRITY_CONSTRAINT_VIOLATION,
              currentConstraint.getName().name + " table: " + refTable.getName().name);
        }
      }
    }

    tTable.remove(dropIndex);
    removeExportedKeys(toDrop);
    aAccess.removeDbObject(toDrop.getName());
    triggerNameList.removeOwner(toDrop.tableName);
    indexNameList.removeOwner(toDrop.tableName);
    toDrop.drop();
    session.setScripting(!toDrop.isTemp());
    session.commit();
  }
  /**
   * This is used to read the *.log file and manage any necessary transaction rollback.
   *
   * @throws HsqlException
   */
  public static void runScript(Database database, String logFilename, int logType)
      throws HsqlException {

    IntKeyHashMap sessionMap = new IntKeyHashMap();
    Session sysSession = database.getSessionManager().getSysSession(null, false);
    Session current = sysSession;
    int currentId = 0;

    database.setReferentialIntegrity(false);

    ScriptReaderBase scr = null;

    try {
      StopWatch sw = new StopWatch();

      scr =
          ScriptReaderBase.newScriptReader(database, logFilename, ScriptWriterBase.SCRIPT_TEXT_170);

      while (scr.readLoggedStatement(current)) {
        int sessionId = scr.getSessionNumber();

        if (currentId != sessionId) {
          currentId = sessionId;
          current = (Session) sessionMap.get(currentId);

          if (current == null) {
            current =
                database
                    .getSessionManager()
                    .newSession(database, sysSession.getUser(), false, true);

            sessionMap.put(currentId, current);
          }
        }

        if (current.isClosed()) {
          sessionMap.remove(currentId);

          continue;
        }

        String schema = current.currentSchema.name;
        Result result = null;

        switch (scr.getStatementType()) {
          case ScriptReaderBase.ANY_STATEMENT:
            result = current.sqlExecuteDirectNoPreChecks(scr.getLoggedStatement());

            if (result != null && result.mode == ResultConstants.ERROR) {
              if (result.getException() != null) {
                throw result.getException();
              }

              throw Trace.error(result);
            }
            break;

          case ScriptReaderBase.SEQUENCE_STATEMENT:
            scr.getCurrentSequence().reset(scr.getSequenceValue());
            break;

          case ScriptReaderBase.COMMIT_STATEMENT:
            current.commit();
            break;

          case ScriptReaderBase.INSERT_STATEMENT:
            {
              Object[] data = scr.getData();

              scr.getCurrentTable().insertNoCheckFromLog(current, data);

              break;
            }
          case ScriptReaderBase.DELETE_STATEMENT:
            {
              Object[] data = scr.getData();

              scr.getCurrentTable().deleteNoCheckFromLog(current, data);

              break;
            }
          case ScriptReaderBase.SCHEMA_STATEMENT:
            {
              current.setSchema(scr.getCurrentSchema());
            }
        }

        if (current.isClosed()) {
          sessionMap.remove(currentId);
        }
      }
    } catch (Throwable e) {
      String message;

      // catch out-of-memory errors and terminate
      if (e instanceof OutOfMemoryError) {
        message = "out of memory processing " + logFilename + " line: " + scr.getLineNumber();

        database.logger.appLog.logContext(message);

        throw Trace.error(Trace.OUT_OF_MEMORY);
      }

      // stop processing on bad log line
      message = logFilename + " line: " + scr.getLineNumber() + " " + e.getMessage();

      database.logger.appLog.logContext(message);
      Trace.printSystemOut(message);
    } finally {
      if (scr != null) {
        scr.close();
      }

      database.getSessionManager().closeAllSessions();
      database.setReferentialIntegrity(true);
    }
  }
  /**
   * 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);
          }
      }
    }
  }