[
https://issues.apache.org/jira/browse/CASSJAVA-93?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18043754#comment-18043754
]
Bret McGuire commented on CASSJAVA-93:
--------------------------------------
I made a mistake in reading through this the first time [~alberto.bortolan] ; I
saw something here that reminded me of issues we were seeing with invalidating
prepared statements involving UDTs when some field of that UDT changed and in
my head I transposed that on to this.
[~tolbertam] actually set me straight; in conversation earlier today he made
the observation that the behaviour described here is pretty much _exactly_
what's described in CASSANDRA-10786. The fix for this is to move to a
configuration that leverages protocol version 5 as that protocol includes a fix
specifically designed to address this issue. There aren't any known fixes for
this for protocol version 4 or lower.
> 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
> Fix For: 4.20.0
>
>
> 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: [email protected]
For additional commands, e-mail: [email protected]