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 rh...@apache.org on 2013/12/23 21:07:35 UTC

svn commit: r1553197 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/sql/compile/ engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/lang/ testing/org/apache/derbyTesting/functionTests/tests/store...

Author: rhillegas
Date: Mon Dec 23 20:07:35 2013
New Revision: 1553197

URL: http://svn.apache.org/r1553197
Log:
DERBY-6429: Bring privilege checks on UPDATE statements into closer alignment with the SQL Standard; tests passed cleanly on derby-6429-01-af-privilegeFilters.diff.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/TagFilter.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/VisitableFilter.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Visitable.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsPermsTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/Derby5234Test.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/CompilerContext.java Mon Dec 23 20:07:35 2013
@@ -585,4 +585,24 @@ public interface CompilerContext extends
 	 */
     boolean isReferenced( SequenceDescriptor sd );
 
+    /**
+     * Add a filter for determining which QueryTreeNodes give rise to privilege checks
+     * at run time. The null filter (the default) says that all QueryTreeNodes potentially give
+     * rise to privilege checks.
+     */
+    public  void    addPrivilegeFilter( VisitableFilter vf );
+
+    /**
+     * Remove a filter for determining which QueryTreeNodes give rise to privilege
+     * checks at run time.
+     */
+    public  void    removePrivilegeFilter( VisitableFilter vf );
+    
+    /**
+     * Return true if a QueryTreeNode passes all of the filters which determine whether
+     * the QueryTreeNode gives rise to run time privilege checks.
+     */
+    public  boolean passesPrivilegeFilters( Visitable visitable )
+        throws StandardException;
+    
 }

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/TagFilter.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/TagFilter.java?rev=1553197&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/TagFilter.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/TagFilter.java Mon Dec 23 20:07:35 2013
@@ -0,0 +1,72 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.sql.compile.TagFilter
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.iapi.sql.compile;
+
+import java.util.List;
+
+import org.apache.derby.iapi.error.StandardException;
+
+/**
+ * Filter which passes Visitables which have been marked with a given tag.
+ *
+ */
+public class TagFilter implements VisitableFilter
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** Tag placed on QueryTreeNodes which need privilege checks for UPDATE statements */
+    public  static  final   String      NEED_PRIVS_FOR_UPDATE_STMT = "updatePrivs";
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    
+    private String  _tag;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** Construct a filter for the given tag. */
+    public  TagFilter( String tag ) { _tag = tag; }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  VisitableFilter BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    
+	public  boolean accept( Visitable visitable ) 
+		throws StandardException
+    {
+        return visitable.taggedWith( _tag );
+    }
+    
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/TagFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Visitable.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Visitable.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Visitable.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Visitable.java Mon Dec 23 20:07:35 2013
@@ -21,6 +21,8 @@
 
 package org.apache.derby.iapi.sql.compile;
 
+import java.util.List;
+
 import org.apache.derby.iapi.error.StandardException;
 
 /**
@@ -38,6 +40,16 @@ public interface Visitable
 	 *
 	 * @exception StandardException on error
 	 */
-	abstract Visitable accept(Visitor v) 
+	public  Visitable accept(Visitor v) 
 		throws StandardException;
+
+    /**
+     * Add a tag to this Visitable.
+     */
+    public  void    addTag( String tag );
+
+    /**
+     * Return true if this Visitable is tagged with the indicated tag.
+     */
+    public  boolean taggedWith( String tag );
 }

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/VisitableFilter.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/VisitableFilter.java?rev=1553197&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/VisitableFilter.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/VisitableFilter.java Mon Dec 23 20:07:35 2013
@@ -0,0 +1,37 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.sql.compile.VisitableFilter
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.iapi.sql.compile;
+
+import org.apache.derby.iapi.error.StandardException;
+
+/**
+ * Filter for qualifying Visitables.
+ *
+ */
+public interface VisitableFilter
+{
+	/**
+	 * Return true if the Visitable passes the filter.
+	 */
+	public  boolean accept( Visitable visitable ) 
+		throws StandardException;
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/VisitableFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java Mon Dec 23 20:07:35 2013
@@ -353,6 +353,7 @@ public class ColumnReference extends Val
 		replacesWindowFunctionCall =
 			oldCR.getGeneratedToReplaceWindowFunctionCall();
 		scoped = oldCR.isScoped();
+        copyTagsFrom( oldCR );
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CompilerContextImpl.java Mon Dec 23 20:07:35 2013
@@ -39,6 +39,8 @@ import org.apache.derby.shared.common.sa
 import org.apache.derby.iapi.sql.compile.CompilerContext;
 import org.apache.derby.iapi.sql.compile.OptimizerFactory;
 import org.apache.derby.iapi.sql.compile.Parser;
+import org.apache.derby.iapi.sql.compile.Visitable;
+import org.apache.derby.iapi.sql.compile.VisitableFilter;
 import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
 import org.apache.derby.iapi.sql.conn.Authorizer;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
@@ -140,6 +142,7 @@ public class CompilerContextImpl extends
 		initRequiredPriv();
 		defaultSchemaStack = null;
         referencedSequences = null;
+        privilegeCheckFilters =  null;
 	}
 
 	//
@@ -969,6 +972,35 @@ public class CompilerContextImpl extends
         return referencedSequences.containsKey( sd.getUUID() );
     }
 
+    public  void    addPrivilegeFilter( VisitableFilter vf )
+    {
+        if ( privilegeCheckFilters == null ) { privilegeCheckFilters = new ArrayList<VisitableFilter>(); }
+        
+        privilegeCheckFilters.add( vf );
+    }
+
+    public  void    removePrivilegeFilter( VisitableFilter vf )
+    {
+        if ( (vf != null) && (privilegeCheckFilters != null) )
+        {
+            privilegeCheckFilters.remove( vf );
+        }
+    }
+
+    public  boolean passesPrivilegeFilters( Visitable visitable )
+        throws StandardException
+    {
+        // if there are no filters, then all QueryTreeNodes pass.
+        if ( privilegeCheckFilters == null ) { return true; }
+
+        for ( VisitableFilter filter : privilegeCheckFilters )
+        {
+            if ( !filter.accept( visitable ) ) { return false; }
+        }
+
+        return true;
+    }
+    
 	/*
 	** Context state must be reset in restContext()
 	*/
@@ -1028,4 +1060,7 @@ public class CompilerContextImpl extends
 	private HashMap<UUID,String> requiredUsagePrivileges;
 	private HashMap<StatementRolePermission,StatementRolePermission> requiredRolePrivileges;
     private HashMap<UUID,SequenceDescriptor> referencedSequences;
+
+    private ArrayList<VisitableFilter> privilegeCheckFilters;
+    
 } // end of class CompilerContextImpl

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java Mon Dec 23 20:07:35 2013
@@ -49,6 +49,7 @@ import org.apache.derby.iapi.sql.compile
 import org.apache.derby.iapi.sql.compile.Optimizer;
 import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;
 import org.apache.derby.iapi.sql.compile.RowOrdering;
+import org.apache.derby.iapi.sql.compile.TagFilter;
 import org.apache.derby.iapi.sql.compile.Visitor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
