Browse Source

AMBARI-20387. Upgrades on MySQL Should Also Drop Indexes With Foreign Key Names (jhurley via dlysnichenko)

Lisnichenko Dmitro 8 years ago
parent
commit
40747a956f

+ 8 - 3
ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessor.java

@@ -341,9 +341,14 @@ public interface DBAccessor {
   void dropSequence(String sequenceName) throws SQLException;
 
   /**
-   * Drop a FK constraint from table
-   * @param tableName name of the table
-   * @param constraintName name of the constraint
+   * Drops a FK constraint from a table. In the case of
+   * {@link DatabaseType#MYSQL}, this will also ensure that any associated
+   * indexes are also dropped.
+   *
+   * @param tableName
+   *          name of the table
+   * @param constraintName
+   *          name of the constraint
    * @throws SQLException
    */
   void dropFKConstraint(String tableName, String constraintName) throws SQLException;

+ 16 - 13
ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java

@@ -274,7 +274,7 @@ public class DBAccessorImpl implements DBAccessor {
 
   @Override
   public boolean tableHasColumn(String tableName, String... columnName) throws SQLException {
-    List<String> columnsList = new ArrayList<String>(Arrays.asList(columnName));
+    List<String> columnsList = new ArrayList<>(Arrays.asList(columnName));
     DatabaseMetaData metaData = getDatabaseMetaData();
 
     CustomStringUtils.toUpperCase(columnsList);
@@ -365,11 +365,11 @@ public class DBAccessorImpl implements DBAccessor {
     ResultSet rs = metaData.getCrossReference(null, dbSchema, convertObjectName(referenceTableName),
             null, dbSchema, convertObjectName(tableName));
 
-    List<String> pkColumns = new ArrayList<String>(referenceColumns.length);
+    List<String> pkColumns = new ArrayList<>(referenceColumns.length);
     for (String referenceColumn : referenceColumns) {
       pkColumns.add(convertObjectName(referenceColumn));
     }
-    List<String> fkColumns = new ArrayList<String>(keyColumns.length);
+    List<String> fkColumns = new ArrayList<>(keyColumns.length);
     for (String keyColumn : keyColumns) {
       fkColumns.add(convertObjectName(keyColumn));
     }
@@ -871,23 +871,26 @@ public class DBAccessorImpl implements DBAccessor {
     dropFKConstraint(tableName, constraintName, false);
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public void dropFKConstraint(String tableName, String constraintName, boolean ignoreFailure) throws SQLException {
-    // ToDo: figure out if name of index and constraint differs
     String checkedConstraintName = getCheckedForeignKey(convertObjectName(tableName), constraintName);
     if (checkedConstraintName != null) {
       String query = dbmsHelper.getDropFKConstraintStatement(tableName, checkedConstraintName);
       executeQuery(query, ignoreFailure);
+    } else {
+      LOG.warn("Foreign key {} from {} table does not exist and will not be dropped",
+          constraintName, tableName);
+    }
 
-      // MySQL also adds indexes in addition to the FK which should be dropped
-      Configuration.DatabaseType databaseType = configuration.getDatabaseType();
-      if (databaseType == DatabaseType.MYSQL) {
-        query = dbmsHelper.getDropIndexStatement(constraintName, tableName);
+    // even if the FK didn't exist, the index constraint might, so check it
+    // indepedently of the FK (but only on MySQL)
+    Configuration.DatabaseType databaseType = configuration.getDatabaseType();
+    if (databaseType == DatabaseType.MYSQL && tableHasIndex(tableName, false, constraintName)) {
+        String query = dbmsHelper.getDropIndexStatement(constraintName, tableName);
         executeQuery(query, true);
-      }
-
-    } else {
-      LOG.warn("Constraint {} from {} table not found, nothing to drop", constraintName, tableName);
     }
   }
 
@@ -1108,7 +1111,7 @@ public class DBAccessorImpl implements DBAccessor {
   public List<String> getIndexesList(String tableName, boolean unique)
     throws SQLException{
     ResultSet rs = getDatabaseMetaData().getIndexInfo(null, dbSchema, convertObjectName(tableName), unique, false);
-    List<String> indexList = new ArrayList<String>();
+    List<String> indexList = new ArrayList<>();
     if (rs != null){
       try{
         while (rs.next()) {