[ https://issues.apache.org/jira/browse/CASSANDRA-15252?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17396609#comment-17396609 ]
Alex Petrov commented on CASSANDRA-15252: ----------------------------------------- Patches for all branches: |[trunk|https://github.com/apache/cassandra/compare/cassandra-3.0...ifesdjeen:CASSANDRA-15252-3.0]|[tests|https://app.circleci.com/pipelines/github/ifesdjeen/cassandra?branch=CASSANDRA-15252-3.0]| |[trunk|https://github.com/apache/cassandra/compare/cassandra-3.11...ifesdjeen:CASSANDRA-15252-3.11]|[tests|https://app.circleci.com/pipelines/github/ifesdjeen/cassandra?branch=CASSANDRA-15252-3.11]| |[trunk|https://github.com/apache/cassandra/compare/cassandra-4.0...ifesdjeen:CASSANDRA-15252-4.0]|[tests|https://app.circleci.com/pipelines/github/ifesdjeen/cassandra?branch=CASSANDRA-15252-4.0]| |[trunk|https://github.com/apache/cassandra/compare/trunk...ifesdjeen:CASSANDRA-15252-trunk]|[tests|https://app.circleci.com/pipelines/github/ifesdjeen/cassandra?branch=CASSANDRA-15252-trunk]| > 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: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org