@@ -2386,7 +2387,7 @@ class FromBaseTable extends FromTable
 				//on the actual view and that is what the following code is
 				//checking.
                 for (ResultColumn rc : resultColumns) {
-                    if (rc.isPrivilegeCollectionRequired()) {
+                    if (isPrivilegeCollectionRequired()) {
 						compilerContext.addRequiredColumnPriv( rc.getTableColumnDescriptor());
                     }
 				}
@@ -2809,6 +2810,19 @@ class FromBaseTable extends FromTable
                     ( (rowLocationColumnName == null) || !(rowLocationColumnName.equals( columnReference.getColumnName() )) )
                     )
 				{
+                    //
+                    // Add a privilege for this column if the bind() phase of an UPDATE
+                    // statement marked it as a selected column. see DERBY-6429.
+                    //
+                    if ( columnReference.isPrivilegeCollectionRequired() )
+                    {
+                        if ( columnReference.taggedWith( TagFilter.NEED_PRIVS_FOR_UPDATE_STMT ) )
+                        {
+                            getCompilerContext().addRequiredColumnPriv
+                                ( tableDescriptor.getColumnDescriptor( columnReference.getColumnName() ) );
+                        }
+                    }
+                         
 					FormatableBitSet referencedColumnMap = tableDescriptor.getReferencedColumnMap();
 					if (referencedColumnMap == null)
 						referencedColumnMap = new FormatableBitSet(

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java Mon Dec 23 20:07:35 2013
@@ -22,6 +22,8 @@
 package	org.apache.derby.impl.sql.compile;
 
 import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import org.apache.derby.catalog.AliasInfo;
 import org.apache.derby.catalog.TypeDescriptor;
@@ -85,6 +87,8 @@ public abstract class QueryTreeNode impl
 	private LanguageConnectionContext lcc;
 	private GenericConstantActionFactory	constantActionFactory;
 
+    private ArrayList<String>   visitableTags;
+
 	/**
 	 * In Derby SQL Standard Authorization, views, triggers and constraints 
 	 * execute with definer's privileges. Taking a specific eg of views
@@ -572,8 +576,11 @@ public abstract class QueryTreeNode impl
 	 * @return true if need to collect privilege requirement for this node
 	 */
     boolean isPrivilegeCollectionRequired()
+        throws StandardException
 	{
-		return(isPrivilegeCollectionRequired);
+        return
+            isPrivilegeCollectionRequired &&
+            getCompilerContext().passesPrivilegeFilters( this );
 	}
 
 	/**
@@ -704,6 +711,28 @@ public abstract class QueryTreeNode impl
 		// no children
 	}
 
+    public  void    addTag( String tag )
+    {
+        if ( visitableTags == null ) { visitableTags = new ArrayList<String>(); }
+        visitableTags.add( tag );
+    }
+
+    public  boolean taggedWith( String tag )
+    {
+        if ( visitableTags == null ) { return false; }
+        else { return visitableTags.contains( tag ); }
+    }
+
+    /** Copy the tags from another QueryTreeNode */
+    protected   void    copyTagsFrom( QueryTreeNode that )
+    {
+        if ( that.visitableTags == null ) { return; }
+        else
+        {
+            for ( String tag : that.visitableTags ) { addTag( tag ); }
+        }
+    }
+    
 	/**
 	 * Get the int value of a Property
 	 *
@@ -1311,6 +1340,21 @@ public abstract class QueryTreeNode impl
         }
     }
 
+    /** Get the AliasDescriptor of a UDT */
+    public  AliasDescriptor getUDTDesc( DataTypeDescriptor dtd )
+        throws StandardException
+    {
+        UserDefinedTypeIdImpl userTypeID = (UserDefinedTypeIdImpl) dtd.getTypeId().getBaseTypeId();
+
+        DataDictionary dd = getDataDictionary();
+        SchemaDescriptor typeSchema = getSchemaDescriptor( userTypeID.getSchemaName() );
+        char  udtNameSpace = AliasInfo.ALIAS_NAME_SPACE_UDT_AS_CHAR;
+        String unqualifiedTypeName = userTypeID.getUnqualifiedName();
+        AliasDescriptor ad = dd.getAliasDescriptor( typeSchema.getUUID().toString(), unqualifiedTypeName, udtNameSpace );
+
+        return ad;
+    }
+
     /**
      * Bind the UDTs in a table type.
      *

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java Mon Dec 23 20:07:35 2013
@@ -1565,6 +1565,8 @@ class ResultColumn extends ValueNode
   			newResultColumn.markGenerated();
   		}
 
+        newResultColumn.copyTagsFrom( this );
+
   		return newResultColumn;
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java Mon Dec 23 20:07:35 2013
@@ -226,6 +226,9 @@ class StaticMethodCallNode extends Metho
                      getContextManager()
                      );
 
+                // Propagate tags used to flag nodes which need privilege checks. See DERBY-6429.
+                resolvedAggregate.copyTagsFrom( this );
+
                 // The parser may have noticed that this aggregate is invoked in a
                 // GROUP BY clause. That is not allowed.
                 if ( appearsInGroupBy )

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java Mon Dec 23 20:07:35 2013
@@ -37,8 +37,11 @@ import org.apache.derby.iapi.services.co
 import org.apache.derby.iapi.services.io.FormatableBitSet;
 import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.sql.StatementType;
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.TagFilter;
 import org.apache.derby.iapi.sql.conn.Authorizer;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
 import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
@@ -53,6 +56,7 @@ import org.apache.derby.iapi.sql.execute
 import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
 import org.apache.derby.iapi.store.access.TransactionController;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.TypeId;
 import org.apache.derby.iapi.util.ReuseFactory;
 import org.apache.derby.vti.DeferModification;
@@ -191,6 +195,15 @@ public final class UpdateNode extends DM
 			}
 		}
 
+        // collect lists of objects which will require privilege checks
+        ArrayList<String>   explicitlySetColumns = getExplicitlySetColumns();
+        List<ValueNode> allValueNodes = collectAllValueNodes();
+        tagPrivilegedNodes();
+
+        // tell the compiler to only add privilege checks for nodes which have been tagged
+        TagFilter   tagFilter = new TagFilter( TagFilter.NEED_PRIVS_FOR_UPDATE_STMT );
+        getCompilerContext().addPrivilegeFilter( tagFilter );
+		
 		bindTables(dataDictionary);
 
 		// wait to bind named target table until the cursor
@@ -257,7 +270,10 @@ public final class UpdateNode extends DM
 		// and we already bound the cursor or the select,
 		// the table descriptor should always be found.
 		verifyTargetTable();
-		
+
+        // add UPDATE_PRIV on all columns on the left side of SET operators
+        addUpdatePriv( explicitlySetColumns );
+
 		/* OVERVIEW - We generate a new ResultColumn, CurrentRowLocation(), and
 		 * prepend it to the beginning of the source ResultColumnList.  This
 		 * will tell us which row(s) to update at execution time.  However,
@@ -339,12 +355,10 @@ public final class UpdateNode extends DM
 		/* Bind the original result columns by column name */
 		normalizeCorrelatedColumns( resultSet.resultColumns, targetTable );
 
-		getCompilerContext().pushCurrentPrivType(getPrivType()); // Update privilege
 		resultSet.bindResultColumns(targetTableDescriptor,
 					targetVTI,
 					resultSet.resultColumns, this,
 					fromList);
-		getCompilerContext().popCurrentPrivType();
 
         // don't allow overriding of generation clauses
         forbidGenerationOverrides( resultSet.getResultColumns(),
@@ -516,9 +530,7 @@ public final class UpdateNode extends DM
 		resultSet.setResultColumns(resultColumnList);
 
 		/* Bind the expressions */
-		getCompilerContext().pushCurrentPrivType(getPrivType()); // Update privilege
 		super.bindExpressions();
-		getCompilerContext().popCurrentPrivType();
 
 		/* Bind untyped nulls directly under the result columns */
 		resultSet.
@@ -603,7 +615,12 @@ public final class UpdateNode extends DM
             }
         }
 
-		getCompilerContext().popCurrentPrivType();		
+		getCompilerContext().popCurrentPrivType();
+
+        // don't remove the privilege filter. additional binding may be
+        // done during the pre-processing phase
+
+        addUDTUsagePriv( allValueNodes );
 
     } // end of bind()
 
