terrymanu opened a new issue, #39251:
URL: https://github.com/apache/shardingsphere/issues/39251

   ## Bug Report
   
   ### Which version of ShardingSphere did you use?
   
   Current development code in #39050, head 
`d7bc11cd2b3767e2227141132a98d3c99d0ad818`.
   
   The previous implementation also had a handle-exhaustion problem because 
BLOB handles used an unbounded statement ID counter. This issue tracks the 
remaining boundary behavior separately from #39050.
   
   ### Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?
   
   ShardingSphere-Proxy with the Firebird frontend protocol.
   
   ### Expected behavior
   
   Each active BLOB should have a unique handle until it is closed or cancelled.
   
   When the available Firebird handle range is exhausted, the Proxy should 
either reuse a released handle or return an appropriate protocol error. It must 
not reuse an active handle.
   
   ### Actual behavior
   
   `FirebirdBlobHandleGenerator` generates handles from `1` to `0xFFFE` and 
then unconditionally wraps to `1`.
   
   If handle `1` is still active, the next create/open operation registers 
another BLOB with the same handle and overwrites the existing cache entry. 
Subsequent get, put, close, or cancel operations may therefore target the wrong 
BLOB.
   
   ### Reason analyze (If you can)
   
   Firebird reserves `0xFFFF` as the invalid/deferred object handle, so the 
available handle range is finite:
   
   
https://firebirdsql.org/file/documentation/html/en/firebirddocs/wireprotocol/firebird-wire-protocol.html
   
   The current generator tracks only the last generated number. It does not 
track active or released handles:
   
   ```java
   return connectionRegistry.get(connectionId)
           .updateAndGet(current -> MAX_OBJECT_HANDLE <= current ? 1 : current 
+ 1);
   ```
   
   BLOB read and write caches are keyed by handle, so registering the wrapped 
handle silently replaces the active entry.
   
   ### Steps to reproduce the behavior
   
   1. Register a Firebird Proxy connection.
   2. Generate handle `1` and keep its BLOB active.
   3. Continue generating handles until `0xFFFE`.
   4. Generate one more handle.
   5. The generator returns `1` again even though the original handle is still 
active.
   6. Registering the new BLOB overwrites the original handle mapping.
   
   ### Example codes for reproduce this issue
   
   ```java
   int firstHandle = generator.nextBlobHandle(connectionId);
   assertThat(firstHandle, is(1));
   
   // Keep the BLOB associated with handle 1 active.
   for (int i = 1; i < 0xFFFE; i++) {
       generator.nextBlobHandle(connectionId);
   }
   
   int wrappedHandle = generator.nextBlobHandle(connectionId);
   assertThat(wrappedHandle, is(1));
   ```
   
   The expected fix should track handle ownership, reuse only handles released 
by close/cancel, and report handle exhaustion when no handle is available.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: 
[email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to