Préfixe de BDD non spip_ et requêtes SQL

Pour info :
Quand le préfixe de la BDD n’est pas spip_, les requêtes de l’api sql_ doivent utiliser quand même le préfixe spip_, et il est transformé par le vrai préfixe de la BDD. Ainsi le code est valable quelque soit le préfixe. Toutefois, quand il y un JOIN dans la requête, SPIP ne transforme le préfixe que s’il y a des alias sur les tables utilisées.
On vient de préciser la doc sur ce point : Éléments communs - Programmer avec SPIP 4.0 (fin de page).
Il y a sur la zone des codes qui ne semblent pas conforme à cette nécessité, et qui donc ne marchent pas lorsque le préfixe n’est pas spip_. Une recherche sur \sjoin\s+[a-z]((?<!\bas\b).)*$ (triée ensuite) ramène les incidences suivantes. C’est pas forcément pertinent dans tous les cas, et il peut y avoir d’autres cas non répertoriés, à vérifier si votre code est concerné…

cog_fonctions.php 
154 'spip_options left join spip_optionsgroupes using(id_optionsgroupe)', 

comptes.php 
32 nal, intitule', 'spip_asso_comptes RIGHT JOIN spip_asso_plan ON journal=code', $critere_periode, "intitule DESC"); // on se permet sql_allfetsel car il s'agit d'une association (mois d'une demie dizaine de comptes) et non d'un etablissement financier (des milliers de comptes clients)
53 code, classe',  'spip_asso_comptes RIGHT JOIN spip_asso_plan ON imputation=code', "$where AND classe<>".sql_quote($GLOBALS['association_metas']['classe_banques']). " AND classe<>".sql_quote($GLOBALS['association_metas']['classe_contributions_volontaires']), 'code'); // une contribution benevole ne doit pas etre comptabilisee en charge/produit
72 'spip_asso_comptes RIGHT JOIN spip_asso_plan ON imputation=code',

determiner_statut_document.php 
36 'spip_documents_liens join spip_documents using(id_document)',

editer_client.php  
202 'spip_contacts_liens LEFT JOIN spip_contacts USING(id_contact)',
219 'spip_adresses_liens LEFT JOIN spip_adresses USING(id_adresse)',
231 'spip_numeros_liens LEFT JOIN spip_numeros USING(id_numero)',
246 'spip_numeros_liens LEFT JOIN spip_numeros USING(id_numero)',
267 'spip_numeros_liens LEFT JOIN spip_numeros USING(id_numero)',

encaisse.php  
25 nal, intitule', 'spip_asso_comptes RIGHT JOIN spip_asso_plan ON journal=code', "date_operation>=date_anterieure AND date_operation<=NOW()", "intitule DESC"); // on se permet sql_allfetsel car il n'y en a pas des masses a priori...

formidable_pipelines.php  
360 sies', 'spip_formulaires_reponses_champs JOIN spip_formulaires_reponses JOIN spip_formulaires', "id_formulaires_reponses_champ=$id AND spip_formulaires_reponses.id_formulaires_reponse = spip_formulaires_reponses_champs.id_formulaires_reponse AND spip_formulaires.id_formulaire = spip_formulaires_reponses.id_formulaire");

formidableparticipation_pipelines.php 
121 _formulaires_reponse', 'spip_formulaires JOIN spip_formulaires_reponses JOIN spip_formulaires_reponses_champs', "id_formulaires_reponses_champ=$id_formulaires_reponses_champ  AND spip_formulaires_reponses.id_formulaires_reponse = spip_formulaires_reponses_champs.id_formulaires_reponse AND spip_formulaires.id_formulaire = spip_formulaires_reponses.id_formulaire");
194 laires.id_formulaire', 'spip_formulaires JOIN spip_formulaires_reponses JOIN spip_evenements_participants', "spip_formulaires.id_formulaire = spip_formulaires_reponses.id_formulaire AND spip_formulaires_reponses.id_formulaires_reponse = spip_evenements_participants.id_formulaires_reponse AND spip_evenements_participants.id_evenement=$id_evenement"); // Pas réussi a reproduire en syntaxe squelette

formulaires_reponses_champ.php
20 l('*', 'spip_formulaires_reponses_champs JOIN spip_formulaires_reponses JOIN spip_formulaires', "id_formulaires_reponses_champ=$id_formulaires_reponses_champ AND spip_formulaires_reponses.id_formulaires_reponse = spip_formulaires_reponses_champs.id_formulaires_reponse AND spip_formulaires.id_formulaire = spip_formulaires_reponses.id_formulaire");

formulaires_reponses_champ.php
19  nom', 'spip_formulaires_reponses_champs JOIN spip_formulaires_reponses JOIN spip_formulaires', "id_formulaires_reponses_champ=$id AND spip_formulaires_reponses.id_formulaires_reponse = spip_formulaires_reponses_champs.id_formulaires_reponse AND spip_formulaires.id_formulaire = spip_formulaires_reponses.id_formulaire");

