db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r899733 [1/2] - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ client/org/apache/derby/client/net/ drda/org/apache/derby/impl/drda/ engine/org/apache/derby/catalog/types/ engine/org/apache/derby/iapi/reference/ engine/org/...
Date Fri, 15 Jan 2010 17:54:22 GMT
Author: rhillegas
Date: Fri Jan 15 17:54:20 2010
New Revision: 899733

URL: http://svn.apache.org/viewvc?rev=899733&view=rev
Log:
DERBY-4491: Correct the network metadata for UDTs and make it possible to pass UDT values across the network.

Added:
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/DynamicByteArrayOutputStream.java   (with props)
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/InputStreamUtil.java   (with props)
Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Types.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/DssConstants.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/Typdef.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/FdocaConstants.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/SQLTypes.java
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/BaseTypeIdImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/DecimalTypeIdImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/TypeDescriptorImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/DRDAConstants.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/DataTypeUtilities.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/JDBC30Translation.java
    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/jdbcapi/DatabaseMetaDataTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/junitTests/compatibility/CompatibilityCombinations.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/junitTests/compatibility/CompatibilitySuite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/junitTests/compatibility/JDBCDriverTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UDTTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/DerbyJUnitTest.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java Fri Jan 15 17:54:20 2010
@@ -67,6 +67,8 @@
     public String[] sqlLabel_;  // column label
     public short[] sqlUnnamed_;
     public String[] sqlComment_;
+    public String[] sqlUDTname_;
+    public String[] sqlUDTclassName_;
 
     //Data from SQLDXGRP
     public short[] sqlxKeymem_;
@@ -148,6 +150,9 @@
 
         sqlName_ = new String[upperBound];
         sqlxParmmode_ = new short[upperBound];
