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/04 19:13:50 UTC

svn commit: r644779 - in /db/derby/code/branches/10.4/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: Fri Apr  4 10:13:32 2008
New Revision: 644779

URL: http://svn.apache.org/viewvc?rev=644779&view=rev
Log:
Migrating revision 643292 for DERBY-3320 from trunk into 10.4 codeline. Following is a brief
description of changes. More can be found by checking the commit comments for 643292.

DERBY-3320 This commit will ensure that if the Collator support does not exist during
a territory based database creation, then we will throw an exception saying Collator
support does not exist. In case of subsequent boot of a successfully created territory
based database, we will check for the Collator support from JVM at the time first collation
related operation is run on the database. This can happen if the database recovery needs
to be done at the boot time or it can happen after the database has booted and user has
issued a SQL which requires Collator support.


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

Modified: db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/DataValueFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/DataValueFactory.java?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/DataValueFactory.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/DataValueFactory.java Fri Apr  4 10:13:32 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.4/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/iapi/types/DataValueFactoryImpl.java Fri Apr  4 10:13:32 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.4/java/engine/org/apache/derby/impl/db/BasicDatabase.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/db/BasicDatabase.java?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/db/BasicDatabase.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/db/BasicDatabase.java Fri Apr  4 10:13:32 2008
@@ -193,15 +193,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.4/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Fri Apr  4 10:13:32 2008
@@ -667,22 +667,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.4/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/engine/org/apache/derby/loc/messages.xml?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/branches/10.4/java/engine/org/apache/derby/loc/messages.xml Fri Apr  4 10:13:32 2008
@@ -3525,6 +3525,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.4/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/branches/10.4/java/shared/org/apache/derby/shared/common/reference/SQLState.java Fri Apr  4 10:13:32 2008
@@ -184,6 +184,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.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java (original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CollationTest.java Fri Apr  4 10:13:32 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;
@@ -33,6 +34,7 @@
 import javax.sql.DataSource;
 
 import junit.framework.Test;
+import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
 import org.apache.derbyTesting.functionTests.tests.jdbcapi.BatchUpdateTest;
@@ -1237,6 +1239,26 @@
     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 url = TestConfiguration.getCurrent().getJDBCUrl("localeXXdb");
+
+      loadDriver();
+      String defaultdburl = url + ";create=true;territory=xx;collation=TERRITORY_BASED";
+	  try {
+	      DriverManager.getConnection(defaultdburl);
+	  } 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
@@ -1245,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")));
@@ -1278,7 +1306,21 @@
         }
         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.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java?rev=644779&r1=644778&r2=644779&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java (original)
+++ db/derby/code/branches/10.4/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java Fri Apr  4 10:13:32 2008
@@ -160,6 +160,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"},