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 2009/12/13 21:30:50 UTC
svn commit: r890115 - in /db/derby/code/trunk/java:
engine/org/apache/derby/iapi/sql/dictionary/
engine/org/apache/derby/impl/sql/execute/ engine/org/apache/derby/loc/
shared/org/apache/derby/shared/common/reference/
testing/org/apache/derbyTesting/fun...
Author: rhillegas
Date: Sun Dec 13 20:30:49 2009
New Revision: 890115
URL: http://svn.apache.org/viewvc?rev=890115&view=rev
Log:
DERBY-651: Add dependencies of routines on UDTs.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TupleDescriptor.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DDLConstantAction.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java
db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/AliasDescriptor.java Sun Dec 13 20:30:49 2009
@@ -23,9 +23,11 @@
import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
import org.apache.derby.iapi.sql.depend.DependencyManager;
+import org.apache.derby.iapi.sql.depend.Dependent;
import org.apache.derby.iapi.sql.depend.Provider;
import org.apache.derby.iapi.store.access.TransactionController;
import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.iapi.services.sanity.SanityManager;
import org.apache.derby.catalog.AliasInfo;
@@ -56,7 +58,7 @@
public final class AliasDescriptor
extends TupleDescriptor
- implements UniqueTupleDescriptor, Provider
+ implements UniqueTupleDescriptor, Provider, Dependent
{
private final UUID aliasID;
private final String aliasName;
@@ -125,6 +127,28 @@
}
/**
+ * Gets the name of the schema that the alias lives in.
+ *
+ * @return A String containing the name of the schema that the alias
+ * lives in.
+ */
+ public String getSchemaName() throws StandardException
+ {
+ return getDataDictionary().getSchemaDescriptor( schemaID, null ).getSchemaName();
+ }
+
+ /**
+ * Gets the full, qualified name of the alias.
+ *
+ * @return A String containing the name of the table.
+ */
+ public String getQualifiedName() throws StandardException
+ {
+ return quoteProtectName(getSchemaName()) + "." +
+ quoteProtectName( aliasName );
+ }
+
+ /**
* Gets the java class name of the alias.
*
* @return The java class name of the alias.
@@ -404,4 +428,78 @@
/* Drop the alias */
dd.dropAliasDescriptor(this, tc);
}
+
+ //////////////////////////////////////////////////////
+ //
+ // DEPENDENT INTERFACE
+ //
+ //////////////////////////////////////////////////////
+ /**
+ * Check that all of the dependent's dependencies are valid.
+ *
+ * @return true if the dependent is currently valid
+ */
+ public synchronized boolean isValid()
+ {
+ return true;
+ }
+
+ /**
+ * Prepare to mark the dependent as invalid (due to at least one of
+ * its dependencies being invalid).
+ *
+ * @param action The action causing the invalidation
+ * @param p the provider
+ *
+ * @exception StandardException thrown if unable to make it invalid
+ */
+ public void prepareToInvalidate(Provider p, int action,
+ LanguageConnectionContext lcc)
+ throws StandardException
+ {
+ DependencyManager dm = getDataDictionary().getDependencyManager();
+
+ switch (action)
+ {
+ /*
+ ** Currently, the only thing we are dependent
+ ** on is an alias descriptor for an ANSI UDT.
+ */
+ default:
+
+ throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_ALIAS,
+ dm.getActionString(action),
+ p.getObjectName(),
+ getQualifiedName());
+ }
+ }
+
+ /**
+ * Mark the dependent as invalid (due to at least one of
+ * its dependencies being invalid). Always an error
+ * for an alias -- should never have gotten here.
+ *
+ * @param action The action causing the invalidation
+ *
+ * @exception StandardException thrown if called in sanity mode
+ */
+ public void makeInvalid(int action, LanguageConnectionContext lcc)
+ throws StandardException
+ {
+ /*
+ ** We should never get here, we should have barfed on
+ ** prepareToInvalidate().
+ */
+ if (SanityManager.DEBUG)
+ {
+ DependencyManager dm;
+
+ dm = getDataDictionary().getDependencyManager();
+
+ SanityManager.THROWASSERT("makeInvalid("+
+ dm.getActionString(action)+
+ ") not expected to get called");
+ }
+ }
+
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java Sun Dec 13 20:30:49 2009
@@ -274,40 +274,6 @@
}
/**
- * If the name has double quotes in it, put two double quotes for every single
- * double quote.
- * Finally put double quotes around string to protect against
- * names with blanks, reserved words being used as identifiers etc.
- * For eg, if table name is m"n, return it as "m""n". For now, this is used
- * by DMLModStatementNode.parseCheckConstraint().
- *
- * Possible improvement: We could possibly analyze string to
- * avoid double quotes in normal cases.
- *
- * @param name The String with or without double quotes
- *
- * @return The quoted String
- */
-
- private String quoteProtectName(String name)
- {
- String quotedString = name;
- int quotePos = name.indexOf("\"");
-
- if (quotePos == -1)
- return "\"" + name + "\"";
-
- //string does have quotes in it.
- while(quotePos != -1) {
- quotedString = quotedString.substring(0,quotePos) + "\"" +
- quotedString.substring(quotePos);
- quotePos = quotedString.indexOf("\"",quotePos+2);
- }
- return "\"" + quotedString + "\"";
-
- }
-
- /**
* Gets the UUID of the table.
*
* @return The UUID of the table.
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TupleDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TupleDescriptor.java?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TupleDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TupleDescriptor.java Sun Dec 13 20:30:49 2009
@@ -91,6 +91,40 @@
}
+ /**
+ * If the name has double quotes in it, put two double quotes for every single
+ * double quote.
+ * Finally put double quotes around string to protect against
+ * names with blanks, reserved words being used as identifiers etc.
+ * For eg, if table name is m"n, return it as "m""n". For now, this is used
+ * by DMLModStatementNode.parseCheckConstraint().
+ *
+ * Possible improvement: We could possibly analyze string to
+ * avoid double quotes in normal cases.
+ *
+ * @param name The String with or without double quotes
+ *
+ * @return The quoted String
+ */
+
+ public String quoteProtectName(String name)
+ {
+ String quotedString = name;
+ int quotePos = name.indexOf("\"");
+
+ if (quotePos == -1)
+ return "\"" + name + "\"";
+
+ //string does have quotes in it.
+ while(quotePos != -1) {
+ quotedString = quotedString.substring(0,quotePos) + "\"" +
+ quotedString.substring(quotePos);
+ quotePos = quotedString.indexOf("\"",quotePos+2);
+ }
+ return "\"" + quotedString + "\"";
+
+ }
+
//////////////////////////////////////////////////////////////////
//
// BEHAVIOR. These are only used by Replication!!
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateAliasConstantAction.java Sun Dec 13 20:30:49 2009
@@ -313,5 +313,7 @@
dd.addDescriptor(ads, null, DataDictionary.SYSALIASES_CATALOG_NUM,
false, tc);
+
+ adjustUDTDependencies( lcc, dd, ads, true );
}
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DDLConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DDLConstantAction.java?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DDLConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DDLConstantAction.java Sun Dec 13 20:30:49 2009
@@ -29,6 +29,8 @@
import org.apache.derby.catalog.AliasInfo;
import org.apache.derby.catalog.DependableFinder;
import org.apache.derby.catalog.UUID;
+import org.apache.derby.catalog.TypeDescriptor;
+import org.apache.derby.catalog.types.RoutineAliasInfo;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.iapi.services.sanity.SanityManager;
@@ -905,11 +907,33 @@
}
}
+ adjustUDTDependencies( lcc, dd, td, addUdtMap, dropUdtMap );
+ }
+ /**
+ * Add and drop dependencies of an object on UDTs.
+ *
+ * @param lcc Interpreter's state variable for this session.
+ * @param dd Metadata
+ * @param dependent Object which depends on UDT
+ * @param addUdtMap Map of UDTs for which dependencies should be added
+ * @param dropUdtMap Map of UDT for which dependencies should be dropped
+ */
+ private void adjustUDTDependencies
+ (
+ LanguageConnectionContext lcc,
+ DataDictionary dd,
+ Dependent dependent,
+ HashMap addUdtMap,
+ HashMap dropUdtMap
+ )
+ throws StandardException
+ {
// again, nothing to do if there are no columns of udt type
if ( (addUdtMap.size() == 0) && (dropUdtMap.size() == 0) ) { return; }
- DependencyManager dm = dd.getDependencyManager();
- ContextManager cm = lcc.getContextManager();
+ TransactionController tc = lcc.getTransactionExecute();
+ DependencyManager dm = dd.getDependencyManager();
+ ContextManager cm = lcc.getContextManager();
// add new dependencies
Iterator addIterator = addUdtMap.values().iterator();
@@ -917,7 +941,7 @@
{
AliasDescriptor ad = (AliasDescriptor) addIterator.next();
- dm.addDependency( td, ad, cm );
+ dm.addDependency( dependent, ad, cm );
}
// drop dependencies that are orphaned
@@ -926,12 +950,69 @@
{
AliasDescriptor ad = (AliasDescriptor) dropIterator.next();
- DependencyDescriptor dependency = new DependencyDescriptor( td, ad );
+ DependencyDescriptor dependency = new DependencyDescriptor( dependent, ad );
dd.dropStoredDependency( dependency, tc );
}
}
+ /**
+ * Add and drop dependencies of a routine on UDTs.
+ *
+ * @param lcc Interpreter's state variable for this session.
+ * @param dd Metadata
+ * @param ad Alias descriptor for the routine
+ * @param adding True if we are adding dependencies, false if we're dropping them
+ */
+ protected void adjustUDTDependencies
+ (
+ LanguageConnectionContext lcc,
+ DataDictionary dd,
+ AliasDescriptor ad,
+ boolean adding
+ )
+ throws StandardException
+ {
+ // nothing to do if this is not a routine
+ switch ( ad.getAliasType() )
+ {
+ case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
+ case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
+ break;
+
+ default: return;
+ }
+
+ TransactionController tc = lcc.getTransactionExecute();
+ RoutineAliasInfo aliasInfo = (RoutineAliasInfo) ad.getAliasInfo();
+ HashMap addUdtMap = new HashMap();
+ HashMap dropUdtMap = new HashMap();
+ HashMap udtMap = adding ? addUdtMap : dropUdtMap;
+ TypeDescriptor rawReturnType = aliasInfo.getReturnType();
+
+ if ( rawReturnType != null )
+ {
+ AliasDescriptor returnTypeAD = dd.getAliasDescriptorForUDT
+ ( tc, DataTypeDescriptor.getType( rawReturnType ) );
+
+ if ( returnTypeAD != null ) { udtMap.put( returnTypeAD.getObjectID().toString(), returnTypeAD ); }
+ }
+
+ TypeDescriptor[] paramTypes = aliasInfo.getParameterTypes();
+ if ( paramTypes != null )
+ {
+ int paramCount = paramTypes.length;
+ for ( int i = 0; i < paramCount; i++ )
+ {
+ AliasDescriptor paramType = dd.getAliasDescriptorForUDT
+ ( tc, DataTypeDescriptor.getType( paramTypes[ i ] ) );
+
+ if ( paramType != null ) { udtMap.put( paramType.getObjectID().toString(), paramType ); }
+ }
+ }
+
+ adjustUDTDependencies( lcc, dd, ad, addUdtMap, dropUdtMap );
+ }
/**
* Mutable Boolean wrapper, initially false
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DropAliasConstantAction.java Sun Dec 13 20:30:49 2009
@@ -108,6 +108,8 @@
{
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, ad.getAliasType(nameSpace), aliasName);
}
+
+ adjustUDTDependencies( lcc, dd, ad, false );
ad.drop(lcc);
Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Sun Dec 13 20:30:49 2009
@@ -3140,7 +3140,15 @@
<text>Operation '{0}' cannot be performed on object '{1}' because TABLE '{2}' is dependent on that object.</text>
<arg>operationName</arg>
<arg>objectName</arg>
- <arg>viewName</arg>
+ <arg>tableName</arg>
+ </msg>
+
+ <msg>
+ <name>X0Y30.S</name>
+ <text>Operation '{0}' cannot be performed on object '{1}' because ROUTINE '{2}' is dependent on that object.</text>
+ <arg>operationName</arg>
+ <arg>objectName</arg>
+ <arg>routineName</arg>
</msg>
<msg>
Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=890115&r1=890114&r2=890115&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Sun Dec 13 20:30:49 2009
@@ -1322,6 +1322,7 @@
String LANG_INDEX_AND_TABLE_IN_DIFFERENT_SCHEMAS = "X0Y26.S";
String LANG_CREATE_SYSTEM_INDEX_ATTEMPTED = "X0Y28.S";
String LANG_PROVIDER_HAS_DEPENDENT_TABLE = "X0Y29.S";
+ String LANG_PROVIDER_HAS_DEPENDENT_ALIAS = "X0Y30.S";
String LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT = "X0Y32.S";
String LANG_CREATE_INDEX_NO_TABLE = "X0Y38.S";
String LANG_INVALID_FK_NO_PK = "X0Y41.S";
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=890115&r1=890114&r2=890115&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 Sun Dec 13 20:30:49 2009
@@ -53,6 +53,7 @@
public static final String SYNTAX_ERROR = "42X01";
public static final String TABLE_DEPENDS_ON_TYPE = "X0Y29";
public static final String VIEW_DEPENDS_ON_TYPE = "X0Y23";
+ public static final String ROUTINE_DEPENDS_ON_TYPE = "X0Y30";
///////////////////////////////////////////////////////////////////////////////////
//
@@ -497,6 +498,108 @@
assertTrue( Price.makePrice().equals( result ) );
}
+ /**
+ * <p>
+ * Dependencies of routines on UDTs.
+ * </p>
+ */
+ public void test_07_routineDependencies() throws Exception
+ {
+ Connection conn = getConnection();
+
+ // function that returns a udt
+ goodStatement
+ ( conn,
+ "create type price_07_a external name 'org.apache.derbyTesting.functionTests.tests.lang.Price' language java\n" );
+ goodStatement
+ ( conn,
+ "create function makePrice_07_a( )\n" +
+ "returns price_07_a\n" +
+ "language java\n" +
+ "parameter style java\n" +
+ "no sql\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.Price.makePrice'\n"
+ );
+ expectExecutionError( conn, ROUTINE_DEPENDS_ON_TYPE, "drop type price_07_a restrict\n" );
+ goodStatement
+ ( conn,
+ "drop function makePrice_07_a\n" );
+ goodStatement
+ ( conn,
+ "drop type price_07_a restrict\n" );
+
+ // function with a udt arg
+ goodStatement
+ ( conn,
+ "create type price_07_b external name 'org.apache.derbyTesting.functionTests.tests.lang.Price' language java\n" );
+ goodStatement
+ ( conn,
+ "create function getCurrencyCode_07_b( priceArg1 price_07_b )\n" +
+ "returns char( 3 )\n" +
+ "language java\n" +
+ "parameter style java\n" +
+ "no sql\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.Price.getCurrencyCode'\n"
+ );
+ expectExecutionError( conn, ROUTINE_DEPENDS_ON_TYPE, "drop type price_07_b restrict\n" );
+ goodStatement
+ ( conn,
+ "drop function getCurrencyCode_07_b\n" );
+ goodStatement
+ ( conn,
+ "drop type price_07_b restrict\n" );
+
+ // procedure with a udt arg
+ goodStatement
+ ( conn,
+ "create type price_07_c external name 'org.apache.derbyTesting.functionTests.tests.lang.Price' language java\n" );
+ goodStatement
+ ( conn,
+ "create procedure oneArgPriceProc_07( price1 price_07_c )\n" +
+ "language java\n" +
+ "parameter style java\n" +
+ "no sql\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.oneArgPriceProc_07'\n"
+ );
+ expectExecutionError( conn, ROUTINE_DEPENDS_ON_TYPE, "drop type price_07_c restrict\n" );
+ goodStatement
+ ( conn,
+ "drop procedure oneArgPriceProc_07\n" );
+ goodStatement
+ ( conn,
+ "drop type price_07_c restrict\n" );
+
+ // procedure with two udt args
+ goodStatement
+ ( conn,
+ "create type price_07_d external name 'org.apache.derbyTesting.functionTests.tests.lang.Price' language java\n" );
+ goodStatement
+ ( conn,
+ "create procedure twoArgPriceProc_07( price1 price_07_d, price2 price_07_d )\n" +
+ "language java\n" +
+ "parameter style java\n" +
+ "no sql\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.UDTTest.twoArgPriceProc_07'\n"
+ );
+ expectExecutionError( conn, ROUTINE_DEPENDS_ON_TYPE, "drop type price_07_d restrict\n" );
+ goodStatement
+ ( conn,
+ "drop procedure twoArgPriceProc_07\n" );
+ goodStatement
+ ( conn,
+ "drop type price_07_d restrict\n" );
+
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // PROCEDURES
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ public static void oneArgPriceProc( Price price1 ) {}
+ public static void twoArgPriceProc( Price price1, Price price2 ) {}
+
///////////////////////////////////////////////////////////////////////////////////
//
// MINIONS