2929import com .alipay .oceanbase .rpc .protocol .payload .ResultCodes ;
3030import com .alipay .oceanbase .rpc .protocol .payload .impl .ObObj ;
3131import com .alipay .oceanbase .rpc .protocol .payload .impl .execute .ObTableApiMove ;
32+ import com .alipay .oceanbase .rpc .protocol .payload .impl .ObRowKey ;
3233import com .alipay .oceanbase .rpc .protocol .payload .impl .execute .ObTableEntityType ;
3334import com .alipay .oceanbase .rpc .protocol .payload .impl .execute .ObTableStreamRequest ;
3435import com .alipay .oceanbase .rpc .protocol .payload .impl .execute .QueryStreamResult ;
@@ -50,6 +51,7 @@ public abstract class AbstractQueryStreamResult extends AbstractPayload implemen
5051 protected volatile boolean closed = false ;
5152 protected volatile List <ObObj > row = null ;
5253 protected volatile int rowIndex = -1 ;
54+ // 调整它的startKey
5355 protected ObTableQuery tableQuery ;
5456 protected long operationTimeout = -1 ;
5557 protected String tableName ;
@@ -63,6 +65,7 @@ public abstract class AbstractQueryStreamResult extends AbstractPayload implemen
6365 protected LinkedList <List <ObObj >> cacheRows = new LinkedList <List <ObObj >>();
6466 private LinkedList <ObPair <ObPair <Long , ObTableParam >, ObTableQueryResult >> partitionLastResult = new LinkedList <ObPair <ObPair <Long , ObTableParam >, ObTableQueryResult >>();
6567 private ObReadConsistency readConsistency = ObReadConsistency .STRONG ;
68+ public ObRowKey currentStartKey ;
6669
6770 /*
6871 * Get pcode.
@@ -243,6 +246,11 @@ protected ObPayload commonExecute(ObTableClient client, Logger logger,
243246 "tablename:{} partition id:{} stream query retry while meet Exception needing refresh, errorCode: {} , retry times {}" ,
244247 indexTableName , partIdWithIndex .getLeft (),
245248 ((ObTableException ) e ).getErrorCode (), tryTimes , e );
249+ // tablet not exists, refresh table entry
250+ if (e instanceof ObTableNeedFetchAllException ) {
251+ client .getOrRefreshTableEntry (tableName , true , true , true );
252+ throw e ;
253+ }
246254 } else {
247255 client .calculateContinuousFailure (indexTableName , e .getMessage ());
248256 throw e ;
@@ -265,12 +273,13 @@ protected ObPayload commonExecute(ObTableClient client, Logger logger,
265273 /*
266274 * Next.
267275 */
276+ // 这个函数中,任何的计算结果都会填充到cacheRows
268277 public boolean next () throws Exception {
269278 checkStatus ();
270279 lock .lock ();
271280 try {
272281 // firstly, refer to the cache
273- if (cacheRows .size () > 0 ) {
282+ if (! cacheRows .isEmpty () ) {
274283 nextRow ();
275284 return true ;
276285 }
@@ -293,6 +302,40 @@ public boolean next() throws Exception {
293302 // lastly, refer to the new partition
294303 boolean hasNext = false ;
295304 List <Map .Entry <Long , ObPair <Long , ObTableParam >>> referPartition = new ArrayList <Map .Entry <Long , ObPair <Long , ObTableParam >>>();
305+ Iterator <Map .Entry <Long , ObPair <Long , ObTableParam >>> it = expectant .entrySet ().iterator ();
306+ while (it .hasNext ()) {
307+ Map .Entry <Long , ObPair <Long , ObTableParam >> entry = it .next ();
308+ referPartition .add (entry );
309+ try {
310+ // Mark the refer partition
311+ referPartition .add (entry );
312+
313+ // Try accessing the new partition
314+ ObTableQueryResult tableQueryResult = (ObTableQueryResult ) referToNewPartition (entry .getValue ());
315+
316+ if (tableQueryResult .getRowCount () == 0 ) {
317+ continue ;
318+ }
319+
320+ hasNext = true ;
321+ nextRow ();
322+ break ;
323+
324+ } catch (Exception e ) {
325+ if (e instanceof ObTableNeedFetchAllException ) {
326+ // Adjust the start key and refresh the expectant
327+ this .tableQuery .adjustStartKey (currentStartKey );
328+ setExpectant (refreshPartition (tableQuery , tableName ));
329+
330+ // Reset the iterator to start over
331+ it = expectant .entrySet ().iterator ();
332+ referPartition .clear (); // Clear the referPartition if needed
333+ } else {
334+ throw e ;
335+ }
336+ }
337+ }
338+
296339 for (Map .Entry <Long , ObPair <Long , ObTableParam >> entry : expectant .entrySet ()) {
297340 // mark the refer partition
298341 referPartition .add (entry );
@@ -317,9 +360,59 @@ public boolean next() throws Exception {
317360 }
318361 }
319362
363+ protected Map <Long , ObPair <Long , ObTableParam >> buildPartitions (ObTableClient client , ObTableQuery tableQuery , String tableName ) throws Exception {
364+ Map <Long , ObPair <Long , ObTableParam >> partitionObTables = new HashMap <>();
365+ String indexName = tableQuery .getIndexName ();
366+ String indexTableName = null ;
367+
368+ if (!client .isOdpMode ()) {
369+ indexTableName = client .getIndexTableName (tableName , indexName , tableQuery .getScanRangeColumns (), false );
370+ }
371+
372+ for (ObNewRange range : tableQuery .getKeyRanges ()) {
373+ ObRowKey startKey = range .getStartKey ();
374+ int startKeySize = startKey .getObjs ().size ();
375+ ObRowKey endKey = range .getEndKey ();
376+ int endKeySize = endKey .getObjs ().size ();
377+ Object [] start = new Object [startKeySize ];
378+ Object [] end = new Object [endKeySize ];
379+
380+ for (int i = 0 ; i < startKeySize ; i ++) {
381+ start [i ] = startKey .getObj (i ).isMinObj () || startKey .getObj (i ).isMaxObj () ?
382+ startKey .getObj (i ) : startKey .getObj (i ).getValue ();
383+ }
384+
385+ for (int i = 0 ; i < endKeySize ; i ++) {
386+ end [i ] = endKey .getObj (i ).isMinObj () || endKey .getObj (i ).isMaxObj () ?
387+ endKey .getObj (i ) : endKey .getObj (i ).getValue ();
388+ }
389+
390+ ObBorderFlag borderFlag = range .getBorderFlag ();
391+ List <ObPair <Long , ObTableParam >> pairs = client .getTables (indexTableName ,
392+ tableQuery , start , borderFlag .isInclusiveStart (), end , borderFlag .isInclusiveEnd (),
393+ false , false );
394+
395+ if (tableQuery .getScanOrder () == ObScanOrder .Reverse ) {
396+ for (int i = pairs .size () - 1 ; i >= 0 ; i --) {
397+ partitionObTables .put (pairs .get (i ).getLeft (), pairs .get (i ));
398+ }
399+ } else {
400+ for (ObPair <Long , ObTableParam > pair : pairs ) {
401+ partitionObTables .put (pair .getLeft (), pair );
402+ }
403+ }
404+ }
405+
406+ return partitionObTables ;
407+ }
408+
409+ // 上层会不断的调getRow, 也就是不断的取出缓存,所以可以在这里给row赋值的时候顺便把这个row记录下来,用来作为最后拿到的key
320410 protected void nextRow () {
321411 rowIndex = rowIndex + 1 ;
322412 row = cacheRows .poll ();
413+ if (row != null ) {
414+ currentStartKey = (ObRowKey ) row .get (0 ).getValue ();
415+ }
323416 }
324417
325418 protected void checkStatus () throws IllegalStateException {
@@ -397,6 +490,7 @@ protected abstract ObTableQueryResult execute(ObPair<Long, ObTableParam> partIdW
397490 protected abstract ObTableQueryAsyncResult executeAsync (ObPair <Long , ObTableParam > partIdWithObTable ,
398491 ObPayload streamRequest )
399492 throws Exception ;
493+ protected abstract Map <Long , ObPair <Long , ObTableParam >> refreshPartition (ObTableQuery tableQuery , String tableName ) throws Exception ;
400494
401495 protected void cacheResultRows (ObTableQueryResult tableQueryResult ) {
402496 cacheRows .addAll (tableQueryResult .getPropertiesRows ());
0 commit comments