Return-Path: X-Original-To: apmail-db-derby-commits-archive@www.apache.org Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 105F2DFE5 for ; Mon, 23 Jul 2012 15:55:46 +0000 (UTC) Received: (qmail 20793 invoked by uid 500); 23 Jul 2012 15:55:46 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 20727 invoked by uid 500); 23 Jul 2012 15:55:45 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 20711 invoked by uid 99); 23 Jul 2012 15:55:44 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Jul 2012 15:55:44 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Jul 2012 15:55:42 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id BAB8223888D2; Mon, 23 Jul 2012 15:55:23 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1364690 - in /db/derby/code/trunk/java: engine/org/apache/derby/catalog/types/BaseTypeIdImpl.java testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java Date: Mon, 23 Jul 2012 15:55:23 -0000 To: derby-commits@db.apache.org From: mamta@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120723155523.BAB8223888D2@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mamta Date: Mon Jul 23 15:55:23 2012 New Revision: 1364690 URL: http://svn.apache.org/viewvc?rev=1364690&view=rev Log: DERBY-5407 When run across the network, dblook produces unusable DDL for VARCHAR FOR BIT DATA columns. The serialization of UDT associated with SYSCOLUMNS.COLUMNBDATATYPE on the wire from the network server end happens correctly. The same serialized data is received by the client but when we try to instantiate the UDT's TypeDescriptor based on this serialized data, we get confused between "VARCHAR () FOR BIT DATA" and "VARCHAR FOR BIT DATA". The deserialization on the client side happens through BaseTypeIdImpl.getTypeFormatId(). Here, we look at the string representation of the type descriptor that we received on the wire and choose the appropriate format id based on that string. The problem is in this BaseTypeIdImpl.getTypeFormatId() code, where the code looks for "VARCHAR FOR BIT DATA" rather than "VARCHAR () FOR BIT DATA" (notice the missing parentheses) else if ( "VARCHAR FOR BIT DATA".equals( unqualifiedName ) ) { return StoredFormatIds.VARBIT_TYPE_ID_IMPL; } Since "VARCHAR FOR BIT DATA" and "VARCHAR () FOR BIT DATA" do not match, we do not use format id VARBIT_TYPE_ID_IMPL. Later, we go through a switch statement based on the format id in BaseTypeIdlImpl.toParsableString(TypeDescriptor). In the switch statement, we are supposed to stuff in the width of the varchar for bit data into the parentheses ie string "VARCHAR () FOR BIT DATA" should get converted into "VARCHAR (NUMBER) FOR BIT DATA" but we don't do it because of getTypeFormatd() code problem explained earlier. To fix this, the patch has added check for If there might be dependencies on the original "VARCHAR FOR BIT DATA" check, then we can add additional check for "VARCHAR () FOR BIT DATA" in addition to the existing check for "VARCHAR FOR BIT DATA" as shown below and that fixes the problem else if ( "VARCHAR FOR BIT DATA".equals( unqualifiedName ) ) { return StoredFormatIds.VARBIT_TYPE_ID_IMPL; } else if ( "VARCHAR () FOR BIT DATA".equals( unqualifiedName ) ) { return StoredFormatIds.VARBIT_TYPE_ID_IMPL; } This commit does similar thing for "CHAR FOR BIT DATA", ie in addition to the existing test for "CHAR FOR BIT DATA", it adds a check for "CHAR () FOR BIT DATA". Keeping the existing checks will not break any dependencies that might exist on "VARCHAR FOR BIT DATA" check and "CHAR FOR BIT DATA" check. Have added a test for SYSCOLUMNS.COLUMNBDATATYPE for all the supported data types. This test will be run in both embedded and network server mode. Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/BaseTypeIdImpl.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/BaseTypeIdImpl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/BaseTypeIdImpl.java?rev=1364690&r1=1364689&r2=1364690&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/BaseTypeIdImpl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/BaseTypeIdImpl.java Mon Jul 23 15:55:23 2012 @@ -255,29 +255,37 @@ public class BaseTypeIdImpl implements F // will lose the format id. This can happen if you pass one of these // objects across the network. Here we recover the format id. // - if ( "BOOLEAN".equals( unqualifiedName ) ) { return StoredFormatIds.BOOLEAN_TYPE_ID_IMPL; } - else if ( "BIGINT".equals( unqualifiedName ) ) { return StoredFormatIds.LONGINT_TYPE_ID_IMPL; } - else if ( "INTEGER".equals( unqualifiedName ) ) { return StoredFormatIds.INT_TYPE_ID_IMPL; } - else if ( "SMALLINT".equals( unqualifiedName ) ) { return StoredFormatIds.SMALLINT_TYPE_ID_IMPL; } - else if ( "TINYINT".equals( unqualifiedName ) ) { return StoredFormatIds.TINYINT_TYPE_ID_IMPL; } - else if ( "LONGINT".equals( unqualifiedName ) ) { return StoredFormatIds.LONGINT_TYPE_ID_IMPL; } - else if ( "DECIMAL".equals( unqualifiedName ) ) { return StoredFormatIds.DECIMAL_TYPE_ID_IMPL; } - else if ( "NUMERIC".equals( unqualifiedName ) ) { return StoredFormatIds.DECIMAL_TYPE_ID_IMPL; } - else if ( "DOUBLE".equals( unqualifiedName ) ) { return StoredFormatIds.DOUBLE_TYPE_ID_IMPL; } - else if ( "REAL".equals( unqualifiedName ) ) { return StoredFormatIds.REAL_TYPE_ID_IMPL; } - else if ( "REF".equals( unqualifiedName ) ) { return StoredFormatIds.REF_TYPE_ID_IMPL; } - else if ( "CHAR".equals( unqualifiedName ) ) { return StoredFormatIds.CHAR_TYPE_ID_IMPL; } - else if ( "VARCHAR".equals( unqualifiedName ) ) { return StoredFormatIds.VARCHAR_TYPE_ID_IMPL; } - else if ( "LONG VARCHAR".equals( unqualifiedName ) ) { return StoredFormatIds.LONGVARCHAR_TYPE_ID_IMPL; } - else if ( "CLOB".equals( unqualifiedName ) ) { return StoredFormatIds.CLOB_TYPE_ID_IMPL; } + if ( TypeId.BOOLEAN_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.BOOLEAN_TYPE_ID_IMPL; } + else if ( TypeId.LONGINT_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.LONGINT_TYPE_ID_IMPL; } + else if ( TypeId.INTEGER_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.INT_TYPE_ID_IMPL; } + else if ( TypeId.SMALLINT_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.SMALLINT_TYPE_ID_IMPL; } + else if ( TypeId.TINYINT_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.TINYINT_TYPE_ID_IMPL; } + else if ( TypeId.LONGINT_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.LONGINT_TYPE_ID_IMPL; } + else if ( TypeId.DECIMAL_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.DECIMAL_TYPE_ID_IMPL; } + else if ( TypeId.NUMERIC_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.DECIMAL_TYPE_ID_IMPL; } + else if ( TypeId.DOUBLE_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.DOUBLE_TYPE_ID_IMPL; } + else if ( TypeId.REAL_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.REAL_TYPE_ID_IMPL; } + else if ( TypeId.REF_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.REF_TYPE_ID_IMPL; } + else if ( TypeId.CHAR_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.CHAR_TYPE_ID_IMPL; } + else if ( TypeId.VARCHAR_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.VARCHAR_TYPE_ID_IMPL; } + else if ( TypeId.LONGVARCHAR_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.LONGVARCHAR_TYPE_ID_IMPL; } + else if ( TypeId.CLOB_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.CLOB_TYPE_ID_IMPL; } + //DERBY-5407 Network Server on wire sends CHAR () FOR BIT DATA + // not CHAR FOR BIT DATA. Keeping the check for CHAR FOR BIT + // DATA just in case if there is any dependency on that check + else if ( TypeId.BIT_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.BIT_TYPE_ID_IMPL; } else if ( "CHAR FOR BIT DATA".equals( unqualifiedName ) ) { return StoredFormatIds.BIT_TYPE_ID_IMPL; } + //DERBY-5407 Network Server on wire sends VARCHAR () FOR BIT DATA + // not VARCHAR FOR BIT DATA. Keeping the check for VARCHAR FOR BIT + // DATA just in case if there is any dependency on that check + else if ( TypeId.VARBIT_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.VARBIT_TYPE_ID_IMPL; } else if ( "VARCHAR FOR BIT DATA".equals( unqualifiedName ) ) { return StoredFormatIds.VARBIT_TYPE_ID_IMPL; } - else if ( "LONG VARCHAR FOR BIT DATA".equals( unqualifiedName ) ) { return StoredFormatIds.LONGVARBIT_TYPE_ID_IMPL; } - else if ( "BLOB".equals( unqualifiedName ) ) { return StoredFormatIds.BLOB_TYPE_ID_IMPL; } - else if ( "DATE".equals( unqualifiedName ) ) { return StoredFormatIds.DATE_TYPE_ID_IMPL; } - else if ( "TIME".equals( unqualifiedName ) ) { return StoredFormatIds.TIME_TYPE_ID_IMPL; } - else if ( "TIMESTAMP".equals( unqualifiedName ) ) { return StoredFormatIds.TIMESTAMP_TYPE_ID_IMPL; } - else if ( "XML".equals( unqualifiedName ) ) { return StoredFormatIds.XML_TYPE_ID_IMPL; } + else if ( TypeId.LONGVARBIT_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.LONGVARBIT_TYPE_ID_IMPL; } + else if ( TypeId.BLOB_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.BLOB_TYPE_ID_IMPL; } + else if ( TypeId.DATE_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.DATE_TYPE_ID_IMPL; } + else if ( TypeId.TIME_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.TIME_TYPE_ID_IMPL; } + else if ( TypeId.TIMESTAMP_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.TIMESTAMP_TYPE_ID_IMPL; } + else if ( TypeId.XML_NAME.equals( unqualifiedName ) ) { return StoredFormatIds.XML_TYPE_ID_IMPL; } else { return 0; } } } Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java?rev=1364690&r1=1364689&r2=1364690&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java Mon Jul 23 15:55:23 2012 @@ -25,7 +25,12 @@ import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.sql.ResultSet; +import java.sql.Types; + +import org.apache.derby.iapi.services.io.StoredFormatIds; +import org.apache.derbyTesting.functionTests.tests.compatibility.JDBCDriverTest.TypeDescriptor; import org.apache.derbyTesting.junit.BaseJDBCTestCase; +import org.apache.derbyTesting.junit.DerbyVersion; import org.apache.derbyTesting.junit.JDBC; import org.apache.derbyTesting.junit.TestConfiguration; import junit.framework.Test; @@ -40,7 +45,7 @@ import junit.framework.TestSuite; */ public class SystemCatalogTest extends BaseJDBCTestCase { - public SystemCatalogTest(String name) { + public SystemCatalogTest(String name) { super(name); } @@ -561,6 +566,117 @@ public class SystemCatalogTest extends B s.execute("drop table uniquekey3"); s.close(); } + + /** + * This test creates a table with all supported datatypes aqnd ensures + * that bound embedded and network server return the identical datatypes + * for those datatypes. DERBY-5407 + * @throws SQLException + */ + public void testColumnDatatypesOfAllDataTypesInSystemCatalogs() throws SQLException { + int totalNumOfColumnDatatypes = 21; + Statement s = createStatement(); + s.execute("create table allTypesTable (" + + " a01 bigint," + + " a02 blob,\n" + + " a03 char( 1 ),\n" + + " a04 char( 1 ) for bit data ,\n" + + " a05 clob,\n" + + " a06 date,\n" + + " a07 decimal,\n" + + " a08 double,\n" + + " a09 float,\n" + + " a10 int,\n" + + " a11 long varchar,\n" + + " a12 long varchar for bit data,\n" + + " a13 numeric,\n" + + " a14 real,\n" + + " a15 smallint,\n" + + " a16 time,\n" + + " a17 timestamp,\n" + + " a18 varchar(10),\n" + + " a19 varchar(10) for bit data,\n" + + " a20 xml,\n" + + " a21 boolean\n" + + ")"); + ResultSet rs = s.executeQuery("select columndatatype "+ + "from sys.systables, sys.syscolumns "+ + "where tablename='ALLTYPESTABLE' "+ + "and tableid=referenceid "+ + "order by columnname"); + for (int i=1; i<=totalNumOfColumnDatatypes; i++) + { + rs.next(); + switch(i) + { + case 1 : + assertTrue(rs.getString(1).startsWith("BIGINT")); + break; + case 2 : + assertTrue(rs.getString(1).startsWith("BLOB(2147483647)")); + break; + case 3 : + assertTrue(rs.getString(1).startsWith("CHAR(1)")); + break; + case 4 : + assertTrue(rs.getString(1).startsWith("CHAR (1) FOR BIT DATA")); + break; + case 5 : + assertTrue(rs.getString(1).startsWith("CLOB(2147483647)")); + break; + case 6 : + assertTrue(rs.getString(1).startsWith("DATE")); + break; + case 7 : + assertTrue(rs.getString(1).startsWith("DECIMAL(5,0)")); + break; + case 8 : + assertTrue(rs.getString(1).startsWith("DOUBLE")); + break; + case 9 : + assertTrue(rs.getString(1).startsWith("DOUBLE")); + break; + case 10 : + assertTrue(rs.getString(1).startsWith("INTEGER")); + break; + case 11 : + assertTrue(rs.getString(1).startsWith("LONG VARCHAR")); + break; + case 12 : + assertTrue(rs.getString(1).startsWith("LONG VARCHAR FOR BIT DATA")); + break; + case 13 : + assertTrue(rs.getString(1).startsWith("NUMERIC(5,0)")); + break; + case 14 : + assertTrue(rs.getString(1).startsWith("REAL")); + break; + case 15 : + assertTrue(rs.getString(1).startsWith("SMALLINT")); + break; + case 16 : + assertTrue(rs.getString(1).startsWith("TIME")); + break; + case 17 : + assertTrue(rs.getString(1).startsWith("TIMESTAMP")); + break; + case 18 : + assertTrue(rs.getString(1).startsWith("VARCHAR(10)")); + break; + case 19 : + assertTrue(rs.getString(1).startsWith("VARCHAR (10) FOR BIT DATA")); + break; + case 20 : + assertTrue(rs.getString(1).startsWith("XML")); + break; + case 21 : + assertTrue(rs.getString(1).startsWith("BOOLEAN")); + break; + } + } + rs.close(); + s.execute("drop table ALLTYPESTABLE"); + } /** * Check that column datatypes are reported correctly, both in