Index: modules/field/field.crud.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.crud.inc,v
retrieving revision 1.73
diff -u -p -r1.73 field.crud.inc
--- modules/field/field.crud.inc	15 Dec 2010 04:13:48 -0000	1.73
+++ modules/field/field.crud.inc	17 Dec 2010 20:04:31 -0000
@@ -583,16 +583,12 @@ function field_read_fields($params = arr
  */
 function field_delete_field($field_name) {
   // Delete all non-deleted instances.
-  $field = field_info_field($field_name);
-  if (isset($field['bundles'])) {
-    foreach ($field['bundles'] as $entity_type => $bundles) {
-      foreach ($bundles as $bundle) {
-        $instance = field_info_instance($entity_type, $field_name, $bundle);
-        field_delete_instance($instance, FALSE);
-      }
-    }
+  $field = field_read_field($field_name, array('include_inactive' => TRUE));
+  $instances = field_read_instances(array('field_id' => $field['id']), array('include_inactive' => TRUE));
+  foreach ($instances as $instance) {
+    field_delete_instance($instance, FALSE);
   }
-
+  
   // Mark field data for deletion.
   module_invoke($field['storage']['module'], 'field_storage_delete_field', $field);
 
@@ -941,15 +937,18 @@ function field_delete_instance($instance
   field_cache_clear();
 
   // Mark instance data for deletion.
-  $field = field_info_field($instance['field_name']);
+  $field = field_read_field($instance['field_name'], array('include_inactive' => TRUE));
   module_invoke($field['storage']['module'], 'field_storage_delete_instance', $instance);
 
   // Let modules react to the deletion of the instance.
   module_invoke_all('field_delete_instance', $instance);
 
   // Delete the field itself if we just deleted its last instance.
-  if ($field_cleanup && count($field['bundles']) == 0) {
-    field_delete_field($field['field_name']);
+  if ($field_cleanup) {
+    $instances = field_read_instances(array('field_id' => $field['id']), array('include_inactive' => TRUE));
+    if (empty($instances)){
+      field_delete_field($field['field_name']);
+    }
   }
 }
 
@@ -1037,13 +1036,17 @@ function field_delete_instance($instance
  *   The maximum number of field data records to purge before returning.
  */
 function field_purge_batch($batch_size) {
-  // Retrieve all deleted field instances. We cannot use field_info_instances()
-  // because that function does not return deleted instances.
-  $instances = field_read_instances(array('deleted' => 1), array('include_deleted' => 1));
+  // Retrieve all deleted field instances, regardless its active status.
+  // A field is inactive when the module providing with its field type has
+  // been disabled.
+  $instances = field_read_instances(array('deleted' => 1), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
 
   foreach ($instances as $instance) {
     // field_purge_data() will need the field array.
-    $field = field_info_field_by_id($instance['field_id']);
+    $field = field_read_field($instance['field_name'], array('include_deleted' => TRUE, 'include_inactive' => TRUE));
+    if (empty($field['storage']['active'])){
+      continue;
+    }
     // Retrieve some entities.
     $query = new EntityFieldQuery();
     $results = $query
@@ -1068,10 +1071,10 @@ function field_purge_batch($batch_size) 
     }
   }
 
-  // Retrieve all deleted fields. Any that have no instances can be purged.
-  $fields = field_read_fields(array('deleted' => 1), array('include_deleted' => 1));
+  // Retrieve all deleted fields. Any that have no bundles can be purged.
+  $fields = field_read_fields(array('deleted' => 1), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
   foreach ($fields as $field) {
-    $instances = field_read_instances(array('field_id' => $field['id']), array('include_deleted' => 1));
+    $instances = field_read_instances(array('field_id' => $field['id']), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
     if (empty($instances)) {
       field_purge_field($field);
     }
@@ -1125,7 +1128,7 @@ function field_purge_instance($instance)
     ->execute();
 
   // Notify the storage engine.
-  $field = field_info_field_by_id($instance['field_id']);
+  $field = field_read_field($instance['field_name'], array('include_deleted' => TRUE, 'include_inactive' => TRUE));
   module_invoke($field['storage']['module'], 'field_storage_purge_instance', $instance);
 
   // Clear the cache.
Index: modules/field/modules/field_sql_storage/field_sql_storage.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/field_sql_storage/field_sql_storage.module,v
retrieving revision 1.57
diff -u -p -r1.57 field_sql_storage.module
--- modules/field/modules/field_sql_storage/field_sql_storage.module	14 Dec 2010 19:50:05 -0000	1.57
+++ modules/field/modules/field_sql_storage/field_sql_storage.module	17 Dec 2010 20:04:31 -0000
@@ -436,13 +436,15 @@ function field_sql_storage_field_storage
  *
  * This function deletes data for all fields for an entity from the database.
  */
-function field_sql_storage_field_storage_delete($entity_type, $entity, $fields) {
-  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
-
-  foreach (field_info_instances($entity_type, $bundle) as $instance) {
-    if (isset($fields[$instance['field_id']])) {
-      $field = field_info_field_by_id($instance['field_id']);
-      field_sql_storage_field_storage_purge($entity_type, $entity, $field, $instance);
+function field_sql_storage_field_storage_delete($entity_type, $entity, $field_ids) {
+  foreach ($field_ids as $field_id) {
+    $fields = field_read_fields(array('id' => $field_id), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
+    $field = $fields ? current($fields) : FALSE;
+    if ($field) {
+      $instances = field_read_instances(array('field_id' => $field_id), array('include_delete' => TRUE, 'include_inactive' => TRUE));
+      foreach ($instances as $instance) {
+        field_sql_storage_field_storage_purge($entity_type, $entity, $field, $instance);
+      }
     }
   }
 }
@@ -605,13 +607,16 @@ function field_sql_storage_field_storage
 
   if (isset($vid)) {
     foreach ($fields as $field_id) {
-      $field = field_info_field_by_id($field_id);
-      $revision_name = _field_sql_storage_revision_tablename($field);
-      db_delete($revision_name)
-        ->condition('entity_type', $entity_type)
-        ->condition('entity_id', $id)
-        ->condition('revision_id', $vid)
-        ->execute();
+      $fields = field_read_fields(array('id' => $field_id), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
+      $field = $fields ? current($fields) : FALSE;
+      if ($field) {
+        $revision_name = _field_sql_storage_revision_tablename($field);
+        db_delete($revision_name)
+          ->condition('entity_type', $entity_type)
+          ->condition('entity_id', $id)
+          ->condition('revision_id', $vid)
+          ->execute();
+      }
     }
   }
 }
@@ -622,7 +627,7 @@ function field_sql_storage_field_storage
  * This function simply marks for deletion all data associated with the field.
  */
 function field_sql_storage_field_storage_delete_instance($instance) {
-  $field = field_info_field($instance['field_name']);
+  $field = field_read_field($instance['field_name'], array('include_inactive' => TRUE));
   $table_name = _field_sql_storage_tablename($field);
   $revision_name = _field_sql_storage_revision_tablename($field);
   db_update($table_name)
Index: modules/field/tests/field.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/tests/field.test,v
retrieving revision 1.47
diff -u -p -r1.47 field.test
--- modules/field/tests/field.test	15 Dec 2010 04:13:48 -0000	1.47
+++ modules/field/tests/field.test	17 Dec 2010 20:04:31 -0000
@@ -2096,11 +2096,13 @@ class FieldCrudTestCase extends FieldTes
   function testDeleteField() {
     // TODO: Also test deletion of the data stored in the field ?
 
-    // Create two fields (so we can test that only one is deleted).
+    // Create three fields (so we can test which is deleted).
     $this->field = array('field_name' => 'field_1', 'type' => 'test_field');
     field_create_field($this->field);
     $this->another_field = array('field_name' => 'field_2', 'type' => 'test_field');
     field_create_field($this->another_field);
+    $this->inactive_field = array('field_name' => 'field_inactive', 'type' => 'test_field');
+    field_create_field($this->inactive_field);
 
     // Create instances for each.
     $this->instance_definition = array(
@@ -2112,10 +2114,21 @@ class FieldCrudTestCase extends FieldTes
       ),
     );
     field_create_instance($this->instance_definition);
+
     $this->another_instance_definition = $this->instance_definition;
     $this->another_instance_definition['field_name'] = $this->another_field['field_name'];
     field_create_instance($this->another_instance_definition);
 
+    $this->inactive_instance_definition = $this->instance_definition;
+    $this->inactive_instance_definition['field_name'] = $this->inactive_field['field_name'];
+    field_create_instance($this->inactive_instance_definition);
+
+    // Simulate an inactive field.
+    db_update('field_config')
+      ->fields(array('active' => 0))
+      ->condition('field_name', $this->inactive_field['field_name'])
+      ->execute();
+
     // Test that the first field is not deleted, and then delete it.
     $field = field_read_field($this->field['field_name'], array('include_deleted' => TRUE));
     $this->assertTrue(!empty($field) && empty($field['deleted']), t('A new field is not marked for deletion.'));
@@ -2145,6 +2158,17 @@ class FieldCrudTestCase extends FieldTes
     $another_instance = field_read_instance('test_entity', $this->another_instance_definition['field_name'], $this->another_instance_definition['bundle']);
     $this->assertTrue(!empty($another_instance) && empty($another_instance['deleted']), t('An instance of a non-deleted field is not marked for deletion.'));
 
+    // Make sure that the inactive field is marked as deleted when it is
+    // specifically loaded.
+    field_delete_field($this->inactive_field['field_name']);
+    $field = field_read_field($this->inactive_field['field_name'], array('include_deleted' => TRUE, 'include_inactive' => TRUE));
+    $this->assertTrue(!empty($field['deleted']), t('A deleted inactive field is marked for deletion.'));
+
+    // Try to load the instance of the inactive field normally and make sure
+    // it does not show up.
+    $instance = field_read_instance('test_entity', $this->inactive_instance_definition['field_name'], $this->inactive_instance_definition['bundle']);
+    $this->assertTrue(empty($instance), t('An instance for a deleted inactive field is not loaded by default.'));
+
     // Try to create a new field the same name as a deleted field and
     // write data into it.
     field_create_field($this->field);
@@ -2961,6 +2985,12 @@ class FieldBulkDeleteTestCase extends Fi
         $id++;
       }
     }
+
+    // Simulate an inactive field.
+    db_update('field_config')
+      ->fields(array('active' => 0))
+      ->condition('field_name', 'bf_2')
+      ->execute();
   }
 
   /**
