@@ -494,4 +494,96 @@ public void testGetStatementType(boolean isReadOnlyTokenUsed) throws Exception {
494494 verify (bigquery , isReadOnlyTokenUsed ? Mockito .never () : Mockito .times (1 ))
495495 .create (any (JobInfo .class ));
496496 }
497+
498+ @ Test
499+ public void testUseReadAPI_SafeguardSmallDataset () throws SQLException {
500+ // Setup: totalRows <= pageSize, so it should not activate the Read API
501+ doReturn (true ).when (bigQueryConnection ).isEnableHighThroughputAPI ();
502+ doReturn (100 ).when (bigQueryConnection ).getHighThroughputMinTableSize ();
503+ doReturn (2 ).when (bigQueryConnection ).getHighThroughputActivationRatio ();
504+ doReturn (1000L ).when (bigQueryConnection ).getMaxResults ();
505+
506+ BigQueryStatement statement = new BigQueryStatement (bigQueryConnection );
507+ TableResult tableResult = mock (TableResult .class );
508+ doReturn (50L ).when (tableResult ).getTotalRows ();
509+
510+ // Standard java collection in values
511+ java .util .List <com .google .cloud .bigquery .FieldValueList > valuesList =
512+ new java .util .ArrayList <>();
513+ for (int i = 0 ; i < 50 ; i ++) {
514+ valuesList .add (mock (com .google .cloud .bigquery .FieldValueList .class ));
515+ }
516+ doReturn (valuesList ).when (tableResult ).getValues ();
517+
518+ boolean useReadApi = statement .useReadAPI (tableResult );
519+ assertThat (useReadApi ).isFalse ();
520+ }
521+
522+ @ Test
523+ public void testUseReadAPI_MeetsRatioCollection () throws SQLException {
524+ // Setup: totalRows = 500, pageSize = 100, MinTableSize = 100, ActivationRatio = 2
525+ // ratio = 5 > 2, should activate Read API
526+ doReturn (true ).when (bigQueryConnection ).isEnableHighThroughputAPI ();
527+ doReturn (100 ).when (bigQueryConnection ).getHighThroughputMinTableSize ();
528+ doReturn (2 ).when (bigQueryConnection ).getHighThroughputActivationRatio ();
529+ doReturn (1000L ).when (bigQueryConnection ).getMaxResults ();
530+
531+ BigQueryStatement statement = new BigQueryStatement (bigQueryConnection );
532+ TableResult tableResult = mock (TableResult .class );
533+ doReturn (500L ).when (tableResult ).getTotalRows ();
534+
535+ java .util .List <com .google .cloud .bigquery .FieldValueList > valuesList =
536+ new java .util .ArrayList <>();
537+ for (int i = 0 ; i < 100 ; i ++) {
538+ valuesList .add (mock (com .google .cloud .bigquery .FieldValueList .class ));
539+ }
540+ doReturn (valuesList ).when (tableResult ).getValues ();
541+
542+ boolean useReadApi = statement .useReadAPI (tableResult );
543+ assertThat (useReadApi ).isTrue ();
544+ }
545+
546+ @ Test
547+ public void testUseReadAPI_FailsMinTableSize () throws SQLException {
548+ // Setup: totalRows = 80 < MinTableSize (100)
549+ doReturn (true ).when (bigQueryConnection ).isEnableHighThroughputAPI ();
550+ doReturn (100 ).when (bigQueryConnection ).getHighThroughputMinTableSize ();
551+ doReturn (2 ).when (bigQueryConnection ).getHighThroughputActivationRatio ();
552+ doReturn (1000L ).when (bigQueryConnection ).getMaxResults ();
553+
554+ BigQueryStatement statement = new BigQueryStatement (bigQueryConnection );
555+ TableResult tableResult = mock (TableResult .class );
556+ doReturn (80L ).when (tableResult ).getTotalRows ();
557+
558+ java .util .List <com .google .cloud .bigquery .FieldValueList > valuesList =
559+ new java .util .ArrayList <>();
560+ for (int i = 0 ; i < 20 ; i ++) {
561+ valuesList .add (mock (com .google .cloud .bigquery .FieldValueList .class ));
562+ }
563+ doReturn (valuesList ).when (tableResult ).getValues ();
564+
565+ boolean useReadApi = statement .useReadAPI (tableResult );
566+ assertThat (useReadApi ).isFalse ();
567+ }
568+
569+ @ Test
570+ public void testUseReadAPI_NonCollectionApproximation () throws SQLException {
571+ // Setup: totalRows = 500, MinTableSize = 100, ActivationRatio = 2, maxResultPerPage = 100
572+ // results.getValues() returns custom non-collection Iterable (ratio = 500/100 = 5 > 2)
573+ doReturn (true ).when (bigQueryConnection ).isEnableHighThroughputAPI ();
574+ doReturn (100 ).when (bigQueryConnection ).getHighThroughputMinTableSize ();
575+ doReturn (2 ).when (bigQueryConnection ).getHighThroughputActivationRatio ();
576+ doReturn (100L ).when (bigQueryConnection ).getMaxResults (); // maxResultPerPage = 100
577+
578+ BigQueryStatement statement = new BigQueryStatement (bigQueryConnection );
579+ TableResult tableResult = mock (TableResult .class );
580+ doReturn (500L ).when (tableResult ).getTotalRows ();
581+
582+ // Mock non-collection iterable
583+ Iterable <com .google .cloud .bigquery .FieldValueList > mockIterable = mock (Iterable .class );
584+ doReturn (mockIterable ).when (tableResult ).getValues ();
585+
586+ boolean useReadApi = statement .useReadAPI (tableResult );
587+ assertThat (useReadApi ).isTrue ();
588+ }
497589}
0 commit comments