db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1517761 - in /db/derby/code/trunk/java/engine/org/apache/derby/iapi: services/io/FormatIdInputStream.java services/io/RegisteredFormatIds.java services/io/StoredFormatIds.java sql/execute/ExecRowBuilder.java
Date Tue, 27 Aug 2013 08:16:01 GMT
Author: kahatlen
Date: Tue Aug 27 08:16:00 2013
New Revision: 1517761

URL: http://svn.apache.org/r1517761
Log:
DERBY-6314: Upgrade from 10.10 fails with ClassCastException

Make ExecRowBuilder implement the Formatable interface so that any
Formatable instances referenced from its fields are stored using
Formatable logic instead of Serializable logic.

Add type checking in FormatIdInputStream's error handlers to prevent
the underlying exception from being shadowed by a ClassCastException
under certain circumstances.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatIdInputStream.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecRowBuilder.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatIdInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatIdInputStream.java?rev=1517761&r1=1517760&r2=1517761&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatIdInputStream.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FormatIdInputStream.java
Tue Aug 27 08:16:00 2013
@@ -27,7 +27,6 @@ import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.StreamCorruptedException;
 import org.apache.derby.iapi.services.monitor.Monitor;
-import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.services.loader.ClassFactory;
 import org.apache.derby.iapi.services.loader.ClassFactoryContext;
@@ -63,7 +62,7 @@ public final class FormatIdInputStream e
 	  Read an object from this stream.
 
 	  @return The read object.
-	  @exception java.io.IOException An IO or serialization error occured.
+      @exception java.io.IOException An IO or serialization error occurred.
 	  @exception java.lang.ClassNotFoundException A class for an object in
 	  the stream could not be found.
 	  */
@@ -94,17 +93,13 @@ public final class FormatIdInputStream e
 					Object result = ois.readObject();
 					return result;
 				} catch (IOException ioe) {
-					setErrorInfo((ErrorInfo) ois);
-					throw ioe;
+                    throw handleReadError(ioe, ois);
 				} catch (ClassNotFoundException cnfe) {
-					setErrorInfo((ErrorInfo) ois);
-					throw cnfe;
+                    throw handleReadError(cnfe, ois);
 				} catch (LinkageError le) {
-					setErrorInfo((ErrorInfo) ois);
-					throw le;
+                    throw handleReadError(le, ois);
 				} catch (ClassCastException cce) {
-					setErrorInfo((ErrorInfo) ois);
-					throw cce;
+                    throw handleReadError(cce, ois);
 				}
 			}
 
@@ -182,6 +177,25 @@ public final class FormatIdInputStream e
         errorInfo = ei;
 	}
 
+    /**
+     * Handle an error that happened within {@code readObject()} when reading
+     * a {@code Serializable} object.
+     *
+     * @param <T> the type of exception that was thrown
+     * @param cause the thrown exception
+     * @param stream the stream from which the exception was thrown
+     * @return the thrown exception
+     */
+    private <T extends Throwable> T handleReadError(
+            T cause, ObjectInputStream stream) {
+        // If the input stream implements the ErrorInfo interface, it contains
+        // extra information about the error, and we want to make that
+        // information available to error handlers on a higher level.
+        if (stream instanceof ErrorInfo) {
+            setErrorInfo((ErrorInfo) stream);
+        }
+        return cause;
+    }
 
     ClassFactory getClassFactory() {
 		if (cf == null) {

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java?rev=1517761&r1=1517760&r2=1517761&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
Tue Aug 27 08:16:00 2013
@@ -328,7 +328,7 @@ private static final    String[] TwoByte
         /* 276 */       null,
         /* 277 */       null,
         /* 278 */       "org.apache.derby.impl.sql.execute.ConstraintInfo",
-        /* 279 */       null,
+        /* 279 */       "org.apache.derby.iapi.sql.execute.ExecRowBuilder",
         /* 280 */       null,
         /* 281 */       null,
         /* 282 */       "org.apache.derby.impl.sql.execute.FKInfo",

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java?rev=1517761&r1=1517760&r2=1517761&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
Tue Aug 27 08:16:00 2013
@@ -1091,6 +1091,9 @@ public interface StoredFormatIds {
     static public final int CONSTRAINT_INFO_V01_ID  =
             (MIN_ID_2 + 278);
 
+    /** Class org.apache.derby.iapi.sql.execute.ExecRowBuilder. */
+    int EXEC_ROW_BUILDER_ID = MIN_ID_2 + 279;
+
     /**
      */
     static public final int UNUSED_2_280 =

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecRowBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecRowBuilder.java?rev=1517761&r1=1517760&r2=1517761&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecRowBuilder.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecRowBuilder.java
Tue Aug 27 08:16:00 2013
@@ -21,37 +21,47 @@
 
 package org.apache.derby.iapi.sql.execute;
 
-import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.io.ArrayUtil;
+import org.apache.derby.iapi.services.io.Formatable;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
 import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 
 /**
+ * <p>
  * A class used for storing information on how to build {@code ExecRow}
  * instances. Typically created by the compiler and used during execution
  * to produce and reset row templates.
+ * </p>
+ *
+ * <p>
+ * This class must be {@code Formatable} so that it can be stored in the
+ * database as part of a stored prepared statement generated for trigger
+ * actions or metadata queries. The stored format does not need to be stable
+ * across different versions, since the stored prepared statements are
+ * discarded on upgrade and will never be read by other Derby versions than
+ * the one that originally wrote them.
+ * </p>
  */
-public class ExecRowBuilder implements Serializable {
-
-    /**
-     * Serial version produced by the serialver utility. Needed in order to
-     * make serialization work reliably across different compilers.
-     */
-    private static final long serialVersionUID = -1078823466492523202L;
+public class ExecRowBuilder implements Formatable {
 
     /** If true, the row should be an {@code ExecIndexRow}. */
-    private final boolean indexable;
+    private boolean indexable;
 
     /**
      * Array of templates used for creating NULL values to put in the row.
      * The templates are either {@code DataValueDescriptor}s or
      * {@code DataTypeDescriptor}s.
      */
-    private final Object[] template;
+    private Object[] template;
 
     /** Array of 1-based column numbers for the columns to access. */
-    private final int[] columns;
+    private int[] columns;
 
     /** The number of columns to set in the row. */
     private int count;
@@ -74,6 +84,13 @@ public class ExecRowBuilder implements S
     }
 
     /**
+     * Public no-arg constructor required by the {@code Formatable} interface.
+     * Should not be called directly.
+     */
+    public ExecRowBuilder() {
+    }
+
+    /**
      * Add a template from which a NULL value of the correct type can be
      * created. It should either be a {@code DataValueDescriptor} or a
      * {@code DataTypeDescriptor}.
@@ -131,4 +148,30 @@ public class ExecRowBuilder implements S
             row.setColumn(col, row.getColumn(col).getNewNull());
         }
     }
+
+    // Methods required by the Formatable interface.
+
+    @Override
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeBoolean(indexable);
+        ArrayUtil.writeArray(out, template);
+        out.writeObject(columns);
+        out.writeInt(count);
+        out.writeInt(maxColumnNumber);
+    }
+
+    @Override
+    public void readExternal(ObjectInput in)
+            throws IOException, ClassNotFoundException {
+        indexable = in.readBoolean();
+        template = ArrayUtil.readObjectArray(in);
+        columns = (int[]) in.readObject();
+        count = in.readInt();
+        maxColumnNumber = in.readInt();
+    }
+
+    @Override
+    public int getTypeFormatId() {
+        return StoredFormatIds.EXEC_ROW_BUILDER_ID;
+    }
 }



Mime
View raw message