+
+        sqlUDTname_ = new String[upperBound];
+        sqlUDTclassName_ = new String[upperBound];
     }
 
     protected void finalize() throws java.lang.Throwable {
@@ -312,6 +317,8 @@
                 return 8;
             case Types.TIMESTAMP:
                 return 26;
+            case Types.JAVA_OBJECT:
+                return JDBC30Translation.DEFAULT_COLUMN_DISPLAY_SIZE;
             case Types.BINARY:
             case Types.VARBINARY:
             case Types.LONGVARBINARY:
@@ -442,6 +449,8 @@
                 return 8;
             case Types.TIMESTAMP:
                 return 26;
+            case Types.JAVA_OBJECT:
+                return JDBC30Translation.UNKNOWN_PRECISION;
             default:
                 throw new SqlException(logWriter_, 
                 		new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
@@ -603,6 +612,9 @@
             case DRDAConstants.DB2_SQLTYPE_NUMERIC:
             case DRDAConstants.DB2_SQLTYPE_NNUMERIC:
                 return "NUMERIC";
+            case DRDAConstants.DB2_SQLTYPE_FAKE_UDT:
+            case DRDAConstants.DB2_SQLTYPE_FAKE_NUDT:
+                return sqlUDTname_[ column - 1 ];
             default:
                 throw new SqlException(logWriter_, 
                 		new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
@@ -715,6 +727,8 @@
                 return "java.sql.Clob";
             case java.sql.Types.REF:
                 return "java.sql.Ref";
+            case java.sql.Types.JAVA_OBJECT:
+                return sqlUDTclassName_[ column - 1 ];
             default:
                 throw new SqlException(logWriter_, 
                 		new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
@@ -833,6 +847,8 @@
             return Types.BLOB;
         case java.sql.Types.CLOB:
             return Types.CLOB;
+        case java.sql.Types.JAVA_OBJECT:
+            return Types.JAVA_OBJECT;
         case java.sql.Types.NULL:
         case java.sql.Types.OTHER:
             throw new SqlException(logWriter_, 
@@ -863,6 +879,8 @@
         sqlLabel_ = null;
         sqlUnnamed_ = null;
         sqlComment_ = null;
+        sqlUDTname_ = null;
+        sqlUDTclassName_ = null;
         sqlxKeymem_ = null;
         sqlxGenerated_ = null;
         sqlxParmmode_ = null;

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java Fri Jan 15 17:54:20 2010
@@ -25,6 +25,8 @@
 import java.sql.SQLException;
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
 import java.io.UnsupportedEncodingException;
 
 // When we calculate column offsets make sure we calculate the correct offsets for double byte charactr5er data
@@ -649,6 +651,34 @@
         return bytes;
     }
 
+    // Deserialize a UDT from a database java.sql.Types.JAVA_OBJECT field.
+    // This is used for user defined types.
+    private final Object get_UDT(int column) throws SqlException {
+        byte[] bytes;
+        int columnLength = 0;
+        columnLength = (maxFieldSize_ == 0) ? columnDataComputedLength_[column - 1] - 2 :
+                java.lang.Math.min(maxFieldSize_, columnDataComputedLength_[column - 1] - 2);
+        bytes = new byte[columnLength];
+        System.arraycopy(dataBuffer_, columnDataPosition_[column - 1] + 2, bytes, 0, bytes.length);
+
+        try {
+            ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
+            ObjectInputStream ois = new ObjectInputStream( bais );
+
+            return ois.readObject();
+        }
+        catch (Exception e)
+        {
+            throw new SqlException
+                (
+                 agent_.logWriter_, 
+                 new ClientMessageId (SQLState.NET_MARSHALLING_UDT_ERROR),
+                 e.getMessage(),
+                 e
+                 );
+        }
+    }
+
     /**
      * Instantiate an instance of Calendar that can be re-used for getting
      * Time, Timestamp, and Date values from this cursor.  Assumption is
@@ -1030,6 +1060,10 @@
                         agent_.crossConverters_.getStringFromBytes(get_VARCHAR_FOR_BIT_DATA(column));
                 return (maxFieldSize_ == 0) ? tempString :
                         tempString.substring(0, java.lang.Math.min(maxFieldSize_, tempString.length()));
+            case java.sql.Types.JAVA_OBJECT:
+                Object obj = get_UDT( column );
+                if ( obj == null ) { return null; }
+                else { return obj.toString(); }
             case java.sql.Types.BLOB:
                 Blob b = getBlobColumn_(column, agent_, false);
                 tempString = agent_.crossConverters_.
@@ -1297,6 +1331,8 @@
         case java.sql.Types.VARBINARY:
         case java.sql.Types.LONGVARBINARY:
             return get_VARCHAR_FOR_BIT_DATA(column);
+        case java.sql.Types.JAVA_OBJECT:
+            return get_UDT( column );
         case java.sql.Types.BLOB:
             return getBlobColumn_(column, agent_, true);
         case java.sql.Types.CLOB:

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java Fri Jan 15 17:54:20 2010
@@ -1000,7 +1000,7 @@
         setInput(parameterIndex, x);
 
     }
-
+    
     /**
      * sets the parameter to the  Binary Stream object
      *
@@ -1420,7 +1420,14 @@
                 if (agent_.loggingEnabled()) {
                     agent_.logWriter_.traceEntry(this, "setObject", parameterIndex, x);
                 }
-                if (x instanceof String) {
+
+                int paramType = getColumnMetaDataX().getColumnType(parameterIndex);
+
+                if ( paramType == java.sql.Types.JAVA_OBJECT )
+                {
+                    setUDTX( parameterIndex, x );
+                }
+                else if (x instanceof String) {
                     setString(parameterIndex, (String) x);
                 } else if (x instanceof Integer) {
                     setInt(parameterIndex, ((Integer) x).intValue());
@@ -1468,6 +1475,53 @@
         }            
     }
 
+    /**
+     * Set a UDT parameter to an object value.
+     */
+    private void setUDTX(int parameterIndex, Object x) throws SqlException, SQLException
+    {
+        int paramType = getColumnMetaDataX().getColumnType(parameterIndex);
+        int expectedType = java.sql.Types.JAVA_OBJECT;
+        
+        if ( !( paramType == expectedType ) )
+        {
+            PossibleTypes.throw22005Exception
+                (agent_.logWriter_, expectedType, paramType );
+        }
+        
+        parameterMetaData_.clientParamtertype_[parameterIndex - 1] = expectedType;
+        if (x == null) {
+            setNullX(parameterIndex, expectedType );
+            return;
+        }
+
+        //
+        // Make sure that we are setting the parameter to an instance of the UDT.
+        //
+        
+        Throwable problem = null;
+        String sourceClassName = x.getClass().getName();
+        String targetClassName = getColumnMetaDataX().getColumnClassName(parameterIndex);
+
+        try {
+            Class targetClass = Class.forName( targetClassName );
+            if ( targetClass.isInstance( x ) )
+            {
+                setInput(parameterIndex, x);
+                return;
+            }
+        }
+        catch (ClassNotFoundException e) { problem = e; }
+
+        throw new SqlException
+            (
+             agent_.logWriter_,
+             new ClientMessageId( SQLState.NET_UDT_COERCION_ERROR ),
+             new Object[] { sourceClassName, targetClassName },
+             problem
+             );
+    }
+
     public void setObject(int parameterIndex, Object x, int targetJdbcType) throws SQLException {
         try
         {
@@ -3069,23 +3123,6 @@
             
         }
         
-        /*
-        static SqlException throwLangDataTypeSetException( LogWriter logWriter, 
-                                                           int valType,
-                                                           int paramType)
-    
-            throws SqlException{
-            
-            throw new SqlException( logWriter,
-                                    new ClientMessageId(SQLState.LANG_DATA_TYPE_SET_MISMATCH) ,
-                                    new Object[]{ 
-                                        Types.getTypeString(valType),
-                                        Types.getTypeString(paramType) 
-                                    },
-                                    (Throwable) null);
-        }
-        */
-        
         static SqlException throw22005Exception( LogWriter logWriter, 
                                                  int valType,
                                                  int paramType)

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Types.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Types.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Types.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Types.java Fri Jan 15 17:54:20 2010
@@ -77,6 +77,8 @@
 
     public final static int CLOB = java.sql.Types.CLOB;          // 2005;
 
+    public final static int JAVA_OBJECT = java.sql.Types.JAVA_OBJECT;          // 2000;
+
     // hide the default constructor
     private Types() {
    }
@@ -169,6 +171,8 @@
             return Types.CLOB;
         case DRDAConstants.DB2_SQLTYPE_BLOB:    // large object bytes
             return java.sql.Types.BLOB;
+        case DRDAConstants.DB2_SQLTYPE_FAKE_UDT:    // user defined types
+            return java.sql.Types.JAVA_OBJECT;
         default:
             return 0;
         }

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/DssConstants.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/DssConstants.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/DssConstants.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/DssConstants.java Fri Jan 15 17:54:20 2010
@@ -21,8 +21,10 @@
 
 package org.apache.derby.client.net;
 
+import org.apache.derby.iapi.reference.DRDAConstants;
+
 class DssConstants {
-    static final int MAX_DSS_LEN = 32767;
+    static final int MAX_DSS_LEN = DRDAConstants.DATA_STREAM_STRUCTURE_MAX_LENGTH;
 
     // Registered SNA GDS identifier indicating DDM data (xD0 for DDM data).
     static final int GDS_ID = 0xD0;

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java Fri Jan 15 17:54:20 2010
@@ -1735,6 +1735,18 @@
     }
 
     /**
+     * Check whether the server supports UDTs
+     * @return true if UDTs are supported
+     */
+    protected final boolean serverSupportsUDTs() {
+
+        NetDatabaseMetaData metadata =
+            (NetDatabaseMetaData) databaseMetaData_;
+
+        return metadata.serverSupportsUDTs();
+    }
+
+    /**
      * Checks whether the server supports locators for large objects.
      *
      * @return {@code true} if LOB locators are supported.

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java Fri Jan 15 17:54:20 2010
@@ -36,6 +36,9 @@
      */
     private boolean supportsSessionDataCaching_;
 
+    /** True if the server supports UDTs */
+    private boolean supportsUDTs_;
+    
     public NetDatabaseMetaData(NetAgent netAgent, NetConnection netConnection) {
         // Consider setting product level during parse
         super(netAgent, netConnection, new ProductLevel(netConnection.productID_,
@@ -94,6 +97,9 @@
 
         supportsSessionDataCaching_ =
                 productLevel_.greaterThanOrEqualTo(10, 4, 0);
+
+        supportsUDTs_ =
+                productLevel_.greaterThanOrEqualTo(10, 6, 0);
     }
 
     /**
@@ -117,4 +123,12 @@
     final boolean serverSupportsSessionDataCaching() {
         return supportsSessionDataCaching_;
     }
+
+    /**
+     * Check if server supports UDTs
+     * @return true if the server supports this
+     */
+    final boolean serverSupportsUDTs() {
+        return supportsSessionDataCaching_;
+    }
 }

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java Fri Jan 15 17:54:20 2010
@@ -2076,19 +2076,26 @@
     // SQLUDTGRP : EARLY FDOCA GROUP
     // SQL User-Defined Data Group Description
     //
-    // FORMAT FOR SQLAM >= 7
-    //   SQLUDTXTYPE; PROTOCOL TYPE I4; ENVLID 0X02; Length Override 4
-    //   SQLUDTRDB; PROTOCOL TYPE VCS; ENVLID 0X32; Length Override 255
-    //   SQLUDTSCHEMA_m; PROTOCOL TYPE VCM; ENVLID 0X3E; Length Override 255
-    //   SQLUDTSCHEMA_s; PROTOCOL TYPE VCS; ENVLID 0X32; Length Override 255
-    //   SQLUDTNAME_m; PROTOCOL TYPE VCM; ENVLID 0X3E; Length Override 255
-    //   SQLUDTNAME_s; PROTOCOL TYPE VCS; ENVLID 0X32; Length Override 255
+    // For an explanation of the format, see the header comment on
+    // DRDAConnThread.writeSQLUDTGRP().
+    //
     private void parseSQLUDTGRP(ColumnMetaData columnMetaData,
-                                int columnNumber) throws DisconnectException {
-        if (readFastUnsignedByte() == CodePoint.NULLDATA) {
-            return;
-        }
+                                int columnNumber) throws DisconnectException
+    {
+        int jdbcType = columnMetaData.types_[columnNumber];
+
+        if ( !(jdbcType == Types.JAVA_OBJECT) || !netAgent_.netConnection_.serverSupportsUDTs() )
+        {
+            if (readFastUnsignedByte() == CodePoint.NULLDATA) { return; }
+        }
+        else
+        {
+            String typeName = parseFastVCMorVCS();
+            String className = parseFastVCMorVCS();
 
+            columnMetaData.sqlUDTname_[columnNumber] = typeName;
+            columnMetaData.sqlUDTclassName_[columnNumber] = className;
+        }
     }
 
     // SQLDOPTGRP : EARLY FDOCA GROUP

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java Fri Jan 15 17:54:20 2010
@@ -758,6 +758,9 @@
                                          i);
                         }
                         break;
+                    case DRDAConstants.DRDA_TYPE_NUDT:
+                        writeUDT( inputs[i] );
+                        break;
                     case DRDAConstants.DRDA_TYPE_NLOBCSBCS:
                     case DRDAConstants.DRDA_TYPE_NLOBCDBCS:
                         // check for a promoted Clob
@@ -1341,6 +1344,10 @@
                         lidAndLengths[i][1] = buildPlaceholderLength(ba.length);
                     }
                     break;
+                case java.sql.Types.JAVA_OBJECT:
+                    lidAndLengths[i][0] = DRDAConstants.DRDA_TYPE_NUDT;
+                    lidAndLengths[i][1] = 32767;
+                    break;
                 case java.sql.Types.BLOB:
                     java.sql.Blob b = (java.sql.Blob) inputRow[i];
                     if (b == null) {

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java Fri Jan 15 17:54:20 2010
@@ -23,9 +23,13 @@
 import org.apache.derby.client.am.DisconnectException;
 import org.apache.derby.client.am.ClientMessageId;
 import org.apache.derby.client.am.SqlException;
+import org.apache.derby.shared.common.io.DynamicByteArrayOutputStream;
 import org.apache.derby.shared.common.reference.SQLState;
+import org.apache.derby.shared.common.sanity.SanityManager;
+import org.apache.derby.iapi.reference.DRDAConstants;
 
 import java.io.BufferedInputStream;
+import java.io.ObjectOutputStream;
 import java.io.UnsupportedEncodingException;
 
 import java.io.IOException;
@@ -1604,10 +1608,63 @@
     // ldSize and bytes.length may not be the same.  this is true
     // when writing graphic ld strings.
     private final void writeLDBytesX(int ldSize, byte[] bytes) {
+        writeLDBytesXSubset( ldSize, bytes.length, bytes );
+    }
+
+    // private helper method for writing just a subset of a byte array
+    private final void writeLDBytesXSubset( int ldSize, int bytesToCopy, byte[] bytes )
+    {
         bytes_[offset_++] = (byte) ((ldSize >>> 8) & 0xff);
         bytes_[offset_++] = (byte) (ldSize & 0xff);
-        System.arraycopy(bytes, 0, bytes_, offset_, bytes.length);
-        offset_ += bytes.length;
+        System.arraycopy( bytes, 0, bytes_, offset_, bytesToCopy );
+        offset_ += bytesToCopy;
+    }
+
+    final void writeUDT( Object val ) throws SqlException
+    {
+        // should not be called if val is null
+        if ( val == null )
+        {
+            SanityManager.THROWASSERT( "UDT is null" );
+        }
+
+        byte[] buffer = null;
+        int length = 0;
+        
+        try
+        {
+            DynamicByteArrayOutputStream dbaos = new DynamicByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream( dbaos );
+
+            oos.writeObject( val );
+
+            buffer = dbaos.getByteArray();
+            length = dbaos.getUsed();
+        }
+        catch (Exception e)
+        {
+            throw new SqlException
+                (
+                 netAgent_.logWriter_, 
+                 new ClientMessageId (SQLState.NET_MARSHALLING_UDT_ERROR),
+                 e.getMessage(),
+                 e
+                 );
+        }
+
+        if ( length > DRDAConstants.MAX_DRDA_UDT_SIZE )
+        {
+            throw new SqlException
+                (
+                 netAgent_.logWriter_, 
+                 new ClientMessageId(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE),
+                 Integer.toString( DRDAConstants.MAX_DRDA_UDT_SIZE ),
+                 val.getClass().getName()
+                 );
+        }
+
+        ensureLength( offset_ + length + 2 );
+        writeLDBytesXSubset( length, length, buffer );
     }
 
     // does it follows

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/Typdef.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/Typdef.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/Typdef.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/Typdef.java Fri Jan 15 17:54:20 2010
@@ -425,10 +425,10 @@
         new FdocaSimpleDataArray(0x4E, FdocaConstants.FDOCA_TYPE_VARCHAR, Cursor.VARIABLE_STRING, CCSIDMBC, 1, 1, 32767, TWOBYTELENGTH),
         /* 0x4F null  MBCS */
         new FdocaSimpleDataArray(0x4F, FdocaConstants.FDOCA_TYPE_NVARCHAR, Cursor.VARIABLE_STRING, CCSIDMBC, 1, 1, 32767, TWOBYTELENGTH),
-        /* 0x50 Empties */
-        null,
-        /* 0x51 Empties */
-        null,
+        /* 0x50 UDT */
+        new FdocaSimpleDataArray(0x50, FdocaConstants.FDOCA_TYPE_VARBYTES, Cursor.VARIABLE_BYTES, NOCCSID, 0, 1, 32767, TWOBYTELENGTH),
+        /* 0x51 null UDT */
+        new FdocaSimpleDataArray(0x51, FdocaConstants.FDOCA_TYPE_NVARBYTES, Cursor.VARIABLE_BYTES, NOCCSID, 0, 1, 32767, TWOBYTELENGTH),
         /* 0x52 Empties */
         null,
         /* 0x53 Empties */
@@ -765,8 +765,8 @@
         java.sql.Types.VARCHAR, // 0x4D null SBCS
         java.sql.Types.VARCHAR, // 0x4E MBCS
         java.sql.Types.VARCHAR, // 0x4F null MBCS
-        0x00, // 0x50 Empties
-        0x00, // 0x51 Empties
+        java.sql.Types.JAVA_OBJECT, // 0x50 UDT
+        java.sql.Types.JAVA_OBJECT, // 0x51 null UDT
         0x00, // 0x52 Empties
         0x00, // 0x53 Empties
         0x00, // 0x54 Empties

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java Fri Jan 15 17:54:20 2010
@@ -298,4 +298,8 @@
 	protected boolean supportsSessionDataCaching() {
 		return (clientType == DNC_CLIENT && greaterThanOrEqualTo(10, 4, 0));
 	}
+
+	protected boolean supportsUDTs() {
+		return (clientType == DNC_CLIENT && greaterThanOrEqualTo(10, 6, 0));
+	}
 }

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DDMWriter.java Fri Jan 15 17:54:20 2010
@@ -24,6 +24,7 @@
 import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.math.BigDecimal;
 import java.nio.ByteBuffer;
@@ -34,9 +35,11 @@
 import java.sql.SQLException;
 import java.util.Arrays;
 
+import org.apache.derby.iapi.reference.DRDAConstants;
 import org.apache.derby.iapi.reference.Property;
 import org.apache.derby.iapi.services.property.PropertyUtil;
 import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;
 
 /**
 	The DDMWriter is used to write DRDA protocol.   The DRDA Protocol is
@@ -1091,6 +1094,51 @@
 	}
 
 	/**
+	 * Write a value of a user defined type.
+	 *
+	 * @param val object to be written
+	 *
+	 * @exception DRDAProtocolException
+	 */
+	protected void writeUDT( Object val, int index ) throws DRDAProtocolException
+	{
+        // should not be called if val is null
+        if ( val == null )
+        {
+            SanityManager.THROWASSERT( "UDT is null" );
+        }
+
+        byte[] buffer = null;
+        int length = 0;
+
+        try {
+            DynamicByteArrayOutputStream dbaos = new DynamicByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream( dbaos );
+
+            oos.writeObject( val );
+
+            buffer = dbaos.getByteArray();
+            length = dbaos.getUsed();
+            
+        } catch(IOException e)
+        {
+            agent.markCommunicationsFailure
+                ( e,"DDMWriter.writeUDT()", "", e.getMessage(), "" );
+        }
+
+        if ( length > DRDAConstants.MAX_DRDA_UDT_SIZE )
+        {
+            agent.markCommunicationsFailure
+                ( "DDMWriter.writeUDT()", "User defined type is longer than " + DRDAConstants.MAX_DRDA_UDT_SIZE + " bytes.", "", "" );
+        }
+        else
+        {
+            writeShort( length );
+            writeBytes( buffer, 0, length );
+        }
+	}
+
+	/**
 	 * Find the maximum number of bytes needed to represent the string in the
 	 * default encoding.
 	 *

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Fri Jan 15 17:54:20 2010
@@ -23,6 +23,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.io.ObjectInputStream;
 import java.io.OutputStream;
 import java.io.InputStreamReader;
 import java.io.IOException;
@@ -4698,6 +4699,12 @@
 				ps.setBytes(i+1, paramVal);
 				break;
 			}
+			case DRDAConstants.DRDA_TYPE_NUDT:
+			{
+                Object paramVal = readUDT();
+				ps.setObject(i+1, paramVal);
+				break;
+			}
 			case DRDAConstants.DRDA_TYPE_NLOBBYTES:
 			case DRDAConstants.DRDA_TYPE_NLOBCMIXED:
 			case DRDAConstants.DRDA_TYPE_NLOBCSBCS:
@@ -4763,6 +4770,28 @@
 		}
 	}
 
+    /** Read a UDT from the stream */
+    private Object readUDT() throws DRDAProtocolException
+    {
+        int length = reader.readNetworkShort();	//protocol control data always follows big endian
+        if (SanityManager.DEBUG) { trace("===== udt param length is: " + length); }
+        byte[] bytes = reader.readBytes(length);
+        
+        try {
+            ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
+            ObjectInputStream ois = new ObjectInputStream( bais );
+
+            return ois.readObject();
+        }
+        catch (Exception e)
+        {
+            markCommunicationsFailure
+                ( e,"DRDAConnThread.readUDT()", "", e.getMessage(), "*" );
+            return null;
+        }
+    }
+
+
 	private long readLobLength(int extLenIndicator) 
 		throws DRDAProtocolException
 	{
@@ -4833,7 +4862,7 @@
 			if (sqlamLevel >= MGRLVL_7 &&
 				FdocaConstants.isNullable(drdaType))
 				checkNullability = true;
-	
+
 			try {	
 				final byte[] paramBytes;
 				final String paramString;
@@ -6597,7 +6626,7 @@
 												 (pmeta.isNullable(i) == JDBC30Translation.PARAMETER_NULLABLE));
 			int colType = (hasRs ? rsmeta.getColumnType(i) : pmeta.getParameterType(i));
 			int[] outlen = {-1};
-			int drdaType = FdocaConstants.mapJdbcTypeToDrdaType(colType,nullable,outlen);
+			int drdaType = FdocaConstants.mapJdbcTypeToDrdaType( colType, nullable, appRequester, outlen );
 				
 
 			boolean isDecimal = ((drdaType | 1) == DRDAConstants.DRDA_TYPE_NDECIMAL);
@@ -7028,7 +7057,7 @@
 					
 					if (stmt.isOutputParam(i)) {
 						int[] outlen = new int[1];
-						drdaType = FdocaConstants.mapJdbcTypeToDrdaType(stmt.getOutputParamType(i),true,outlen);
+						drdaType = FdocaConstants.mapJdbcTypeToDrdaType( stmt.getOutputParamType(i), true, appRequester, outlen );
 						precision = stmt.getOutputParamPrecision(i);
 						scale = stmt.getOutputParamScale(i);
                                                 
@@ -7352,9 +7381,9 @@
 			(pmeta.isNullable(jdbcElemNum) == JDBC30Translation.PARAMETER_NULLABLE);
 		
 		int sqlType = SQLTypes.mapJdbcTypeToDB2SqlType(elemType,
-													   nullable,
+													   nullable, appRequester,
 													   outlen);
-		
+
 		if (outlen[0] == -1) //some types not set
 		{
 			switch (elemType)
@@ -7461,13 +7490,68 @@
 	}
 
   
+	/**
+	 * Write SQLUDTGRP (SQL Descriptor User-Defined Type Group Descriptor)
+	 * 
+	 * This is the format from the DRDA spec, Volume 1, section 5.6.4.10.
+     * However, this format is not rich enough to carry the information needed
+     * by JDBC. This format does not have a subtype code for JAVA_OBJECT and
+     * this format does not convey the Java class name needed
+     * by ResultSetMetaData.getColumnClassName().
+	 *
+	 *   SQLUDXTYPE; DRDA TYPE I4; ENVLID 0x02; Length Override 4
+     *                        Constants which map to java.sql.Types constants DISTINCT, STRUCT, and REF.
+     *                        But DRDA does not define a constant which maps to java.sql.Types.JAVA_OBJECT.
+	 *   SQLUDTRDB; DRDA TYPE VCS; ENVLID 0x32; Length Override 255
+     *                       Database name.
+	 *   SQLUDTSCHEMA_m; DRDA TYPE VCM; ENVLID 0x3E; Length Override 255
+	 *   SQLUDTSCHEMA_s; DRDA TYPE VCS; ENVLID 0x32; Length Override 255
+     *                         Schema name. One of the above.
+	 *   SQLUDTNAME_m; DRDA TYPE VCM; ENVLID 0x3E; Length Override 255
+	 *   SQLUDTNAME_s; DRDA TYPE VCS; ENVLID 0x32; Length Override 255
+     *                         Unqualified UDT name. One of the above.
+	 *
+	 * Instead, we use the following format and only for communication between
+     * Derby servers and Derby clients which are both at version 10.6 or higher.
+     * For all other client/server combinations, we send null.
+	 *
+	 *   SQLUDTNAME_m; DRDA TYPE VCM; ENVLID 0x3E; Length Override 255
+	 *   SQLUDTNAME_s; DRDA TYPE VCS; ENVLID 0x32; Length Override 255
+     *                         Fully qualified UDT name. One of the above.
+	 *   SQLUDTCLASSNAME_m; DRDA TYPE VCM; ENVLID 0x3E; Length Override FdocaConstants.LONGVARCHAR_MAX_LEN
+	 *   SQLUDTCLASSNAME_s; DRDA TYPE VCS; ENVLID 0x32; Length Override FdocaConstants.LONGVARCHAR_MAX_LEN
+     *                         Name of the Java class bound to the UDT. One of the above.
+	 *
+	 * @param rsmeta	resultset meta data
+	 * @param pmeta		parameter meta data
+	 * @param elemNum	column number we are returning (in case of result set), or,
+	 *					parameter number (in case of parameter)
+	 * @param rtnOutput	whether this is for a result set	
+	 *
+	 * @throws DRDAProtocolException
+     * @throws SQLException
+	 */
 	private void writeSQLUDTGRP(ResultSetMetaData rsmeta,
 								ParameterMetaData pmeta,
 								int jdbcElemNum, boolean rtnOutput)
 		throws DRDAProtocolException,SQLException
 	{
-		writer.writeByte(CodePoint.NULLDATA);
+        int jdbcType = rtnOutput ?
+            rsmeta.getColumnType( jdbcElemNum) : pmeta.getParameterType( jdbcElemNum );
 
+        if ( !(jdbcType == Types.JAVA_OBJECT) || !appRequester.supportsUDTs() )
+        {
+            writer.writeByte(CodePoint.NULLDATA);
+            return;
+        }
+        
+		String typeName = rtnOutput ?
+            rsmeta.getColumnTypeName( jdbcElemNum ) : pmeta.getParameterTypeName( jdbcElemNum );
+        String className = rtnOutput ?
+            rsmeta.getColumnClassName( jdbcElemNum ) : pmeta.getParameterClassName( jdbcElemNum );
+        
+		writeVCMorVCS( typeName );
+		writeVCMorVCS( className );
 	}
 
 	private void writeSQLDOPTGRP(ResultSetMetaData rsmeta,
@@ -7674,6 +7758,9 @@
 				case DRDAConstants.DRDA_TYPE_NCLOBLOC:
 					writer.writeInt(((EngineLOB)val).getLocator());
 					break;
+				case DRDAConstants.DRDA_TYPE_NUDT:
+					writer.writeUDT( val, index );
+					break;
 				default:
 					if (SanityManager.DEBUG) 
 						trace("ndrdaType is: "+ndrdaType);

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/FdocaConstants.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/FdocaConstants.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/FdocaConstants.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/FdocaConstants.java Fri Jan 15 17:54:20 2010
@@ -129,10 +129,11 @@
 	 * Map jdbctype to fdoca drda type
 	 * @param jdbcType - Jdbc type for mappingy
 	 * @param nullable - true if type is nullable
+	 * @param appRequester - state variable for the connection
 	 * @param outlen - output parameter with length of type.
 	 * @return standard drdaTypeLength. -1 if we don't know.
 	 **/
-	protected static int mapJdbcTypeToDrdaType(int jdbcType, boolean nullable,
+	protected static int mapJdbcTypeToDrdaType(int jdbcType, boolean nullable, AppRequester appRequester,
 											   int[] outlen)
 		throws SQLException
 	{
@@ -195,8 +196,18 @@
 				// we will just convert a java object to a string
 				// since jcc doesn't support it.
 			case java.sql.Types.JAVA_OBJECT:
-				drdaType = DRDAConstants.DRDA_TYPE_NLONG;
-				outlen[0] = LONGVARCHAR_MAX_LEN;
+                //boolean b = false;
+                //if ( b )
+                if ( appRequester.supportsUDTs() )
+                {
+                    drdaType = DRDAConstants.DRDA_TYPE_NUDT;
+                    outlen[0] = -1;
+                }
+                else
+                {
+                    drdaType = DRDAConstants.DRDA_TYPE_NLONG;
+                    outlen[0] = LONGVARCHAR_MAX_LEN;
+                }
 				break;
 			case java.sql.Types.LONGVARCHAR:
 					drdaType = DRDAConstants.DRDA_TYPE_NLONG;

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/SQLTypes.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/SQLTypes.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/SQLTypes.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/SQLTypes.java Fri Jan 15 17:54:20 2010
@@ -122,6 +122,7 @@
  /**  Map JDBC Type to DB2 SqlType
   * @param jdbctype   JDBC Type from java.sql.Types
   * @param nullable   true if this is a nullable type
+	 * @param appRequester - state variable for the connection
   * @param outlen     output parameter with type length
   *
   * @return Corresponding DB2 SQL Type (See DRDA Manual FD:OCA Meta 
@@ -130,7 +131,7 @@
   * @exception SQLException thrown for unrecognized SQLType
   */
 
- static protected int mapJdbcTypeToDB2SqlType (int jdbctype, boolean nullable,
+    static protected int mapJdbcTypeToDB2SqlType (int jdbctype, boolean nullable, AppRequester appRequester,
 											   int[] outlen)
 	 throws SQLException
   {
@@ -140,7 +141,7 @@
 		  nullAddVal =1; 
 	  
 	  // Call FdocaConstants just to get the length
-	  FdocaConstants.mapJdbcTypeToDrdaType(jdbctype,nullable,outlen);
+	  FdocaConstants.mapJdbcTypeToDrdaType(jdbctype,nullable,appRequester,outlen);
 
 	  switch(jdbctype)
 	  {
@@ -176,7 +177,14 @@
 		  case java.sql.Types.LONGVARBINARY:
 			  return DRDAConstants.DB2_SQLTYPE_LONG + nullAddVal;
 		  case java.sql.Types.JAVA_OBJECT:
-			  return DRDAConstants.DB2_SQLTYPE_LONG + nullAddVal;
+              if ( appRequester.supportsUDTs() )
+              {
+                  return DRDAConstants.DB2_SQLTYPE_FAKE_UDT + nullAddVal;
+              }
+              else
+              {
+                  return DRDAConstants.DB2_SQLTYPE_LONG + nullAddVal;
+              }
 		  case java.sql.Types.BLOB:
 			  return DRDAConstants.DB2_SQLTYPE_BLOB + nullAddVal;
 		  case java.sql.Types.CLOB:

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=899733&r1=899732&r2=899733&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 Fri Jan 15 17:54:20 2010
@@ -39,6 +39,7 @@
 import org.apache.derby.iapi.reference.SQLState;
 
 import org.apache.derby.iapi.services.info.JVMInfo;
+import org.apache.derby.iapi.util.IdUtil;
 
 import java.sql.Types;
 
@@ -137,7 +138,7 @@
     public String   getSQLTypeName()
     {
         if ( schemaName == null ) { return unqualifiedName; }
-        else { return doubleQuote( schemaName ) + '.' + doubleQuote( unqualifiedName ); }
+        else { return IdUtil.mkQualifiedName( schemaName, unqualifiedName ); }
     }
 
     /** Get the schema name of this type. Non-null only for UDTs */
@@ -183,7 +184,7 @@
     {
         String retval = getSQLTypeName();
 
-        switch (formatId)
+        switch (getTypeFormatId())
         {
           case StoredFormatIds.BIT_TYPE_ID_IMPL:
           case StoredFormatIds.VARBIT_TYPE_ID_IMPL:
@@ -255,7 +256,39 @@
      */
     public int getTypeFormatId()
     {
-        return formatId;
+        if ( formatId != 0 ) { return formatId; }
+        else
+        {
+            //
+            // If you serialize this class outside the formatable machinery, you
+            // 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; }
+            else if ( "CHAR FOR BIT DATA".equals( unqualifiedName ) ) { return StoredFormatIds.BIT_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 { return 0; }
+        }
     }
 
     /**
@@ -310,7 +343,7 @@
 
     private void setTypeIdSpecificInstanceVariables()
     {
-        switch (formatId)
+        switch (getTypeFormatId())
         {
           case StoredFormatIds.BOOLEAN_TYPE_ID_IMPL:
               schemaName = null;
@@ -441,7 +474,7 @@
           default:
                 if (SanityManager.DEBUG)
                 {
-                        SanityManager.THROWASSERT("Unexpected formatId " + formatId);
+                    SanityManager.THROWASSERT("Unexpected formatId " + getTypeFormatId());
                 }
                 break;
         }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/DecimalTypeIdImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/DecimalTypeIdImpl.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/DecimalTypeIdImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/DecimalTypeIdImpl.java Fri Jan 15 17:54:20 2010
@@ -28,6 +28,12 @@
 
 public class DecimalTypeIdImpl extends BaseTypeIdImpl
 {
+	/**
+	 * Public niladic constructor. Needed for Serializable interface to work.
+	 *
+	 */
+	public	DecimalTypeIdImpl() { super(); }
+
 	/* this class is needed because writeexternal for this class stores
 	   extra information; when the object is sent over the wire the niladic
 	   constructor is first called and then we call the readExternal method. 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/TypeDescriptorImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/TypeDescriptorImpl.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/TypeDescriptorImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/TypeDescriptorImpl.java Fri Jan 15 17:54:20 2010
@@ -30,6 +30,7 @@
 import org.apache.derby.iapi.services.io.Formatable;
 import org.apache.derby.iapi.services.io.StoredFormatIds;
 import org.apache.derby.iapi.types.StringDataValue;
+import org.apache.derby.shared.common.reference.JDBC30Translation;
                              
 public class TypeDescriptorImpl implements TypeDescriptor, Formatable
 {
@@ -135,6 +136,9 @@
 		this.typeId = typeId;
 		this.isNullable = isNullable;
 		this.maximumWidth = maximumWidth;
+
+        this.scale = JDBC30Translation.UNKNOWN_SCALE;
+        this.precision = JDBC30Translation.UNKNOWN_PRECISION;
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/DRDAConstants.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/DRDAConstants.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/DRDAConstants.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/DRDAConstants.java Fri Jan 15 17:54:20 2010
@@ -41,6 +41,9 @@
 	//
 	public	static	final	String	DERBY_DRDA_SERVER_ID = "CSS";
 	public	static	final	String	DERBY_DRDA_CLIENT_ID = "DNC";
+
+    // Maximum size of a DDM block
+    public static final int DATA_STREAM_STRUCTURE_MAX_LENGTH = 32767;
 	
 	///////////////////////
 	//
@@ -126,6 +129,12 @@
 	public	static final int DRDA_TYPE_NMDATALINK = 0x4F;
 
 	// --- Override LIDs 0x50 - 0xAF
+
+    // this type is shown in the DRDA spec, volume 1, in the
+    // section on SQLUDTGRP
+	public	static final int DRDA_TYPE_UDT = 0x50;
+	public	static final int DRDA_TYPE_NUDT = 0x51;
+    
 	public	static final int DRDA_TYPE_LOBBYTES = 0xC8;
 	public	static final int DRDA_TYPE_NLOBBYTES = 0xC9;
 	public	static final int DRDA_TYPE_LOBCSBCS = 0xCA;
@@ -141,7 +150,11 @@
 	
 	// public	static final int DRDA_TYPE_BOOLEAN = 0xBE;
 	// public	static final int DRDA_TYPE_NBOOLEAN = 0xBF;
-	
+
+    // This is the maximum size which a udt can serialize to in order to
+    // be transported across DRDA
+    public static final int MAX_DRDA_UDT_SIZE = DATA_STREAM_STRUCTURE_MAX_LENGTH;
+    
 	///////////////////////
 	//
 	// DB2 datatypes
@@ -212,4 +225,8 @@
     // public	static final  int DB2_SQLTYPE_BOOLEAN = 1000;     // BOOLEAN
     // public	static final  int DB2_SQLTYPE_NBOOLEAN = 1001;
 
+    // there is no DB2 type for UDTs. we invent one
+    public   static final int DB2_SQLTYPE_FAKE_UDT = 2000;
+    public   static final int DB2_SQLTYPE_FAKE_NUDT = 2001;
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/DynamicByteArrayOutputStream.java Fri Jan 15 17:54:20 2010
@@ -33,217 +33,10 @@
 	the user of this class to have more control over the position of the stream
 	and can get a direct reference of the array.
 */
-public class DynamicByteArrayOutputStream extends OutputStream {
-
-	private static int INITIAL_SIZE = 4096;
-
-	private byte[] buf;
-	private int		position;
-	private int		used;		// how many bytes are used
-	private int		beginPosition;
-
-	public DynamicByteArrayOutputStream() {
-		this(INITIAL_SIZE);
-	}
-
-	public DynamicByteArrayOutputStream(int size) {
-		super();
-
-		buf = new byte[size];
-	}
-
-	public DynamicByteArrayOutputStream(byte[] data) {
-		super();
-
-		buf = data;
-	}
-
-	public DynamicByteArrayOutputStream(DynamicByteArrayOutputStream toBeCloned) {
-
-		byte[] cbuf = toBeCloned.getByteArray();
-		buf = new byte[cbuf.length];
-
-		write(cbuf, 0, cbuf.length);
-		position = toBeCloned.getPosition();
-		used = toBeCloned.getUsed();
-		beginPosition = toBeCloned.getBeginPosition();
-	}
-
-	/*
-	 *	OutputStream methods
-	 */
-	public void write(int b) 
-	{
-		if (position >= buf.length)
-			expandBuffer(INITIAL_SIZE);
-
-		buf[position++] = (byte) b;
-
-		if (position > used)
-			used = position;
-	}
-	
-	public void write(byte[] b, int off, int len) 
-	{
-		if ((position+len) > buf.length)
-			expandBuffer(len);
-
-		System.arraycopy(b, off, buf, position, len);
-		position += len;
-
-		if (position > used)
-			used = position;
-	}
-
-	void writeCompleteStream(InputStream dataIn, int len) throws IOException
-	{
-		if ((position+len) > buf.length)
-			expandBuffer(len);
-
-		org.apache.derby.iapi.services.io.InputStreamUtil.readFully(dataIn, buf, position, len);
-		position += len;
-
-		if (position > used)
-			used = position;
-	}
-
-	public void close()
-	{
-		buf = null;
-		reset();
-	}
-
-	/*
-	 *	Specific methods
-	 */
-
-	/**
-		Reset the stream for reuse
-	*/
-	public void reset()
-	{
-		position = 0;
-		beginPosition = 0;
-		used = 0;
-	}
-
-	/**
-		Get a reference to the byte array stored in the byte array output
-		stream. Note that the byte array may be longer that getPosition().
-		Bytes beyond and including the current poistion are invalid.
-	*/
-	public byte[] getByteArray()
-	{
-		return buf;
-	}
-
-	/**
-		Get the number of bytes that was used.
-	*/
-	public int getUsed()
-	{
-		return used;
-	}
-
-	/**
-		Get the current position in the stream
-	*/
-	public int getPosition()
-	{
-		return position;
-	}
-
-	/**
-		Get the current position in the stream
-	*/
-	public int getBeginPosition()
-	{
-		return beginPosition;
-	}
-
-	/**
-		Set the position of the stream pointer.
-		It is up to the caller to make sure the stream has no gap of garbage in
-		it or useful information is not left out at the end because the stream
-		does not remember anything about the previous position.
-	*/
-	public void setPosition(int newPosition)
-	{
-		if (newPosition > position)
-		{
-			if (newPosition > buf.length)
-				expandBuffer(newPosition - buf.length);
-		}
-
-		position = newPosition;
-
-		if (position > used)
-			used = position;
-
-		return ;
-	}
-
-	/**
-		Set the begin position of the stream pointer.
-		If the newBeginPosition is larger than the stream itself,
-		then, the begin position is not set.
-	*/
-	public void setBeginPosition(int newBeginPosition)
-	{
-
-		if (newBeginPosition > buf.length)
-			return;
-
-		beginPosition = newBeginPosition;
-	}
-
-	/**
-		Shrink the buffer left by the amount given. Ie.
-		bytes from 0 to amountToShrinkBy are thrown away
-	*/
-	public void discardLeft(int amountToShrinkBy) {
-
-		System.arraycopy(buf, amountToShrinkBy, buf, 0,
-			used - amountToShrinkBy);
-
-		position -= amountToShrinkBy;
-		used -= amountToShrinkBy;
-	}
-
-	/**
-		Expand the buffer by at least the number of bytes requested in minExtension.
-
-		To optimize performance and reduce memory copies and allocation, we have a staged buffer
-		expansion.
-
-		<UL>
-		<LI> buf.length < 128k - increase by 4k
-		<LI> buf.length < 1Mb - increase by 128k
-		<LI> otherwise increase by 1Mb.
-		</UL>
-
-		In all cases, if minExpansion is greater than the value about then the buffer will
-		be increased by minExtension.
-	*/
-	private void expandBuffer(int minExtension)
-	{
-		if (buf.length < (128 * 1024)) {
-			if (minExtension < INITIAL_SIZE)
-				minExtension = INITIAL_SIZE;
-		} else if (buf.length < (1024 * 1024)) {
-
-			if (minExtension < (128 * 1024))
-				minExtension = (128 * 1024);
-		} else {
-			if (minExtension < (1024 * 1024))
-				minExtension = 1024 * 1024;
-		}
-
-		int newsize = buf.length + minExtension;
-
-		byte[] newbuf = new byte[newsize];
-		System.arraycopy(buf, 0, newbuf, 0, buf.length);
-		buf = newbuf;
-	}
-
+public class DynamicByteArrayOutputStream extends org.apache.derby.shared.common.io.DynamicByteArrayOutputStream
+{
+	public DynamicByteArrayOutputStream() { super(); }
+	public DynamicByteArrayOutputStream(int size) { super( size ); }
+	public DynamicByteArrayOutputStream(byte[] data) { super( data ); }
+	public DynamicByteArrayOutputStream(DynamicByteArrayOutputStream toBeCloned) { super( toBeCloned ); }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/InputStreamUtil.java Fri Jan 15 17:54:20 2010
@@ -28,156 +28,5 @@
 	a small subset of DataInput methods. This avoids pushing
 	a DataInputStream just to get this functionality.
 */
-public final class InputStreamUtil {
-    private static final int SKIP_FRAGMENT_SIZE = Integer.MAX_VALUE;
-
-	/**
-		Read an unsigned byte from an InputStream, throwing an EOFException
-		if the end of the input is reached.
-
-		@exception IOException if an I/O error occurs.
-		@exception EOFException if the end of the stream is reached
-
-		@see DataInput#readUnsignedByte
-	
-	*/
-	public static int readUnsignedByte(InputStream in) throws IOException {
-		int b = in.read();
-		if (b < 0)
-			throw new EOFException();
-
-		return b;
-	}
-
-	/**
-		Read a number of bytes into an array.
-
-		@exception IOException if an I/O error occurs.
-		@exception EOFException if the end of the stream is reached
-
-		@see DataInput#readFully
-
-	*/
-	public static void readFully(InputStream in, byte b[],
-                                 int offset,
-                                 int len) throws IOException
-	{
-		do {
-			int bytesRead = in.read(b, offset, len);
-			if (bytesRead < 0)
-				throw new EOFException();
-			len -= bytesRead;
-			offset += bytesRead;
-		} while (len != 0);
-	}
-
-
-	/**
-		Read a number of bytes into an array.
-        Keep reading in a loop until len bytes are read or EOF is reached or
-        an exception is thrown. Return the number of bytes read.
-        (InputStream.read(byte[],int,int) does not guarantee to read len bytes
-         even if it can do so without reaching EOF or raising an exception.)
-
-		@exception IOException if an I/O error occurs.
-	*/
-	public static int readLoop(InputStream in,
-                                byte b[],
-                                int offset,
-                                int len)
-        throws IOException
-	{
-        int firstOffset = offset;
-		do {
-			int bytesRead = in.read(b, offset, len);
-			if (bytesRead <= 0)
-                break;
-			len -= bytesRead;
-			offset += bytesRead;
-		} while (len != 0);
-        return offset - firstOffset;
-	}
-
-    /**
-     * Skips until EOF, returns number of bytes skipped.
-     * @param is
-     *      InputStream to be skipped.
-     * @return
-     *      number of bytes skipped in fact.
-     * @throws IOException
-     *      if IOException occurs. It doesn't contain EOFException.
-     * @throws NullPointerException
-     *      if the param 'is' equals null.
-     */
-    public static long skipUntilEOF(InputStream is) throws IOException {
-        if(is == null)
-            throw new NullPointerException();
-
-        long bytes = 0;
-        while(true){
-            long r = skipPersistent(is, SKIP_FRAGMENT_SIZE);
-            bytes += r;
-            if(r < SKIP_FRAGMENT_SIZE)
-                return bytes;
-        }
-    }
-
-    /**
-     * Skips requested number of bytes,
-     * throws EOFException if there is too few bytes in the stream.
-     * @param is
-     *      InputStream to be skipped.
-     * @param skippedBytes
-     *      number of bytes to skip. if skippedBytes <= zero, do nothing.
-     * @throws EOFException
-     *      if EOF meets before requested number of bytes are skipped.
-     * @throws IOException
-     *      if IOException occurs. It doesn't contain EOFException.
-     * @throws NullPointerException
-     *      if the param 'is' equals null.
-     */
-    public static void skipFully(InputStream is, long skippedBytes)
-    throws IOException {
-        if(is == null)
-            throw new NullPointerException();
-
-        if(skippedBytes <= 0)
-            return;
-
-        long bytes = skipPersistent(is, skippedBytes);
-
-        if(bytes < skippedBytes)
-            throw new EOFException();
-    }
-
-    /**
-     * Tries harder to skip the requested number of bytes.
-     * <p>
-     * Note that even if the method fails to skip the requested number of bytes,
-     * it will not throw an exception. If this happens, the caller can be sure
-     * that end-of-stream has been reached.
-     *
-     * @param in byte stream
-     * @param bytesToSkip the number of bytes to skip
-     * @return The number of bytes skipped.
-     * @throws IOException if reading from the stream fails
-     */
-    public static final long skipPersistent(InputStream in, long bytesToSkip)
-    throws IOException {
-        long skipped = 0;
-        while (skipped < bytesToSkip) {
-            long skippedNow = in.skip(bytesToSkip - skipped);
-            if (skippedNow == 0) {
-                if (in.read() == -1) {
-                    // EOF, return what we have and leave it up to caller to
-                    // decide what to do about it.
-                    break;
-                } else {
-                    skippedNow = 1; // Added to count below.
-                }
-            }
-            skipped += skippedNow;
-        }
-        return skipped;
-    }
-}
+public final class InputStreamUtil extends org.apache.derby.shared.common.io.InputStreamUtil
+{}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/DataTypeUtilities.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/DataTypeUtilities.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/DataTypeUtilities.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/DataTypeUtilities.java Fri Jan 15 17:54:20 2010
@@ -23,6 +23,7 @@
 
 import org.apache.derby.iapi.error.StandardException;
 
+import org.apache.derby.iapi.reference.JDBC30Translation;
 import org.apache.derby.iapi.reference.JDBC40Translation;
 import org.apache.derby.iapi.services.io.StoredFormatIds;
 
@@ -201,7 +202,7 @@
 			default: 
 				// MaximumWidth is -1 when it is unknown.
 				int w = storageLength;
-				size = (w > 0 ? w : 15);
+				size = (w > 0 ? w : JDBC30Translation.DEFAULT_COLUMN_DISPLAY_SIZE);
 				break;
 		}
 		return size;

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=899733&r1=899732&r2=899733&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 Fri Jan 15 17:54:20 2010
@@ -4943,6 +4943,19 @@
                 <arg>value</arg>
             </msg>
 
+            <msg>
+                <name>XN020.S</name>
+                <text>Error marshalling or unmarshalling a user defined type: {0}</text>
+                <arg>messageDetail</arg>
+            </msg>
+
+            <msg>
+                <name>XN021.S</name>
+                <text>An object of type {0} cannot be cast to an object of type {1}.</text>
+                <arg>sourceClassName</arg>
+                <arg>targetClassName</arg>
+            </msg>
+
         </family>
 
 

Added: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/DynamicByteArrayOutputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/DynamicByteArrayOutputStream.java?rev=899733&view=auto
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/DynamicByteArrayOutputStream.java (added)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/DynamicByteArrayOutputStream.java Fri Jan 15 17:54:20 2010
@@ -0,0 +1,249 @@
+/*
+
+   Derby - Class org.apache.derby.shared.common.io.DynamicByteArrayOutputStream
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.shared.common.io;
+
+import org.apache.derby.shared.common.sanity.SanityManager;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+	A DynamicByteArrayOutputStream allows writing to a dynamically resizable
+	array of bytes.   In addition to dynamic resizing, this extension allows
+	the user of this class to have more control over the position of the stream
+	and can get a direct reference of the array.
+*/
+public class DynamicByteArrayOutputStream extends OutputStream {
+
+	private static int INITIAL_SIZE = 4096;
+
+	private byte[] buf;
+	private int		position;
+	private int		used;		// how many bytes are used
+	private int		beginPosition;
+
+	public DynamicByteArrayOutputStream() {
+		this(INITIAL_SIZE);
+	}
+
+	public DynamicByteArrayOutputStream(int size) {
+		super();
+
+		buf = new byte[size];
+	}
+
+	public DynamicByteArrayOutputStream(byte[] data) {
+		super();
+
+		buf = data;
+	}
+
+	public DynamicByteArrayOutputStream(DynamicByteArrayOutputStream toBeCloned) {
+
+		byte[] cbuf = toBeCloned.getByteArray();
+		buf = new byte[cbuf.length];
+
+		write(cbuf, 0, cbuf.length);
+		position = toBeCloned.getPosition();
+		used = toBeCloned.getUsed();
+		beginPosition = toBeCloned.getBeginPosition();
+	}
+
+	/*
+	 *	OutputStream methods
+	 */
+	public void write(int b) 
+	{
+		if (position >= buf.length)
+			expandBuffer(INITIAL_SIZE);
+
+		buf[position++] = (byte) b;
+
+		if (position > used)
+			used = position;
+	}
+	
+	public void write(byte[] b, int off, int len) 
+	{
+		if ((position+len) > buf.length)
+			expandBuffer(len);
+
+		System.arraycopy(b, off, buf, position, len);
+		position += len;
+
+		if (position > used)
+			used = position;
+	}
+
+	void writeCompleteStream(InputStream dataIn, int len) throws IOException
+	{
+		if ((position+len) > buf.length)
+			expandBuffer(len);
+
+		InputStreamUtil.readFully(dataIn, buf, position, len);
+		position += len;
+
+		if (position > used)
+			used = position;
+	}
+
+	public void close()
+	{
+		buf = null;
+		reset();
+	}
+
+	/*
+	 *	Specific methods
+	 */
+
+	/**
+		Reset the stream for reuse
+	*/
+	public void reset()
+	{
+		position = 0;
+		beginPosition = 0;
+		used = 0;
+	}
+
+	/**
+		Get a reference to the byte array stored in the byte array output
+		stream. Note that the byte array may be longer that getPosition().
+		Bytes beyond and including the current poistion are invalid.
+	*/
+	public byte[] getByteArray()
+	{
+		return buf;
+	}
+
+	/**
+		Get the number of bytes that was used.
+	*/
+	public int getUsed()
+	{
+		return used;
+	}
+
+	/**
+		Get the current position in the stream
+	*/
+	public int getPosition()
+	{
+		return position;
+	}
+
+	/**
+		Get the current position in the stream
+	*/
+	public int getBeginPosition()
+	{
+		return beginPosition;
+	}
+
+	/**
+		Set the position of the stream pointer.
+		It is up to the caller to make sure the stream has no gap of garbage in
+		it or useful information is not left out at the end because the stream
+		does not remember anything about the previous position.
+	*/
+	public void setPosition(int newPosition)
+	{
+		if (newPosition > position)
+		{
+			if (newPosition > buf.length)
+				expandBuffer(newPosition - buf.length);
+		}
+
+		position = newPosition;
+
+		if (position > used)
+			used = position;
+
+		return ;
+	}
+
+	/**
+		Set the begin position of the stream pointer.
+		If the newBeginPosition is larger than the stream itself,
+		then, the begin position is not set.
+	*/
+	public void setBeginPosition(int newBeginPosition)
+	{
+
+		if (newBeginPosition > buf.length)
+			return;
+
+		beginPosition = newBeginPosition;
+	}
+
+	/**
+		Shrink the buffer left by the amount given. Ie.
+		bytes from 0 to amountToShrinkBy are thrown away
+	*/
+	public void discardLeft(int amountToShrinkBy) {
+
+		System.arraycopy(buf, amountToShrinkBy, buf, 0,
+			used - amountToShrinkBy);
+
+		position -= amountToShrinkBy;
+		used -= amountToShrinkBy;
+	}
+
+	/**
+		Expand the buffer by at least the number of bytes requested in minExtension.
+
+		To optimize performance and reduce memory copies and allocation, we have a staged buffer
+		expansion.
+
+		<UL>
+		<LI> buf.length < 128k - increase by 4k
+		<LI> buf.length < 1Mb - increase by 128k
+		<LI> otherwise increase by 1Mb.
+		</UL>
+
+		In all cases, if minExpansion is greater than the value about then the buffer will
+		be increased by minExtension.
+	*/
+	private void expandBuffer(int minExtension)
+	{
+		if (buf.length < (128 * 1024)) {
+			if (minExtension < INITIAL_SIZE)
+				minExtension = INITIAL_SIZE;
+		} else if (buf.length < (1024 * 1024)) {
+
+			if (minExtension < (128 * 1024))
+				minExtension = (128 * 1024);
+		} else {
+			if (minExtension < (1024 * 1024))
+				minExtension = 1024 * 1024;
+		}
+
+		int newsize = buf.length + minExtension;
+
+		byte[] newbuf = new byte[newsize];
+		System.arraycopy(buf, 0, newbuf, 0, buf.length);
+		buf = newbuf;
+	}
+
+}

Propchange: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/DynamicByteArrayOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/InputStreamUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/InputStreamUtil.java?rev=899733&view=auto
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/InputStreamUtil.java (added)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/InputStreamUtil.java Fri Jan 15 17:54:20 2010
@@ -0,0 +1,183 @@
+/*
+
+   Derby - Class org.apache.derby.shared.common.io.InputStreamUtil
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.shared.common.io;
+
+import java.io.*;
+
+/**
+	Utility methods for InputStream that are stand-ins for
+	a small subset of DataInput methods. This avoids pushing
+	a DataInputStream just to get this functionality.
+*/
+public class InputStreamUtil {
+    private static final int SKIP_FRAGMENT_SIZE = Integer.MAX_VALUE;
+
+	/**
+		Read an unsigned byte from an InputStream, throwing an EOFException
+		if the end of the input is reached.
+
+		@exception IOException if an I/O error occurs.
+		@exception EOFException if the end of the stream is reached
+
+		@see DataInput#readUnsignedByte
+	
+	*/
+	public static int readUnsignedByte(InputStream in) throws IOException {
+		int b = in.read();
+		if (b < 0)
+			throw new EOFException();
+
+		return b;
+	}
+
+	/**
+		Read a number of bytes into an array.
+
+		@exception IOException if an I/O error occurs.
+		@exception EOFException if the end of the stream is reached
+
+		@see DataInput#readFully
+
+	*/
+	public static void readFully(InputStream in, byte b[],
+                                 int offset,
+                                 int len) throws IOException
+	{
+		do {
+			int bytesRead = in.read(b, offset, len);
+			if (bytesRead < 0)
+				throw new EOFException();
+			len -= bytesRead;
+			offset += bytesRead;
+		} while (len != 0);
+	}
+
+
+	/**
+		Read a number of bytes into an array.
+        Keep reading in a loop until len bytes are read or EOF is reached or
+        an exception is thrown. Return the number of bytes read.
+        (InputStream.read(byte[],int,int) does not guarantee to read len bytes
+         even if it can do so without reaching EOF or raising an exception.)
+
+		@exception IOException if an I/O error occurs.
+	*/
+	public static int readLoop(InputStream in,
+                                byte b[],
+                                int offset,
+                                int len)
+        throws IOException
+	{
+        int firstOffset = offset;
+		do {
+			int bytesRead = in.read(b, offset, len);
+			if (bytesRead <= 0)
+                break;
+			len -= bytesRead;
+			offset += bytesRead;
+		} while (len != 0);
+        return offset - firstOffset;
+	}
+
+    /**
+     * Skips until EOF, returns number of bytes skipped.
+     * @param is
+     *      InputStream to be skipped.
+     * @return
+     *      number of bytes skipped in fact.
+     * @throws IOException
+     *      if IOException occurs. It doesn't contain EOFException.
+     * @throws NullPointerException
+     *      if the param 'is' equals null.
+     */
+    public static long skipUntilEOF(InputStream is) throws IOException {
+        if(is == null)
+            throw new NullPointerException();
+
+        long bytes = 0;
+        while(true){
+            long r = skipPersistent(is, SKIP_FRAGMENT_SIZE);
+            bytes += r;
+            if(r < SKIP_FRAGMENT_SIZE)
+                return bytes;
+        }
+    }
+
+    /**
+     * Skips requested number of bytes,
+     * throws EOFException if there is too few bytes in the stream.
+     * @param is
+     *      InputStream to be skipped.
+     * @param skippedBytes
+     *      number of bytes to skip. if skippedBytes <= zero, do nothing.
+     * @throws EOFException
+     *      if EOF meets before requested number of bytes are skipped.
+     * @throws IOException
+     *      if IOException occurs. It doesn't contain EOFException.
+     * @throws NullPointerException
+     *      if the param 'is' equals null.
+     */
+    public static void skipFully(InputStream is, long skippedBytes)
+    throws IOException {
+        if(is == null)
+            throw new NullPointerException();
+
+        if(skippedBytes <= 0)
+            return;
+
+        long bytes = skipPersistent(is, skippedBytes);
+
+        if(bytes < skippedBytes)
+            throw new EOFException();
+    }
+
+    /**
+     * Tries harder to skip the requested number of bytes.
+     * <p>
+     * Note that even if the method fails to skip the requested number of bytes,
+     * it will not throw an exception. If this happens, the caller can be sure
+     * that end-of-stream has been reached.
+     *
+     * @param in byte stream
+     * @param bytesToSkip the number of bytes to skip
+     * @return The number of bytes skipped.
+     * @throws IOException if reading from the stream fails
+     */
+    public static final long skipPersistent(InputStream in, long bytesToSkip)
+    throws IOException {
+        long skipped = 0;
+        while (skipped < bytesToSkip) {
+            long skippedNow = in.skip(bytesToSkip - skipped);
+            if (skippedNow == 0) {
+                if (in.read() == -1) {
+                    // EOF, return what we have and leave it up to caller to
+                    // decide what to do about it.
+                    break;
+                } else {
+                    skippedNow = 1; // Added to count below.
+                }
+            }
+            skipped += skippedNow;
+        }
+        return skipped;
+    }
+}

Propchange: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/io/InputStreamUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/JDBC30Translation.java Fri Jan 15 17:54:20 2010
@@ -22,31 +22,44 @@
 package org.apache.derby.shared.common.reference;
 import java.sql.ParameterMetaData;
 /**
+        <P>
         This class contains public statics that map directly
         to the new public statics in the jdbc 3.0 classes.
         By providing an intermediary class, we can use the
         same statics without having to import the jdbc 3.0 classes
         into other classes.
+        </P>
+
 
+        <P>
+        This class also contains some constants shared by the network server and client.
+        </P>
 
         <P>
         This class should not be shipped with the product.
+        </P>
 
         <P>
         This class has no methods, all it contains are constants
         are public, static and final since they are declared in an interface.
+        </P>
 */
 
 public interface JDBC30Translation {
 
-        /*
-        ** public statics from 3.0 version of java.sql.ParameterMetaData
-        */
-        public static final int PARAMETER_NO_NULLS = ParameterMetaData.parameterNoNulls;
-        public static final int PARAMETER_NULLABLE = ParameterMetaData.parameterNullable;
-        public static final int PARAMETER_NULLABLE_UNKNOWN = ParameterMetaData.parameterNullableUnknown;
-        public static final int PARAMETER_MODE_UNKNOWN = ParameterMetaData.parameterModeUnknown;
-        public static final int PARAMETER_MODE_IN = ParameterMetaData.parameterModeIn;
-        public static final int PARAMETER_MODE_IN_OUT = ParameterMetaData.parameterModeInOut;
-        public static final int PARAMETER_MODE_OUT = ParameterMetaData.parameterModeOut;
+    /*
+    ** public statics from 3.0 version of java.sql.ParameterMetaData
+    */
+    public static final int PARAMETER_NO_NULLS = ParameterMetaData.parameterNoNulls;
+    public static final int PARAMETER_NULLABLE = ParameterMetaData.parameterNullable;
+    public static final int PARAMETER_NULLABLE_UNKNOWN = ParameterMetaData.parameterNullableUnknown;
+    public static final int PARAMETER_MODE_UNKNOWN = ParameterMetaData.parameterModeUnknown;
+    public static final int PARAMETER_MODE_IN = ParameterMetaData.parameterModeIn;
+    public static final int PARAMETER_MODE_IN_OUT = ParameterMetaData.parameterModeInOut;
+    public static final int PARAMETER_MODE_OUT = ParameterMetaData.parameterModeOut;
+
+    // Constants shared by network client and server
+    public static final int DEFAULT_COLUMN_DISPLAY_SIZE = 15;
+    public static final int UNKNOWN_SCALE = 0;
+    public static final int UNKNOWN_PRECISION = 0;
 }

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=899733&r1=899732&r2=899733&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 Fri Jan 15 17:54:20 2010
@@ -1596,6 +1596,8 @@
     String NET_PREMATURE_EOS                                        = "XN017.S";
     String NET_READER_LENGTH_TOO_SMALL                              = "XN018.S";
     String NET_XARETVAL_ERROR                                       = "XN019.S";
+    String NET_MARSHALLING_UDT_ERROR                     = "XN020.S";
+    String NET_UDT_COERCION_ERROR                               = "XN021.S";
     
     // XML - Derby-specific XML errors not covered by
     // SQL standard.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DatabaseMetaDataTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DatabaseMetaDataTest.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DatabaseMetaDataTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DatabaseMetaDataTest.java Fri Jan 15 17:54:20 2010
@@ -14,7 +14,8 @@
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
+   See the License for the specific language go1481
+   verning permissions and
    limitations under the License.
 
  */
@@ -1473,7 +1474,7 @@
      * for a SELECT * from the table. All columns in
      * all tables are checked.
      */
-    public void testGetColumnsReadOnly() throws SQLException
+    public void testGetColumnsReadOnly() throws Exception
     {
         ResultSet[] rs = getColumns(null, null, null, null);
         for ( int j =0 ; j<2 ; j++) {
@@ -1487,7 +1488,7 @@
      * 
      * @throws SQLException
      */
-    public void testGetColumnsModify() throws SQLException {
+    public void testGetColumnsModify() throws Exception {
            
         // skip XML datatype as our cross check with
         // ResultSetMetaData will fail
@@ -1746,7 +1747,7 @@
      */
     private void crossCheckGetColumnsAndResultSetMetaData(ResultSet rs,
             boolean partial, int odbc)
-    throws SQLException
+    throws Exception
     {
         Statement s = createStatement();
         while (rs.next())
@@ -1798,11 +1799,12 @@
      *    in using BUFFER_LENGTH (ODBC) or no(JDBC).
      * @throws SQLException
      */
-    public static void crossCheckGetColumnRowAndResultSetMetaData(
+    public void crossCheckGetColumnRowAndResultSetMetaData(
             ResultSet rs, ResultSetMetaData rsmdt, int odbc)
-        throws SQLException
+        throws Exception
     {
         int col = rs.getInt("ORDINAL_POSITION");
+        Version dataVersion = getDataVersion( getConnection() );
         
         assertEquals("RSMD.getCatalogName",
                 rsmdt.getCatalogName(col), rs.getString("TABLE_CAT"));
@@ -1829,7 +1831,8 @@
             assertEquals("DATA_TYPE",
                     Types.SMALLINT, rsmdt.getColumnType(col));
         }
-        else if (dmdColumnType == Types.JAVA_OBJECT && usingDerbyNetClient())
+        else if (dmdColumnType == Types.JAVA_OBJECT && usingDerbyNetClient()
+                 &&  ( dataVersion.compareTo( new Version( 10, 6, 0, 0 ) ) < 0 ) )
         {
             // DMD returns JAVA_OBJECT
             // RSMD returns LONGVARBINARY!                    

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/junitTests/compatibility/CompatibilityCombinations.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/junitTests/compatibility/CompatibilityCombinations.java?rev=899733&r1=899732&r2=899733&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/junitTests/compatibility/CompatibilityCombinations.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/junitTests/compatibility/CompatibilityCombinations.java Fri Jan 15 17:54:20 2010
@@ -1042,7 +1042,7 @@
             );
             DEBUG("************** Do .start().");
             serverThread.start();
-            pingServer(5); // Wait for the server to come up in a reasonable time....
+            pingServer(1, envElements); // Wait for the server to come up in a reasonable time....
             serverThread.join();
             DEBUG("************** Done .join().");
         }
@@ -1173,27 +1173,32 @@
      * come up in a reasonable amount of time, (re-)throw the
      * final exception.
      * </p>
-     * @param iterations How many times to try pinging the server to see if it is running.
-     * Sleeps <CODE>SLEEP_TIME_MILLIS</CODE> between tries.
+     * @param iterations How many times to try pinging the server to see if it is running. Sleeps <CODE>SLEEP_TIME_MILLIS</CODE> between tries.
+     * @param serverEnvironment Paths used in bringing up server
      * @throws java.lang.Exception .
      */
     // Copied from org.apache.derbyTesting.functionTests.tests.junitTests.compatibility.Pinger
-    private	void	pingServer( int iterations )
+    private	void	pingServer( int iterations, String[] serverEnvironment )
     throws Exception
     {
         DEBUG("+++ pingServer");
-        ping( new NetworkServerControl(), iterations );
+        ping( new NetworkServerControl(), iterations, serverEnvironment );
         DEBUG("--- pingServer");
     }
     
-    
-  private	void	ping( NetworkServerControl controller, int iterations )
+    /**
+     * It used to be possible to ping down-rev servers using an up-rev NetworkServerControl.
+     * This is no longer possible. So we will just take it on faith that the server comes up after
+     * a decent interval.
+     */
+    private	void	ping( NetworkServerControl controller, int iterations, String[] serverEnvironment )
     throws Exception
     {
         Exception	finalException = null;
         
         for ( int i = 0; i < iterations; i++ )
         {
+            /*
             try
             {
                 controller.ping();
@@ -1202,12 +1207,22 @@
             }
             catch (Exception e)
           { finalException = e; }
+            */
             
             Thread.sleep( SLEEP_TIME_MILLIS );
         }
-        
-        System.out.println( "Server did not come up: " + finalException.getMessage() );
+
+        /*
+        StringBuffer buffer = new StringBuffer();
+        buffer.append( "Server did not come up: " + finalException.getMessage() );
+        int pathCount = serverEnvironment.length;
+        for ( int i = 0; i < pathCount; i++ )
+        {
+            buffer.append( "\n\t" + serverEnvironment[ i ] );
+        }
+        System.out.println( buffer.toString() );
         finalException.printStackTrace();
+        */
         
     }
     



Mime
View raw message