/**
   * 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();
  }
  public Result execute(Session session) {

    Result result;

    if (targetTable != null && session.isReadOnly() && !targetTable.isTemp()) {
      HsqlException e = Error.error(ErrorCode.X_25006);

      return Result.newErrorResult(e);
    }

    if (isExplain) {
      return getExplainResult(session);
    }

    try {
      if (subqueries.length > 0) {
        materializeSubQueries(session);
      }

      result = getResult(session);
    } catch (Throwable t) {
      result = Result.newErrorResult(t, null);

      result.getException().setStatementType(group, type);
    }

    session.sessionContext.clearStructures(this);

    return result;
  }
  /**
   * 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);
  }
  /** Drops a trigger with the specified name in the given context. */
  void dropTrigger(Session session, String name) throws HsqlException {

    boolean found = triggerNameList.containsName(name);

    Trace.check(found, Trace.TRIGGER_NOT_FOUND, name);

    HsqlName tableName = (HsqlName) triggerNameList.removeName(name);
    Table t = this.findUserTable(session, tableName.name);

    t.dropTrigger(name);
    session.setScripting(!t.isTemp());
  }
  /** Drops from this Database any temporary tables owned by the specified Session. */
  void dropTempTables(Session ownerSession) {

    int i = tTable.size();

    while (i-- > 0) {
      Table toDrop = (Table) tTable.get(i);

      if (toDrop.isTemp() && toDrop.getOwnerSessionId() != ownerSession.getId()) {
        tTable.remove(i);
      }
    }
  }
  Result getWriteAccessResult(Session session) {

    try {
      if (targetTable != null && !targetTable.isTemp()) {
        session.checkReadWrite();
      }
    } catch (HsqlException e) {
      return Result.newErrorResult(e);
    }

    return null;
  }
  /**
   * 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);
  }
  // this fk references -> other  :  other read lock
  void collectTableNamesForRead(OrderedHashSet set) {

    for (int i = 0; i < rangeVariables.length; i++) {
      Table rangeTable = rangeVariables[i].rangeTable;
      HsqlName name = rangeTable.getName();

      if (rangeTable.isReadOnly() || rangeTable.isTemp()) {
        continue;
      }

      if (name.schema == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
        continue;
      }

      set.add(name);
    }

    for (int i = 0; i < subqueries.length; i++) {
      if (subqueries[i].queryExpression != null) {
        subqueries[i].queryExpression.getBaseTableNames(set);
      }
    }
  }
Esempio n. 9
0
  /**
   * Method declaration
   *
   * @param db
   * @param file
   * @param full
   * @param session
   * @throws SQLException
   */
  static void scriptToFile(Database db, String file, boolean full, Session session)
      throws SQLException {

    if ((new File(file)).exists()) {

      // there must be no such file; overwriting not allowed for security
      throw Trace.error(Trace.FILE_IO_ERROR, file);
    }

    try {
      long time = 0;

      if (Trace.TRACE) {
        time = System.currentTimeMillis();
      }

      // only ddl commands; needs not so much memory
      Result r;

      if (full) {

        // no drop, no insert, and no positions for cached tables
        r = db.getScript(false, false, false, session);
      } else {

        // no drop, no insert, but positions for cached tables
        r = db.getScript(false, false, true, session);
      }

      Record n = r.rRoot;
      FileWriter w = new FileWriter(file);

      while (n != null) {
        writeLine(w, (String) n.data[0]);

        n = n.next;
      }

      // inserts are done separetely to save memory
      HsqlArrayList tables = db.getTables();

      for (int i = 0; i < tables.size(); i++) {
        Table t = (Table) tables.get(i);

        // cached tables have the index roots set in the ddl script
        if ((full || !t.isCached())
            && !t.isTemp()
            && !t.isView()
            && (!t.isText() || !t.isDataReadOnly())) {
          Index primary = t.getPrimaryIndex();
          Node x = primary.first();

          while (x != null) {
            writeLine(w, t.getInsertStatement(x.getData()));

            x = primary.next(x);
          }
        }

        // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
        if (t.isDataReadOnly() && !t.isTemp() && !t.isText()) {
          HsqlStringBuffer a = new HsqlStringBuffer("SET TABLE ");

          a.append(t.getName().statementName);
          a.append(" READONLY TRUE");
          writeLine(w, a.toString());
        }
      }

      w.close();

      if (Trace.TRACE) {
        Trace.trace(time - System.currentTimeMillis());
      }
    } catch (IOException e) {
      throw Trace.error(Trace.FILE_IO_ERROR, file + " " + e);
    }
  }
  /**
   * 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();
  }
  /**
   * Determines if the authorizations are adequate to execute the compiled object. Completion
   * requires the list of all database objects in a compiled statement.
   */
  void checkAccessRights(Session session) {

    if (targetTable != null && !targetTable.isTemp()) {
      Grantee owner = targetTable.getOwner();

      if (owner != null && owner.isSystem()) {
        if (!session.getUser().isSystem()) {
          throw Error.error(ErrorCode.X_42501, targetTable.getName().name);
        }
      }

      if (!session.isProcessingScript) {
        targetTable.checkDataReadOnly();
      }

      session.checkReadWrite();
    }

    if (session.isAdmin()) {
      return;
    }

    for (int i = 0; i < sequences.length; i++) {
      session.getGrantee().checkAccess(sequences[i]);
    }

    for (int i = 0; i < routines.length; i++) {
      if (routines[i].isLibraryRoutine()) {
        continue;
      }

      session.getGrantee().checkAccess(routines[i]);
    }

    for (int i = 0; i < rangeVariables.length; i++) {
      RangeVariable range = rangeVariables[i];

      if (range.rangeTable.getSchemaName() == SqlInvariants.SYSTEM_SCHEMA_HSQLNAME) {
        continue;
      }

      session.getGrantee().checkSelect(range.rangeTable, range.usedColumns);
    }

    switch (type) {
      case StatementTypes.CALL:
        {
          break;
        }
      case StatementTypes.INSERT:
        {
          session.getGrantee().checkInsert(targetTable, insertCheckColumns);

          break;
        }
      case StatementTypes.SELECT_CURSOR:
        break;

      case StatementTypes.DELETE_WHERE:
        {
          session.getGrantee().checkDelete(targetTable);

          break;
        }
      case StatementTypes.UPDATE_WHERE:
        {
          session.getGrantee().checkUpdate(targetTable, updateCheckColumns);

          break;
        }
      case StatementTypes.MERGE:
        {
          session.getGrantee().checkInsert(targetTable, insertCheckColumns);
          session.getGrantee().checkUpdate(targetTable, updateCheckColumns);

          break;
        }
    }
  }