/**
   * Removes any foreign key Constraint objects (exported keys) held by any tables referenced by the
   * specified table.
   *
   * <p>This method is called as the last step of a successful call to dropTable() in order to
   * ensure that the dropped Table ceases to be referenced when enforcing referential integrity.
   *
   * @param toDrop The table to which other tables may be holding keys. This is typically a table
   *     that is in the process of being dropped.
   */
  void removeExportedKeys(Table toDrop) {

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

      for (int j = constraintvector.size() - 1; j >= 0; j--) {
        Constraint currentConstraint = (Constraint) constraintvector.get(j);
        Table refTable = currentConstraint.getRef();

        if (toDrop == refTable) {
          constraintvector.remove(j);
        }
      }
    }
  }
Example #2
0
 Constraint duplicate() {
   Constraint localConstraint = new Constraint();
   localConstraint.core = this.core.duplicate();
   localConstraint.name = this.name;
   localConstraint.constType = this.constType;
   localConstraint.isForward = this.isForward;
   localConstraint.check = this.check;
   localConstraint.isNotNull = this.isNotNull;
   localConstraint.notNullColumnIndex = this.notNullColumnIndex;
   localConstraint.rangeVariable = this.rangeVariable;
   return localConstraint;
 }
Example #3
0
  Constraint duplicate() {

    Constraint copy = new Constraint();

    copy.core = core.duplicate();
    copy.name = name;
    copy.constType = constType;
    copy.isForward = isForward;

    //
    copy.check = check;
    copy.isNotNull = isNotNull;
    copy.notNullColumnIndex = notNullColumnIndex;
    copy.rangeVariable = rangeVariable;
    copy.schemaObjectNames = schemaObjectNames;

    return copy;
  }
  /** Throws if the table is referenced in a foreign key constraint. */
  private void checkTableIsReferenced(Table toDrop) throws HsqlException {

    Constraint[] constraints = toDrop.getConstraints();
    Constraint currentConstraint = null;
    Table refTable = null;
    boolean isRef = false;
    boolean isSelfRef = false;
    int refererIndex = -1;

    for (int i = 0; i < constraints.length; i++) {
      currentConstraint = constraints[i];

      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) {
          throw Trace.error(
              Trace.TABLE_REFERENCED_CONSTRAINT,
              Trace.Database_dropTable,
              new Object[] {currentConstraint.getName().name, refTable.getName().name});
        }
      }
    }
  }
  /**
   * 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();
  }
 Result getResult(Session paramSession) {
   HsqlNameManager.HsqlName localHsqlName1 = this.statements[0].getSchemaName();
   if (this.isExplain)
     return Result.newSingleColumnStringResult("OPERATION", describe(paramSession));
   Result localResult = this.statements[0].execute(paramSession);
   HsqlArrayList localHsqlArrayList = new HsqlArrayList();
   StatementSchema localStatementSchema2 = new StatementSchema(null, 1199);
   if ((this.statements.length == 1) || (localResult.isError())) return localResult;
   HsqlNameManager.HsqlName localHsqlName2 = paramSession.getCurrentSchemaHsqlName();
   Table localTable;
   for (int i = 1; i < this.statements.length; i++) {
     try {
       paramSession.setSchema(localHsqlName1.name);
     } catch (HsqlException localHsqlException3) {
     }
     this.statements[i].setSchemaHsqlName(localHsqlName1);
     paramSession.parser.reset(this.statements[i].getSQL());
     try {
       paramSession.parser.read();
       StatementSchema localStatementSchema1;
       switch (this.statements[i].getType()) {
         case 48:
         case 49:
           localResult = this.statements[i].execute(paramSession);
           break;
         case 77:
           localStatementSchema1 = paramSession.parser.compileCreate();
           localStatementSchema1.isSchemaDefinition = true;
           localStatementSchema1.setSchemaHsqlName(localHsqlName1);
           if (paramSession.parser.token.tokenType != 848)
             throw paramSession.parser.unexpectedToken();
           localStatementSchema1.isLogged = false;
           localResult = localStatementSchema1.execute(paramSession);
           HsqlNameManager.HsqlName localHsqlName3 =
               ((Table) localStatementSchema1.arguments[0]).getName();
           localTable =
               (Table) paramSession.database.schemaManager.getSchemaObject(localHsqlName3);
           localHsqlArrayList.addAll((HsqlArrayList) localStatementSchema1.arguments[1]);
           ((HsqlArrayList) localStatementSchema1.arguments[1]).clear();
           localStatementSchema2.sql = localTable.getSQL();
           localStatementSchema2.execute(paramSession);
           break;
         case 8:
         case 10:
         case 61:
         case 83:
         case 133:
           localResult = this.statements[i].execute(paramSession);
           break;
         case 14:
         case 23:
         case 80:
         case 84:
         case 1073:
           localStatementSchema1 = paramSession.parser.compileCreate();
           localStatementSchema1.isSchemaDefinition = true;
           localStatementSchema1.setSchemaHsqlName(localHsqlName1);
           if (paramSession.parser.token.tokenType != 848)
             throw paramSession.parser.unexpectedToken();
           localResult = localStatementSchema1.execute(paramSession);
           break;
         case 6:
         case 52:
         case 79:
         case 114:
         case 117:
           throw paramSession.parser.unsupportedFeature();
         default:
           throw Error.runtimeError(201, "");
       }
       if (localResult.isError()) break;
     } catch (HsqlException localHsqlException4) {
       localResult = Result.newErrorResult(localHsqlException4, this.statements[i].getSQL());
       break;
     }
   }
   if (!localResult.isError())
     try {
       for (i = 0; i < localHsqlArrayList.size(); i++) {
         Constraint localConstraint = (Constraint) localHsqlArrayList.get(i);
         localTable =
             paramSession.database.schemaManager.getUserTable(
                 paramSession, localConstraint.core.refTableName);
         ParserDDL.addForeignKey(paramSession, localTable, localConstraint, null);
         localStatementSchema2.sql = localConstraint.getSQL();
         localStatementSchema2.execute(paramSession);
       }
     } catch (HsqlException localHsqlException1) {
       localResult = Result.newErrorResult(localHsqlException1, this.sql);
     }
   if (localResult.isError())
     try {
       paramSession.database.schemaManager.dropSchema(paramSession, localHsqlName1.name, true);
       paramSession.database.logger.writeOtherStatement(
           paramSession, getDropSchemaStatement(localHsqlName1));
     } catch (HsqlException localHsqlException2) {
     }
   paramSession.setCurrentSchemaHsqlName(localHsqlName2);
   return localResult;
 }