Hello,
plusieurs remarques sur ton mail.
1/ il y a incomprehension de la notion de jointure explicite. Tu dis "le compilateur DOIT l'ajouter". Non, ce n'est pas comme ça que ça marche. Cela doit se comprendre en "si le compilateur a besoin de champs supplémentaires, il doit regarder dans ces tables"
C'est une nuance de taille.
2/ oui il manque des tests unitaires sur la compilation des boucles, oui il faut les formaliser et les écrire, mais cela dit on sait qu'on a changé le comportement de certaines jointures un peu exotiques qui marchaient par chance en 3.0
3/ oui le commit en cause est très certainement
https://core.spip.net/projects/spip/repository/revisions/21875
qui fait un bugfix sur certains cas où le compilateur doublonnait des jointures car il piochait dans la jointure explicite sans verifier que le champ cherché existait déjà dans les jointures posées
4/ le critère {auteurs_liens.id_auteur?} ne veut pas dire que le compilateur ajoute la jointure uniquement si il y a un id_auteur dans le env, ça ne serait pas possible : la jointure est créer lors de la compilation, le env est connu a l'execution.
En pratique le compilateur ajoute la jointure dans la construction de la boucle (elle est donc toujours là), le critère where est lui ajouté de façon facultative en fonction du env, et l'executeur de requete se charge in fine de nettoyer les jointures et autres critères inutiles.
5/ on ne peut pas debug ta boucle car il faut connaitre son contenu, qui déclenche ou non les jointures. Je présume que ta boucle contient des #OBJET et #ID_OBJET
6/ si tu as bien suivi tu comprends ce qui se passe :
- le compilateur crée la boucle avec jointure sur spip_auteurs
- il voit un #ID_OBJET dans le corps de la boucle
- il cherche le champ dans la requete SQL et le trouve sur la table auteurs_liens
- lors de l'execution sans id_auteur dans le env, la jointure auteurs_liens est conservée car elle sert pour le champ #ID_OBJET
En 3.0 on avait
- le compilateur crée la boucle avec jointure sur spip_auteurs
- il voit un #ID_OBJET dans le corps de la boucle
- il cherche le champ dans les jointures explicites
- il ajoute la jointure sur selections_liens
- lors de l'execution sans id_auteur dans le env, la jointure auteurs_liens est supprimée
C'est pur coup de chance que ta boucle ait marché en 3.0 car il y a ambiguité sur le sens de #ID_OBJET qui peut venir aussi bien de selections_liens que de auteurs_liens, les deux jointures étant explicites dans ta boucle
Peut-être que la solution serait de modifier le sens des jointures explicites pour lui donner celui que tu suppose : une jointure que l'on force, explicitement, avant toute autre analyse de la boucle, quitte à ce qu'elle soit optimisée ensuite si elle ne sert pas.
Mais c'est une modification non mineure a tester en 3.2-dev
Par ailleurs il ne me parait pas judicieux de revenir sur le r21875 car celui ci corrige un vrai bug.
Je vais reflechir aux possibilités, côté compilateur, mais en attendant je vois deux solutions :
1/ faire une première boucle de selection avec un {id_auteur?} et un {doublons} et ensuite une boucle d'utilisation
2/ centrer ta boucle sur selections_liens avec les jointures explicites sur selections et auteurs_liens, mais je ne suis pas certain que id_auteur sera bien interprété dans ce cas, je crains qu'on ait une jointure directe selections_liens - auteurs_liens