Problem
drupal_flush_all_caches() clears the persistent/database cache of the schema but not the static cache. Thus, if the schema changes within a request, you do not only have to call drupal_flush_all_caches() to account for possible changes, but also drupal_get_schema(NULL, TRUE).
Details
Given following example code:
<?php
/**
* Implements hook_schema().
*/
function example_schema() {
$table = variable_get('example_tablename', 'foo')
$schema[$table] = array(
...
);
return $schema;
}
/**
* Some function that gets called at runtime, e.g. a page callback.
*/
function example_page_callback() {
variable_set('example_tablename', 'bar');
drupal_flush_all_caches();
$schema = drupal_get_schema('bar');
}
?>
The expected result for me would be that $schema contains the declared schema. It contains FALSE, however. It order to get your schema you need to also call drupal_get_schema(NULL, TRUE);
Proposed resolutions
Choose one of the following:
- This is considered the expected behavior. Dynamic schemas are seldom (and, I guess, discouraged) and when they change you generally don't want to access the new schema directly after. And if you do, it's really not that hard to call drupal_get_schema(NULL, TRUE) yourself.
- drupal_flush_all_caches() not flushing *all* caches is considered a bug. Since using it should be discouraged in most runtime code anyway, we want to make sure you can rely on it, even in edge cases. In this case add drupal_get_schema(NULL, TRUE); to drupal_flush_all_caches()
Additional notes
- I found this in D7 and did not verify this problem still exists in D8. (That's why the example code is very D7-y :-).) What we want to do here can be discussed and decided regardless of that, however.
- As this is an extreme edge case, I thought about marking this minor. However, it's pretty awful to debug if you hit it, as generally your trust in drupal_flush_all_caches() will be high, so I went with normal.