[spip-dev] Problème WHERE

Bonjour,

lors d'un ajout de document via l'api action/ajouter_documents, je tombe sur cette erreur mysql (dans les logs)

2021-04-13 06:02:01 127.0.0.1 (pid 509) ecrire/base/connect_sql.php:L170:spip_sql_erreur()::Pub:ERREUR: Erreur 1064 de mysql: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sql_quote('article')) GROUP BY auteurs.id_auteur /* BOUCLEauteurs @ | /spip....' at line 8 in /home/http/www/spip33/sngpckda.spip/ecrire/public/composer.php L941 [sql_select(),calculer_select(),objet_test_si_publie(),inc_determiner_statut_document(),document_instituer(),medias_post_edition(),minipipe(),execute_pipeline_post_edition(),pipeline(),action_ajouter_un_document_dist(),action_ajouter_documents_dist(),inc_bigform_traiter_dist(),formulaires_admin_adherent_traiter_dist(),traiter_formulaires_dynamiques(),include()]

SELECT L3.id_auteur AS id_auteur

FROM `spip33_sngpckda`.spip_auteurs AS `auteurs`

INNER JOIN `spip33_sngpckda`.spip_auteurs_liens AS L3 ON ( L3.id_auteur = auteurs.id_auteur )

INNER JOIN `spip33_sngpckda`.spip_articles AS L4 ON ( L4.id_article = L3.id_objet AND L3.objet='article')

WHERE (L4.statut = 'publie')

 AND NOT\(\(auteurs\.statut = '5poubelle'\)\)

 AND auteurs\.id\_auteur=21

 AND \('L3\.objet' '=' sql\_quote\('article'\)\)

GROUP BY auteurs.id_auteur

Le problème se situe : ('L3.objet' '=' sql_quote('article'))

Est qu'une personne aurait une idée ?

Hello,

Le code qui génère la requête est mal écrit ; le sql_quote devrait être interprété. D’après le message d’erreur on peut supposer que l’erreur se produit dans une boucle auteur.
Tu n’as pas un plugin qui défini de nouveaux critères ou un bout de code perso dans un pipeline pre_boucle qui viendrait modifier la boucle auteur? (Adhérents??)

Il peut s’agir aussi d’une coquiille dans la déclaration de table_jointure ou execptions_des_jointures…

En ce qui concerne la relation entre les documents et les auteurs, Il me semble que media vérifie juste une autorisation basic d’ajout ou d’association sur l’objet, mais pas de cette manière.

précisions :

c’est dans le traiter d’un cvt, j’utilise :

		$ajouter_document = charger_fonction('ajouter_documents', 'action');
		$Tid_doc = $ajouter_document('new', $files, $objet, $id_objet, $mode);

la fonction calculer_mysql_where($where)

si elle prend en entrée un array :

Array (

[0] => '='

[1] => 'L1.objet'

[2] => sql_quote('article')

)

va produire :

$arg = "'L1.objet'";

$arg2 = "sql_quote('article')";

$op = "'='";

Donc

return "($arg $op $arg2)"; => donne : ('L1.objet' '=' sql_quote('article'))

Pourquoi dans la valeur d'entrée le = et L1.objet sont entre quote ?

Je continue mes investigations

C’est entre quote car ça doit génère du code à interpréter. Il me semble que les fonctions calculer_XX s’exécutent dans l’environnement de compilation pour produire du php.

Est-ce que c’est une erreur bloquante qui t’empêche de joindre le document?

Vu le code, je dirai que c’est une requête générée par une boucle. Je pense plutôt que ça vient d’un critère foireux ou d’un mauvais paramètre passer en critère.
T’as pas une Boucle AUTEURS avec une jointure qui se ferait sur documents_liens et articles? (AUTEURS documents_liens){objet?} ou un truc du genre (pour afficher un résumer de l’upload par exemple…)

Perso je vois pas où pourrait se cacher cette requête dans l’api joindre_document…

Bon courage & bonne nuit :wink:

C'est surtout le calcul de ces critères qui a foiré son calcul
en laissant les quotes autour de "'='" et "'sql_quote(..)'"
et après c'est normal que ça provoque une erreur.

Je demandais hier sur irc : quand tu cites le message d'erreur
il y a ce qui ressemble à la pile d'appel :
"[sql_select(), calculer_select(), objet_test_si_publie(), inc_determiner_statut_document(), document_instituer(), medias_post_edition(), etc ]
C'est étonnant ça : c'est SPIP qui a gardé une trace de la pile d'appel ayant calculé les critères
et qui la présente ainsi ou c'est toi ?

Cette pile c'est justement ce qui semble construire les critères.
Ça décrit, dans le pipeline post_edition, le calcul du statut du document
à partir du statut de l'objet auteur il est lié.

objet_test_si_publie appelle instituer_boucle
et on dirait que instituer_boucle se trompe :
- Dans le cas où il y a une exception (cas 'visiteur'), ça retourne prématurément
et ça n'appelle pas fabrique_jointures et ça se passe bien
- mais dans le cas administrateur, ça appelle fabrique_jointures
et c'est un peu comme si fabrique_jointures était alors appelé avec $echap=true
et du coup le calculer_select se plante après

Note que dans ton message d'erreur, c'est id_auteur 21 qui apparaît
et non 13 comme tu le dis. Ça change quelque chose ?

JL

C'est surtout le calcul de ces critères qui a foiré son calcul
en laissant les quotes autour de "'='" et "'sql_quote(..)'"
et après c'est normal que ça provoque une erreur.

Je demandais hier sur irc : quand tu cites le message d'erreur
il y a ce qui ressemble à la pile d'appel :
"[sql_select(), calculer_select(), objet_test_si_publie(), inc_determiner_statut_document(), document_instituer(), medias_post_edition(), etc ]
C'est étonnant ça : c'est SPIP qui a gardé une trace de la pile d'appel ayant calculé les critères
et qui la présente ainsi ou c'est toi ?

==> cette pile d'appel -> c'est une récup dans les log mysql.log

Cette pile c'est justement ce qui semble construire les critères.
Ça décrit, dans le pipeline post_edition, le calcul du statut du document
à partir du statut de l'objet auteur il est lié.

objet_test_si_publie appelle instituer_boucle
et on dirait que instituer_boucle se trompe :
- Dans le cas où il y a une exception (cas 'visiteur'), ça retourne prématurément
et ça n'appelle pas fabrique_jointures et ça se passe bien
- mais dans le cas administrateur, ça appelle fabrique_jointures
et c'est un peu comme si fabrique_jointures était alors appelé avec $echap=true
et du coup le calculer_select se plante après

Note que dans ton message d'erreur, c'est id_auteur 21 qui apparaît
et non 13 comme tu le dis. Ça change quelque chose ?

==> ca ne change rien, j'ai testé sur différents auteurs

J'ai trouvé

C'est depuis ce commit

https://git.spip.net/spip/spip/commit/81b3f6dd22d699986ca2d5a068959ec0011b4253

et l'ajout de :

$boucle->where["JOIN-L$n"] = array("'='","'$obj'","sql_quote('$type')");

si on remplace cette ligne par :

$boucle->where["JOIN-L$n"] = $echap ? array("'='","'$obj'","sql_quote('$type')") : array("=","$obj","sql_quote('$type')");

Cela fonctionne sauf que maintenant :

ecrire/base/connect_sql.php:L170:spip_sql_erreur()::Pub:ERREUR: Erreur 1305 de mysql: FUNCTION spip33_sngpckda.sql_quote does not exist

Ah bien vu, je pense que tu l’as quasiment.
Dans le second cas c’est probablement array("=" , "$obj",sql_quote($type))

Oui effectivement, on peut enlever les quote autour de $type.

par contre, il y a un log dans mysql.log:

ecrire/base/connect_sql.php:L169:spip_sql_erreur()::Pub:ERREUR: Erreur 1305 de mysql: FUNCTION spip33_sngpckda.sql_quote does not exist

ce problème de sql_quote c’est ici que cela plante :

ce qui est etonnant, c’est une fonction sql_select qui est appelé et qui fait planté sql_quote.

C’est normalement corrigé par
https://git.spip.net/spip/spip/commit/e0e29f27d9d883811f5713bbe5eefa5f9aeb3c22

Il faut peut etre que tu recalcule pour te débarasser de code compilé faux lorsque tu as essayé de debug ?

Merci

sujet #close