Michael, I re-wrote __wt_schema_open_index() to set a cursor at "index:[table-name]:" instead of reading through the entire schema file, and I noticed this chunk of code:
295 if ((size_t)i * sizeof(const char *) >= table->idx_name_alloc) 296 WT_ERR(__wt_realloc(session, &table->idx_name_alloc, 297 WT_MAX(10 * sizeof(const char *), 298 2 * table->idx_name_alloc), &table->idx_name)); 299 300 if (table->idx_name[i] == NULL) 301 WT_ERR(__wt_strdup(session, uri, &table->idx_name[i]));
Specifically, the test for table->idx_name[i] already being set bothers me.
If you open the indices, and then create a new index that sorts in the middle of the existing indices, the indices won't be in the same order, and so table->idx_name[i] won't be NULL, but it won't be the right name, either. It's pretty easy to make it happen, this test script gets it to fire for me:
import wiredtiger, wttest class test_f(wttest.WiredTigerTestCase): # This test drops core. def test_f(self): uri = "table:xxx" self.session.create(uri, 'key_format=i,value_format=SiS,' + 'columns=(record,column2,column3,column4)') indxname = 'index:' + uri.split(":")[1] self.session.create(indxname + ':indx1', 'columns=(column2)') self.session.create(indxname + ':indx3', 'columns=(column4)') self.session.truncate(uri, None, None, None) self.session.create(indxname + ':indx2', 'columns=(column3)') self.session.truncate(uri, None, None, None) self.session.drop(uri, None) if __name__ == '__main__': wttest.run()
I was thinking the simplest fix would be have an interior loop that steps through the list of indices looking for a matching index name, and if it doesn't find one, it allocates new space. But that's N*2 in the number of indices the table has, would we care?
Anyway, me know if this needs fixing and how you'd like it fixed, and I'll make it happen.