[ https://issues.apache.org/jira/browse/CASSJAVA-93 ]


    Lukasz Antoniak deleted comment on CASSJAVA-93:
    -----------------------------------------

was (Author: lukasz.antoniak):
Just for the record, IT that will expose bad behaviour on old C* versions:

 
{code:java}
@Test
public void should_update_metadata_when_column_dropped_across_sessions() {
  // Given
  CqlSession session1 = sessionRule.session();
  CqlSession session2 = SessionUtils.newSession(ccmRule, 
sessionRule.keyspace());

  PreparedStatement ps1 = session1.prepare("SELECT * FROM 
prepared_statement_test WHERE a = ?");
  PreparedStatement ps2 = session2.prepare("SELECT * FROM 
prepared_statement_test WHERE a = ?");

  ByteBuffer id1a = ps1.getResultMetadataId();
  ByteBuffer id2a = ps2.getResultMetadataId();

  ResultSet rows1 = session1.execute(ps1.bind(11));
  ResultSet rows2 = session2.execute(ps2.bind(11));

  assertThat(rows1.getColumnDefinitions()).hasSize(3);
  assertThat(rows2.getColumnDefinitions()).hasSize(3);

  // When
  session1.execute("ALTER TABLE prepared_statement_test DROP b");
  rows1 = session1.execute(ps1.bind(11));
  rows2 = session2.execute(ps2.bind(11));

//  ByteBuffer id1b = ps1.getResultMetadataId();
//  ByteBuffer id2b = ps2.getResultMetadataId();
//
//  // Then
//  assertThat(Bytes.toHexString(id1b)).isNotEqualTo(Bytes.toHexString(id1a));
//  assertThat(Bytes.toHexString(id2b)).isNotEqualTo(Bytes.toHexString(id2a));

  assertThat(ps1.getResultSetDefinitions()).hasSize(2);
  assertThat(ps1.getResultSetDefinitions().contains("b")).isFalse();
  assertThat(ps2.getResultSetDefinitions()).hasSize(2);
  assertThat(ps2.getResultSetDefinitions().contains("b")).isFalse();

  assertThat(rows1.getColumnDefinitions()).hasSize(2);
  assertThat(rows1.getColumnDefinitions().contains("b")).isFalse();
  assertThat(rows2.getColumnDefinitions()).hasSize(2);
  assertThat(rows2.getColumnDefinitions().contains("b")).isFalse();

  Row row1 = rows1.one();
  int a1 = row1.getInt("a");
//  int b1 = row1.getInt("b");
  int c1 = row1.getInt("c");

  Row row2 = rows2.one();
  int a2 = row2.getInt("a");
//  int b2 = row2.getInt("b");
  int c2 = row2.getInt("c");  session2.close();
}{code}
 

 

> Wildcard prepared statements don't get updated metadata with older DSE and 
> Cassandra versions
> ---------------------------------------------------------------------------------------------
>
>                 Key: CASSJAVA-93
>                 URL: https://issues.apache.org/jira/browse/CASSJAVA-93
>             Project: Apache Cassandra Java driver
>          Issue Type: Bug
>          Components: Core
>            Reporter: Alberto Bortolan
>            Priority: Normal
>
> h2. Problem description
> You prepare a wildcard select statement ({{{}SELECT *{}}}) and while the 
> application using it is running, the table is altered dropping one column. 
> What happens is that under the hood, the driver re-prepares the statement, 
> but does not change the metadata associated, in particular
> the map between a column name and it's position within the returned tuple.
> As an example, if you have a table with non PK columns c1, c2, c3, c4 :
> {code:java}
> CREATE TABLE myks.t1 (
>   id text PRIMARY KEY,
>   c1 text,
>   c2 text,
>   c3 text,
>   c4 text ); {code}
> and prepare the statement
> {code:java}
> "SELECT * FROM myks.t1 WHERE id = ?"{code}
> If, after the prepare occurred column "c2" is dropped, when going through the 
> row contained in a resultSet returned by the execution of the prepared 
> statement, you get:
> {code:java}
> row.getString("c1")  //data from c1
> row.getString("c2")  //data from c3   (column shift)
> row.getString("c3")  //data from c4   (column shift) 
> row.getString("c4")  // IndexOutOfBoundsException  {code}
> while the correct behavior should be:
> {code:java}
> row.getString("c1")  //data from c1
> row.getString("c2")  // IllegalArgumentException: c2 is not a column in this 
> row
> row.getString("c3")  //data from c3
> row.getString("c4")  //data from c4 {code}
> h2. Some observations
> This issue is reproducible when running an application using the Cassandra 
> Java driver against Cassandra < 4.0 and DSE < 6.x. I'm aware that at the time 
> this jira is defined, Cassandra 3.x and older are in EOL, while DSE 5.1 is 
> still supported (EOSL 12/31/2026)
> The issue appears to be linked to the changes in the protocols in DSE 6 and 
> Cassandra 4 ( CASSANDRA-10786 ) which add a hash of the metadata for PREPARE 
> and EXECUTE.
> Older server versions do not return this information (although they still 
> returns the actual metadata)
> If the statement is explicitly prepared again using the same string, the 
> behavior with the new prepared object will still be incorrect.
> If the statement is explicitly prepared again using a string with trivial 
> changes (such as adding spaces or an ending semicolon) the new prepared 
> object will behave correctly ( presumably because it's tied to a separate 
> prepared statement ID on server side) 
> Restarting the application makes things work.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to