db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1572665 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Thu, 27 Feb 2014 17:50:26 GMT
Author: rhillegas
Date: Thu Feb 27 17:50:25 2014
New Revision: 1572665

URL: http://svn.apache.org/r1572665
Log:
DERBY-3155: Enforce correct privileges for DELETE actions of MERGE statements; tests passed
cleanly on derby-3155-31-aa-deletePrivs.diff.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Permission.java
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.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/MatchingClauseNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MergeNode.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/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/GrantRevokeDDLTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/MergeStatementTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java?rev=1572665&r1=1572664&r2=1572665&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java Thu
Feb 27 17:50:25 2014
@@ -297,11 +297,7 @@ class DeleteNode extends DMLModStatement
             ScopeFilter scopeFilter = new ScopeFilter( getCompilerContext(), CompilerContext.WHERE_SCOPE,
1 );
             getCompilerContext().addPrivilegeFilter( scopeFilter );
 			super.bindExpressions();
-
-            //
-            // Don't remove the WHERE scopeFilter. Pre-processing may try to
-            // add other privileges which we don't need.
-            //
+            getCompilerContext().removePrivilegeFilter( scopeFilter );
 
 			/* Bind untyped nulls directly under the result columns */
 			resultSet.getResultColumns().
@@ -880,6 +876,10 @@ class DeleteNode extends DMLModStatement
     @Override
 	public void optimizeStatement() throws StandardException
 	{
+        // Don't add any more permissions during pre-processing
+        IgnoreFilter    ignorePermissions = new IgnoreFilter();
+        getCompilerContext().addPrivilegeFilter( ignorePermissions );
+        
 		if(cascadeDelete)
 		{
 			for(int index=0 ; index < dependentNodes.length ; index++)
@@ -889,6 +889,10 @@ class DeleteNode extends DMLModStatement
 		}
 
         super.optimizeStatement();
+
+        // allow more permissions to be added in case we're just one action
+        // of a MERGE statement
+        getCompilerContext().removePrivilegeFilter( ignorePermissions );
 	}
 
     /**

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=1572665&r1=1572664&r2=1572665&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 Thu
Feb 27 17:50:25 2014
@@ -2761,7 +2761,9 @@ class FromBaseTable extends FromTable
 
         if(columnsTableName != null) {
             if(columnsTableName.getSchemaName() == null && correlationName == null)
+            {
                 columnsTableName.bind(this.getDataDictionary());
+            }
         }
 		/*
 		** If there is a correlation name, use that instead of the

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MatchingClauseNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MatchingClauseNode.java?rev=1572665&r1=1572664&r2=1572665&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MatchingClauseNode.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MatchingClauseNode.java
Thu Feb 27 17:50:25 2014
@@ -39,6 +39,7 @@ import org.apache.derby.shared.common.sa
 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
 import org.apache.derby.iapi.sql.ResultDescription;
 import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.IgnoreFilter;
 import org.apache.derby.iapi.sql.compile.Visitor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
@@ -431,10 +432,7 @@ public class MatchingClauseNode extends 
         }
 
         // Now associate the columns on the right side of SET operators.
-        CollectNodesVisitor<ColumnReference> getCRs =
-            new CollectNodesVisitor<ColumnReference>(ColumnReference.class);
-        _updateColumns.accept(getCRs);
-        List<ColumnReference> colRefs = getCRs.getList();
+        List<ColumnReference> colRefs = getColumnReferences( _updateColumns );
         for ( ColumnReference cr : colRefs )
         {
             mergeNode.associateColumn( fullFromList, cr, ColumnReference.MERGE_UNKNOWN );
@@ -699,6 +697,12 @@ public class MatchingClauseNode extends 
          )
         throws StandardException
     {
+        //
+        // Don't add any privileges until we bind the DELETE.
+        //
+        IgnoreFilter    ignorePermissions = new IgnoreFilter();
+        getCompilerContext().addPrivilegeFilter( ignorePermissions );
+            
         FromBaseTable   deleteTarget = new FromBaseTable
             ( targetTable.getTableNameField(), null, null, null, getContextManager() );
         FromList    dummyFromList = new FromList( getContextManager() );
@@ -722,6 +726,9 @@ public class MatchingClauseNode extends 
              );
         _dml = new DeleteNode( targetTable.getTableNameField(), selectNode, this, getContextManager()
);
 
+        // ready to add permissions
+        getCompilerContext().removePrivilegeFilter( ignorePermissions );
+
         _dml.bindStatement();
 
         buildThenColumnsForDelete();
@@ -1345,17 +1352,13 @@ public class MatchingClauseNode extends 
         if( isDeleteClause()) { return; }
         else
         {
-            CollectNodesVisitor<ColumnReference> getCRs =
-                new CollectNodesVisitor<ColumnReference>(ColumnReference.class);
-
             ValueNode   checkConstraints = isInsertClause() ?
                 ((InsertNode) _dml).checkConstraints :
                 ((UpdateNode) _dml).checkConstraints;
 
             if ( checkConstraints != null )
             {
-                checkConstraints.accept(getCRs);
-                List<ColumnReference> colRefs = getCRs.getList();
+                List<ColumnReference> colRefs = getColumnReferences( checkConstraints
);
                 for ( ColumnReference cr : colRefs )
                 {
                     cr.getSource().setResultSetNumber( NoPutResultSet.TEMPORARY_RESULT_SET_NUMBER
);
@@ -1498,11 +1501,8 @@ public class MatchingClauseNode extends 
         throws StandardException
     {
         ResultColumnList    leftJoinResult = generatedScan.getResultColumns();
-        CollectNodesVisitor<ColumnReference> getCRs =
-            new CollectNodesVisitor<ColumnReference>( ColumnReference.class );
-        node.accept( getCRs );
 
-        for ( ColumnReference cr : getCRs.getList() )
+        for ( ColumnReference cr : getColumnReferences( node ) )
         {
             ResultColumn    leftJoinRC = leftJoinResult.elementAt( getSelectListOffset( selectList,
cr ) - 1 );
             cr.setSource( leftJoinRC );
@@ -1561,4 +1561,22 @@ public class MatchingClauseNode extends 
         else { return "DELETE"; }
 	}
 
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // MINIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /** Get a list of column references in an expression */
+    private List<ColumnReference>   getColumnReferences( QueryTreeNode expression )
+        throws StandardException
+    {
+        CollectNodesVisitor<ColumnReference> getCRs =
+            new CollectNodesVisitor<ColumnReference>(ColumnReference.class);
+
+        expression.accept(getCRs);
+        
+        return getCRs.getList();
+    }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MergeNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MergeNode.java?rev=1572665&r1=1572664&r2=1572665&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MergeNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MergeNode.java Thu Feb
27 17:50:25 2014
@@ -33,7 +33,9 @@ import org.apache.derby.iapi.services.cl
 import org.apache.derby.iapi.services.compiler.MethodBuilder;
 import org.apache.derby.iapi.services.context.ContextManager;
 import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.IgnoreFilter;
 import org.apache.derby.iapi.sql.compile.Visitor;
