Sam Veloso created CASSCPP-17:
---------------------------------

             Summary: Crash in update_indexes when adding an index for a table 
missing from schema metadata
                 Key: CASSCPP-17
                 URL: https://issues.apache.org/jira/browse/CASSCPP-17
             Project: Apache Cassandra C/C++ driver
          Issue Type: Bug
            Reporter: Sam Veloso


During control-connection schema refresh (Cluster::on_reconnect → update_schema 
→ update_indexes), the driver can dereference a null TableMetadata::Ptr and 
abort. This happens when system_schema.indexes contains two or more index rows 
for a table that is not present in the in-memory table metadata.
 
Observed with cpp-driver 2.17.1. The same unguarded add_index() is still 
present on master (src/metadata.cpp, Metadata::InternalData::update_indexes).
 
*Possible root cause*
update_indexes() already skips a missing table on the *first* index row, but it 
leaves table null while table_name is set to that missing table. Later index 
rows for the same table skip the lookup and call add_index() unconditionally:
 
{code:cpp}
if (table_name != temp_table_name) {
table_name = temp_table_name;
table = keyspace->get_table(table_name);
if (!table) continue;
table->clear_indexes();
}
 
table->add_index(IndexMetadata::from_row(index_name, buffer, row));
{code}
 
*Sequence:*
# First index row for missing table T: get_table() fails, \{{if (!table) 
continue}}, table stays null, table_name is T.
# Next index row for the same T: \{{table_name != temp_table_name}} is false, 
so the lookup is skipped.
# \{{table->add_index(...)}} runs on a null TableMetadata::Ptr.
 
A single leftover index row for a missing table does not crash (the continue 
already skips it). Two or more index rows for that table do.
 
This is inconsistent with the sibling helpers in the same file: 
update_columns() and update_legacy_indexes() wrap the mutation in \{{if 
(table)}}.
 
The window is realistic whenever tables and indexes are queried as separate 
result sets during reconnect, especially if a table was dropped (or not yet in 
metadata) while system_schema.indexes still has multiple indexes for it.
 
*Expected*
Index rows whose table is not in metadata should be skipped for every row, not 
only the first. The driver should not crash.
 
*Possible fix*
Guard add_index() the same way update_legacy_indexes() does:
 
{code:cpp}
if (table) {
table->add_index(IndexMetadata::from_row(index_name, buffer, row));
}
{code}
 
*Environment*
* cpp-driver 2.17.1 (also current master)
* Cassandra 3.x/4.x-style system_schema.indexes (update_indexes, not the legacy 
column-index path)
* Trigger: control connection reconnect / schema metadata refresh while indexes 
exist for a table the driver does not have



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to