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