problem with the reply-to, so fwd.
--- Begin Message ---
Thanks, that seems reasonable.  I have reviewed the rest and it
looks good.  Once tests pass on my machine I will commit.

Sunitha Kambhampati wrote:

> Mike Matrigali wrote:
> 
>> I am looking at commiting this, one question:
>> o in ReaderToUTF8Stream.java you changed close() to not do a
>> reader.close() - why is this ok?
>>
>>  
>>
> Thanks Mike  for reviewing this patch.
> 
> E.g.: So user application calls the following api to set the stream.
> ps.setCharacterStream(i, mystream, pos)   //mystream is user 's stream.
> 
> Internally, ReaderToUTF8Stream is the stream that wraps the user's
> stream as LimitReader object.    Thus calling reader.close()  will close
> the user's stream and I think that is incorrect. I think it is the
> responsibility of the application to either close the stream or do
> whatever the application wishess and derby should not close the 'user's
> stream' internally.
> 
> E.g.  The user could have passed in a Resetable stream and then after
> the statement execution can reset his stream and use the same object to
> do some other work. If derby closes the user's stream internally, any
> other call on the stream would throw an exception and user is forced to
> create another stream object. .
> 
> Also previously (before this fix), ReaderToUTF8Stream.close() was never
> exercised,but now I believe it correctly does return resources back to
> the VM.
> 
> Sunitha.
> 
>> Sunitha Kambhampati (JIRA) wrote:
>>
>>  
>>
>>>     [ http://issues.apache.org/jira/browse/DERBY-500?page=all ]
>>>
>>> Sunitha Kambhampati updated DERBY-500:
>>> --------------------------------------
>>>
>>>    Attachment: Derby500.diff.txt
>>>
>>> Background :
>>> In Derby, when a stream is set as a parameter value, the wrapper
>>> stream object used for character data is ReaderToUTF8Stream and for
>>> binary data it is RawToBinaryFormatStream.Both these stream objects
>>> on read() return data in a format that is used to store the
>>> respective datatype value. E.g in case of char, the characters read
>>> from the user stream are converted using utf-8 derby specific
>>> encoding and read calls return the data as expected by store layer.
>>> Beginning 2 bytes either have the utflen or has zeroes, or if it is a
>>> long string, then the value is ended with the special marker 0xE0 ,
>>> 0x00, 0x00. For binary data, the stream data is prepended with 4 zeroes.
>>> Problem:
>>> once,the stream has been read fully and end of file reached, further
>>> read() returns a -1.  If a stream is re-read, it returns a -1 which
>>> is incorrect data.  E.g.in the repro for DERBY-500, the update
>>> statement has multiple rows that qualify and since the stream
>>> parameter is used; the first row gets updated with the correct value
>>> and the stream is drained. For the subsequent rows, the read from the
>>> stream parameter value returns -1 and thus is updated with incorrect
>>> data.When retrieving the row back, the format of the fields is
>>> incorrect and thus the exception. __________
>>> This patch
>>>
>>> 1. adds changes to RawToBinaryFormatStream and ReaderToUTF8Stream to
>>> throw an EOFException if stream is re-read.
>>> If a stream value has been fully read and end of file reached, any
>>> further reads on the stream object  will result in an EOFException.
>>> This seems reasonable and more correct than using incorrect values. 
>>> Adds a new error message - 'Stream has already been read and
>>> end-of-file reached and cannot be re-used.'
>>>
>>> 2. changes to RememberBytesInputStream to keep track of the stream
>>> state and not call read on the stream objects once eof is reached.
>>>
>>> 3. Fix a bug in StoredPage.logColumn related to streams. In one
>>> particular scenario, column was not being set to
>>> RememberBytesInputStream object and thus losing the data that would
>>> be read from stream into RememberBytesInputStream.
>>>
>>> 4. adds testcases to store/streamingColumn.java and lang/forbitdata.java
>>>
>>> Also note
>>> - This fix affects cases when a stream is re-used in which case an
>>> exception will be thrown. So code that reads the stream once and
>>> materializes it will not be affected. E.g.  Currently in case of
>>> char,varchar,long varchar, streams are materialized and this will
>>> work fine as before.
>>>
>>>
>>> Ran tests ok on jdk142/win2k (using classes directory)
>>>
>>> svn stat
>>> M     
>>> java\engine\org\apache\derby\impl\jdbc\RawToBinaryFormatStream.java
>>> M      java\engine\org\apache\derby\impl\jdbc\ReaderToUTF8Stream.java
>>> M     
>>> java\engine\org\apache\derby\impl\store\raw\data\RememberBytesInputStream.java
>>>
>>> M      java\engine\org\apache\derby\impl\store\raw\data\StoredPage.java
>>> M      java\engine\org\apache\derby\iapi\reference\SQLState.java
>>> M      java\engine\org\apache\derby\loc\messages_en.properties
>>> M     
>>> java\testing\org\apache\derbyTesting\functionTests\tests\lang\forbitdata.java
>>>
>>> M     
>>> java\testing\org\apache\derbyTesting\functionTests\tests\store\streamingColumn.java
>>>
>>> M     
>>> java\testing\org\apache\derbyTesting\functionTests\master\streamingColumn.out
>>>
>>> M     
>>> java\testing\org\apache\derbyTesting\functionTests\master\forbitdata.out
>>>
>>> I'll add clarifications to the paper - JDBCImplementation.html and
>>> attach it as another patch to this jira entry.
>>>
>>> Can someone please review it. Thanks.
>>>
>>>
>>>
>>>   
>>>
>>>> Update/Select failure when BLOB/CLOB fields updated in several rows
>>>> by PreparedStatement using setBinaryStream and setCharacterStream
>>>> -------------------------------------------------------------------------------------------------------------------------------------
>>>>
>>>>
>>>>        Key: DERBY-500
>>>>        URL: http://issues.apache.org/jira/browse/DERBY-500
>>>>    Project: Derby
>>>>       Type: Bug
>>>> Components: JDBC
>>>>   Versions: 10.1.1.0
>>>> Environment: Windows 2000, java SDK 1.4
>>>>   Reporter: Peter Kovgan
>>>>   Assignee: Sunitha Kambhampati
>>>>    Fix For: 10.1.2.0
>>>> Attachments: Derby500.diff.txt, Derby500.stat.txt
>>>>
>>>> I have table contained BLOB and CLOB fields:
>>>> Create table string is:
>>>> private static final String CREATE = "CREATE TABLE ta (" +
>>>>           "ta_id INTEGER NOT NULL," +
>>>>           "mname VARCHAR( 254 ) NOT NULL," +
>>>>           "mvalue INT NOT NULL," +
>>>>           "mdate DATE NOT NULL," +
>>>>           "bytedata BLOB NOT NULL," +
>>>>           "chardata CLOB NOT NULL," +
>>>>           "PRIMARY KEY ( ta_id ))";
>>>> Then I insert 2000 rows in the table.
>>>> Then I update all 2000 rows by command:
>>>> private static final String UPDATE  =  "UPDATE ta " +
>>>>           "SET bytedata=? ,chardata=? " +
>>>>           "WHERE mvalue=?";
>>>> /**create blob and clob arrays**/
>>>>       int len1 = 10000;//for blob length data
>>>>       int len2 = 15000;//for clob length data
>>>>       byte buf [] = new byte[len1];
>>>>       for(int i=0;i<len1;i++){
>>>>           buf [i] = (byte)45;
>>>>       }
>>>>       ByteArrayInputStream bais = new ByteArrayInputStream(buf);
>>>>             char[] bufc = new char[len2];
>>>>       for (int i = 0; i < bufc.length; i++) {
>>>>           bufc[i] = (char)'b';
>>>>         }
>>>>       CharArrayReader car = new CharArrayReader(bufc);
>>>> /***/
>>>> PreparedStatement pstmt = connection.prepareStatement(UPDATE);
>>>> pstmt.setBinaryStream(1,bais, len1);
>>>> pstmt.setCharacterStream(2,car, len2);
>>>> pstmt.setInt(3,5000);
>>>> int updated =  pstmt.executeUpdate();
>>>> pstmt.close();
>>>> System.out.printlen("updated ="+updated );
>>>> all 2000 rows updated , because I receive output : updated =2000
>>>> But If I run select (SELECT bytedata ,chardata  FROM ta)  after
>>>> update, select failed with error:
>>>> ERROR XSDA7: Restore of a serializable or SQLData object of class ,
>>>> attempted to
>>>> read more data than was originally stored
>>>>       at
>>>> org.apache.derby.iapi.error.StandardException.newException(StandardEx
>>>> ception.java)
>>>>       at
>>>> org.apache.derby.impl.store.raw.data.StoredPage.readRecordFromArray(S
>>>> toredPage.java)
>>>>       at
>>>> org.apache.derby.impl.store.raw.data.StoredPage.restoreRecordFromSlot
>>>> (StoredPage.java)
>>>>       at
>>>> org.apache.derby.impl.store.raw.data.BasePage.fetchFromSlot(BasePage.
>>>> java)
>>>>       at
>>>> org.apache.derby.impl.store.access.conglomerate.GenericScanController
>>>> .fetchRows(GenericScanController.java)
>>>>       at
>>>> org.apache.derby.impl.store.access.heap.HeapScan.fetchNextGroup(HeapS
>>>> can.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.BulkTableScanResultSet.reloadArray(
>>>> BulkTableScanResultSet.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.BulkTableScanResultSet.getNextRowCo
>>>> re(BulkTableScanResultSet.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.NestedLoopJoinResultSet.getNextRowC
>>>> ore(NestedLoopJoinResultSet.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.NestedLoopLeftOuterJoinResultSet.ge
>>>> tNextRowCore(NestedLoopLeftOuterJoinResultSet.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.getNextRow
>>>> Core(ProjectRestrictResultSet.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.SortResultSet.getRowFromResultSet(S
>>>> ortResultSet.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.SortResultSet.getNextRowFromRS(Sort
>>>> ResultSet.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.SortResultSet.loadSorter(SortResult
>>>> Set.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.SortResultSet.openCore(SortResultSe
>>>> t.java)
>>>>       at
>>>> org.apache.derby.impl.sql.execute.BasicNoPutResultSetImpl.open(BasicN
>>>> oPutResultSetImpl.java)
>>>>       at
>>>> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPre
>>>> paredStatement.java)
>>>>       at
>>>> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedState
>>>> ment.java)
>>>>       at
>>>> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Em
>>>> bedPreparedStatement.java)
>>>>       at
>>>> org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(EmbedPrepar
>>>> edStatement.java)
>>>>       at com.beep_beep.dbtest.complex.Benchmark.testSelect(Unknown
>>>> Source)
>>>>       at
>>>> com.beep_beep.dbtest.complex.Benchmark.executeSimplestBigTable(Unknown
>>>> Sour
>>>> ce)
>>>>       at com.beep_beep.dbtest.complex.Benchmark.testBigTable(Unknown
>>>> Source)
>>>>       at
>>>> com.beep_beep.dbtest.complex.Benchmark.executeDegradationBenchmark(Unknown
>>>>
>>>> Source)
>>>>       at com.beep_beep.dbtest.complex.Benchmark.main(Unknown Source)
>>>>     
>>>> From the stack trace and from console I see that Update passed, but
>>>> error was raised in Select after Update.
>>>
>>>   
>>>
>>>> When I try the same update, but with difference(I changed WHERE
>>>> clause, causing update only 1 row):
>>>> private static final String UPDATE  =  "UPDATE ta " +
>>>>           "SET bytedata=? ,chardata=? " +
>>>>           "WHERE mname=?";
>>>> PreparedStatement pstmt = connection.prepareStatement(UPDATE);
>>>> pstmt.setBinaryStream(1,bais, len1);
>>>> pstmt.setCharacterStream(2,car, len2);
>>>> pstmt.setInt(3,"PETER");
>>>> int updated =  pstmt.executeUpdate();
>>>> pstmt.close();
>>>> System.out.printlen("updated ="+updated );
>>>> Only 1 row updated , because I receive output : updated =1
>>>> In this case I have NO errors in select(the same as previous) .
>>>> My assumption:
>>>> It seems that Update receives ByteArrayInputStream and updates
>>>> correctly only 1 row, then all rows updated by some
>>>> incorrect value(may be because ByteArrayInputStream reached its end
>>>> in first update), causing select failure.
>>>> I tested PointBase by the same test and PointBase passed this stage
>>>> without errors, no matter how many rows was updated.
>>>> So I think it is a bug.
>>>> Thank you.
>>>>     
>>>
>>>   
>>
>>
>>  
>>
> 
> 


--- End Message ---

Reply via email to