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"},