user warning: Duplicate entry 'home-es' for key 2 query: UPDATE url_alias SET src = 'node/19', dst = 'home', language = 'es' WHERE dst = 'home' in /home/amir/websites/drupal-translation/drupal-6.9/modules/path/path.module on line 108.

The current code updates the url_alias based only on the alias

db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE dst = '%s'", $path, $alias, $language, $alias);

This patch updates the url_alias based on the alias and the path. This will be safe because the previous line checks that the alias is correct for the path and language.

    if ($alias == drupal_get_path_alias($path, $language)) {
      // There is already such an alias, neutral or in this language.
      // Update the alias based on alias; setting the language if not yet done.
      db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE dst = '%s' AND src='%s'", $path, $alias, $language, $alias, $path);
    }

Attached is a patch against the drupal-6.9 release.

CommentFileSizeAuthor
#2 370089_path_duplicate.patch1001 byteseffata
path.module.patch737 bytesbrucepearson
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

hovel’s picture

I ran into this same problem today.
This warning occures when adding a translation for a node and the option Synchronise translations (Internationalisation module) is used.
As a result the translated node is created as an independant node, not as translation of the original node.

Althoug it is a warning message in the path module, it results in an incorrect output of the translation.

effata’s picture

FileSize
1001 bytes

This is a big problem since it can cause aliases to disappear on multilingual sites with synced fields. Not pretty if that happens on a custom home node.
Supplying a patch working with 6.16 and with proper base path.

haffmans’s picture

Status: Needs review » Reviewed & tested by the community

Suffering from the same issue here, and would like to see this committed. Patch from #2 seems fine and works for me.

gnindl’s picture

Status: Reviewed & tested by the community » Needs work

I'd prefer to go the patch in the issue #790338: All aliases get deleted when translatable nodes with same URL alias are reverted to previous revision.

What happens if you have the same URL alias on different nodes in the SAME language? Then this patch doesn't work, so it's better the update the alias by the language rather than the standard URL.

haffmans’s picture

Status: Needs work » Active

If you have the same URL alias on different nodes in the same language, there is an ambiguity when resolving that alias back to its node. Basically the same (full) URL points to two pages, which should never be possible in the first place.

Perhaps I'm missing a use case in which this ambiguity is allowed? The situation you describe sounds rather silly to me...

I am aware that the (unique) dst_language_pid index/constraint in the url_alias table also contains the pid and therefore basically permits the ambiguity, but right now I cannot find any documentation as to why this is allowed - that's a whole different issue.

On the other hand, this issue may be related or even be a duplicate of #269877: path_set_alias() doesn't account for same alias in different languages - but that issue seems to be discussing the INSERT rather than the UPDATE mostly. I am currently not able to test if that issue solves the problem discussed here, so I'm setting this back to active for now.

gnindl’s picture

Sorry haffmans, the statement in #4 sound a bit silly.

What I really meant was: "I don't think the patch in #2 works, when you have ONE OR MORE aliases on the SAME node in the SAME language". I think there's use case for that, at least for me.

haffmans’s picture

The patch changes the query, to match both source and destination in the WHERE clause. So even if you have two aliases (src) to the same node (dst) in the same language, only one of them will be updated (as only one src will match the WHERE clause). The updated alias will also be valid for the language because of the if() block surrounding the query.

The only issue that may be possible with this patch - I must admit I haven't tested that - is when you have the same alias to the same node (same src and dest) in multiple languages. In that case all defined aliases will have the language field set to the new language, effectively removing the aliases for other languages.

I don't have time to test that right now, but I suppose you'd have to follow these steps (roughly):
- Create a node, make sure you assign a path to it
- Add the same alias (path) for language 2 to that node
- Trigger the update of one of the aliases, _without_ explicitly updating the alias (I assume that passes a 'pid' as parameter and then the code block won't be triggered). That may require adding a translation with a different (or no) alias and saving that, such that the original node is saved through node_save (and not by posting the form, if I remember correctly that too passes the pid to the function).

If the aliases don't break in the above case, this patch should work completely. Matching the language in the query (either to the same language or language neutral) may solve that:

db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE dst = '%s' AND src='%s' AND (language = '' OR language = '%s')", $path, $alias, $language, $alias, $path, $language);

I might have time to try out the above this weekend, but feel free to beat me to it :)

roderik’s picture

Status: Active » Closed (duplicate)

The database error reported in the original post hasn't existed since D6.16.

An equivalent of the patch uploaded here, has been committed to D6.23 - as per #269877: path_set_alias() doesn't account for same alias in different languages