|
23 | 23 |
|
24 | 24 | from cassandra import ConsistencyLevel |
25 | 25 | from cassandra.cluster import Cluster |
26 | | -from cassandra.query import PreparedStatement, UNSET_VALUE |
| 26 | +from cassandra.query import PreparedStatement, UNSET_VALUE, tuple_factory |
27 | 27 | from tests.integration import get_server_versions |
28 | 28 |
|
29 | 29 |
|
@@ -385,3 +385,39 @@ def test_raise_error_on_prepared_statement_execution_dropped_table(self): |
385 | 385 |
|
386 | 386 | with self.assertRaises(InvalidRequest): |
387 | 387 | self.session.execute(prepared, [0]) |
| 388 | + |
| 389 | + def test_invalidated_result_metadata(self): |
| 390 | + """ |
| 391 | + Tests to make sure cached metadata is updated when an invalidated prepared statement is reprepared. |
| 392 | +
|
| 393 | + @since 2.7.0 |
| 394 | + @jira_ticket PYTHON-621 |
| 395 | +
|
| 396 | + Prior to this fix, the request would blow up with a protocol error when the result was decoded expecting a different |
| 397 | + number of columns. |
| 398 | + """ |
| 399 | + s = self.session |
| 400 | + s.result_factory = tuple_factory |
| 401 | + |
| 402 | + table = "test1rf.%s" % self._testMethodName.lower() |
| 403 | + |
| 404 | + s.execute("DROP TABLE IF EXISTS %s" % table) |
| 405 | + s.execute("CREATE TABLE %s (k int PRIMARY KEY, a int, b int, c int)" % table) |
| 406 | + s.execute("INSERT INTO %s (k, a, b, c) VALUES (0, 0, 0, 0)" % table) |
| 407 | + |
| 408 | + wildcard_prepared = s.prepare("SELECT * FROM %s" % table) |
| 409 | + original_result_metadata = wildcard_prepared.result_metadata |
| 410 | + self.assertEqual(len(original_result_metadata), 4) |
| 411 | + |
| 412 | + r = s.execute(wildcard_prepared) |
| 413 | + self.assertEqual(r[0], (0, 0, 0, 0)) |
| 414 | + |
| 415 | + s.execute("ALTER TABLE %s DROP c" % table) |
| 416 | + |
| 417 | + # Get a bunch of requests in the pipeline with varying states of result_meta, reprepare, resolved |
| 418 | + futures = set(s.execute_async(wildcard_prepared.bind(None)) for _ in range(200)) |
| 419 | + for f in futures: |
| 420 | + self.assertEqual(f.result()[0], (0, 0, 0)) |
| 421 | + self.assertIsNot(wildcard_prepared.result_metadata, original_result_metadata) |
| 422 | + s.execute("DROP TABLE %s" % table) |
| 423 | + |
0 commit comments