[ 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