+import org.apache.derby.iapi.sql.conn.Authorizer;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
@@ -220,6 +222,12 @@ public final class MergeNode extends DML
         // synonyms not allowed
         forbidSynonyms( dd );
 
+        //
+        // Don't add any privileges until we bind the matching clauses.
+        //
+        IgnoreFilter    ignorePermissions = new IgnoreFilter();
+        getCompilerContext().addPrivilegeFilter( ignorePermissions );
+            
         FromList    dfl = new FromList( getContextManager() );
         FromTable   dflSource = cloneFromTable( _sourceTable );
         FromBaseTable   dflTarget = (FromBaseTable) cloneFromTable( _targetTable );
@@ -230,6 +238,9 @@ public final class MergeNode extends DML
         // target table must be a base table
         if ( !targetIsBaseTable( dflTarget ) ) { notBaseTable(); }
 
+        // ready to add permissions
+        getCompilerContext().removePrivilegeFilter( ignorePermissions );
+
         for ( MatchingClauseNode mcn : _matchingClauses )
         {
             FromList    dummyFromList = cloneFromList( dd, dflTarget );
@@ -261,8 +272,17 @@ public final class MergeNode extends DML
         dummyFromList.addFromTable( dummySourceTable );
         dummyFromList.addFromTable( dummyTargetTable );
         
+        //
+        // Don't add any privileges while binding the tables.
+        //
+        IgnoreFilter    ignorePermissions = new IgnoreFilter();
+        getCompilerContext().addPrivilegeFilter( ignorePermissions );
+             
         dummyFromList.bindTables( dd, new FromList( getOptimizerFactory().doJoinOrderOptimization(),
getContextManager() ) );
 
+        // ready to add permissions
+        getCompilerContext().removePrivilegeFilter( ignorePermissions );
+        
         return dummyFromList;
     }
 
