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 "Oyvind Bakksjo (JIRA)" <de...@db.apache.org> on 2005/08/12 17:27:54 UTC

[jira] Created: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Implement Statement.setQueryTimeout in the Client Driver
--------------------------------------------------------

         Key: DERBY-506
         URL: http://issues.apache.org/jira/browse/DERBY-506
     Project: Derby
        Type: New Feature
  Components: JDBC  
    Versions: 10.1.1.0    
    Reporter: Oyvind Bakksjo
 Assigned to: Oyvind Bakksjo 


Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.

For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:

* If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
* In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
* In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


Re: [jira] Created: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by Oy...@Sun.COM.
David Van Couvering wrote:
> Hi, Oyvind, you may have already done this, but can you linke this to 
> DERBY-310?

That was my intention, yes. Thanks for reminding me. :) Done now.

-- 
Øyvind Bakksjø
Sun Microsystems, Database Technology Group
Haakon VII gt. 7b, N-7485 Trondheim, Norway
Tel: x43419 / +47 73842119, Fax: +47 73842101

Re: [jira] Created: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by David Van Couvering <Da...@Sun.COM>.
Hi, Oyvind, you may have already done this, but can you linke this to 
DERBY-310?

Thanks,

David

Oyvind Bakksjo (JIRA) wrote:

>Implement Statement.setQueryTimeout in the Client Driver
>--------------------------------------------------------
>
>         Key: DERBY-506
>         URL: http://issues.apache.org/jira/browse/DERBY-506
>     Project: Derby
>        Type: New Feature
>  Components: JDBC  
>    Versions: 10.1.1.0    
>    Reporter: Oyvind Bakksjo
> Assigned to: Oyvind Bakksjo 
>
>
>Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
>
>For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
>
>* If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
>* In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
>* In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 
>
>  
>

[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Satheesh Bandaram (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12357725 ] 

Satheesh Bandaram commented on DERBY-506:
-----------------------------------------

Thanks Oyvind for removing QueryTimerTask.java. Thanks Army and Oyvind for pointing out that unrecognized SET statements raise a warning... While not unpleasant, might confuse some users who actually look at warnings. But only under mixed setup, 10.2 or higher client talking to 10.1 or lower servers. No biggie, either way! 

Thanks Oyvind for updating the docs too... How did you figure that out ...:)

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Updated: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-506?page=all ]

Oyvind Bakksjo updated DERBY-506:
---------------------------------

    Attachment: DERBY-506.status

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Updated: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-506?page=all ]

Oyvind Bakksjo updated DERBY-506:
---------------------------------

    Attachment:     (was: DERBY-506_PRE.diff)

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo

>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12357680 ] 

Oyvind Bakksjo commented on DERBY-506:
--------------------------------------

Answers to Satheesh:

1) You're right, I'll remove this class.
2) As Army pointed out in his mail, unrecognized SET statements simply cause a warning to be generated.

Thank you for reviewing the patch.

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12331512 ] 

Kathey Marsden commented on DERBY-506:
--------------------------------------

I think the EXCSQLSET is a good way to go but would  prefer to see it made as a call with setQueryTimeout  when the JDBC call is made instead of being resent with each Statement execution. The SET statement would then need to send the package name and section number for the Statement.  

The trouble that I see with this approach as things stand now is that I think  the statement table currently includes the package name, section number, and consistency token.  The consistency token is non-ascii and so would cause problems with our SET statement, but I really think that the statement lookup could be changed to not include the consistiency token.  I  think that the package name and section number are unique for each open statement, but this should be verified.


This mechanism could also be used for setMaxRows.


> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506_PRE.diff
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


Re: [jira] Updated: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by Oy...@Sun.COM.
Oyvind Bakksjo (JIRA) wrote:
>      [ http://issues.apache.org/jira/browse/DERBY-506?page=all ]
> 
> Oyvind Bakksjo updated DERBY-506:
> ---------------------------------
> 
>     Attachment: DERBY-506_PRE.diff

I'd like to get some feedback on this approach. Since the DRDA protocol 
doesn't have any field for the query timeout, it's a bit of a hack (the 
approach is described in the JIRA issue).

The patch itself is very small and simple, so please have a look if 
you're interested. All feedback is appreciated.

-- 
Oyvind Bakksjo
Sun Microsystems, Database Technology Group
Trondheim, Norway
http://weblogs.java.net/blog/bakksjo/

[jira] Updated: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-506?page=all ]

Oyvind Bakksjo updated DERBY-506:
---------------------------------

    Attachment: DERBY-506_PRE.diff

This patch is not intended for inclusion, it just illustrates the idea and is a basis for discussion about the approach.

The patch enables setQueryTimeout() for prepared update statements in the client driver.

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506_PRE.diff
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12357682 ] 

Oyvind Bakksjo commented on DERBY-506:
--------------------------------------

Deleting       java/client/org/apache/derby/client/am/QueryTimerTask.java
 
Committed revision 344344.


> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12331738 ] 

Oyvind Bakksjo commented on DERBY-506:
--------------------------------------

