We've got revisioning switched on in a site and we use it quite heavily along with rules to create custom workflows (this pre-dates the Workbench project.) However, when we implement tac_lite as well, we often get errors like the following when we re-save a previously saved node:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '12-1-tac_lite' for key 'PRIMARY': INSERT INTO {node_access} (nid, realm, gid, grant_view, grant_update, grant_delete) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5), (:db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11); Array ( [:db_insert_placeholder_0] => 12 [:db_insert_placeholder_1] => tac_lite [:db_insert_placeholder_2] => 1 [:db_insert_placeholder_3] => 1 [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => 0 [:db_insert_placeholder_6] => 12 [:db_insert_placeholder_7] => tac_lite [:db_insert_placeholder_8] => 1 [:db_insert_placeholder_9] => 1 [:db_insert_placeholder_10] => 0 [:db_insert_placeholder_11] => 0 ) in node_access_write_grants() (line 3394 of /client-site/modules/node/node.module).

Hidden in there is the fact that tac_lite_node_access_records() is generating duplicate records for node_access_write_grants(): "12-1-tac_lite" decomposes to "node nid=12, term tid=1, realm=tac_lite". This is in turn because _tac_lite_get_terms() is not guaranteed to return an array of unique tids (no duplicates). I think at certain points during revisioning's node-save cycle, the db_select() in that function can return more than one SQL row for different revisions, as there's no $node->vid restriction.

Please find attached a patch that fixes this. It doesn't actually bother checking $node->vid, because the query might generate multiple rows for some other reason. Instead it just changes the return array to be keyed off $term->tid, so it must always contain unique entries of the form $term->tid => $term->tid. This forces the grants hook to return unique entries for the node_access table too.

Comments

Dave Cohen’s picture

Status: Active » Fixed

Thanks committed it.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.