@@ -613,6 +630,157 @@ public final class UpdateNode extends DM
 		return Authorizer.UPDATE_PRIV;
 	}
 
+    /**
+     * Get the names of the explicitly set columns, that is, the columns on the left side
+     * of SET operators.
+     */
+    private ArrayList<String>   getExplicitlySetColumns()
+        throws StandardException
+    {
+        ArrayList<String>   result = new ArrayList<String>();
+        ResultColumnList    rcl = resultSet.getResultColumns();
+
+        for ( int i = 0; i < rcl.size(); i++ )
+        {
+            result.add( rcl.elementAt( i ).getName() );
+        }
+
+        return result;
+    }
+
+    /**
+     * Collect all of the ValueNodes in the WHERE clause and on the right side
+     * of SET operators. Later on, we will need to add permissions for all UDTs
+     * mentioned by these nodes.
+     */
+    private List<ValueNode>    collectAllValueNodes()
+        throws StandardException
+    {
+        CollectNodesVisitor<ValueNode> getValues =
+            new CollectNodesVisitor<ValueNode>(ValueNode.class);
+
+        // process the WHERE clause
+        ValueNode   whereClause = ((SelectNode) resultSet).whereClause;
+        if ( whereClause != null ) { whereClause.accept( getValues ); }
+
+        // process the right sides of the SET operators
+        ResultColumnList    rcl = resultSet.getResultColumns();
+        for ( int i = 0; i < rcl.size(); i++ )
+        {
+            rcl.elementAt( i ).getExpression().accept( getValues );
+        }
+
+        return getValues.getList();
+    }
+
+    /**
+     * Add USAGE privilege for all UDTs mentioned in the WHERE clause and
+     * on the right side of SET operators.
+     */
+    private void    addUDTUsagePriv( List<ValueNode> valueNodes )
+        throws StandardException
+    {
+        if ( !isPrivilegeCollectionRequired() ) { return; }
+        
+        for ( ValueNode val : valueNodes )
+        {
+            DataTypeDescriptor  dtd = val.getTypeServices();
+            if ( (dtd != null) && dtd.getTypeId().userType() )
+            {
+                AliasDescriptor ad = getUDTDesc( dtd );
+                getCompilerContext().addRequiredUsagePriv( ad );
+            }
+        }
+    }
+
+    /**
+     * Tag all of the nodes which may require privilege checks.
+     * These are various QueryTreeNodes in the WHERE clause and on the right
+     * side of SET operators.
+     */
+    private void    tagPrivilegedNodes()
+        throws StandardException
+    {
+        ArrayList<QueryTreeNode>    result = new ArrayList<QueryTreeNode>();
+
+        SelectNode  selectNode = (SelectNode) resultSet;
+
+        // add this node so that addUpdatePriv() and addUDTUsagePriv() will work
+        result.add( this );
+
+        // process the WHERE clause
+        ValueNode   whereClause = selectNode.whereClause;
+        if ( whereClause !=  null ) { collectPrivilegedNodes( result, whereClause ); }
+
+        // process the right sides of the SET operators
+        ResultColumnList    rcl = resultSet.getResultColumns();
+        for ( int i = 0; i < rcl.size(); i++ )
+        {
+            collectPrivilegedNodes( result, rcl.elementAt( i ).getExpression() );
+        }
+
+        // now tag all the nodes we collected
+        for ( QueryTreeNode expr : result )
+        {
+            expr.addTag( TagFilter.NEED_PRIVS_FOR_UPDATE_STMT );
+        }
+    }
+
+    /**
+     * Add to an evolving list all of the nodes under an expression which may require privilege checks.
+     */
+    private void    collectPrivilegedNodes
+        ( ArrayList<QueryTreeNode> result, QueryTreeNode expr )
+        throws StandardException
+    {
+        // get all column references
+        CollectNodesVisitor<ColumnReference> getCRs =
+            new CollectNodesVisitor<ColumnReference>(ColumnReference.class);
+        expr.accept( getCRs );
+        result.addAll( getCRs.getList() );
+
+        // get all function references
+        CollectNodesVisitor<StaticMethodCallNode> getSMCNs =
+            new CollectNodesVisitor<StaticMethodCallNode>(StaticMethodCallNode.class);
+        expr.accept( getSMCNs );
+        result.addAll( getSMCNs.getList() );
+
+        // get all FromBaseTables in order to bulk-get their selected columns
+        CollectNodesVisitor<FromBaseTable> getFBTs =
+            new CollectNodesVisitor<FromBaseTable>(FromBaseTable.class);
+        expr.accept( getFBTs );
+        result.addAll( getFBTs.getList() );
+    }
+
+    /**
+     * Add UPDATE_PRIV on all columns on the left side of SET operators.
+     */
+    private void    addUpdatePriv( ArrayList<String> explicitlySetColumns )
+        throws StandardException
+    {
+        if ( !isPrivilegeCollectionRequired() ) { return; }
+        
+        CompilerContext cc = getCompilerContext();
+
+        cc.pushCurrentPrivType( Authorizer.UPDATE_PRIV );
+        try {
+            for ( String columnName : explicitlySetColumns )
+            {
+                ColumnDescriptor    cd = targetTableDescriptor.getColumnDescriptor( columnName );
+                cc.addRequiredColumnPriv( cd );
+            }
+        }
+        finally
+        {
+            cc.popCurrentPrivType();
+        }
+    }
+
+    /**
+     * Add privilege checks for UDTs referenced by this statement.
+     */
+
+    
 	/**
 	 * Return true if the node references SESSION schema tables (temporary or permanent)
 	 *

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java Mon Dec 23 20:07:35 2013
@@ -132,107 +132,6 @@ public class GeneratedColumnsHelper exte
     ///////////////////////////////////////////////////////////////////////////////////
 
     /**
-     * Run good DDL.
-     * @throws SQLException 
-     */
-    protected void    goodStatement( Connection conn, String ddl ) throws SQLException
-    {
-        PreparedStatement    ps = chattyPrepare( conn, ddl );
-
-        ps.execute();
-        ps.close();
-    }
-    
-    /**
-     * Run a good update statement with an expected row count.
-     * @throws SQLException 
-     */
-    protected void    goodUpdate( Connection conn, String update, int expectedRowCount ) throws SQLException
-    {
-        PreparedStatement    ps = chattyPrepare( conn, update );
-
-        int actualRowCount = ps.executeUpdate();
-        ps.close();
-
-        println( "Expecting to touch " + expectedRowCount + " rows." );
-        assertEquals( expectedRowCount, actualRowCount );
-    }
-    
-	protected	static	ResultSet	executeQuery( Statement stmt, String text )
-		throws SQLException
-	{
-		println( "Executing '" + text + "'" );
-
-        return stmt.executeQuery( text );
-	}
-
-    /**
-     * Prepare a statement and report its sql text.
-     */
-    protected PreparedStatement   chattyPrepare( Connection conn, String text )
-        throws SQLException
-    {
-        println( "Preparing statement:\n\t" + text );
-        
-        return conn.prepareStatement( text );
-    }
-
-    /**
-     * Prepare a callable statement and report its sql text.
-     */
-    protected CallableStatement   chattyPrepareCall( Connection conn, String text )
-        throws SQLException
-    {
-        println( "Preparing callable statement:\n\t" + text );
-        
-        return conn.prepareCall( text );
-    }
-
-    /**
-     * Assert that the statement text, when compiled, raises an exception
-     */
-    protected void    expectCompilationError( String sqlState, String query )
-    {
-        println( "\nExpecting " + sqlState + " when preparing:\n\t" + query );
-
-        assertCompileError( sqlState, query );
-    }
-
-    /**
-     * Assert that the statement text, when compiled, raises an exception
-     */
-    protected void    expectCompilationError( Connection conn, String sqlState, String query )
-    {
-        println( "\nExpecting " + sqlState + " when preparing:\n\t" + query );
-
-        PreparedStatement ps = null;
-
-        try {
-            ps = conn.prepareStatement( query );
-        } catch (SQLException se )
-        {
-            assertSQLState( sqlState, se );
-
-            return;
-        }
-
-        fail( "Expected SQL state: " + sqlState );
-    }
-
-    /**
-     * Assert that the statement text, when executed, raises an error.
-     */
-    protected void    expectExecutionError( Connection conn, String sqlState, String query )
-        throws Exception
-    {
-        println( "\nExpecting " + sqlState + " when executing:\n\t"  );
-        PreparedStatement   ps = chattyPrepare( conn, query );
-
-        assertStatementError( sqlState, ps );
-        ps.close();
-    }
-
-    /**
      * Assert that the in-place update raises the expected error.
      */
     protected void    expectUpdateRowError( ResultSet rs, String sqlState )

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsPermsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsPermsTest.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsPermsTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsPermsTest.java Mon Dec 23 20:07:35 2013
@@ -145,17 +145,16 @@ public class GeneratedColumnsPermsTest e
              dboConnection,
              "grant update ( a ) on t_bp_1 to public"
              );
