11 Replies Latest reply on Sep 24, 2012 10:26 AM by markaddleman

    ResultSet.isLast() blocks with submitExecute under non-continuous mode?

    markaddleman

      I am executing a query using submitExecute(StatementCallback) under non-continuous mode.  In the onRow() method of the callback, I execute ResultSet.isLast().  The query is against an execution whose next() method initially throws DataNotAvailable.NO_POLLING.  Some time later, it calls ExecutionContext.dataAvailable().  After 255 rows reported through the callback's onRow(), ResultSet.isLast() hangs.

       

      I know that the entire result set is ultimately returned from the execution's next() and it returns null at the last call.

       

      Naively, I wouldn't expect ResultSet.isLast() to block in this case.  Am I missing something?

        • 1. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
          markaddleman

          A bit more info:

           

          Using reflection hackery, I'm substituting the ResultSet.isLast() call with BatchResults.hasNext(1, false) and it seems to give me what I want without blocking.

          • 2. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
            shawkins

            hasNext(1, false) would almost work, but it's possible for that call to return null, so you could get an npe.  With the currently logic, it's not really meaningful to call isLast in continuous mode (it should likely either just return true or throw an exception), since there is typically no last row.  Are you trying to find out when a single iteration has finished?  That would require new logic as the client is not informed when another iteration begins.

             

            Steve

            • 3. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
              markaddleman

              Actually, this is for non continuous query

              • 4. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                shawkins

                Ah, yes I saw continuous and jumped on a conclusion.  The likely issue is a bad interaction with using the calling thread of a local connection.  That is not expected, can you log an issue?

                • 5. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                  markaddleman

                  hasNext(1, false) would almost work, but it's possible for that call to return null, so you could get an npe

                  Yep, discovered this.  I currently map null to false.  Is there some other meaning

                   

                  The likely issue is a bad interaction with using the calling thread of a local connection.  That is not expected, can you log an issue?

                  I'll log an issue later today.

                   

                  On a related note:  Under continuous execution, is there a way to find out if the current batch is exhausted?  Is this the result of BatchResult.hasNext(1, false)? I'm writing a Teiid stored procedure to fill a buffer kept in H2.  Ideally, for every onRow(), I would add to an H2 batch and when the current batch is exhausted, I would commit the data to H2 and inform clients that new data is available.  Obviously, committing and informing clients on every row would be a huge performance problem.

                   

                  If Teiid knows when the current batch is exhausted, I'll submit a second Jira to improve the Statement callback interface to include that information.  I'm thinking the simplest would be to introduce StatementCallback2

                  public interface StatementCallback2 extends StatementCallback {

                     public void beforeFirst(Statement s, ResultSetMetadata rsm);

                     public void afterResultSetOrBatchExhausted(Statement s);

                  }

                  • 6. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                    shawkins

                    There are a couple of things here.  Any blocking cursor positioning operation is a problem.  This would be absolute, next, isLast, isAfterLast when requesting results that have not yet been formed.  This is because the engine thread is already holding the lock on the work item and we are asynch - so the engine thread blocks and won't complete the process method and no work proceeds.  We can easily throw an exception and prevent the hanging behavior, but it's much more difficult to provide a blocking implementation in the asynch callback.  The options would be:

                     

                    1. to  provide asynch versions of those methods - submitAbsolute, etc.  However I think this gets confusing quickly as you'd have to attach a completion listener to know when the absolute takes effect.

                    2. use a known exception type, such as AsynchPositioningException that can be caught if when the positioning operation is not allowed. 

                     

                    In your case the workaround is not call isLast, but rely on onCompletion handling instead.

                     

                    Steve

                    • 7. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                      markaddleman

                      Just to be clear:  There's no mechanism to know if the next call to a blocking operation could block?  It would be acceptable if the mechanism returned false positives (ie, reported that the next call would block when it, in fact, wouldn't) as long as it never returned false negatives (reported the next call would not block when it would).

                      • 8. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                        shawkins

                        > There's no mechanism to know if the next call to a blocking operation could block?  It would be acceptable if the mechanism returned false positives (ie, reported that the next call would block when it, in fact, wouldn't) as long as it never returned false negatives (reported the next call would not block when it would).

                         

                        That can be exposed as a JDBC extension on TeiidResultSet - int available() - similar to the contract of InputStream available.

                         

                        > If Teiid knows when the current batch is exhausted, I'll submit a second Jira to improve the Statement callback interface to include that information.  I'm thinking the simplest would be to introduce StatementCallback2

                         

                        That could also be satisfied with the available method I think.

                        • 9. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                          markaddleman

                          That can be exposed as a JDBC extension on TeiidResultSet - int available() - similar to the contract of InputStream available.

                          Seems ideal.  https://issues.jboss.org/browse/TEIID-2224

                           

                          I am executing a query using submitExecute(StatementCallback) under non-continuous mode.  In the onRow() method of the callback, I execute ResultSet.isLast().  The query is against an execution whose next() method initially throws DataNotAvailable.NO_POLLING.  Some time later, it calls ExecutionContext.dataAvailable().  After 255 rows reported through the callback's onRow(), ResultSet.isLast() hangs.

                           

                          https://issues.jboss.org/browse/TEIID-2224

                          • 10. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                            shawkins

                            These will be resolved in 8.2 alpha2.

                            • 11. Re: ResultSet.isLast() blocks with submitExecute under non-continuous mode?
                              markaddleman

                              Saw the jira ticket, thanks.