I understand your points, but with regards to setQueryTimeout(), I honestly think you're making too much of this. ;-) To make my point clearer, I don't (logically) think of the setQueryTimeout call as a separate request which gets queued, it's just setting an attribute of a statement before it is executed. Without the execute, setting the attribute has no meaning, so it is ok to flow the attribute together with the execute request. I don't see any issues with keeping client and server in sync, and the only error message related to the setQueryTimeout call we need to handle is if the user supplies a negative value.

Consider this:

PreparedStatement ps = connection.prepareStatement(SQL);
ps.setMaxFieldSize(512);
ps.setMaxRows(100);
ps.setFetchDirection(ResultSet.FETCH_FORWARD);
ps.setFetchSize(10);
ps.setQueryTimeout(10);
while (condition) {
    ....
    ResultSet rs = ps.execute();
    ....
}

None of the other setX() calls result in a round trip to the server. The difference, as I see it, is simply that the DRDA protocol does not have a field for the timeout attribute (the protocol does not target JDBC, and SQL has no such attribute for statements). This is what forces my slight "abuse" of EXCSQLSET for transferring the attribute to the server.

I really think extra round trips are a big deal in terms of performance, so I would prefer to avoid that. We have done some in-house performance comparisons with other open source databases and discovered that Derby uses more round trips per transaction than the others, and that this actually matters.

My point with unprepared statements is that you cannot send a timeout value in an separate round trip and bind it to a statement which hasn't reached the server yet, it has to flow with the execute operation. And yes, I know unprepared statements use EXCSQLIMM, so I'll have to add the EXCSQLSET to this operation as well (the patch I have attached was just meant to illustrate the approach, it's not complete).

In my opinion, setQueryTImeout is relevant to all kinds of DML statements, not just selects. (We already had a discussion about the semantics for timeout, what it should apply to etc.)

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506_PRE.diff
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12331714 ] 

Oyvind Bakksjo commented on DERBY-506:
--------------------------------------

Sending the EXCSQLSET when the JDBC call [to Statement.setQueryTimeout()] is made would cause an additional round-trip between the client and the server, which is what I was trying to avoid by piggybacking the execute flow. Are you concerned with the extra bytes sent during the execute call? For a prepared statement, we only need to transmit the timeout once; for the first execute (or if the timeout is changed with a subsequent call to setQueryTimeout() on the client side). In code like the example below, we would only need to piggyback the execute message for the first iteration, thus avoiding both an extra round-trip and message overhead.

PreparedStatement ps = connection.prepareStatement(SQL);
ps.setQueryTimeout(TIMEOUT);
while (condition) {
    ps.execute();
    ....
}

Have I understood you correctly, or do you have other concerns that makes you prefer transmitting the timeout at the JDBC call time? By the way, is that viable for unprepared statements (the server does not yet know about the statement for which the client sets a timeout)?

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506_PRE.diff
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Resolved: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-506?page=all ]
     
Oyvind Bakksjo resolved DERBY-506:
----------------------------------

    Resolution: Fixed

Had to disable some testing because of DERBY-694

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


Re: [jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by Army <qo...@sbcglobal.net>.
Satheesh Bandaram (JIRA) wrote:

>     2) What would happen if a 10.2 client tries to send a SET STATEMENT_TIMEOUT 
> statement to a 10.1 server? There doesn't seem to be any mechanism to prevent 
> unpleasant events.

I was reviewing the patch and decided to look into your question more, and I 
think there is actually code there to catch this.  The choice of a "SET ..." 
syntax was a good one in this particular case: there is already code in 
DRDAConnThread that looks for "SET ..." statements that are included as part of 
an EXCSQLSET command, and if the statement isn't recognized, the server will 
simply return a warning and ignore it.  The code that does this is in the 
"parseEXCSQLSETobjects()" method:

...

	try {
		drdaStmt.getStatement().executeUpdate(sqlStmt);
	} catch (SQLException e) {

		// if this is a syntax error, then we take it
		// to mean that the given SET statement is not
		// recognized; take note (so we can throw a
		// warning later), but don't interfere otherwise.
		if (e.getSQLState().equals(SYNTAX_ERR))
			hadUnrecognizedStmt = true;
		else
		// something else; assume it's serious.
			throw e;
	}
	break;

...

	// Now that we've processed all SET statements (assuming no
	// severe exceptions), check for warnings and, if we had any,
	// note this in the SQLCARD reply object (but DON'T cause the
	// EXCSQLSET statement to fail).
	if (hadUnrecognizedStmt) {
		SQLWarning warn = new SQLWarning("One or more SET statements " +
			"not recognized.", "01000");
		throw warn;
	} // end if.

...

To confirm, I tried to run jdbcapi/SetQueryTimeoutTest from a client that had 
the patch applied against a server that did not.  The result was the following 
diff, which looks correct to me:

 > Test SetQueryTimeoutTest FAILED
 > 
org.apache.derbyTesting.functionTests.tests.jdbcapi.SetQueryTimeoutTest$TestFailedException: 
fetch did not time out. Highest execution time: 7000 ms

In other words, the call to "SET QUERY_TIMEOUT" failed with a syntax error and 
was ignored, and thus the statement never timed out.

