You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by "Kristian Waagan (JIRA)" <ji...@apache.org> on 2008/02/26 11:09:51 UTC

[jira] Created: (DERBY-3469) Clob.length() doesn't detect a closed underlying connection in a consistent way

Clob.length() doesn't detect a closed underlying connection in a consistent way
-------------------------------------------------------------------------------

                 Key: DERBY-3469
                 URL: https://issues.apache.org/jira/browse/DERBY-3469
             Project: Derby
          Issue Type: Bug
          Components: JDBC, Network Client
    Affects Versions: 10.3.2.1, 10.4.0.0
         Environment: Client-driver
            Reporter: Kristian Waagan
            Priority: Minor


Depending on the state of the Clob, the method length gives two different SQL states when the underlying connection has been closed.
According to BlobClob4BlobTest.testClobAfterConnectionClose, it should throw 08003 (no current connection), but it might also throw XJ215 (invalid lob).

I think this is caused indirectly by the following method in Lob:
    long sqlLength() throws SqlException 
    {
        if (lengthObtained_) return sqlLength_;
        
        if (isLocator()) {
            sqlLength_ = getLocatorLength();
            lengthObtained_ = true;
        } else if (willBeLayerBStreamed()) {
            throw new SqlException(agent_.logWriter_,
                                   LOB_OBJECT_LENGTH_UNKNOWN_YET);
        } else {
            materializeStream();  // Will set sqlLength_
        }

        return sqlLength_;
    }

In this method, getLocatorLength will check for a closed connection (somewhere down in prepareCallX i believe), whereas the cached length is returned if it has already been determined. Clob.length does not check for a closed connection.
There are multiple fixes, but I think a proper investigation should be carried out before a solution is chosen. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (DERBY-3469) Clob.length() doesn't detect a closed underlying connection in a consistent way

Posted by "Kristian Waagan (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/DERBY-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Kristian Waagan updated DERBY-3469:
-----------------------------------

    Attachment: ClosedClobTest.java