-        
+
         expectExecutionError
             (
              janetConnection,
              LACK_TABLE_PRIV,
              "insert into test_dbo.t_bp_1( a ) values ( 100 )"
              );
-        expectExecutionError
+        goodStatement
             (
              janetConnection,
-             LACK_COLUMN_PRIV,
              "update test_dbo.t_bp_1 set a = a+ 1"
              );
         expectExecutionError
@@ -176,7 +175,7 @@ public class GeneratedColumnsPermsTest e
              "select a from test_dbo.t_bp_1 order by a",
              new String[][]
              {
-                 { "1", },
+                 { "2", },
              },
              false
              );
@@ -195,10 +194,9 @@ public class GeneratedColumnsPermsTest e
              LACK_TABLE_PRIV,
              "insert into test_dbo.t_bp_1( a ) values ( 100 )"
              );
-        expectExecutionError
+        goodStatement
             (
              janetConnection,
-             LACK_COLUMN_PRIV,
              "update test_dbo.t_bp_1 set a = a+ 1"
              );
         expectExecutionError
@@ -213,7 +211,7 @@ public class GeneratedColumnsPermsTest e
              "select * from test_dbo.t_bp_1 order by a",
              new String[][]
              {
-                 { "1", "-1", },
+                 { "3", "-3", },
              },
              false
              );
@@ -249,7 +247,7 @@ public class GeneratedColumnsPermsTest e
              "select * from test_dbo.t_bp_1 order by a",
              new String[][]
              {
-                 { "2", "-2", },
+                 { "4", "-4", },
              },
              false
              );
@@ -279,7 +277,7 @@ public class GeneratedColumnsPermsTest e
              "select * from test_dbo.t_bp_1 order by a",
              new String[][]
              {
-                 { "2", "-2", },
+                 { "4", "-4", },
                  { "100", "-100", },
              },
              false
@@ -296,7 +294,7 @@ public class GeneratedColumnsPermsTest e
         goodStatement
             (
              janetConnection,
-             "delete from test_dbo.t_bp_1 where a = 2"
+             "delete from test_dbo.t_bp_1 where a = 4"
              );
         assertResults
             (
@@ -379,12 +377,13 @@ public class GeneratedColumnsPermsTest e
              "no sql\n" +
              "external name 'java.lang.Math.abs'\n"
              );
-        expectExecutionError
+        goodStatement
             (
              janetConnection,
-             LACK_EXECUTE_PRIV,
              "update test_dbo.t_fp_1 set a = a + 1"
              );
+
+        // this is a wrong result. see DERBY-6434
         expectExecutionError
             (
              janetConnection,
@@ -397,7 +396,7 @@ public class GeneratedColumnsPermsTest e
              "select * from test_dbo.t_fp_1 order by a",
              new String[][]
              {
-                 { "100", "-100", },
+                 { "101", "-101", },
              },
              false
              );