Does that sound correct?
Army


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Satheesh Bandaram (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12357610 ] 

Satheesh Bandaram commented on DERBY-506:
-----------------------------------------

Thanks for the useful and good patch!! I did a quick review of the code and have couple of comments:

   1) Is there any need to keep the am/QueryTimerTask.java still? Since there doesn't seem to be any users of this, may be this class could be dropped?
    2) What would happen if a 10.2 client tries to send a SET STATEMENT_TIMEOUT statement to a 10.1 server? There doesn't seem to be any mechanism to prevent unpleasant events.


> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12331742 ] 

Kathey Marsden commented on DERBY-506:
--------------------------------------


I see your point about  it being similar to the other attributes.   Your approach sounds ok to me then, especially  since there is just a single error condition which needs to be duplicated on the client.  

 I only make a bit much of the general point because I have spent many, many, many,  many, many  cycles in the past dealing with issues created by  roundtrip optimization.  In general I think a thin client is best and the confusion and bugs created by such optimizations is rarely worth it, but that is just a general philosophy thing that is not related to this change.


> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506_PRE.diff
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Updated: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-506?page=all ]

Oyvind Bakksjo updated DERBY-506:
---------------------------------

    Attachment: DERBY-506.diff

Diff from revision 332067.

> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12331730 ] 

Kathey Marsden commented on DERBY-506:
--------------------------------------

My experience with  client side code that has tried to do this in past is that it has historically caused trouble.    Common issues with this approach.

1) The error messages don't make sense because they are delayed.  The embedded call to the corresponding client method  happens when the statement is executed and any related exception will happen at that  time.   Not really in keeping with JDBC, embedded compatibility or user expectations.  

2)  The client has to have a lot of code to make sure it recovers  properly and keeps the proper state.     For instance if the first statement executed fails for some reason, is the queued method really going to be executed? Will server and client be in sync?   Maybe so in this case but I know with XA there were really big problems with client code that tried to keep track of the server's XA state.  

3) Queued up client requests are really hard to debug for everyone but the person who put  that code in the first place because the execution is so far removed from the place where it was expected.

Perhaps for setQueryTimeout these are not issues, but it is just a single round trip per setQueryTimeout call,  so I don't think queing up requests really buys us a whole lot here in terms of performance.  All that said I realize it is extra work to change the statement lookup, so I am not strongly against your change as long as the three issues above have been considered.  In general though I think  queuing up the protocol for multiple JDBC calls on the client side is bad news.

Regarding uprepared statements, I think the implications are the same with the queued approach or sending the EXCSQLSET with the JDBC call. Unprepared update/delete/insert goes through EXCSQLIMM rather than EXCSQLSTT, so would not be covered by  sending the EXCSQLSET with  EXCSQLSTT. Selects even those not prepared in JDBC,  go the PRPSQLSTT-> EXCSQLSTT route.    Is setQueryTimout relevant to statements other than selects?



> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506_PRE.diff
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Closed: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-506?page=all ]
     
Oyvind Bakksjo closed DERBY-506:
--------------------------------


> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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


[jira] Commented: (DERBY-506) Implement Statement.setQueryTimeout in the Client Driver

Posted by "Oyvind Bakksjo (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-506?page=comments#action_12357597 ] 

Oyvind Bakksjo commented on DERBY-506:
--------------------------------------

Sending        java/client/org/apache/derby/client/am/PreparedStatement.java
Sending        java/client/org/apache/derby/client/am/Statement.java
Sending        java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
Sending        java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude
Sending        java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SetQueryTimeoutTest.java
Transmitting file data .....
Committed revision 344147.


> Implement Statement.setQueryTimeout in the Client Driver
> --------------------------------------------------------
>
>          Key: DERBY-506
>          URL: http://issues.apache.org/jira/browse/DERBY-506
>      Project: Derby
>         Type: New Feature
>   Components: JDBC
>     Versions: 10.1.1.0
>     Reporter: Oyvind Bakksjo
>     Assignee: Oyvind Bakksjo
>  Attachments: DERBY-506.diff, DERBY-506.status
>
> Currently, the Embedded Driver supports Statement.setQueryTimeout(), but the Client Driver does not. The Client Driver should be enhanced and match the Embedded Driver.
> For this, we need to transfer the timeout value from the client to the server, preferably without a separate round-trip. I have some loose thoughts on how to do this:
> * If the client has set a timeout value for a statement, prepend the (DRDA) EXCSQLSTT command with an EXCSQLSET command which contains the timeout value; conceptually a "SET STATEMENT TIMEOUT <seconds>" (this does not mean that we need to extend the Derby grammar; only the Network Server needs to understand this DRDA EXCSQLSET command).
> * In DRDAConnThread.parseEXCSQLSETobjects() on the server side, recognize the "SET STATEMENT TIMEOUT" text, parse the timeout value and remember it for the coming EXCSQLSTT command. Do NOT invoke executeUpdate() with the SET statement [see note below].
> * In DRDAConnThread.parseEXCSQLSTT(), check if a timeout value has been set; if so, use it (by setting the timeout value on the server-side Statement object before calling execute/executeQuery). 

-- 
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