Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions cassandra/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -4724,13 +4724,18 @@ def _set_result(self, host, connection, pool, response):
self.prepared_statement = self.session.cluster._prepared_statements[query_id]
except KeyError:
if not self.prepared_statement:
log.error("Tried to execute unknown prepared statement: id=%s", hexlify(query_id))
log.error(
"Tried to execute unknown prepared statement: id=%s",
hexlify(query_id).decode('ascii'),
)
self._set_final_exception(response)
return
log.warning(
"UNPREPARED for query id %s while executing statement id %s. "
"Could not resolve returned id in cache, proceeding with in-flight context.",
hexlify(query_id), hexlify(self.prepared_statement.query_id))
hexlify(query_id).decode('ascii'),
hexlify(self.prepared_statement.query_id).decode('ascii'),
)

current_keyspace = self._connection.keyspace
prepared_keyspace = self.prepared_statement.keyspace
Expand Down
8 changes: 7 additions & 1 deletion tests/unit/test_response_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,12 @@ def test_prepared_query_not_found_bad_keyspace(self):
rf.result()

def test_prepared_query_not_found_uses_local_prepared_context(self):
"""
Regression test: the original code asserted response.info == self.prepared_statement.query_id,
which raised AssertionError when the server returned a different query id (e.g. due to a
coordinator race or restart), preventing recovery. The fix removes the assertion and falls
back to the in-flight prepared_statement context so reprepare can still proceed.
"""
session = self.make_session()
pool = session._pools.get.return_value
connection = Mock(spec=Connection)
Expand All @@ -639,7 +645,7 @@ def test_prepared_query_not_found_uses_local_prepared_context(self):
rf.prepared_statement.query_string = "SELECT * FROM foobar"
rf.prepared_statement.keyspace = "FooKeyspace"

# Different query id in UNPREPARED response should not prevent reprepare when local context exists.
# Server returns a *different* query id in UNPREPARED — old code would raise AssertionError here.
result = Mock(spec=PreparedQueryNotFound, info=b"other-query-id")
rf._set_result(None, None, None, result)

Expand Down