I am extensively using the "Add to nodequeue" and "Remove from nodequeue" actions. Somehow positions may get out of sync, e. g. resulting in two nodes with the same position (cause unkown yet):

qid sqid nid position timestamp
7 20 76477 5 1302096639
7 20 75636 1 1297930240
7 20 76134 3 1300352414
7 20 76258 3 1301414845
7 20 76290 4 1301567390

I discovered that the re-index algorithm in nodequeue_subqueue_remove() cannot fix positions which have gotten out of sync as it only decrements higher positions by one on node removal.

The attached patch reorders the positions of all nodes. Be aware that it introduces n + 1 (n = number of nodes in queue) db queries instead of 1. I don't know a smarter way to do this, but maybe we can eliminate the cause.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

amateescu’s picture

zyxware’s picture

@amateescu - Is it required for the positions to be continuous on the number line?

Would a subquery to set the position work when you insert the node? Wouldn't that eliminate the duplicate node position issue?

druninja’s picture

Subscribing

zyxware’s picture

I think transaction is one way and another would be a subquery to get the max+1 position. Here is a patch for getting the position as a subquery and using that in the insert query in the nodequeue_subqueue_add function. It is a bit ugly with the subquery but I think this would work until (unless) another solution is found.

ezra-g’s picture

I don't see a problem with doing a subquery, so would be fine committing this with folks saying it resolves the issue.

amateescu’s picture

I also like the subquery fix, but why is there an extra select? Shouldn't it be: SELECT MAX(position) + 1 FROM {nodequeue_nodes} WHERE sqid = %d ?

zyxware’s picture

MySQL doesn’t allow selecting and inserting into the same table. The sub sub query works around this.

amateescu’s picture

Status: Needs review » Fixed
FileSize
983 bytes
850 bytes

@zyxware: your patch had some extra code in there that wasn't part of nodequeue and had some problems when inserting the first node in a queue so I added a ISNULL check in there. Commited attached patches to 6.x and 7.x.

http://drupalcode.org/project/nodequeue.git/commit/f5a9807
http://drupalcode.org/project/nodequeue.git/commit/4fcf255

zyxware’s picture

Status: Fixed » Active

There is still an issue here. When multiple nodes get added into a nodequeue simultaneously the patch will ensure correct positions but the subqueue size is handled via variables in the page and this might have changed during the page load via another add request. So the count will have to be queried back again after the insert. Otherwise the spill over code will not be triggered during simultaneous inserts and nodequeue could grow larger than the limit.

$subqueue->count++;

should be

$subqueue->count = db_result(db_query("SELECT count(nid) FROM {nodequeue_nodes} WHERE sqid = %d", $subqueue->sqid));

(not sure if this had to be added as a new issue or hitchhike with this one)

amateescu’s picture

Good catch, thanks for being so vigilant :)

Commited attached patches to 6.x-2.x and 7.x-2.x.

http://drupalcode.org/project/nodequeue.git/commit/beb0851
http://drupalcode.org/project/nodequeue.git/commit/6690682

Status: Fixed » Closed (fixed)

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