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 ma...@apache.org on 2008/04/08 08:39:52 UTC

svn commit: r645775 - in /db/derby/code/branches/10.3/java: engine/org/apache/derby/iapi/types/ engine/org/apache/derby/impl/db/ engine/org/apache/derby/impl/sql/catalog/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ tes...

Author: mamta
Date: Mon Apr  7 23:39:46 2008
New Revision: 645775

URL: http://svn.apache.org/viewvc?rev=645775&view=rev
Log:
Merging revisions 643292 and 645665 from trunk into 10.3 codeline for DERBY-3320. These
changes are to catch missing Collator support when a user has requested territory based
database. More info can be found in commit comments of 643292 and 645665.


Modified:
    db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactory.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/db/BasicDatabase.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/branches/10.3/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactory.java?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactory.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactory.java Mon Apr  7 23:39:46 2008
@@ -31,8 +31,6 @@
 
 import java.text.RuleBasedCollator;
 
-import java.util.Locale;
-
 /**
  * This interface is how we get data values of different types.
  * 
@@ -607,7 +605,8 @@
          * otherwise set it to null and return that value.
          */
         StringDataValue         getNullChar(StringDataValue dataValue,
-                int collationType);
+                int collationType)
+        throws StandardException;
 
         /**
          * Get a SQL VARCHAR (UCS_BASIC) with a SQL null value. If the supplied value
@@ -623,7 +622,8 @@
          * otherwise set it to null and return that value.
          */
         StringDataValue         getNullVarchar(StringDataValue dataValue,
-                int collationType);
+                int collationType)
+        throws StandardException;
 
         /**
          * Get a SQL LONG VARCHAR (UCS_BASIC) with a SQL null value. If the supplied value
@@ -639,7 +639,8 @@
          * otherwise set it to null and return that value.
          */
         StringDataValue         getNullLongvarchar(StringDataValue dataValue,
-                int collationType);
+                int collationType)
+        throws StandardException;
 
         /**
          * Get a SQL CLOB (UCS_BASIC) with a SQL null value. If the supplied value
@@ -655,7 +656,8 @@
          * otherwise set it to null and return that value.
          */
         StringDataValue         getNullClob(StringDataValue dataValue,
-                int collationType);
+                int collationType)
+        throws StandardException;
 
         /**
          * Get a User-defined data value with a SQL null value. If the supplied value
@@ -702,27 +704,16 @@
          * that value.
          */
         XMLDataValue            getNullXML(XMLDataValue dataValue);
-
-        /**
-         * Set the locale on DVF. This method gets called by the boot method of
-         * BasicDatabase after BasicDatabase has finished booting DVF. This 
-         * Locale will be either the Locale obtained from the territory 
-         * attribute supplied by the user on the JDBC url at database create 
-         * time or if user didn't provide the territory attribute at database
-         * create time, then it will be set to the default JVM locale. The 
-         * Locale object will be used to construct the Collator object if user 
-         * has requested territory based collation.
-         *
-         * @param localeOfTheDatabase Use this object to construct the 
-         *   Collator object
-         */
-        void setLocale(Locale localeOfTheDatabase);
         
         /**
          * Return the RuleBasedCollator depending on the collation type. 
          * If the collation type is UCS_BASIC, then this method will return 
          * null. If the collation type is TERRITORY_BASED then the return
          * value will be the Collator derived from the database's locale.
+         * If this is the first time Collator is being requested for a
+         * database with collation type of TERRITORY_BASED, then we will check 
+         * to make sure that JVM supports the Collator for the database's 
+         * locale. If not, we will throw an exception 
          * 
          * This method will be used when Store code is trying to create a DVD
          * template row using the format ids and the collation types. First a
@@ -742,7 +733,8 @@
          * @return Collator null if the collation type is UCS_BASIC.
          *  Collator based on territory if the collation type is TERRITORY_BASED
          */
