[
https://issues.apache.org/jira/browse/CASSANDRA-15252?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Alex Petrov reassigned CASSANDRA-15252:
---------------------------------------
Assignee: Alex Petrov
> Don't consider current keyspace in prepared statement id when the query is
> qualified
> ------------------------------------------------------------------------------------
>
> Key: CASSANDRA-15252
> URL: https://issues.apache.org/jira/browse/CASSANDRA-15252
> Project: Cassandra
> Issue Type: Bug
> Reporter: Olivier Michallat
> Assignee: Alex Petrov
> Priority: Normal
>
> {{QueryProcessor.computeId}} takes into account the session's current
> keyspace in the MD5 digest.
> {code}
> String toHash = keyspace == null ? queryString : keyspace + queryString;
> {code}
> This is desirable for unqualified queries, because switching to a different
> keyspace produces a different statement. However, for a qualified query, the
> current keyspace makes no difference, the prepared id should always be the
> same.
> This can lead to an infinite reprepare loop on the client. Consider this
> example (Java driver 3.x):
> {code}
> Cluster cluster = null;
> try {
> cluster = Cluster.builder().addContactPoint("127.0.0.1").build();
> Session session = cluster.connect();
> session.execute(
> "CREATE KEYSPACE IF NOT EXISTS test WITH replication = {'class':
> 'SimpleStrategy', 'replication_factor': 1}");
> session.execute("CREATE TABLE IF NOT EXISTS test.foo(k int PRIMARY
> KEY)");
> PreparedStatement pst = session.prepare("SELECT * FROM test.foo WHERE
> k=?");
> // Drop and recreate the table to invalidate the prepared statement
> server-side
> session.execute("DROP TABLE test.foo");
> session.execute("CREATE TABLE test.foo(k int PRIMARY KEY)");
> session.execute("USE test");
> // This will try to reprepare on the fly
> session.execute(pst.bind(0));
> } finally {
> if (cluster != null) cluster.close();
> }
> {code}
> When the driver goes to execute the bound statement (last line before the
> finally block), it will get an UNPREPARED response because the statement was
> evicted from the server cache (as a result of dropping the table earlier).
> In those cases, the driver recovers transparently by sending another PREPARE
> message and retrying the bound statement.
> However, that second PREPARE cached the statement under a different id,
> because we switched to another keyspace. Yet the driver is still using the
> original id (stored in {{pst}}) when it retries, so it will get UNPREPARED
> again, etc.
> I would consider this low priority because issuing a {{USE}} statement after
> having prepared statements is a bad idea to begin with. And even if we fix
> the generated id for qualified query strings, the issue will remain for
> unqualified ones.
> We'll add a check in the driver to fail fast and avoid the infinite loop if
> the id returned by the second PREPARE doesn't match the original one. That
> might be enough to cover this issue.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]