You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2012/02/02 23:44:47 UTC

svn commit: r1239898 - /db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ViewDescriptor.java

Author: dag
Date: Thu Feb  2 22:44:46 2012
New Revision: 1239898

URL: http://svn.apache.org/viewvc?rev=1239898&view=rev
Log:
DERBY-5567 AlterTableTest#testDropColumn fails: drop view cannot be performed due to dependency

When a view (b) is defined on another view (a), dropping a column in
the base table can lead to both view being invalidated. This patch
(DERBY-5567-1) fixes a problem in the logic:

Depending on the order in which dependencies of the base table column
are registered, the invalidation will happen either view a or view b.
If it happens on view a first, this view in turn will try to
invalidate view b (since that depends on view a), but with the
DROP_VIEW action which fails. The patch changes this recursive
invalidation to use the original action, e.g. DROP_COLUMN which will
allow dropping the dependent view (dropping a column is allowed to
cause cascading drops of dependent views).

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ViewDescriptor.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ViewDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ViewDescriptor.java?rev=1239898&r1=1239897&r2=1239898&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ViewDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ViewDescriptor.java Thu Feb  2 22:44:46 2012
@@ -35,6 +35,7 @@ import org.apache.derby.iapi.services.sa
 import org.apache.derby.catalog.DependableFinder;
 import org.apache.derby.catalog.Dependable;
 import org.apache.derby.iapi.services.io.StoredFormatIds;
+import org.apache.derby.impl.sql.depend.BasicDependencyManager;
 
 /**
  * This is the implementation of ViewDescriptor. Users of View descriptors
@@ -359,20 +360,28 @@ public final class ViewDescriptor extend
 				// types SELECT, UPDATE, DELETE, INSERT, REFERENCES, TRIGGER),
 				// we make the ViewDescriptor drop itself. REVOKE_ROLE also
 				// drops the dependent view.
+            case DependencyManager.DROP_COLUMN:
 		    case DependencyManager.REVOKE_PRIVILEGE:
-		    case DependencyManager.DROP_COLUMN:
 			case DependencyManager.REVOKE_ROLE:
-				drop(lcc, 
-						getDataDictionary().getTableDescriptor(uuid).getSchemaDescriptor(),
-						getDataDictionary().getTableDescriptor(uuid));
-
-                                lcc.getLastActivation().addWarning(
-                                    StandardException.newWarning(
-                                        SQLState.LANG_VIEW_DROPPED,
-                                        this.getObjectName() ));
-                                return;
+                
+                TableDescriptor td = 
+                        getDataDictionary().getTableDescriptor(uuid);
+                
+                if (td == null) { 
+                    // DERBY-5567 already dropped via another dependency 
+                    break;
+                }
+                
+                // DERBY-5567 keep original action
+                drop(lcc, td.getSchemaDescriptor(), td, action);
+
+                lcc.getLastActivation().addWarning(
+                        StandardException.newWarning(
+                        SQLState.LANG_VIEW_DROPPED,
+                        this.getObjectName() ));
+                break;
 
-		    default:
+            default:
 
 				/* We should never get here, since we can't have dangling references */
 				if (SanityManager.DEBUG)
@@ -409,14 +418,43 @@ public final class ViewDescriptor extend
 		}
 	}
 
-	public void drop(LanguageConnectionContext lcc,
-							  SchemaDescriptor sd, TableDescriptor td)
-		throws StandardException
-	{
+    /**
+     * Drop this descriptor, if not already done.
+     * 
+     * @param lcc current language connection context
+     * @param sd schema descriptor
+     * @param td table descriptor for this view
+     * @throws StandardException standard error policy
+     */
+    public void drop(
+            LanguageConnectionContext lcc,
+            SchemaDescriptor sd,
+            TableDescriptor td) throws StandardException
+    {
+        drop(lcc, sd, td, DependencyManager.DROP_VIEW);
+    }
+
+    /**
+     * Drop this descriptor, if not already done, due to action.
+     * If action is not {@code DependencyManager.DROP_VIEW}, the descriptor is 
+     * dropped due to dropping some other object, e.g. a table column.
+     * 
+     * @param lcc current language connection context
+     * @param sd schema descriptor
+     * @param td table descriptor for this view
+     * @param action action
+     * @throws StandardException standard error policy
+     */
+    private void drop(
+            LanguageConnectionContext lcc,
+            SchemaDescriptor sd,
+            TableDescriptor td,
+            int action) throws StandardException
+    {
         DataDictionary dd = getDataDictionary();
         DependencyManager dm = dd.getDependencyManager();
         TransactionController tc = lcc.getTransactionExecute();
-        
+
 		/* Drop the columns */
 		dd.dropAllColumnDescriptors(td.getUUID(), tc);
 
@@ -425,7 +463,7 @@ public final class ViewDescriptor extend
 		 * cursor referencing a table/view that the user is attempting to
 		 * drop.) If no one objects, then invalidate any dependent objects.
 		 */
-		dm.invalidateFor(td, DependencyManager.DROP_VIEW, lcc);
+        dm.invalidateFor(td, action, lcc);
 
 		/* Clear the dependencies for the view */
 		dm.clearDependencies(lcc, this);
@@ -440,5 +478,8 @@ public final class ViewDescriptor extend
 		dd.dropTableDescriptor(td, sd, tc);
 	}
 
+    public String getName() {
+        return viewName;
+    }
 
 }