/**
   * 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();
  }
  /** Returns an array of views that reference a sequence. */
  View[] getViewsWithSequence(NumberSequence sequence) {

    HsqlArrayList list = null;

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

      if (t.isView()) {
        boolean found = ((View) t).hasSequence(sequence);

        if (found) {
          if (list == null) {
            list = new HsqlArrayList();
          }

          list.add(t);
        }
      }
    }

    return list == null ? null : (View[]) list.toArray(new View[list.size()]);
  }
  /**
   * Returns an array of views that reference the specified table or the specified column if column
   * parameter is not null.
   */
  private View[] getViewsWithTable(String table, String column) {

    HsqlArrayList list = null;

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

      if (t.isView()) {
        boolean found =
            column == null ? ((View) t).hasTable(table) : ((View) t).hasColumn(table, column);

        if (found) {
          if (list == null) {
            list = new HsqlArrayList();
          }

          list.add(t);
        }
      }
    }

    return list == null ? null : (View[]) list.toArray(new View[list.size()]);
  }
  void moveConditionsToInner(Session session, RangeVariable[] ranges) {

    Expression[] colExpr;
    int exclude;
    HsqlArrayList conditionsList;
    Expression condition = null;

    if (whereConditions.length > 1) {
      return;
    }

    if (joinConditions.length > 1) {
      return;
    }

    for (int i = 0; i < ranges.length; i++) {
      if (ranges[i].isLeftJoin || ranges[i].isRightJoin) {
        return;
      }
    }

    exclude = ArrayUtil.find(ranges, this);
    conditionsList = new HsqlArrayList();

    addConditionsToList(conditionsList, joinConditions[0].indexCond);

    if (joinConditions[0].indexCond != null
        && joinConditions[0].indexCond[0] != joinConditions[0].indexEndCond[0]) {
      addConditionsToList(conditionsList, joinConditions[0].indexEndCond);
    }

    addConditionsToList(conditionsList, whereConditions[0].indexCond);
    addConditionsToList(conditionsList, whereConditions[0].indexEndCond);
    RangeVariableResolver.decomposeAndConditions(
        session, joinConditions[0].nonIndexCondition, conditionsList);
    RangeVariableResolver.decomposeAndConditions(
        session, whereConditions[0].nonIndexCondition, conditionsList);

    for (int i = conditionsList.size() - 1; i >= 0; i--) {
      Expression e = (Expression) conditionsList.get(i);

      if (e == null || e.isTrue() || e.hasReference(ranges, exclude)) {
        conditionsList.remove(i);

        continue;
      }
    }

    if (conditionsList.size() == 0) {
      if (rangeTable.isView()) {
        ((TableDerived) rangeTable).resetToView();
      }

      return;
    }

    QueryExpression queryExpression = rangeTable.getQueryExpression();

    colExpr = ((QuerySpecification) queryExpression).exprColumns;

    for (int i = 0; i < conditionsList.size(); i++) {
      Expression e = (Expression) conditionsList.get(i);
      OrderedHashSet set = e.collectRangeVariables(null);

      e = e.duplicate();
      e = e.replaceColumnReferences(this, colExpr);

      if (e.collectAllSubqueries(null) != null) {
        return;
      }

      if (set != null) {
        for (int j = 0; j < set.size(); j++) {
          RangeVariable range = (RangeVariable) set.get(j);

          if (this != range && range.rangeType == RangeVariable.TABLE_RANGE) {
            queryExpression.setCorrelated();
          }
        }
      }

      condition = ExpressionLogical.andExpressions(condition, e);
    }

    queryExpression.addExtraConditions(condition);
  }
示例#5
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();
  }