3030
3131import com .codahale .metrics .Gauge ;
3232import com .datastax .oss .driver .api .core .CqlSession ;
33+ import com .datastax .oss .driver .api .core .Version ;
3334import com .datastax .oss .driver .api .core .config .DefaultDriverOption ;
3435import com .datastax .oss .driver .api .core .config .DriverConfigLoader ;
3536import com .datastax .oss .driver .api .core .cql .AsyncResultSet ;
5758import com .google .common .collect .ImmutableList ;
5859import java .nio .ByteBuffer ;
5960import java .time .Duration ;
61+ import java .util .Objects ;
6062import java .util .concurrent .CompletionStage ;
6163import junit .framework .TestCase ;
6264import org .assertj .core .api .AbstractThrowableAssert ;
6365import org .junit .Before ;
64- import org .junit .Ignore ;
6566import org .junit .Rule ;
6667import org .junit .Test ;
6768import org .junit .experimental .categories .Category ;
7980@ Category (ParallelizableTests .class )
8081public class PreparedStatementIT {
8182
83+ private static final Version SCYLLA_METADATA_ID_SUPPORT_VERSION =
84+ Objects .requireNonNull (Version .parse ("2025.3" ));
85+
8286 private final CcmRule ccmRule = CcmRule .getInstance ();
8387
8488 private final SessionRule <CqlSession > sessionRule =
@@ -159,13 +163,14 @@ public void should_have_non_empty_variable_definitions_for_select_query_with_bou
159163
160164 @ Test
161165 @ BackendRequirement (type = BackendType .CASSANDRA , minInclusive = "4.0" )
162- @ BackendRequirement (type = BackendType .SCYLLA , maxExclusive = "2025.3" )
163- public void should_update_metadata_when_schema_changed_across_executions_with_no_metadata_id_feature () {
166+ @ BackendRequirement (type = BackendType .SCYLLA )
167+ public void
168+ should_update_metadata_when_schema_changed_across_executions () {
164169 // Given
165170 CqlSession session = sessionRule .session ();
166171 PreparedStatement ps = session .prepare ("SELECT * FROM prepared_statement_test WHERE a = ?" );
167172 ByteBuffer idBefore = ps .getResultMetadataId ();
168- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
173+ if (hasNoScyllaMetadataIdSupport ( )) {
169174 // Scylla does not support CQL5 extensions and metadata id
170175 assertThat (idBefore ).isNull ();
171176 }
@@ -180,7 +185,7 @@ public void should_update_metadata_when_schema_changed_across_executions_with_no
180185
181186 // Then
182187 ByteBuffer idAfter = ps .getResultMetadataId ();
183- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
188+ if (hasNoScyllaMetadataIdSupport ( )) {
184189 // Scylla does not support CQL5 extensions and metadata id
185190 assertThat (idAfter ).isNull ();
186191 for (ColumnDefinitions columnDefinitions :
@@ -205,37 +210,6 @@ public void should_update_metadata_when_schema_changed_across_executions_with_no
205210 }
206211 }
207212
208- @ Test
209- @ BackendRequirement (type = BackendType .SCYLLA , minInclusive = "2025.3" , description = "SCYLLA_USE_METADATA_ID feature is added in Scylla 2025.3" )
210- public void should_update_metadata_when_schema_changed_across_executions_with_metadata_id_feature_support () {
211- // Given
212- CqlSession session = sessionRule .session ();
213- PreparedStatement ps = session .prepare ("SELECT * FROM prepared_statement_test WHERE a = ?" );
214- ByteBuffer idBefore = ps .getResultMetadataId ();
215- assertThat (idBefore ).isNotNull ();
216-
217- // When
218- session .execute (
219- SimpleStatement .builder ("ALTER TABLE prepared_statement_test ADD d int" )
220- .setExecutionProfile (sessionRule .slowProfile ())
221- .build ());
222- BoundStatement bs = ps .bind (1 );
223- ResultSet rows = session .execute (bs );
224-
225- // Then
226- ByteBuffer idAfter = ps .getResultMetadataId ();
227- assertThat (idAfter ).isNotNull ();
228- assertThat (Bytes .toHexString (idAfter )).isNotEqualTo (Bytes .toHexString (idBefore ));
229- for (ColumnDefinitions columnDefinitions :
230- ImmutableList .of (
231- ps .getResultSetDefinitions (),
232- bs .getPreparedStatement ().getResultSetDefinitions (),
233- rows .getColumnDefinitions ())) {
234- assertThat (columnDefinitions ).hasSize (4 );
235- assertThat (columnDefinitions .get ("d" ).getType ()).isEqualTo (DataTypes .INT );
236- }
237- }
238-
239213 @ Test
240214 @ BackendRequirement (type = BackendType .CASSANDRA , minInclusive = "4.0" )
241215 @ BackendRequirement (type = BackendType .SCYLLA )
@@ -244,7 +218,7 @@ public void should_update_metadata_when_schema_changed_across_pages() {
244218 CqlSession session = sessionRule .session ();
245219 PreparedStatement ps = session .prepare ("SELECT * FROM prepared_statement_test" );
246220 ByteBuffer idBefore = ps .getResultMetadataId ();
247- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
221+ if (hasNoScyllaMetadataIdSupport ( )) {
248222 // Scylla does not support CQL5 and result metadata id
249223 assertThat (idBefore ).isNull ();
250224 }
@@ -281,7 +255,7 @@ public void should_update_metadata_when_schema_changed_across_pages() {
281255 assertThat (rows .getColumnDefinitions ().get ("d" ).getType ()).isEqualTo (DataTypes .INT );
282256 // Should have updated the prepared statement too
283257 ByteBuffer idAfter = ps .getResultMetadataId ();
284- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
258+ if (hasNoScyllaMetadataIdSupport ( )) {
285259 // Scylla does not support CQL5 and result metadata id
286260 assertThat (idAfter ).isNull ();
287261 assertThat (ps .getResultSetDefinitions ()).hasSize (3 );
@@ -306,7 +280,7 @@ public void should_update_metadata_when_schema_changed_across_sessions() {
306280
307281 ByteBuffer id1a = ps1 .getResultMetadataId ();
308282 ByteBuffer id2a = ps2 .getResultMetadataId ();
309- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
283+ if (hasNoScyllaMetadataIdSupport ( )) {
310284 // Scylla does not support CQL5 extensions and metadata id
311285 assertThat (id1a ).isNull ();
312286 assertThat (id2a ).isNull ();
@@ -330,7 +304,7 @@ public void should_update_metadata_when_schema_changed_across_sessions() {
330304 ByteBuffer id2b = ps2 .getResultMetadataId ();
331305
332306 // Then
333- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
307+ if (hasNoScyllaMetadataIdSupport ( )) {
334308 // Scylla does not support CQL5 extensions and metadata id
335309 assertThat (id1b ).isNull ();
336310 assertThat (id2b ).isNull ();
@@ -471,7 +445,7 @@ private void should_not_store_metadata_for_conditional_updates(CqlSession sessio
471445 // Then
472446 // Failed conditional update => regular metadata that should also contain the new column
473447 assertThat (rs .wasApplied ()).isFalse ();
474- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
448+ if (hasNoScyllaMetadataIdSupport ( )) {
475449 // Scylla does not update column definitions is such case
476450 assertThat (rs .getColumnDefinitions ()).hasSize (4 );
477451 } else {
@@ -481,16 +455,20 @@ private void should_not_store_metadata_for_conditional_updates(CqlSession sessio
481455 assertThat (nextRow .getBoolean ("[applied]" )).isFalse ();
482456 assertThat (nextRow .getInt ("a" )).isEqualTo (5 );
483457 assertThat (nextRow .getInt ("b" )).isEqualTo (5 );
484- if (CcmBridge . isDistributionOf ( BackendType . SCYLLA )) {
458+ if (hasNoScyllaMetadataIdSupport ( )) {
485459 // Scylla does not support CQL5 and metadata id, that is why response metadata does not
486460 // contain "d"
487461 assertThrows (IllegalArgumentException .class , () -> nextRow .isNull ("d" ));
488462 assertThat (ps .getResultSetDefinitions ()).hasSize (4 );
463+ } else if (CcmBridge .isDistributionOf (BackendType .SCYLLA )) {
464+ assertThat (nextRow .isNull ("d" )).isTrue ();
465+ assertThat (ps .getResultSetDefinitions ()).hasSize (5 );
466+ assertThat (Bytes .toHexString (ps .getResultMetadataId ())).isNotEqualTo (Bytes .toHexString (idBefore ));
489467 } else {
490468 assertThat (nextRow .isNull ("d" )).isTrue ();
491469 assertThat (ps .getResultSetDefinitions ()).hasSize (0 );
470+ assertThat (Bytes .toHexString (ps .getResultMetadataId ())).isEqualTo (Bytes .toHexString (idBefore ));
492471 }
493- assertThat (Bytes .toHexString (ps .getResultMetadataId ())).isEqualTo (Bytes .toHexString (idBefore ));
494472 }
495473
496474 @ Test
@@ -594,6 +572,7 @@ public void should_create_separate_instances_for_different_statement_parameters(
594572
595573 // Add version bounds to the DSE requirement if there is a version containing fix for
596574 // CASSANDRA-15252
575+
597576 @ BackendRequirement (
598577 type = BackendType .DSE ,
599578 description = "No DSE version contains fix for CASSANDRA-15252" )
@@ -603,8 +582,8 @@ public void should_create_separate_instances_for_different_statement_parameters(
603582 minInclusive = "3.11.0" ,
604583 maxExclusive = "3.11.12" )
605584 @ BackendRequirement (type = BackendType .CASSANDRA , minInclusive = "4.0.0" , maxExclusive = "4.0.2" )
585+ @ BackendRequirement (type = BackendType .SCYLLA )
606586 @ Test
607- @ Ignore ("@IntegrationTestDisabledCassandra3Failure" )
608587 public void should_fail_fast_if_id_changes_on_reprepare () {
609588 assertableReprepareAfterIdChange ()
610589 .isInstanceOf (IllegalStateException .class )
@@ -730,4 +709,10 @@ private static long getPreparedCacheSize(CqlSession session) {
730709 "Could not access metric "
731710 + DefaultSessionMetric .CQL_PREPARED_CACHE_SIZE .getPath ()));
732711 }
712+
713+ private static boolean hasNoScyllaMetadataIdSupport () {
714+ return CcmBridge .isDistributionOf (BackendType .SCYLLA )
715+ && CcmBridge .getScyllaVersion ().isPresent ()
716+ && CcmBridge .getScyllaVersion ().get ().compareTo (SCYLLA_METADATA_ID_SUPPORT_VERSION ) < 0 ;
717+ }
733718}
0 commit comments