@@ -426,7 +425,7 @@ public class GeneratedColumnsPermsTest e
              "select * from test_dbo.t_fp_1 order by a",
              new String[][]
              {
-                 { "101", "-101", },
+                 { "102", "-102", },
                  { "200", "-200", },
              },
              false

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GrantRevokeDDLTest.java Mon Dec 23 20:07:35 2013
@@ -42,11 +42,29 @@ import org.apache.derbyTesting.junit.Tes
 
 public final class GrantRevokeDDLTest extends BaseJDBCTestCase {
 
+    private static  final   String      TEST_DBO = "TEST_DBO";
+    private static  final   String      RUTH = "RUTH";
+
 	private static String[] users = { "TEST_DBO", "george", "sam", 
 			"monica", "swiper", "sam", "satheesh", "bar",
 			"mamta4", "mamta3", "mamta2", "mamta1", "sammy",
-			"user5", "user4", "user3", "user2", "user1"
+            "user5", "user4", "user3", "user2", "user1", RUTH
 	};
+
+    public static  final   String  NO_GENERIC_PERMISSION = "42504";
+    public static  final   String  NO_SELECT_OR_UPDATE_PERMISSION = "42502";
+
+    public  static  class   Permission
+    {
+        public  final   String  text;
+        public  final   String  sqlStateWhenMissing;
+
+        public  Permission( String text, String sqlStateWhenMissing )
+        {
+            this.text = text;
+            this.sqlStateWhenMissing = sqlStateWhenMissing;
+        }
+    }
 	
     /**
      * Public constructor required for running test as standalone JUnit.
@@ -129,7 +147,7 @@ public final class GrantRevokeDDLTest ex
         
         st_satConnection.executeUpdate(
             "create table satheesh.tsat(i int not null primary "
-            + "key, j int)");
+            + "key, j int, noselect int)");
         
         st_satConnection.executeUpdate(
             " create index tsat_ind on satheesh.tsat(j)");
@@ -481,7 +499,7 @@ public final class GrantRevokeDDLTest ex
             "select * from satheesh.tsat");
         
         assertStatementError("42500", st_swiperConnection,
-            " insert into satheesh.tsat values (1, 2)");
+            " insert into satheesh.tsat(i, j) values (1, 2)");
         
         assertStatementError("42502", st_swiperConnection,
             " update satheesh.tsat set i=j");
@@ -496,7 +514,7 @@ public final class GrantRevokeDDLTest ex
         
         
         st_satConnection.executeUpdate(
-            " grant select(i), update(j) on tsat to swiper");
+            " grant select(i, j), update(j) on tsat to swiper");
         
         st_satConnection.executeUpdate(
             " grant all privileges on table1 to swiper");
@@ -520,7 +538,7 @@ public final class GrantRevokeDDLTest ex
         JDBC.assertEmpty(rs);
         
         assertStatementError("42502", st_swiperConnection,
-            " select i from satheesh.tsat where j=2");
+            " select i from satheesh.tsat where noselect=2");
         
         rs = st_swiperConnection.executeQuery(
             " select i from satheesh.tsat where 2 > (select "
@@ -533,7 +551,7 @@ public final class GrantRevokeDDLTest ex
         
         assertStatementError("42502", st_swiperConnection,
             " select i from satheesh.tsat where 2 > (select "
-            + "count(j) from satheesh.tsat)");
+            + "count(noselect) from satheesh.tsat)");
         
         rs = st_swiperConnection.executeQuery(
             " select i from satheesh.tsat where 2 > (select "
@@ -551,7 +569,7 @@ public final class GrantRevokeDDLTest ex
             " update satheesh.tsat set j=2 where i=2");
         
         assertStatementError("42502", st_swiperConnection,
-            " update satheesh.tsat set j=2 where j=1");
+            " update satheesh.tsat set j=2 where noselect=1");
         
         rs = st_swiperConnection.executeQuery(
             " select * from satheesh.table1");
@@ -572,7 +590,7 @@ public final class GrantRevokeDDLTest ex
         
         assertStatementError("42502", st_swiperConnection,
             " select b from satheesh.table1 t1, satheesh.tsat t2 "
-            + "where t1.a = t2.j");
+            + "where t1.a = t2.noselect");
         
         rs = st_swiperConnection.executeQuery(
             " select * from satheesh.table1, (select i from "
@@ -584,15 +602,12 @@ public final class GrantRevokeDDLTest ex
         JDBC.assertEmpty(rs);
         
         assertStatementError("42502", st_swiperConnection,
-            " select * from satheesh.table1, (select j from "
+            " select * from satheesh.table1, (select noselect from "
             + "satheesh.tsat) table2");
         
-        // GrantRevoke TODO: This one should pass, but currently 
-        // fails. Bind update expression in two steps.
-        
-        assertStatementError("42502", st_swiperConnection,
+        st_swiperConnection.executeUpdate(
             "update satheesh.tsat set j=i");
-        
+                
         st_swiperConnection.executeUpdate(
             " create table my_tsat (i int not null, c char(10), "
             + "constraint fk foreign key(i) references satheesh.tsat)");
@@ -10636,5 +10651,848 @@ public final class GrantRevokeDDLTest ex
         st_user2Connection.executeUpdate("drop schema user2 restrict");
     }
 
+    /**
+     * Test that UPDATE statements require the correct privileges as
+     * described on DERBY-6429. Tables are referenced in SET and WHERE clauses.
+     */
+    public void test_6429_tables()
+        throws Exception
+    {
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  ruthConnection = openUserConnection( RUTH );
+
+        //
+        // Schema
+        //
+        goodStatement
+            (
+             dboConnection,
+             "create table t1_simple_6429(x int, y int, z int)"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create view v1_simple_6429(a, b) as select x, y from t1_simple_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type SelectHashMap_6429 external name 'java.util.HashMap' language java\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type CheckHashMap_6429 external name 'java.util.HashMap' language java\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type WhereHashMap_6429 external name 'java.util.HashMap' language java\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function generationFunction_6429( rawValue int ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'java.lang.Math.abs'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function setFunction_6429( hashMap SelectHashMap_6429, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function checkFunction_6429( hashMap CheckHashMap_6429, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function whereFunction_6429( hashMap WhereHashMap_6429, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create derby aggregate setAggregate_6429 for int\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create derby aggregate whereAggregate_6429 for int\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create procedure addHistoryRow_6429\n" +
+             "(\n" +
+             "    actionString varchar( 20 ),\n" +
+             "    actionValue int\n" +
+             ")\n" +
+             "language java parameter style java reads sql data\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.MergeStatementTest.addHistoryRow'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table primaryTable_6429\n" +
+             "(\n" +
+             "    key1 int,\n" +
+             "    key2 int,\n" +
+             "    primary key( key1, key2 )\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table setTable_6429\n" +
+             "(\n" +
+             "    a int\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table whereTable_6429\n" +
+             "(\n" +
+             "    a int\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table updateTable_6429\n" +
+             "(\n" +
+             "    updateColumn int,\n" +
+             "    selectColumn SelectHashMap_6429,\n" +
+             "    untouchedGenerationSource int,\n" +
+             "    generatedColumn generated always as ( updateColumn + generationFunction_6429( untouchedGenerationSource ) ),\n" +
+             "    untouchedCheckSource CheckHashMap_6429,\n" +
+             "    untouchedForeignSource int,\n" +
+             "    untouchedBeforeTriggerSource int,\n" +
+             "    untouchedAfterTriggerSource int,\n" +
+             "    whereColumn WhereHashMap_6429,\n" +
+             "    check ( updateColumn > checkFunction_6429( untouchedCheckSource, 'foo' ) ),\n" +
+             "    foreign key ( updateColumn, untouchedForeignSource ) references primaryTable_6429( key1, key2 )\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create trigger beforeUpdateTrigger_6429\n" +
+             "no cascade before update of updateColumn on updateTable_6429\n" +
+             "referencing old as old\n" +
+             "for each row\n" +
+             "call addHistoryRow_6429( 'before', old.updateColumn + old.untouchedBeforeTriggerSource )\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create trigger afterUpdateTrigger_6429\n" +
+             "after update of updateColumn on updateTable_6429\n" +
+             "referencing old as old\n" +
+             "for each row\n" +
+             "call addHistoryRow_6429( 'before', old.updateColumn + old.untouchedAfterTriggerSource )\n"
+             );
+
+        //
+        // Permissions
+        //
+        goodStatement
+            (
+             dboConnection,
+             "grant update on t1_simple_6429 to ruth"
+             );
+        Permission[]    permissions = new Permission[]
+        {
+            new Permission( "execute on function setFunction_6429", NO_GENERIC_PERMISSION ),
+            new Permission( "execute on function whereFunction_6429", NO_GENERIC_PERMISSION ),
+            new Permission( "usage on derby aggregate setAggregate_6429", NO_GENERIC_PERMISSION ),
+            new Permission( "usage on derby aggregate whereAggregate_6429", NO_GENERIC_PERMISSION ),
+            new Permission( "update ( updateColumn ) on updateTable_6429", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( selectColumn ) on updateTable_6429", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( whereColumn ) on updateTable_6429", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( a ) on setTable_6429", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select( a ) on whereTable_6429", NO_SELECT_OR_UPDATE_PERMISSION ),
+        };
+        for ( Permission permission : permissions )
+        {
+            grant_6429( dboConnection, permission.text );
+        }
+
+        // Should fail because ruth doesn't have SELECT privilege on column y.
+        expectExecutionError
+            ( ruthConnection, NO_SELECT_OR_UPDATE_PERMISSION,
+              "update test_dbo.t1_simple_6429 set x = y" );
+
+        // Should fail because ruth doesn't have SELECT permission on v1_simple_6429.a
+        String  simpleViewUpdate =
+            "update test_dbo.t1_simple_6429\n" +
+            "  set x =\n" +
+            "  ( select b from test_dbo.v1_simple_6429 where a = 1 )\n";
+        expectExecutionError
+            ( ruthConnection, NO_SELECT_OR_UPDATE_PERMISSION, simpleViewUpdate );
+
+        // Succeeds after we grant ruth that permission.
+        goodStatement
+            (
+             dboConnection,
+             "grant select on v1_simple_6429 to ruth"
+             );
+        goodStatement( ruthConnection, simpleViewUpdate );
+
+        // Should fail because ruth doesn't have SELECT permission on t1_simple_6429.z
+        String  simpleViewUpdate2 =
+            "update test_dbo.t1_simple_6429 g\n" +
+            "  set x =\n" +
+            "  ( select b from test_dbo.v1_simple_6429 where a = g.z )\n";
+        expectExecutionError
+            ( ruthConnection, NO_SELECT_OR_UPDATE_PERMISSION, simpleViewUpdate2 );
+
+        // Succeeds after we grant ruth that permission.
+        goodStatement
+            (
+             dboConnection,
+             "grant select( z ) on t1_simple_6429 to ruth"
+             );
+        goodStatement( ruthConnection, simpleViewUpdate2 );
+
+        //
+        // Try adding and dropping privileges.
+        //
+        String  update =
+            "update test_dbo.updateTable_6429\n" +
+            "    set updateColumn =\n" +
+            "        test_dbo.setFunction_6429( selectColumn, 'foo' ) +\n" +
+            "        ( select test_dbo.setAggregate_6429( a ) from test_dbo.setTable_6429 )\n" +
+            "where\n" +
+            "    test_dbo.whereFunction_6429( whereColumn, 'foo' ) >\n" +
+            "    ( select test_dbo.whereAggregate_6429( a ) from test_dbo.whereTable_6429 )\n";
+
+        // fails because ruth does not have USAGE permission on SelectHashMap_6429 and WhereHashMap_6429
+        expectExecutionError( ruthConnection, NO_GENERIC_PERMISSION, update );
+
+        // armed with those permissions, ruth can execute the update
+        grant_6429( dboConnection, "usage on type SelectHashMap_6429" );
+        grant_6429( dboConnection, "usage on type WhereHashMap_6429" );
+        goodStatement( ruthConnection, update );
+
+        //
+        // Verify that revoking each permission in isolation raises
+        // the correct error.
+        //
+        for ( Permission permission : permissions )
+        {
+            vetPermission_6429( permission, dboConnection, ruthConnection, update );
+        }
+        
+        //
+        // Drop schema.
+        //
+        goodStatement
+            (
+             dboConnection,
+             "drop view v1_simple_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table t1_simple_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table updateTable_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table whereTable_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table setTable_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table primaryTable_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop procedure addHistoryRow_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop derby aggregate whereAggregate_6429 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop derby aggregate setAggregate_6429 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function whereFunction_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function checkFunction_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function setFunction_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function generationFunction_6429"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type WhereHashMap_6429 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type CheckHashMap_6429 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type SelectHashMap_6429 restrict"
+             );
+        
+    }
+    /**
+     * Verify that the update fails with the correct error after you revoke
+     * a permission and that the update succeeds after you add the permission back.
+     */
+    private void    vetPermission_6429
+        (
+         Permission permission,
+         Connection dboConnection,
+         Connection ruthConnection,
+         String update
+         )
+        throws Exception
+    {
+        revoke_6429( dboConnection, permission.text );
+        expectExecutionError( ruthConnection, permission.sqlStateWhenMissing, update );
+        grant_6429( dboConnection, permission.text );
+        goodStatement( ruthConnection, update );
+    }
+    private void    grant_6429( Connection conn, String permission )
+        throws Exception
+    {
+        String  command = "grant " + permission + " to ruth";
+
+        goodStatement( conn, command );
+    }
+    private void    revoke_6429( Connection conn, String permission )
+        throws Exception
+    {
+        String  command = "revoke " + permission + " from ruth";
+        if ( permission.startsWith( "execute" ) || permission.startsWith( "usage" ) )   { command += " restrict"; }
+
+        goodStatement( conn, command );
+    }
+    
+    /**
+     * Test that UPDATE statements require the correct privileges as
+     * described on DERBY-6429. Views are referenced in SET and WHERE clauses.
+     */
+    public void test_6429_views()
+        throws Exception
+    {
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  ruthConnection = openUserConnection( RUTH );
+
+        //
+        // Schema
+        //
+        goodStatement
+            (
+             dboConnection,
+             "create type SelectHashMap_6429_2 external name 'java.util.HashMap' language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type CheckHashMap_6429_2 external name 'java.util.HashMap' language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type WhereHashMap_6429_2 external name 'java.util.HashMap' language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function generationFunction_6429_2( rawValue int ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'java.lang.Math.abs'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function setFunction_6429_2( hashMap SelectHashMap_6429_2, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function checkFunction_6429_2( hashMap CheckHashMap_6429_2, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function whereFunction_6429_2( hashMap WhereHashMap_6429_2, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create derby aggregate setAggregate_6429_2 for int\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create derby aggregate whereAggregate_6429_2 for int\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table primaryTable_6429_2\n" +
+             "(\n" +
+             "    key1 int,\n" +
+             "    key2 int,\n" +
+             "    primary key( key1, key2 )\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table setTable_6429_2\n" +
+             "(\n" +
+             "    a int\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create view setView_6429_2( setViewCol ) as select a from setTable_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table whereTable_6429_2\n" +
+             "(\n" +
+             "    a int\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create view whereView_6429_2( whereViewCol ) as select a from whereTable_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table updateTable_6429_2\n" +
+             "(\n" +
+             "    updateColumn int,\n" +
+             "    selectColumn SelectHashMap_6429_2,\n" +
+             "    untouchedGenerationSource int,\n" +
+             "    generatedColumn generated always as ( updateColumn + generationFunction_6429_2( untouchedGenerationSource ) ),\n" +
+             "    untouchedCheckSource CheckHashMap_6429_2,\n" +
+             "    untouchedForeignSource int,\n" +
+             "    untouchedBeforeTriggerSource int,\n" +
+             "    untouchedAfterTriggerSource int,\n" +
+             "    whereColumn WhereHashMap_6429_2,\n" +
+             "    check ( updateColumn > checkFunction_6429_2( untouchedCheckSource, 'foo' ) ),\n" +
+             "    foreign key ( updateColumn, untouchedForeignSource ) references primaryTable_6429_2( key1, key2 )\n" +
+             ")\n"
+             );
+
+        Permission[]    permissions = new Permission[]
+        {
+            new Permission( "execute on function setFunction_6429_2", NO_GENERIC_PERMISSION ),
+            new Permission( "execute on function whereFunction_6429_2", NO_GENERIC_PERMISSION ),
+            new Permission( "usage on derby aggregate setAggregate_6429_2", NO_GENERIC_PERMISSION ),
+            new Permission( "usage on derby aggregate whereAggregate_6429_2", NO_GENERIC_PERMISSION ),
+            new Permission( "update ( updateColumn ) on updateTable_6429_2", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( selectColumn ) on updateTable_6429_2", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( whereColumn ) on updateTable_6429_2", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( setViewCol ) on setView_6429_2", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select( whereViewCol ) on whereView_6429_2", NO_SELECT_OR_UPDATE_PERMISSION ),
+        };
+        for ( Permission permission : permissions )
+        {
+            grant_6429( dboConnection, permission.text );
+        }
+
+        //
+        // Try adding and dropping privileges.
+        //
+        String  update =
+            "update test_dbo.updateTable_6429_2\n" +
+            "    set updateColumn =\n" +
+            "        test_dbo.setFunction_6429_2( selectColumn, 'foo' ) +\n" +
+            "        ( select test_dbo.setAggregate_6429_2( setViewCol ) from test_dbo.setView_6429_2 )\n" +
+            "where\n" +
+            "    test_dbo.whereFunction_6429_2( whereColumn, 'foo' ) >\n" +
+            "    ( select test_dbo.whereAggregate_6429_2( whereViewCol ) from test_dbo.whereView_6429_2 )\n";
+
+        // fails because ruth does not have USAGE permission on SelectHashMap_6429_2 and WhereHashMap_6429_2
+        expectExecutionError( ruthConnection, NO_GENERIC_PERMISSION, update );
+
+        // armed with those permissions, ruth can execute the update
+        grant_6429( dboConnection, "usage on type SelectHashMap_6429_2" );
+        grant_6429( dboConnection, "usage on type WhereHashMap_6429_2" );
+        goodStatement( ruthConnection, update );
+
+        //
+        // Verify that revoking each permission in isolation raises
+        // the correct error.
+        //
+        for ( Permission permission : permissions )
+        {
+            vetPermission_6429( permission, dboConnection, ruthConnection, update );
+        }
+        
+        //
+        // Drop schema.
+        //
+        goodStatement
+            (
+             dboConnection,
+             "drop table updateTable_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop view whereView_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table whereTable_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop view setView_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table setTable_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table primaryTable_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop derby aggregate whereAggregate_6429_2 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop derby aggregate setAggregate_6429_2 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function whereFunction_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function checkFunction_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function setFunction_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function generationFunction_6429_2"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type WhereHashMap_6429_2 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type CheckHashMap_6429_2 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type SelectHashMap_6429_2 restrict"
+             );
+
+    }
+    
+    /**
+     * Test that UPDATE statements require the correct privileges as
+     * described on DERBY-6429. Table functions are referenced in SET and WHERE clauses.
+     */
+    public void test_6429_tableFunctions()
+        throws Exception
+    {
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  ruthConnection = openUserConnection( RUTH );
+
+        //
+        // Schema
+        //
+        goodStatement
+            (
+             dboConnection,
+             "create type SelectHashMap_6429_3 external name 'java.util.HashMap' language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type CheckHashMap_6429_3 external name 'java.util.HashMap' language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type WhereHashMap_6429_3 external name 'java.util.HashMap' language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function generationFunction_6429_3( rawValue int ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'java.lang.Math.abs'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function setFunction_6429_3( hashMap SelectHashMap_6429_3, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function checkFunction_6429_3( hashMap CheckHashMap_6429_3, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function whereFunction_6429_3( hashMap WhereHashMap_6429_3, hashKey varchar( 32672 ) ) returns int\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.getIntValue'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create derby aggregate setAggregate_6429_3 for int\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create derby aggregate whereAggregate_6429_3 for int\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table primaryTable_6429_3\n" +
+             "(\n" +
+             "    key1 int,\n" +
+             "    key2 int,\n" +
+             "    primary key( key1, key2 )\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function setTableFunction_6429_3()\n" +
+             "returns table( x int, y int, z int, w int )\n" +
+             "language java\n" +
+             "parameter style derby_jdbc_result_set\n" +
+             "no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.RestrictedVTITest.integerList'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function whereTableFunction_6429_3()\n" +
+             "returns table( x int, y int, z int, w int )\n" +
+             "language java\n" +
+             "parameter style derby_jdbc_result_set\n" +
+             "no sql\n" +
+             "external name 'org.apache.derbyTesting.functionTests.tests.lang.RestrictedVTITest.integerList'\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table updateTable_6429_3\n" +
+             "(\n" +
+             "    updateColumn int,\n" +
+             "    selectColumn SelectHashMap_6429_3,\n" +
+             "    untouchedGenerationSource int,\n" +
+             "    generatedColumn generated always as ( updateColumn + generationFunction_6429_3( untouchedGenerationSource ) ),\n" +
+             "    untouchedCheckSource CheckHashMap_6429_3,\n" +
+             "    untouchedForeignSource int,\n" +
+             "    untouchedBeforeTriggerSource int,\n" +
+             "    untouchedAfterTriggerSource int,\n" +
+             "    whereColumn WhereHashMap_6429_3,\n" +
+             "    check ( updateColumn > checkFunction_6429_3( untouchedCheckSource, 'foo' ) ),\n" +
+             "    foreign key ( updateColumn, untouchedForeignSource ) references primaryTable_6429_3( key1, key2 )\n" +
+             ")\n"
+             );
+
+        Permission[]    permissions = new Permission[]
+        {
+            new Permission( "execute on function setFunction_6429_3", NO_GENERIC_PERMISSION ),
+            new Permission( "execute on function whereFunction_6429_3", NO_GENERIC_PERMISSION ),
+            new Permission( "usage on derby aggregate setAggregate_6429_3", NO_GENERIC_PERMISSION ),
+            new Permission( "usage on derby aggregate whereAggregate_6429_3", NO_GENERIC_PERMISSION ),
+            new Permission( "update ( updateColumn ) on updateTable_6429_3", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( selectColumn ) on updateTable_6429_3", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "select ( whereColumn ) on updateTable_6429_3", NO_SELECT_OR_UPDATE_PERMISSION ),
+            new Permission( "execute on function setTableFunction_6429_3", NO_GENERIC_PERMISSION ),
+            new Permission( "execute on function whereTableFunction_6429_3", NO_GENERIC_PERMISSION ),
+        };
+        for ( Permission permission : permissions )
+        {
+            grant_6429( dboConnection, permission.text );
+        }
+
+        //
+        // Try adding and dropping privileges.
+        //
+        String  update =
+            "update test_dbo.updateTable_6429_3\n" +
+            "  set updateColumn =\n" +
+            "    test_dbo.setFunction_6429_3( selectColumn, 'foo' ) + \n" +
+            "    ( select test_dbo.setAggregate_6429_3( x ) from table( test_dbo.setTableFunction_6429_3() ) stf )\n" +
+            "where test_dbo.whereFunction_6429_3( whereColumn, 'foo' ) >\n" +
+            "    ( select test_dbo.whereAggregate_6429_3( x ) from table ( test_dbo.whereTableFunction_6429_3() ) wtf )\n";
+
+        // fails because ruth does not have USAGE permission on SelectHashMap_6429_2 and WhereHashMap_6429_2
+        expectExecutionError( ruthConnection, NO_GENERIC_PERMISSION, update );
+
+        // armed with those permissions, ruth can execute the update
+        grant_6429( dboConnection, "usage on type SelectHashMap_6429_3" );
+        grant_6429( dboConnection, "usage on type WhereHashMap_6429_3" );
+        goodStatement( ruthConnection, update );
+
+        //
+        // Verify that revoking each permission in isolation raises
+        // the correct error.
+        //
+        for ( Permission permission : permissions )
+        {
+            vetPermission_6429( permission, dboConnection, ruthConnection, update );
+        }
+        
+        //
+        // Drop schema.
+        //
+        goodStatement
+            (
+             dboConnection,
+             "drop table updateTable_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function whereTableFunction_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function setTableFunction_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop table primaryTable_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop derby aggregate whereAggregate_6429_3 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop derby aggregate setAggregate_6429_3 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function whereFunction_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function checkFunction_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function setFunction_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop function generationFunction_6429_3"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type WhereHashMap_6429_3 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type CheckHashMap_6429_3 restrict"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "drop type SelectHashMap_6429_3 restrict"
+             );
+    }
     
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java Mon Dec 23 20:07:35 2013
@@ -1276,6 +1276,11 @@ public class UDTTest  extends GeneratedC
 
     public static Number makeNumber( int arg ) { return new Integer( arg ); }
 
+    public  static  Integer getIntValue( HashMap<String,Integer> map, String key )
+    {
+        return map.get( key );
+    }
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // MINIONS

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/Derby5234Test.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/Derby5234Test.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/Derby5234Test.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/Derby5234Test.java Mon Dec 23 20:07:35 2013
@@ -219,27 +219,4 @@ public class Derby5234Test extends BaseJ
     //
     ///////////////////////////////////////////////////////////////////////////////////
 
-    /**
-     * Run a successful statement.
-     * @throws SQLException 
-     */
-    private void    goodStatement( Connection conn, String command ) throws SQLException
-    {
-        PreparedStatement    ps = chattyPrepare( conn, command );
-
-        ps.execute();
-        ps.close();
-    }
-    
-    /**
-     * Prepare a statement and report its sql text.
-     */
-    private PreparedStatement   chattyPrepare( Connection conn, String text )
-        throws SQLException
-    {
-        println( "Preparing statement:\n\t" + text );
-        
-        return conn.prepareStatement( text );
-    }
-
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java?rev=1553197&r1=1553196&r2=1553197&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java Mon Dec 23 20:07:35 2013
@@ -1663,6 +1663,111 @@ public abstract class BaseJDBCTestCase
     protected static void dumpRs(ResultSet s) throws SQLException {
         dumpRs(s, System.out);
     }
+
+    // helper methods moved from GeneratedColumnsHelper
+
+    /**
+     * Run good DDL.
+     * @throws SQLException 
+     */
+    protected void    goodStatement( Connection conn, String command ) throws SQLException
+    {
+        PreparedStatement    ps = chattyPrepare( conn, command );
+
+        ps.execute();
+        ps.close();
+    }
+    
+    /**
+     * Run a good update statement with an expected row count.
+     * @throws SQLException 
+     */
+    protected void    goodUpdate( Connection conn, String update, int expectedRowCount ) throws SQLException
+    {
+        PreparedStatement    ps = chattyPrepare( conn, update );
+
+        int actualRowCount = ps.executeUpdate();
+        ps.close();
+
+        println( "Expecting to touch " + expectedRowCount + " rows." );
+        assertEquals( expectedRowCount, actualRowCount );
+    }
+    
+	protected	static	ResultSet	executeQuery( Statement stmt, String text )
+		throws SQLException
+	{
+		println( "Executing '" + text + "'" );
+
+        return stmt.executeQuery( text );
+	}
+
+    /**
+     * Prepare a statement and report its sql text.
+     */
+    protected PreparedStatement   chattyPrepare( Connection conn, String text )
+        throws SQLException
+    {
+        println( "Preparing statement:\n\t" + text );
+        
+        return conn.prepareStatement( text );
+    }
+
+    /**
+     * Prepare a callable statement and report its sql text.
+     */
+    protected CallableStatement   chattyPrepareCall( Connection conn, String text )
+        throws SQLException
+    {
+        println( "Preparing callable statement:\n\t" + text );
+        
+        return conn.prepareCall( text );
+    }
+
+    /**
+     * Assert that the statement text, when compiled, raises an exception
+     */
+    protected void    expectCompilationError( String sqlState, String query )
+    {
+        println( "\nExpecting " + sqlState + " when preparing:\n\t" + query );
+
+        assertCompileError( sqlState, query );
+    }
+
+    /**
+     * Assert that the statement text, when compiled, raises an exception
+     */
+    protected void    expectCompilationError( Connection conn, String sqlState, String query )
+    {
+        println( "\nExpecting " + sqlState + " when preparing:\n\t" + query );
+
+        PreparedStatement ps = null;
+
+        try {
+            ps = conn.prepareStatement( query );
+        } catch (SQLException se )
+        {
+            assertSQLState( sqlState, se );
+
+            return;
+        }
+
+        fail( "Expected SQL state: " + sqlState );
+    }
+
+    /**
+     * Assert that the statement text, when executed, raises an error.
+     */
+    protected void    expectExecutionError( Connection conn, String sqlState, String query )
+        throws Exception
+    {
+        println( "\nExpecting " + sqlState + " when executing:\n\t"  );
+        PreparedStatement   ps = chattyPrepare( conn, query );
+
+        assertStatementError( sqlState, ps );
+        ps.close();
+    }
+    
+
 } // End class BaseJDBCTestCase