-        RuleBasedCollator getCharacterCollator(int collationType);
+        RuleBasedCollator getCharacterCollator(int collationType) 
+        throws StandardException;
         
         /**
          * Return an object based on the format id and collation type. For

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java Mon Apr  7 23:39:46 2008
@@ -44,11 +44,14 @@
 import org.apache.derby.iapi.services.io.RegisteredFormatIds;
 import org.apache.derby.iapi.services.io.StoredFormatIds;
 import org.apache.derby.iapi.services.monitor.ModuleControl;
+import org.apache.derby.iapi.services.monitor.ModuleFactory;
 import org.apache.derby.iapi.services.monitor.Monitor;
 
 import org.apache.derby.iapi.services.loader.ClassInfo;
 import org.apache.derby.iapi.services.loader.InstanceGetter;
 
+import org.apache.derby.iapi.reference.Attribute;
+import org.apache.derby.iapi.reference.Property;
 import org.apache.derby.iapi.reference.SQLState;
 
 import java.sql.Date;
@@ -98,15 +101,61 @@
     		TypeId.decimalImplementation = decimalImplementation;
     		RegisteredFormatIds.TwoByte[StoredFormatIds.SQL_DECIMAL_ID]
     									= decimalImplementation.getClass().getName();
-    		
-    		
+    		    		
     		// Generate a DECIMAL value represetentation of 0
     		decimalImplementation = decimalImplementation.getNewNull();
     		decimalImplementation.setValue(0L);
-    		NumberDataType.ZERO_DECIMAL = decimalImplementation;
-    		
-    		
-    		
+    		NumberDataType.ZERO_DECIMAL = decimalImplementation;    		
+
+    		ModuleFactory monitor = Monitor.getMonitor();
+    		//The Locale on monitor has already been set by the boot code in
+    		//BasicDatabase so we can simply do a get here.
+    		//This Locale will be either the Locale obtained from the territory
+    		//attribute supplied by the user on the JDBC url at database create
+    		//time or if user didn't provide the territory attribute at database
+    		//create time, then it will be set to the default JVM locale. The
+    		//Locale object will be used to construct the Collator object which
+    		//will be used if user has requested territory based collation.
+    		databaseLocale = monitor.getLocale(this);
+
+    		//If we are here for database create time, verify that there is 
+    		//Collator support for the database's locale. If not, then we 
+    		//will throw an exception. 
+    		//Notice that this Collator support check is happening only during 
+    		//database creation time. This is because, during database create
+    		//time, DVF has access to collation property of the database and
+    		//hence it can do the Collator support check
+    		//(collation property is available through JDBC url at the database
+    		//create time, if user has asked for a particular collation) eg
+    		//connect 'jdbc:derby:db;create=true;territory=no;collation=TERRITORY_BASED';
+    		//Once the database is created, the collation property gets
+    		//saved in the database and during susbsequent boots of the
+    		//database, collation attribute of the database is only available
+    		//once store has finished reading it. So, during subsequent 
+    		//database boot up time, the collation attribute of the database 
+    		//will be checked the first time a collation operation is done.
+    		//And if the Collator support is not found at that point, user will 
+    		//get an exception for Collator unavailability. This first 
+    		//collation operation can happen if the database needs to be 
+    		//recovered during boot time or otherwise it will happen when the
+    		//user has executed a SQL which requires collation operation.
+	    	if (create) {
+	    		//Get the collation property from the JDBC url(this will be 
+	    		//available only during database create time). It can only have 
+	    		//one of the 2 possible values - UCS_BASIC or TERRITORY_BASED.
+	    		//This property can only be specified at database create time.
+	    		//If the user has requested for territory based database, then 
+	    		//verify that JVM has Collator support for the database locale.
+	    		String userDefinedCollation = 
+	    			properties.getProperty(Attribute.COLLATION);		
+	    		if (userDefinedCollation != null) {//Invalid value handling
+	    			if (!userDefinedCollation.equalsIgnoreCase(Property.UCS_BASIC_COLLATION)
+	    					&& !userDefinedCollation.equalsIgnoreCase(Property.TERRITORY_BASED_COLLATION))
+	    				throw StandardException.newException(SQLState.INVALID_COLLATION, userDefinedCollation);
+	    			if (userDefinedCollation.equalsIgnoreCase(Property.TERRITORY_BASED_COLLATION))
+	    				collatorForCharacterTypes = verifyCollatorSupport();
+	    		}    		
+	    	}
     	}
 
     	/* (non-Javadoc)
@@ -813,6 +862,7 @@
          */
         public StringDataValue         getNullChar(StringDataValue previous,
                 int collationType)