@@ -327,6 +347,12 @@ public final class MergeNode extends DML
         
         try {
             cc.setReliability( previousReliability | CompilerContext.SQL_IN_ROUTINES_ILLEGAL
);
+
+            //
+            // Don't add any privileges until we bind the matching refinement clauses.
+            //
+            IgnoreFilter    ignorePermissions = new IgnoreFilter();
+            getCompilerContext().addPrivilegeFilter( ignorePermissions );
             
             _hojn = new HalfOuterJoinNode
                 (
@@ -350,6 +376,9 @@ public final class MergeNode extends DML
             FromList    topFromList = new FromList( getOptimizerFactory().doJoinOrderOptimization(),
getContextManager() );
             topFromList.addFromTable( _hojn );
 
+            // ready to add permissions
+            getCompilerContext().removePrivilegeFilter( ignorePermissions );
+
             // preliminary binding of the matching clauses to resolve column
             // references. this ensures that we can add all of the columns from
             // the matching refinements to the SELECT list of the left join.
@@ -399,7 +428,21 @@ public final class MergeNode extends DML
                  null,
                  getContextManager()
                  );
+            
+            //
+            // We're only interested in privileges related to the ON clause.
+            // Otherwise, the driving left join should not contribute any
+            // privilege requirements.
+            //
+            getCompilerContext().addPrivilegeFilter( ignorePermissions );
+
             _leftJoinCursor.bindStatement();
+            
+            // ready to add permissions again
+            getCompilerContext().removePrivilegeFilter( ignorePermissions );
+
+            // now figure out what privileges are needed for the ON clause
+            addOnClausePrivileges();
         }
         finally
         {
@@ -550,6 +593,68 @@ public final class MergeNode extends DML
 
     /**
      * <p>
+     * Add the privileges required by the ON clause.
+     * </p>
+     */
+    private void addOnClausePrivileges() throws StandardException
+    {
+        // now add USAGE priv on referenced types
+        addUDTUsagePriv( getValueNodes( _searchCondition ) );
+
+        // add SELECT privilege on columns
+        for ( ColumnReference cr : getColumnReferences( _searchCondition ) )
+        {
+            addColumnPrivilege( cr );
+        }
+        
+        // add EXECUTE privilege on routines
+        for ( StaticMethodCallNode routine : getRoutineReferences( _searchCondition ) )
+        {
+            addRoutinePrivilege( routine );
+        }
+    }
+
+    /**
+     * <p>
+     * Add SELECT privilege on the indicated column.
+     * </p>
+     */
+    private void    addColumnPrivilege( ColumnReference cr )
+        throws StandardException
+    {
+        CompilerContext cc = getCompilerContext();
+        ResultColumn    rc = cr.getSource();
+        
+        if ( rc != null )
+        {
+            ColumnDescriptor    colDesc = rc.getColumnDescriptor();
+            
+            if ( colDesc != null )
+            {
+                cc.pushCurrentPrivType( Authorizer.SELECT_PRIV );
+                cc.addRequiredColumnPriv( colDesc );
+                cc.popCurrentPrivType();
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Add EXECUTE privilege on the indicated routine.
+     * </p>
+     */
+    private void    addRoutinePrivilege( StaticMethodCallNode routine )
+        throws StandardException
+    {
+        CompilerContext cc = getCompilerContext();
+        
+        cc.pushCurrentPrivType( Authorizer.EXECUTE_PRIV );
+        cc.addRequiredRoutinePriv( routine.ad );
+        cc.popCurrentPrivType();
+    }
+
+    /**
+     * <p>
      * Add to an evolving select list the columns from the indicated table.
      * </p>
      */
@@ -599,13 +704,45 @@ public final class MergeNode extends DML
     {
         if ( expression == null ) { return; }
 
+        List<ColumnReference> colRefs = getColumnReferences( expression );
+
+        getColumnsFromList( map, colRefs, mergeTableID );
+    }
+
+    /** Get a list of ValueNodes in an expression */
+    private List<ValueNode>   getValueNodes( QueryTreeNode expression )
+        throws StandardException
+    {
+        CollectNodesVisitor<ValueNode> getVNs =
+            new CollectNodesVisitor<ValueNode>(ValueNode.class);
+
+        expression.accept(getVNs);
+        
+        return getVNs.getList();
+    }
+
+    /** Get a list of routines in an expression */
+    private List<StaticMethodCallNode>   getRoutineReferences( QueryTreeNode expression
)
+        throws StandardException
+    {
+        CollectNodesVisitor<StaticMethodCallNode> getSMCNs =
+            new CollectNodesVisitor<StaticMethodCallNode>(StaticMethodCallNode.class);
+
+        expression.accept(getSMCNs);
+        
+        return getSMCNs.getList();
+    }
+
+    /** Get a list of column references in an expression */
+    private List<ColumnReference>   getColumnReferences( QueryTreeNode expression )
+        throws StandardException
+    {
         CollectNodesVisitor<ColumnReference> getCRs =
             new CollectNodesVisitor<ColumnReference>(ColumnReference.class);
 
         expression.accept(getCRs);
-        List<ColumnReference> colRefs = getCRs.getList();
-
-        getColumnsFromList( map, colRefs, mergeTableID );
+        
+        return getCRs.getList();
     }
 
     /** Add a list of columns to the the evolving map */
@@ -613,11 +750,7 @@ public final class MergeNode extends DML
         ( HashMap<String,ColumnReference> map, ResultColumnList rcl, int mergeTableID
)
         throws StandardException
     {
-        CollectNodesVisitor<ColumnReference> getCRs =
-            new CollectNodesVisitor<ColumnReference>( ColumnReference.class );
-
-        rcl.accept( getCRs );
-        List<ColumnReference> colRefs = getCRs.getList();
+        List<ColumnReference> colRefs = getColumnReferences( rcl );
 
         getColumnsFromList( map, colRefs, mergeTableID );
     }
@@ -645,7 +778,8 @@ public final class MergeNode extends DML
         if ( cr.getTableName() == null )
         {
             ResultColumn    rc = _leftJoinFromList.bindColumnReference( cr );
-            TableName       tableName = new TableName( null, rc.getTableName(), getContextManager()
);
+            TableName       tableName = cr.getQualifiedTableName();
+            if ( tableName == null ) { tableName = new TableName( null, rc.getTableName(),
getContextManager() ); }
             cr = new ColumnReference( cr.getColumnName(), tableName, getContextManager()
);
         }
 
@@ -703,19 +837,25 @@ public final class MergeNode extends DML
         CompilerContext cc = getCompilerContext();
         final int previousReliability = cc.getReliability();
 
-        try {
-            cc.setReliability( previousReliability | CompilerContext.SQL_IN_ROUTINES_ILLEGAL
);
+        cc.setReliability( previousReliability | CompilerContext.SQL_IN_ROUTINES_ILLEGAL
);
+        cc.pushCurrentPrivType( Authorizer.SELECT_PRIV );
             
+        try {
+            // this adds SELECT priv on referenced columns and EXECUTE privs on referenced
routines
             value.bindExpression
                 (
                  fromList,
                  new SubqueryList( getContextManager() ),
                  new ArrayList<AggregateNode>()
                  );
+
+            // now add USAGE priv on referenced types
+            addUDTUsagePriv( getValueNodes( value ) );
         }
         finally
         {
             // Restore previous compiler state
+            cc.popCurrentPrivType();
             cc.setReliability( previousReliability );
         }
     }
@@ -729,6 +869,12 @@ public final class MergeNode extends DML
     @Override
 	public void optimizeStatement() throws StandardException
 	{
+        //
+        // Don't add any privileges during optimization.
+        //
+        IgnoreFilter    ignorePermissions = new IgnoreFilter();
+        getCompilerContext().addPrivilegeFilter( ignorePermissions );
+            
 		/* First optimize the left join */
 		_leftJoinCursor.optimizeStatement();
 
@@ -744,6 +890,9 @@ public final class MergeNode extends DML
         {
             mcn.optimize();
         }
+        
+        // ready to add permissions again
+        getCompilerContext().removePrivilegeFilter( ignorePermissions );
 	}
     ///////////////////////////////////////////////////////////////////////////////////
     //

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=1572665&r1=1572664&r2=1572665&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 Thu
Feb 27 17:50:25 2014
@@ -1356,6 +1356,25 @@ public abstract class QueryTreeNode impl
     }
 
     /**
+     * Add USAGE privilege for all UDTs mentioned in the indicated ValueNodes.
+     */
+    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 );
+            }
+        }
+    }
+
+    /**
      * Bind the UDTs in a table type.
      *
      * @param originalDTD A datatype: might be an unbound UDT and might not be

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=1572665&r1=1572664&r2=1572665&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 Thu
Feb 27 17:50:25 2014
@@ -639,6 +639,10 @@ public final class UpdateNode extends DM
         // don't remove the privilege filter. additional binding may be
         // done during the pre-processing phase
 
+        //
+        // Add USAGE privilege for all UDTs mentioned in the WHERE clause and
+        // on the right side of SET operators.
+        //
         addUDTUsagePriv( allValueNodes );
 
     } // end of bind()
@@ -734,26 +738,6 @@ public final class UpdateNode extends DM
     }
 
     /**
-     * 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.

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=1572665&r1=1572664&r2=1572665&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
Thu Feb 27 17:50:25 2014
@@ -103,6 +103,10 @@ public class GeneratedColumnsHelper exte
     protected static  final   String  TOO_MUCH_CONTENTION = "X0Y84";
     protected static  final   String  STRING_TRUNCATION = "22001";
 
+    protected   static  final   String  NO_GENERIC_PERMISSION = "42504";
+    protected   static  final   String  NO_SELECT_OR_UPDATE_PERMISSION = "42502";
+    protected   static  final   String  NO_TABLE_PERMISSION = "42500";
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // STATE

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=1572665&r1=1572664&r2=1572665&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
Thu Feb 27 17:50:25 2014
@@ -54,18 +54,6 @@ public final class GrantRevokeDDLTest ex
     public static  final   String  NO_GENERIC_PERMISSION = "42504";
     public static  final   String  NO_SELECT_OR_UPDATE_PERMISSION = "42502";
     public static  final   String  NO_TABLE_PERMISSION = "42500";
-
-    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.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/MergeStatementTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/MergeStatementTest.java?rev=1572665&r1=1572664&r2=1572665&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/MergeStatementTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/MergeStatementTest.java
Thu Feb 27 17:50:25 2014
@@ -6002,6 +6002,234 @@ public class MergeStatementTest extends 
         goodStatement( dboConnection, "drop type BeforeTriggerType_043 restrict" );
     }
     
+    /**
+     * <p>
+     * Verify privileges needed for DELETE actions.
+     * </p>
+     */
+    public  void    test_044_deletePrivileges()
+        throws Exception
+    {
+        Connection  dboConnection = openUserConnection( TEST_DBO );
+        Connection  ruthConnection = openUserConnection( RUTH );
+
+        //
+        // create schema
+        //
+        goodStatement
+            (
+             dboConnection,
+             "create type SourceOnClauseType_044 external name 'java.util.HashMap' language
java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type SourceMatchingClauseType_044 external name 'java.util.HashMap'
language java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type BeforeTriggerType_044 external name 'java.util.HashMap' language
java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create type AfterTriggerType_044 external name 'java.util.HashMap' language
java"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create function sourceOnClauseFunction_044( hashMap SourceOnClauseType_044,
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 sourceMatchingClauseFunction_044( hashMap SourceMatchingClauseType_044,
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 beforeTriggerFunction_044( hashMap BeforeTriggerType_044, 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 afterTriggerFunction_044( hashMap AfterTriggerType_044, 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 procedure addHistoryRow_044\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_044\n" +
+             "(\n" +
+             "    key1 int primary key\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table sourceTable_044\n" +
+             "(\n" +
+             "    sourceUnreferencedColumn int,\n" +
+             "    sourceOnClauseColumn SourceOnClauseType_044,\n" +
+             "    sourceMatchingClauseColumn SourceMatchingClauseType_044\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table targetTable_044\n" +
+             "(\n" +
+             "    privateForeignColumn int references primaryTable_044( key1 ),\n" +
+             "    privatePrimaryColumn int primary key,\n" +
+             "    privateBeforeTriggerSource BeforeTriggerType_044,\n" +
+             "    privateAfterTriggerSource AfterTriggerType_044,\n" +
+             "    targetOnClauseColumn int,\n" +
+             "    targetMatchingClauseColumn int\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create table foreignTable_044\n" +
+             "(\n" +
+             "    key1 int references targetTable_044( privatePrimaryColumn )\n" +
+             ")\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create trigger beforeDeleteTrigger_044\n" +
+             "no cascade before delete on targetTable_044\n" +
+             "referencing old as old\n" +
+             "for each row\n" +
+             "call addHistoryRow_044( 'before', beforeTriggerFunction_044( old.privateBeforeTriggerSource,
'foo' ) )\n"
+             );
+        goodStatement
+            (
+             dboConnection,
+             "create trigger afterDeleteTrigger_044\n" +
+             "after delete on targetTable_044\n" +
+             "referencing old as old\n" +
+             "for each row\n" +
+             "call addHistoryRow_044( 'after', afterTriggerFunction_044( old.privateAfterTriggerSource,
'foo' ) )\n"
+             );
+
+        //
+        // Privileges
+        //
+        Permission[]    permissions = new Permission[]
+        {
+            new Permission( "delete on targetTable_044", NO_TABLE_PERMISSION ),
+            new Permission( "execute on function sourceOnClauseFunction_044", NO_GENERIC_PERMISSION
),
+            new Permission( "execute on function sourceMatchingClauseFunction_044", NO_GENERIC_PERMISSION
),
+            new Permission( "select ( sourceOnClauseColumn ) on sourceTable_044", NO_SELECT_OR_UPDATE_PERMISSION
),
+            new Permission( "select ( sourceMatchingClauseColumn ) on sourceTable_044", NO_SELECT_OR_UPDATE_PERMISSION
),
+            new Permission( "select ( targetOnClauseColumn ) on targetTable_044", NO_SELECT_OR_UPDATE_PERMISSION
),
+            new Permission( "select ( targetMatchingClauseColumn ) on targetTable_044", NO_SELECT_OR_UPDATE_PERMISSION
),
+        };
+        for ( Permission permission : permissions )
+        {
+            grantPermission( dboConnection, permission.text );
+        }
+
+        //
+        // Try adding and dropping privileges.
+        //
+        String  mergeStatement =
+            "merge into test_dbo.targetTable_044\n" +
+            "using test_dbo.sourceTable_044\n" +
+            "on targetOnClauseColumn = test_dbo.sourceOnClauseFunction_044( sourceOnClauseColumn,
'foo' )\n" +
+"when matched and targetMatchingClauseColumn = test_dbo.sourceMatchingClauseFunction_044(
sourceMatchingClauseColumn, 'foo' )\n " +
+            "     then delete\n";
+
+        // fails because ruth does not have USAGE permission on SourceOnClauseType_044 and
SourceMatchingClauseType_044
+        expectExecutionError( ruthConnection, NO_GENERIC_PERMISSION, mergeStatement );
+
+        // armed with those permissions, ruth can execute the MERGE statement
+        grantPermission( dboConnection, "usage on type SourceOnClauseType_044" );
+        grantPermission( dboConnection, "usage on type SourceMatchingClauseType_044" );
+        expectExecutionWarning( ruthConnection, NO_ROWS_AFFECTED, mergeStatement );
+        
+        //
+        // Verify that revoking each permission in isolation raises
+        // the correct error.
+        //
+        for ( Permission permission : permissions )
+        {
+            vetPermission( permission, dboConnection, ruthConnection, mergeStatement );
+        }
+        
+        //
+        // drop schema
+        //
+        goodStatement( dboConnection, "drop table foreignTable_044" );
+        goodStatement( dboConnection, "drop table targetTable_044" );
+        goodStatement( dboConnection, "drop table sourceTable_044" );
+        goodStatement( dboConnection, "drop table primaryTable_044" );
+        goodStatement( dboConnection, "drop procedure addHistoryRow_044" );
+        goodStatement( dboConnection, "drop function afterTriggerFunction_044" );
+        goodStatement( dboConnection, "drop function beforeTriggerFunction_044" );
+        goodStatement( dboConnection, "drop function sourceMatchingClauseFunction_044" );
+        goodStatement( dboConnection, "drop function sourceOnClauseFunction_044" );
+        goodStatement( dboConnection, "drop type AfterTriggerType_044 restrict" );
+        goodStatement( dboConnection, "drop type BeforeTriggerType_044 restrict" );
+        goodStatement( dboConnection, "drop type SourceMatchingClauseType_044 restrict" );
+        goodStatement( dboConnection, "drop type SourceOnClauseType_044 restrict" );
+    }
+    
+    /**
+     * Verify that the MERGE statement fails with the correct error after you revoke
+     * a permission and that the MERGE statement succeeds after you add the permission back.
+     */
+    private void    vetPermission
+        (
+         Permission permission,
+         Connection dboConnection,
+         Connection ruthConnection,
+         String mergeStatement
+         )
+        throws Exception
+    {
+        revokePermission( dboConnection, permission.text );
+        expectExecutionError( ruthConnection, permission.sqlStateWhenMissing, mergeStatement
);
+        grantPermission( dboConnection, permission.text );
+        expectExecutionWarning( ruthConnection, NO_ROWS_AFFECTED, mergeStatement );
+    }
+    private void    grantPermission( Connection conn, String permission )
+        throws Exception
+    {
+        String  command = "grant " + permission + " to ruth";
+
+        goodStatement( conn, command );
+    }
+    private void    revokePermission( Connection conn, String permission )
+        throws Exception
+    {
+        String  command = "revoke " + permission + " from ruth";
+        if ( permission.startsWith( "execute" ) || permission.startsWith( "usage" ) )   {
command += " restrict"; }
+
+        goodStatement( conn, command );
+    }
+    
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // ROUTINES

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Permission.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Permission.java?rev=1572665&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Permission.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Permission.java
Thu Feb 27 17:50:25 2014
@@ -0,0 +1,39 @@
+/*
+
+Derby - Class org.apache.derbyTesting.functionTests.tests.lang.GrantRevokeDDLTest
+
+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.derbyTesting.functionTests.tests.lang;
+
+/**
+ * <p>
+ * Helper class for testing sql authorization.
+ * </p>
+ */
+public  class   Permission
+{
+    public  final   String  text;
+    public  final   String  sqlStateWhenMissing;
+
+    public  Permission( String text, String sqlStateWhenMissing )
+    {
+        this.text = text;
+        this.sqlStateWhenMissing = sqlStateWhenMissing;
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Permission.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message