Attached a very simple repro ('ClosedClobTest.java').
To use it with the client driver, you must do two things:
 1) Start you own network server.
 2) Supply an argument to the repro (doesn't matter what it is)

Sorry for the rather bad quality of the repro, but it should demonstrate the problem.
Note that you must comment/uncomment the various parts to run the different scenarios.

> Clob.length() doesn't detect a closed underlying connection in a consistent way
> -------------------------------------------------------------------------------
>
>                 Key: DERBY-3469
>                 URL: https://issues.apache.org/jira/browse/DERBY-3469
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions: 10.3.2.1, 10.4.0.0
>         Environment: Client-driver
>            Reporter: Kristian Waagan
>            Priority: Minor
>         Attachments: ClosedClobTest.java
>
>
> Depending on the state of the Clob, the method length gives two different SQL states when the underlying connection has been closed.
> According to BlobClob4BlobTest.testClobAfterConnectionClose, it should throw 08003 (no current connection), but it might also throw XJ215 (invalid lob).
> I think this is caused indirectly by the following method in Lob:
>     long sqlLength() throws SqlException 
>     {
>         if (lengthObtained_) return sqlLength_;
>         
>         if (isLocator()) {
>             sqlLength_ = getLocatorLength();
>             lengthObtained_ = true;
>         } else if (willBeLayerBStreamed()) {
>             throw new SqlException(agent_.logWriter_,
>                                    LOB_OBJECT_LENGTH_UNKNOWN_YET);
>         } else {
>             materializeStream();  // Will set sqlLength_
>         }
>         return sqlLength_;
>     }
> In this method, getLocatorLength will check for a closed connection (somewhere down in prepareCallX i believe), whereas the cached length is returned if it has already been determined. Clob.length does not check for a closed connection.
> There are multiple fixes, but I think a proper investigation should be carried out before a solution is chosen. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (DERBY-3469) Clob.length() doesn't detect a closed underlying connection in a consistent way

Posted by "Kristian Waagan (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/DERBY-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Kristian Waagan updated DERBY-3469:
-----------------------------------

    Attachment: ClosedClobTest.java

Output from a version with inconsistent behavior:
----- Test case 1
Get clob, get length, get substring, close connection, get length again.
Expect to get exception at the last length call.
#
Clob length: 8
Clob content: a string
Clob length: 8
FAILURE! No exception thrown.
----- Test case 2
No autocommit, get clob, get length, get substring, free clob, get length again.
Expect to get exception at the last length call.
#
Clob length: 8
Clob content: a string
EXCEPTION! (expected)
You cannot invoke other java.sql.Clob/java.sql.Blob methods after calling the free() method or after the Blob/Clob's transaction has been committed or rolled back.
----- Test case 3
Get clob, get length, get substring, get length, commit & close, free clob.
Expect to get exception when calling free.
#
Clob length: 8
Clob content: a string
EXCEPTION! (expected)
No current connection.

Expect all exceptions to be 'No current connection'
REPRO FAILURE!!


Output from a version with consistent behavior:
----- Test case 1
Get clob, get length, get substring, close connection, get length again.
Expect to get exception at the last length call.
#
Clob length: 8
Clob content: a string
EXCEPTION! (expected)
No current connection.
----- Test case 2
No autocommit, get clob, get length, get substring, free clob, get length again.
Expect to get exception at the last length call.
#
Clob length: 8
Clob content: a string
EXCEPTION! (expected)
No current connection.
----- Test case 3
Get clob, get length, get substring, get length, commit & close, free clob.
Expect to get exception when calling free.
#
Clob length: 8
Clob content: a string
EXCEPTION! (expected)
No current connection.

Expect all exceptions to be 'No current connection'
REPRO SUCCESS!!


> Clob.length() doesn't detect a closed underlying connection in a consistent way
> -------------------------------------------------------------------------------
>
>                 Key: DERBY-3469
>                 URL: https://issues.apache.org/jira/browse/DERBY-3469
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions: 10.3.2.1, 10.4.1.3
>         Environment: Client-driver
>            Reporter: Kristian Waagan
>            Priority: Minor
>         Attachments: ClosedClobTest.java, ClosedClobTest.java
>
>
> Depending on the state of the Clob, the method length gives two different SQL states when the underlying connection has been closed.
> According to BlobClob4BlobTest.testClobAfterConnectionClose, it should throw 08003 (no current connection), but it might also throw XJ215 (invalid lob).
> I think this is caused indirectly by the following method in Lob:
>     long sqlLength() throws SqlException 
>     {
>         if (lengthObtained_) return sqlLength_;
>         
>         if (isLocator()) {
>             sqlLength_ = getLocatorLength();
>             lengthObtained_ = true;
>         } else if (willBeLayerBStreamed()) {
>             throw new SqlException(agent_.logWriter_,
>                                    LOB_OBJECT_LENGTH_UNKNOWN_YET);
>         } else {
>             materializeStream();  // Will set sqlLength_
>         }
>         return sqlLength_;
>     }
> In this method, getLocatorLength will check for a closed connection (somewhere down in prepareCallX i believe), whereas the cached length is returned if it has already been determined. Clob.length does not check for a closed connection.
> There are multiple fixes, but I think a proper investigation should be carried out before a solution is chosen. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (DERBY-3469) Clob.length() doesn't detect a closed underlying connection in a consistent way

Posted by "V.Narayanan (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/DERBY-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12586387#action_12586387 ] 

V.Narayanan commented on DERBY-3469:
------------------------------------

This issue will have unexpected ramifications for the update sensitive Clob and Blob streams.

The update sensitive streams upon creation depend on the sqlLength() method to determine the
validity of the underlying Lob. If the sqlLength method returns the cached length value these
streams will not fail upon creation (getBinaryStream() and other methods) but when a read or
write is called upon them. I think they should uniformly fail when getBinaryStream() is called.

A easy way I can think of resolving this problem is to reset the "lengthObtained_" boolean, when
free(). This would ensure that the cached value is not used after a free is called.

I would design this by introducing a free() method in Lob and setting lengthObtained_=false in that
method and do a super.free() in the free methods of am/Clob and am/Blob.

I have not tested this solution yet, but it seems OK to me at first look.

> Clob.length() doesn't detect a closed underlying connection in a consistent way
> -------------------------------------------------------------------------------
>
>                 Key: DERBY-3469
>                 URL: https://issues.apache.org/jira/browse/DERBY-3469
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions: 10.3.2.1, 10.4.0.0
>         Environment: Client-driver
>            Reporter: Kristian Waagan
>            Priority: Minor
>         Attachments: ClosedClobTest.java
>
>
> Depending on the state of the Clob, the method length gives two different SQL states when the underlying connection has been closed.
> According to BlobClob4BlobTest.testClobAfterConnectionClose, it should throw 08003 (no current connection), but it might also throw XJ215 (invalid lob).
> I think this is caused indirectly by the following method in Lob:
>     long sqlLength() throws SqlException 
>     {
>         if (lengthObtained_) return sqlLength_;
>         
>         if (isLocator()) {
>             sqlLength_ = getLocatorLength();
>             lengthObtained_ = true;
>         } else if (willBeLayerBStreamed()) {
>             throw new SqlException(agent_.logWriter_,
>                                    LOB_OBJECT_LENGTH_UNKNOWN_YET);
>         } else {
>             materializeStream();  // Will set sqlLength_
>         }
>         return sqlLength_;
>     }
> In this method, getLocatorLength will check for a closed connection (somewhere down in prepareCallX i believe), whereas the cached length is returned if it has already been determined. Clob.length does not check for a closed connection.
> There are multiple fixes, but I think a proper investigation should be carried out before a solution is chosen. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (DERBY-3469) Clob.length() doesn't detect a closed underlying connection in a consistent way

Posted by "Kristian Waagan (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/DERBY-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Kristian Waagan updated DERBY-3469:
-----------------------------------

    Affects Version/s: 10.5.0.0
             Assignee: Tiago R. Espinha

Updating affects version and assigning to Tiago, as he fixed DERBY-3574 which also fixes this issue.

> Clob.length() doesn't detect a closed underlying connection in a consistent way
> -------------------------------------------------------------------------------
>
>                 Key: DERBY-3469
>                 URL: https://issues.apache.org/jira/browse/DERBY-3469
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions: 10.3.2.1, 10.4.1.3, 10.5.0.0
>         Environment: Client-driver
>            Reporter: Kristian Waagan
>            Assignee: Tiago R. Espinha
>            Priority: Minor
>         Attachments: ClosedClobTest.java, ClosedClobTest.java
>
>
> Depending on the state of the Clob, the method length gives two different SQL states when the underlying connection has been closed.
> According to BlobClob4BlobTest.testClobAfterConnectionClose, it should throw 08003 (no current connection), but it might also throw XJ215 (invalid lob).
> I think this is caused indirectly by the following method in Lob:
>     long sqlLength() throws SqlException 
>     {
>         if (lengthObtained_) return sqlLength_;
>         
>         if (isLocator()) {
>             sqlLength_ = getLocatorLength();
>             lengthObtained_ = true;
>         } else if (willBeLayerBStreamed()) {
>             throw new SqlException(agent_.logWriter_,
>                                    LOB_OBJECT_LENGTH_UNKNOWN_YET);
>         } else {
>             materializeStream();  // Will set sqlLength_
>         }
>         return sqlLength_;
>     }
> In this method, getLocatorLength will check for a closed connection (somewhere down in prepareCallX i believe), whereas the cached length is returned if it has already been determined. Clob.length does not check for a closed connection.
> There are multiple fixes, but I think a proper investigation should be carried out before a solution is chosen. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Closed: (DERBY-3469) Clob.length() doesn't detect a closed underlying connection in a consistent way

Posted by "Kristian Waagan (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/DERBY-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Kristian Waagan closed DERBY-3469.
----------------------------------

       Resolution: Fixed
    Fix Version/s: 10.5.0.0
                   10.4.1.4

Closing issue. See DERBY-3574 for revision numbers.
Ran regression tests on the 10.4 branch and trunk, and the repro succeeds on both 10.4 and trunk.

> Clob.length() doesn't detect a closed underlying connection in a consistent way
> -------------------------------------------------------------------------------
>
>                 Key: DERBY-3469
>                 URL: https://issues.apache.org/jira/browse/DERBY-3469
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions: 10.3.2.1, 10.4.1.3, 10.5.0.0
>         Environment: Client-driver
>            Reporter: Kristian Waagan
>            Assignee: Tiago R. Espinha
>            Priority: Minor
>             Fix For: 10.4.1.4, 10.5.0.0
>
>         Attachments: ClosedClobTest.java, ClosedClobTest.java
>
>
> Depending on the state of the Clob, the method length gives two different SQL states when the underlying connection has been closed.
> According to BlobClob4BlobTest.testClobAfterConnectionClose, it should throw 08003 (no current connection), but it might also throw XJ215 (invalid lob).
> I think this is caused indirectly by the following method in Lob:
>     long sqlLength() throws SqlException 
>     {
>         if (lengthObtained_) return sqlLength_;
>         
>         if (isLocator()) {
>             sqlLength_ = getLocatorLength();
>             lengthObtained_ = true;
>         } else if (willBeLayerBStreamed()) {
>             throw new SqlException(agent_.logWriter_,
>                                    LOB_OBJECT_LENGTH_UNKNOWN_YET);
>         } else {
>             materializeStream();  // Will set sqlLength_
>         }
>         return sqlLength_;
>     }
> In this method, getLocatorLength will check for a closed connection (somewhere down in prepareCallX i believe), whereas the cached length is returned if it has already been determined. Clob.length does not check for a closed connection.
> There are multiple fixes, but I think a proper investigation should be carried out before a solution is chosen. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.