+        throws StandardException
         {
             if (collationType == StringDataValue.COLLATION_TYPE_UCS_BASIC)
                 return getNullChar(previous);
@@ -844,6 +894,7 @@
          */
         public StringDataValue         getNullVarchar(StringDataValue previous,
                 int collationType)
+        throws StandardException
         {
             if (collationType == StringDataValue.COLLATION_TYPE_UCS_BASIC)
                 return getNullChar(previous);
@@ -875,6 +926,7 @@
          */
         public StringDataValue         getNullLongvarchar(StringDataValue previous,
                 int collationType)
+        throws StandardException
         {
             if (collationType == StringDataValue.COLLATION_TYPE_UCS_BASIC)
                 return getNullChar(previous);
@@ -906,6 +958,7 @@
          */
         public StringDataValue         getNullClob(StringDataValue previous,
                 int collationType)
+        throws StandardException
         {
             if (collationType == StringDataValue.COLLATION_TYPE_UCS_BASIC)
                 return getNullChar(previous);
@@ -1070,21 +1123,46 @@
         }
     }
 
-    /** @see DataValueFactory#setLocale(Locale) */
-    public void setLocale(Locale localeOfTheDatabase){
-    	databaseLocale = localeOfTheDatabase;
-    	collatorForCharacterTypes = 
-    		(RuleBasedCollator) Collator.getInstance(databaseLocale);
-    }
-
     /** @see DataValueFactory#getCharacterCollator(int) */
-    public RuleBasedCollator getCharacterCollator(int collationType){
+    public RuleBasedCollator getCharacterCollator(int collationType) 
+    throws StandardException {
     	if (collationType == StringDataValue.COLLATION_TYPE_UCS_BASIC)
     		return (RuleBasedCollator)null;
-    	else
+    	else if (collatorForCharacterTypes == null) {
+    		//This is the first access to Collator because otherwise
+    		//it will not be null. Verify that JVM has support for
+    		//the Collator for the database locale.
+    		collatorForCharacterTypes = verifyCollatorSupport();
+    		return collatorForCharacterTypes;    	    		
+    	} else
     		return collatorForCharacterTypes;    	
     }
-
+    
+    /**
+     * Verify that JVM has support for the Collator for the datbase's locale.
+     * 
+     * @return Collator for database's locale
+     * @throws StandardException if JVM does not have support for Collator
+     */
+    private RuleBasedCollator verifyCollatorSupport() 
+    throws StandardException {
+    	Locale[] availLocales =  Collator.getAvailableLocales();
+    	//Verify that Collator can be instantiated for the given locale.
+    	boolean localeFound = false;
+    	for (int i=0; i<availLocales.length;i++)
+    	{
+    		if (availLocales[i].equals(databaseLocale)) {
+    			localeFound = true;
+    			break;
+    		}
+    	}
+    	if (!localeFound)
+			throw StandardException.newException(
+					SQLState.COLLATOR_NOT_FOUND_FOR_LOCALE, 
+					databaseLocale.toString());
+    	
+    	return (RuleBasedCollator) Collator.getInstance(databaseLocale);
+    }
     /** 
      * @see DataValueFactory#getNull(int, int)
      */

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/db/BasicDatabase.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/db/BasicDatabase.java?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/db/BasicDatabase.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/db/BasicDatabase.java Mon Apr  7 23:39:46 2008
@@ -178,15 +178,6 @@
 				org.apache.derby.iapi.reference.ClassName.DataValueFactory, 
                 startParams);
 
-		//After booting the DVF, set the Locale information into it. This 
-		//Locale will be either the Locale obtained from the territory 
-		//attribute supplied by the user on the JDBC url at database create 
-		//time or if user didn't provide the territory attribute at database
-		//create time, then it will be set to the default JVM locale. If user 
-		//has requested territory based collation then a Collator object will
-		//be constructed from this Locale object. 
-		dvf.setLocale(databaseLocale);
-
 		bootStore(create, startParams);
 
 		// create a database ID if one doesn't already exist

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Mon Apr  7 23:39:46 2008
@@ -665,22 +665,19 @@
 			//method.
 			String userDefinedCollation;		
 			if (create) {
-				// Get the collation attribute from the JDBC url. It can only have one of
-				// 2 possible values - UCS_BASIC or TERRITORY_BASED
-				// This attribute can only be specified at database create time.
-				userDefinedCollation = startParams.getProperty(Attribute.COLLATION);		
-				if (userDefinedCollation == null)
-					userDefinedCollation = Property.UCS_BASIC_COLLATION;
-				else {//Invalid value handling
-					if (!userDefinedCollation.equalsIgnoreCase(Property.UCS_BASIC_COLLATION)
-							&& !userDefinedCollation.equalsIgnoreCase(Property.TERRITORY_BASED_COLLATION))
-						throw StandardException.newException(SQLState.INVALID_COLLATION, userDefinedCollation);
-					}
+				//Get the collation attribute from the JDBC url. It can only 
+				//have one of 2 possible values - UCS_BASIC or TERRITORY_BASED
+				//This attribute can only be specified at database create time. 
+				//The attribute value has already been verified in DVF.boot and
+				//hence we can be assured that the attribute value if provided
+				//is either UCS_BASIC or TERRITORY_BASED. If none provided, 
+				//then we will take it to be the default which is UCS_BASIC.
+				userDefinedCollation = startParams.getProperty(
+						Attribute.COLLATION, Property.UCS_BASIC_COLLATION);		
 				bootingTC.setProperty(Property.COLLATION,userDefinedCollation,true);
 			} else {
-				userDefinedCollation = startParams.getProperty(Property.COLLATION);
-				if (userDefinedCollation == null)
-					userDefinedCollation = Property.UCS_BASIC_COLLATION;
+				userDefinedCollation = startParams.getProperty(
+						Property.COLLATION, Property.UCS_BASIC_COLLATION);
 			}
 
 			//Initialize the collation type of user schemas after looking at 

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/loc/messages.xml?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/loc/messages.xml Mon Apr  7 23:39:46 2008
@@ -3423,6 +3423,12 @@
             </msg>
 
             <msg>
+                <name>XBM04.D</name>
+                <text>Collator support not available from the JVM for the database's locale '{0}'.</text>
+                <arg>value</arg>
+            </msg>
+
+            <msg>
                 <name>XBM0Y.D</name>
                 <text>Backup database directory {0} not found. Please make sure that the specified backup path is right.</text>
                 <arg>directoryName</arg>

Modified: db/derby/code/branches/10.3/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/branches/10.3/java/shared/org/apache/derby/shared/common/reference/SQLState.java Mon Apr  7 23:39:46 2008
@@ -179,6 +179,7 @@
 	String REGISTERED_CLASS_INSTANCE_ERROR		= "XBM0W.S";
 	String INVALID_LOCALE_DESCRIPTION			= "XBM0X.D";
 	String INVALID_COLLATION			        = "XBM03.D";
+	String COLLATOR_NOT_FOUND_FOR_LOCALE        = "XBM04.D";
 	String SERVICE_DIRECTORY_NOT_IN_BACKUP      = "XBM0Y.D";
 	String UNABLE_TO_COPY_FILE_FROM_BACKUP      = "XBM0Z.D";
 	String PROPERTY_FILE_NOT_FOUND_IN_BACKUP    = "XBM0Q.D";

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java (original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java Mon Apr  7 23:39:46 2008
@@ -22,6 +22,7 @@
 package org.apache.derbyTesting.functionTests.tests.lang;
 
 import java.sql.Connection;
+import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -31,6 +32,7 @@
 import javax.sql.DataSource;
 
 import junit.framework.Test;
+import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
 import org.apache.derbyTesting.functionTests.tests.jdbcapi.DatabaseMetaDataTest;
@@ -42,6 +44,7 @@
 import org.apache.derbyTesting.junit.JDBC;
 import org.apache.derbyTesting.junit.JDBCDataSource;
 import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.functionTests.util.TestUtil;
 
 public class CollationTest extends BaseJDBCTestCase {
 
@@ -1234,6 +1237,28 @@
     else
     	JDBC.assertFullResultSet(rs,expectedResult);
 }
+
+/**
+ * We should get a locale unavailable message because there is no support for 
+ * locale xx.
+ */
+public void testMissingCollatorSupport() throws SQLException {
+      String createDBurl = ";create=true;territory=xx;collation=TERRITORY_BASED";
+	  try {
+		  //Use following utility method rather than 
+		  //DriverManager.getConnection because the following utility method 
+		  //will use DataSource or DriverManager depending on the VM that is 
+		  //being used. Use of DriverManager to get a Connection will faile
+		  //on JSR169 VMs. DERBY-3052
+		  TestUtil.getConnection("missingCollatorDB", createDBurl);
+	  } catch (SQLException sqle) {
+          //Database can't be created because Collator support does not exist
+		  //for the requested locale
+		  BaseJDBCTestCase.assertSQLState("Unexpected error when connecting to database ",
+                  "XBM04",
+                  sqle);
+      }
+}
     
   /**
    * Tests only need to run in embedded since collation
@@ -1242,6 +1267,12 @@
   public static Test suite() {
       
       TestSuite suite = new TestSuite("CollationTest");
+      //Add the test case for a locale which does not exist. We have asked for
+      //locale as 'xx' and since there is not support Collator support for such
+      //a locale, we will get an exception during database create time.
+      TestCase missingCollatorDbTest = new CollationTest(
+    		  "testMissingCollatorSupport");
+      suite.addTest(missingCollatorDbTest);
 
         suite.addTest(new CleanDatabaseTestSetup(
                 new CollationTest("testDefaultCollation")));
@@ -1250,7 +1281,21 @@
         suite.addTest(collatedSuite("pl", "testPolishCollation"));
         return suite;
     }
-  
+
+  /**
+     Load the appropriate driver for the current framework
+   */
+  private static void loadDriver()
+  {
+      String driverClass =
+          TestConfiguration.getCurrent().getJDBCClient().getJDBCDriverName();
+      try {
+          Class.forName(driverClass).newInstance();
+      } catch (Exception e) {
+          fail ("could not instantiate driver");
+      }
+  }
+ 
   /**
    * Return a suite that uses a single use database with
    * a primary fixture from this test plus potentially other

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java?rev=645775&r1=645774&r2=645775&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java (original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java Mon Apr  7 23:39:46 2008
@@ -156,6 +156,7 @@
                 {"XBM01","Startup failed due to an exception. See next exception for details. ","45000"},
                 {"XBM02","Startup failed due to missing functionality for {0}. Please ensure your classpath includes the correct Derby software.","45000"},
                 {"XBM03","Supplied value '{0}' for collation attribute is invalid, expecting UCS_BASIC or TERRITORY_BASED.","45000"},
+                {"XBM04","Collator support not available from the JVM for the database's locale '{0}'.","45000"},
                 {"XBM05","Startup failed due to missing product version information for {0}.","45000"},
                 {"XBM06","Startup failed. An encrypted database cannot be accessed without the correct boot password.  ","45000"},
                 {"XBM07","Startup failed. Boot password must be at least 8 bytes long.","45000"},