Alberto Bortolan created CASSJAVA-93:
----------------------------------------

             Summary: 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


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