[
http://issues.apache.org/jira/browse/DERBY-802?page=comments#action_12421121 ]
Fernanda Pizzorno commented on DERBY-802:
-----------------------------------------
I have looked at the patch (derby-802.diff), and I have a few
comments/questions.
In ScrollInsensitiveResultSet you are building an array for mapping the
positions in the original row to the positions on the projected row (origPos).
+ // Array of original position in row
+ final int[] origPos = new int[newRowData.length];
+
+ for (int i=0; i<origPos.length; i++) {
+ origPos[i] = -1 ;
+ }
+
+ // Make the origPos, by brute-force comparison of
identity:
+ for (int i=0; i<newRowData.length; i++) {
+ for (int j=0; j<rowData.length; j++) {
+ if (rowData[j]==newRowData[i]) {
+ origPos[i] = j;
+ break;
+ }
+ }
+ }
[...]
+ for (int i=0; i<origPos.length; i++) {
+ if (origPos[i]>=0) {
+ rowData[origPos[i]] = backedData[i];
+ }
+ }
ProjectRestrictResultSet already contains (projectMapping) a similar array to
the one you are building here (origPos), wouldn't it be better to build this
array in ProjectRestrictRestultSet using "projectMapping" instead of using
brute-force comparison of identity?
Suggestion:
ScrollInsensitiveResultSet:
+ // Array of original position in row
+ int[] origPos =
((ProjectRestrictResultSet)source).getBaseProjectMapping();
[...]
+ for (int i=0; i<origPos.length; i++) {
+ if (origPos[i]>=0) {
+ rowData[origPos[i] - 1] = backedData[i];
+ }
+ }
ProjectRestrictResultSet:
+ public int[] getBaseProjectMapping() {
+ int[] result;
+ if (source instanceof ProjectRestrictResultSet) {
+ result = new int[projectMapping.length];
+ ProjectRestrictResultSet prs = (ProjectRestrictResultSet) source;
+ int[] sourceMap = prs.getBaseProjectMapping();
+ for (int i=0; i<projectMapping.length; i++) {
+ if (projectMapping[i] > 0) {
+ result[i] = sourceMap[projectMapping[i] - 1];
+ }
+ }
+ } else {
+ result = projectMapping;
+ }
+ return result;
+ }
I have also looked into the tests added in DERBY-1477 and I found out that
neither of them use projection. Since part of the changes made in DERBY-802 are
for cases where you have a projection, it would be nice if you could add some
tests where projections where being used.
> OutofMemory Error when reading large blob when statement type is
> ResultSet.TYPE_SCROLL_INSENSITIVE
> --------------------------------------------------------------------------------------------------
>
> Key: DERBY-802
> URL: http://issues.apache.org/jira/browse/DERBY-802
> Project: Derby
> Issue Type: Bug
> Components: JDBC
> Affects Versions: 10.0.2.0, 10.0.2.1, 10.1.1.0, 10.1.1.1, 10.1.1.2,
> 10.1.2.0, 10.1.2.1, 10.2.0.0, 10.1.3.0, 10.1.2.2, 10.0.2.2
> Environment: all
> Reporter: Sunitha Kambhampati
> Assigned To: Andreas Korneliussen
> Priority: Minor
> Attachments: derby-802.diff, derby-802.stat, derby-802v2.diff
>
>
> Grégoire Dubois on the list reported this problem. From his mail: the
> reproduction is attached below.
> When statement type is set to ResultSet.TYPE_SCROLL_INSENSITIVE, outofmemory
> exception is thrown when reading large blobs.
> import java.sql.*;
> import java.io.*;
> /**
> *
> * @author greg
> */
> public class derby_filewrite_fileread {
>
> private static File file = new
> File("/mnt/BigDisk/Clips/BabyMamaDrama-JShin.wmv");
> private static File destinationFile = new
> File("/home/greg/DerbyDatabase/"+file.getName());
>
> /** Creates a new instance of derby_filewrite_fileread */
> public derby_filewrite_fileread() {
>
> }
>
> public static void main(String args[]) {
> try {
>
> Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
> Connection connection = DriverManager.getConnection
> ("jdbc:derby:/home/greg/DerbyDatabase/BigFileTestDB;create=true", "APP", "");
> connection.setAutoCommit(false);
>
> Statement statement =
> connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
> ResultSet.CONCUR_READ_ONLY);
> ResultSet result = statement.executeQuery("SELECT TABLENAME FROM
> SYS.SYSTABLES");
>
> // Create table if it doesn't already exists.
> boolean exist=false;
> while ( result.next() ) {
> if ("db_file".equalsIgnoreCase(result.getString(1)))
> exist=true;
> }
> if ( !exist ) {
> System.out.println("Create table db_file.");
> statement.execute("CREATE TABLE db_file ("+
> " name VARCHAR(40),"+
> " file BLOB(2G) NOT
> NULL)");
> connection.commit();
> }
>
> // Read file from disk, write on DB.
> System.out.println("1 - Read file from disk, write on DB.");
> PreparedStatement
> preparedStatement=connection.prepareStatement("INSERT INTO db_file(name,file)
> VALUES (?,?)");
> FileInputStream fileInputStream = new FileInputStream(file);
> preparedStatement.setString(1, file.getName());
> preparedStatement.setBinaryStream(2, fileInputStream,
> (int)file.length());
> preparedStatement.execute();
> connection.commit();
> System.out.println("2 - END OF Read file from disk, write on
> DB.");
>
>
> // Read file from DB, and write on disk.
> System.out.println("3 - Read file from DB, and write on disk.");
> result = statement.executeQuery("SELECT file FROM db_file WHERE
> name='"+file.getName()+"'");
> byte[] buffer = new byte [1024];
> result.next();
> BufferedInputStream inputStream=new
> BufferedInputStream(result.getBinaryStream(1),1024);
> FileOutputStream outputStream = new
> FileOutputStream(destinationFile);
> int readBytes = 0;
> while (readBytes!=-1) {
> readBytes=inputStream.read(buffer,0,buffer.length);
> if ( readBytes != -1 )
> outputStream.write(buffer, 0, readBytes);
> }
> inputStream.close();
> outputStream.close();
> System.out.println("4 - END OF Read file from DB, and write on
> disk.");
> }
> catch (Exception e) {
> e.printStackTrace(System.err);
> }
> }
> }
> It returns
> 1 - Read file from disk, write on DB.
> 2 - END OF Read file from disk, write on DB.
> 3 - Read file from DB, and write on disk.
> java.lang.OutOfMemoryError
> if the file is ~10MB or more
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira