I recently updated the search_api module to 7.x-1.8. I am not able to save any nodes(old or new) on my site since then. I am getting the message
The website encountered an error.
Logs showed this error
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'item_id' cannot be null: INSERT INTO {search_api_et_item}
I was able to trace it down to
/**
* Implements hook_node_access_records_alter().
*
* Marks the node as "changed" in indexes that use the "Node access" data
* alteration. Also marks the node's comments as changed in indexes that use the
* "Comment access" data alteration.
*/
function search_api_node_access_records_alter(&$grants, $node) {
foreach (search_api_index_load_multiple(FALSE) as $index) {
$item_ids = array();
if (!empty($index->options['data_alter_callbacks']['search_api_alter_node_access']['status'])) {
$item_id = $index->datasource()->getItemId($node);
$item_ids = array($item_id);
}
elseif (!empty($index->options['data_alter_callbacks']['search_api_alter_comment_access']['status'])) {
if (!isset($comments)) {
$comments = comment_load_multiple(FALSE, array('nid' => $node->nid));
}
foreach ($comments as $comment) {
$item_ids[] = $index->datasource()->getItemId($comment);
}
}
if ($item_ids) {
$indexes = array($index->machine_name => $index);
search_api_track_item_change_for_indexes($index->item_type, $item_ids, $indexes);
}
}
}
The line $item_id = $index->datasource()->getItemId($node); is returning NULL for all my nodes for the default_multilingual_node_index from the Search API Entity Translation module.
Comments
Comment #2
nidaismailshah commentedComment #3
gaëlgI face the same bug. The code you highlighted was introduced on 04/20, by http://cgit.drupalcode.org/search_api/commit/search_api.module?id=91df71...
I'm on it, should be easy to fix.
Comment #4
gaëlgThere might be cases where
$index->datasource()->getItemId($node)returns NULL while it shouldn't, but anyway, there are cases where it's right to return NULL, according to the doc:So that I added a check to avoid adding NULL in the $item_ids array.
Comment #5
nidaismailshah commentedSeems to work fine for me.
Comment #6
drunken monkeyI'm amazed that we currently allow
NULLas the return value forgetItemId(). That doesn't sound like a good idea. (We already changed it in the D8 version.)I'm pretty sure the correct way to fix this would be to fix the
search_api_etmodule to always return an item ID for an entity. It really just seems like laziness that they don't already do that, from how the code looks.Applying this fix here would lead to the same security issue that was fixed with that hook implementation to pop up again for multilingual node indexes. (Also, if we really want to apply that fix, we at least should also apply it for comments.)
Comment #8
thepanz commentedI am still unsure about latest patch, in which case the $item would be missing the `search_api_et_id`?
Could it be related to a dirty data in the index?
Do you think it would be correct to throw the SearchApiDataSourceException exception?
Comment #9
nico.knaepen commentedWe also encountered issues with getItemId returning NULL. Patch seems to work fine.
Also a memory allocation error on entity save, which occured before, doesn't occur anymore.
Comment #10
thepanz commented@nico.knaepen thank you for your feedback.
Could you check that the search functionality still works correctly? Are nodes correctly retrieved during a search, regarding their language?
Comment #11
minoroffense commentedThe null return value also causes a chain of events to trigger a reindex of all items within a given index. We have a site with 7000 nodes and it triggers an entity load on each to get the en, fr and und values to be indexed.
Comment #12
idebr commentedComment #14
idebr commentedSaving a node with search_api_et enabled no longer triggers a fatal error after #2742053: Node access records change implementation could pass wrong parameters to trackItemChange was committed in Search API. However, this change still makes sense to commit.