jeux_pipelines.php
163 esultat AS id","spip_jeux_resultats LEFT JOIN spip_auteurs ON spip_jeux_resultats.id_auteur = spip_auteurs.id_auteur","spip_auteurs.id_auteur IS NULL");
166 $res           = sql_select   ("spip_jeux_resultats.id_resultat AS id","spip_jeux_resultats LEFT JOIN spip_jeux ON spip_jeux_resultats.id_jeu = spip_jeux.id_jeu","spip_jeux.id_jeu IS NULL");

nettoyer_inscriptions_sans_evenement.php
29 ql_select('email', 'spip_mailsubscribers JOIN spip_mailsubscriptions', "spip_mailsubscribers.id_mailsubscriber = spip_mailsubscriptions.id_mailsubscriber AND `id_mailsubscribinglist`=$id_mailsubscribinglist AND `id_segment` = $id_segment");

reservation_communication.php 
31 				LEFT JOIN spip_types_documents USING(extension)', 'dl.id_objet = ' . $id_reservation_communication . '

reservations_credits_pipelines.php 
57 LEFT JOIN spip_reservations USING (id_reservation)
58 LEFT JOIN spip_prix_objets USING (id_prix_objet)',
61 riptif', 'spip_reservations_details LEFT JOIN spip_reservations USING (id_reservation)', 'id_evenement=' . $flux['args']['id_objet'] . ' AND spip_reservations_details.statut="accepte"');
response.php  (1 usage found)
61 'spip_reservations LEFT JOIN spip_reservations_details USING (id_reservation)',

secteur_langue_pipelines.php  
57 $parent = sql_fetsel('r.id_rubrique,r.lang AS lang_rub, a.lang AS lang_art', 'spip_articles a JOIN spip_rubriques r ON a.id_rubrique = r.id_rubrique', 'id_article=' . $id_article);

souscription_pipelines.php 
94 'spip_souscriptions LEFT JOIN spip_souscriptions_liens USING (id_souscription)',

soyezcreateurs_fonctions.php 
196 'spip_articles LEFT JOIN spip_rubriques ON spip_rubriques.id_rubrique = spip_articles.id_rubrique', 

spip_thelia_fonctions.php
512 JOIN produit ON produit.id = spip_produits_{$type}s.id_produit 
513 JOIN produitdesc ON produitdesc.id = spip_produits_{$type}s.id_produit 
563 JOIN rubrique ON rubrique.id = spip_rubriquesthelia_{$type}s.id_rubriquethelia
564 JOIN rubriquedesc ON rubriquedesc.rubrique = spip_rubriquesthelia_{$type}s.id_rubriquethelia

adherent.php 
503 INNER JOIN pg_catalog.pg_namespace ON pg_constraint.connamespace = pg_namespace.oid
504 INNER JOIN pg_catalog.pg_class ON pg_constraint.conrelid = pg_class.oid AND pg_constraint.connamespace = pg_class.relnamespace

bilan.php
58 $join = ' RIGHT JOIN spip_asso_plan ON imputation=code';

merci pour la recherhce.

Tu es sûr que ta copie de la zone est à jour ? formidable et formidable_participations ont été corrigés ce matin (suite précisement à ce rapport de bug !)

Mais est-ce que c’est pas un bug de SPIP quand même ?

Pourquoi est-ce qu’il ne transformerait pas le préfixe dans ces cas ? Pourquoi seulement quand ya un alias, selon quelle logique ? Ya une raison ?


RastaPopoulos

oui il y a bien un bug de spip, et utiliser l’alias permet de contourner.

En gros tout ce qui est après WHERE n’est pas transformé. J’ai essayé de comprendre où cela se passait, mais pas évident.

mIas on en discute dans le ticket ?

J’ai bien mis à jour mes repos avant de faire la recherche mais ç’a du être quasi-concomitant avec ton commit.

Ça me semble pas forcément un bug qu’il faille des alias… à partir du moment où c’est documenté.
Ça m’a étonné d’ailleurs de trouver aussi peu de requêtes sans alias. Les exemples de la doc ont visiblement été bien inspirants car ils ont toujours des alias eux.
Et pour rien cacher le ticket en question est #5112 - Les préfixes de table ne sont pas ajustés dans les clause WHERE - spip - SPIP on GIT

la discussion est erronée, car le postulat de départ de JLuc est faux. Le préfixe des tables présentes dans la clause join est bien remplacé. Le problème ne se pose que si on fait ensuite référence à la table dans la clause where (ce qui n’est pas toujours le cas, car il n’y a pas forcément ambiguité).

Pour faire court : on peut toujours faire mieux, au prix d’un impact performance important car cela veut dire parser la requete avec un vrai parseur là on on se contente d’un str_replace actuellement.

Donc oui la bonne réponse c’est toujours utiliser un alias à partir du moment où on besoin de référencer les tables dans la suite de la requête