The case-sensitivity of queries created using EntityFieldQuery rely on the underlying database's collation [*]. So if the collation for a particular field is 'utf8_general_ci', then all the queries created with EntityFieldQuery are case insensitive.
Given that it's not always possible to change the schema (say, if you are developing a module that acts on third party fields) how can you ensure case sensitivity when using EntityFieldQuery ?
My solution so far consists of using a tag and a hook_query_TAG_alter hook to cast the value to a BINARY value (and EFQ allows us to create our own operator for this). Here is an example:
function mymodule_query_case_sensitive_alter($query) {
foreach ($conditions as $index => $condition) {
if (is_array($condition) && $condition['operator'] == '=c') {
$placeholder = ':db_condition_placeholder_' . $query->nextPlaceHolder();
$conditions[$index]['field'] = 'CAST(' . $conditions[$index]['field'] . ' AS BINARY) = ' . $placeholder;
$conditions[$index]['value'] = array($placeholder => $conditions[$index]['value']);
$conditions[$index]['operator'] = NULL;
}
}
}
Then one could run:
$r = (new EntityFieldQuery())
->fieldCondition('field_my_field', 'value', 'ExaMple', '=c')
->addTag('case_sensitive')
->execute();
Based on this, my questions are:
- It is quite cumbersome. Is there really no simpler way ?
- Does such a tag already exist ?
- This is limited to MySql field storage backend - how could it be adapted to work on other field storage backends ?
[*] I am assuming a MySql field storage backend here.