[spip-dev] Oups, Maj SPIP-Contrib...

Hello,

Je viens de passer SPIP-Contrib en 12199, il était en 11820 je crois.

Après la demande de maj de la base, il m'a dit :
http://www.spip-contrib.net/ecrire/?action=purger&arg=cache&hash=3909fb1ca99c2a0dfa234025066f369a&redirect=.%2F

Page blanche : ecrire/ en trop.

http://www.spip-contrib.net/ecrire/?exec=admin_vider donne page blanche.
J'ai plein d'erreurs de compilations sur les squelettes de contrib...
&var_mode=calcul ou recalcul = page blanche aussi...

Pour les erreurs de compil, elles semblent dues à :

     static $where =
              array(
              array('=', 'rubriques.statut', '\'publie\''),
              array('=', 'rubriques.id_parent', 0),
             array('!=', 'id_secteur', _q(boucle_exclure_secteur())));

le static et la fonction boucle_exclure...()

_q ne doit pas être utilisée dans le code compilé, c'est sql_quote qu'il faut utiliser sinon spip-sqlite ne marchera pas.

Avec le static en plus, ça ne marche donc plus nulle part ce qui n'est pas plus mal, ça force à la portabilité.

Committo,Ergo:Sum

Matthieu Marcillaud a écrit :

Hello,

Je viens de passer SPIP-Contrib en 12199, il était en 11820 je crois.

Je suis remonté en 12118 pour ne plus avoir l'erreur.

Committo,Ergo:sum a écrit :

Pour les erreurs de compil, elles semblent dues à :

   static $where =
            array(
            array('=', 'rubriques.statut', '\'publie\''),
            array('=', 'rubriques.id_parent', 0),
           array('!=', 'id_secteur', _q(boucle_exclure_secteur())));

_q ne doit pas être utilisée dans le code compilé, c'est sql_quote qu'il faut utiliser sinon spip-sqlite ne marchera pas.

Avec le static en plus, ça ne marche donc plus nulle part ce qui n'est pas plus mal, ça force à la portabilité.

Oui, mais là, c'est le compilo qui sort ça (me semble-t-il)... ou alors, ou alors... ... ...
en tout cas, c'était un extrait de ?var_mode=debug sur la page d'accueil, inc-entete.html de contrib.

MM.

Committo,Ergo:sum a écrit :

_q ne doit pas être utilisée dans le code compilé, c'est sql_quote qu'il

Ok, c'était une fonction perso de spip-contrib pour le _q()

Par contre, il reste le problème de static + fonction() non ?

boucle_exclure_secteur n'est pas dans les sources de SPIP ...

Committo,Ergo:Sum

Non, justement: le compilateur connait les fonctions qu'il produit, s'il voit sql_* il sait que ce n'est pas statique, s'il n'en voit pas et qu'il considère que oui.

Committo,Ergo:Sum

* Matthieu Marcillaud tapuscrivait, le 25/07/2008 18:52:

Committo,Ergo:sum a écrit :

_q ne doit pas être utilisée dans le code compilé, c'est sql_quote qu'il

Ok, c'était une fonction perso de spip-contrib pour le _q()

Par contre, il reste le problème de static + fonction() non ?

Pour contourner ce bug là, j'ai suivi les conseils de Cédric et fait :
http://permalink.gmane.org/gmane.comp.web.spip.devel/48788

Donc, la seule ligne à modifier est la 358

Committo,Ergo:sum a écrit :

Par contre, il reste le problème de static + fonction() non ?

Non, justement: le compilateur connait les fonctions qu'il produit, s'il voit sql_* il sait que ce n'est pas statique, s'il n'en voit pas et qu'il considère que oui.

Ok, donc, si on utilise une fonction perso qui ne commencerait pas par sql_, alors ça plante ? ...

En tout cas, là, Contrib semble tourner correctement en 12119. Merci pour ton aide.

Oui. Le hack de Cédric est un moyen de contourner ça mais il faut bien voir que le but n'est évidemment pas de forcer les gens à préfixer leurs fonctions par "sql_", mais de permettre au compilateur de toujours maîtriser la grammaire du sous-ensemble de PHP qu'il produit. Une fonction qui change le compilateur doit comprendre la grammaire de ce qu'il produit, c'est assez normal. L'optimisation permise par static ajoute comme règle de grammaire que les seules fonctions autorisées ici sont celles définies dans base/abstract_sql.php.

Committo,Ergo:Sum

Je reviens la dessus, c'est extremement gênant de produire du code php qui plante dès qu'on a une fonction dans un critere where personalisé. Cela va faire planter plus d'un site, et on ne peut pas laisser cela comme ça.
Soit on detecte correctement les fonctions pour ne pas produire le static, soit on décide que les fonctions sont considérées invariantes sur un hit, et on produit le code php valide, soit on enlève complètement ce static.

Du code qui marchait se retrouve injouable par la faute d'une optimisation ; on casse donc volontairement une compatibilité, pour un gain ponctuel ; difficile d'expliquer à tous ceux dont le code est cassé que c'est une amélioration.

Cédric

Je reviens la dessus, c'est extremement gênant de produire du code php qui plante dès qu'on a une fonction dans un critere where personalisé. Cela va faire planter plus d'un site, et on ne peut pas laisser cela comme ça.
Soit on detecte correctement les fonctions pour ne pas produire le static, soit on décide que les fonctions sont considérées invariantes sur un hit, et on produit le code php valide, soit on enlève complètement ce static.

Comment peux-tu proposer la solution 2 parce qu'alors comme tu dis pour l'existant:

Du code qui marchait se retrouve injouable par la faute d'une optimisation ;

à la seule différence que ce ne sera pas une erreur de syntaxe mais de sémantique on signalée, donc encore plus difficile à détecter. Je trouve assez fou de devoir répéter 36 fois qu'il vaut mieux déclencher une erreur de syntaxe que de laisser passer une erreur de sémantique. Et je dois visiblement répétér que pour cette raison ton hack est FAUX dans le cas général, il vaudrait mieux l'oublier. Ce qui marche c'est de coller le résultat de la fonction dans une variable, et de faire apparaître cette variable dans la valeur de $where.

Pour la solution 1, il faut bien voir qu'il y a dans les valeurs analysées les parenthèses des constructions SQL (DATE, NOW, FIELD, IN et à la limite des procédures SQL stockées); autrement dit il faut redévelopper un analyseur syntaxique de SQL, c'est évidemment hors de question.

Reste donc la solution 3: renoncer à cette optimisation. Evidemment on peut, ce serait pas dramatique. Mais je pose quand même la question: combien de gens sont concernés par la question, et sur ceux-ci combien trouveront au contraire intéressant d'approfondir leur compréhension du compilateur afin de produire du code meilleur ?

Committo,Ergo:Sum

Reste donc la solution 3: renoncer à cette optimisation. Evidemment on peut,

On pourrait peut-être décider que c'est aux fonctions qu'on appelle de
savoir si elles peuvent s'optimiser en utilisant un static en interne
(comme le font déjà plein de fonctions du core).

-- Fil

J'énumérais juste les possibilités.

Considérant que de toute façon, en l'état, on forçait à passer par le stockage du résultat de la fonction dans une variable, donc on n'optimisait pas avec "static", j'ai commis
http://trac.rezo.net/trac/spip/changeset/12202
qui detecte tout ce qui ressemble à une fonction dans le $val, à l'exception des array() et des fonctions SQL présentes dans les chaînes de caractères.

Au moins, les critères personnalisés qui fonctionnaient jusqu'ici restent fonctionnels.
Pour ce qui est de l'optimisation, il est dans ce cas du ressort de la fonction appelée de gérer ses static si nécessaire (ce qui est le cas des fonctions Accesrestreint_xxx depuis longtemps)

Cédric

C'est mieux que rien mais c'est dommage de ne pas aller plus loin: la variable $where est un tableau qui peut être assez gros, si on arrive à le déclarer statique il ne sera construit qu'une fois. Et sur le principe, il est anormal que le code compilé contiennent des fonctions sorties de nulle part: ces fonctions doivent produire du code SQL donc être exécutées à la compilation et retourner des noms de champs ou des constantes, et $where pourra alors être statique, ou alors une chaîne contenant des "sql_...", et $where ne sera pas statique.

Bon, encore une fois c'est mineur et le problème de fond est PHP n'est pas un bon langage de développement, on n'y peut rien.
Mais je trouve dommage d'encourager l'absence de réflexion chez ceux qui enrichissent le compilateur.

Committo,Ergo:Sum

En l'occurence, le gars qui a commit la dite fonction s'est assez arraché les cheveux dessus et sur son optimisation pour savoir qu'elle n'est actuellement pas résumable à une requete sql en l'état de la base de donnée.

Et l'absence de réflexion vaut alors aussi pour ceux qui développent le compilateur :stuck_out_tongue:
http://trac.rezo.net/trac/spip/browser/spip/ecrire/public/criteres.php#L240

Cédric

En l'occurence, le gars qui a commit la dite fonction s'est assez arraché les cheveux dessus et sur son optimisation pour savoir qu'elle n'est actuellement pas résumable à une requete sql en l'état de la base de donnée.

Mais enfin si puisque ce sera du SQL in fine ! C'est là que j'ai l'impression que tu encourages toutes les bidouilles: un compilateur DOIT savoir la grammaire du langage qu'il produit. S'il ne le sait pas, c'est la porte ouverte aux trous de sécurité, et la porte fermée à toute optimisation sérieuse. Sur le pb du jour c'est suffisamment circonscrit pour qu'on voit encore à peu près ce qui se passe, mais tôt ou tard on paira ces licences que l'usage de "static" permettaient de contrer.
Je trouve donc qu'on prépare infiniment mieux l'avenir en disant de revoir leur copie aux pour l'instant rares personnes qui savent que SPIP est aussi une plate-forme de développement, qu'en donnant la possibilité de faire produire au compilateur du code ingérable.

Et l'absence de réflexion vaut alors aussi pour ceux qui développent le compilateur :stuck_out_tongue:
http://trac.rezo.net/trac/spip/browser/spip/ecrire/public/criteres.php#L240

SPIP a démarré avec une certaine ignorance des problématiques de compilation, Arnaud ne me contredira pas; ce qu'on fait pour assurer la compatibilité ne peut être invoqué comme contre argument à un apprentissage que tout ceux qui veulent faire de la compilation on intérêt à faire le plus rapidement possible.

Committo,Ergo:Sum

Je vais sans doute dire une connerie, ce ne serait pas la première fois, et j'avoue que j'ai du mal à suivre votre discussion d'experts, mais... et si justement il n'y avait pas que SQL in fine ?

-Nicolas

Pour moi le problème du compilateur c'est que grosso modo seul esj
comprend ce qu'il fait ; deux ou trois autres zozos s'accrochent tant
bien que mal, grâce au débugueur, pour essayer de placer du code à tel
ou tel endroit. L'absence de commentaires et le code plein de a ? b :
c n'encourage pas la prise en mains.

-- Fil

L'argument de la compatibilité pour le critère branche vaut aussi pour le cas du plugin Acces restreint :
La structure de la base de donnée ne permet pas de sélectionner tous les enfants d'une branche avec une requête SQL mais oblige à passer par du php et while.

Tant que cela sera le cas, on ne peut exclure le besoin de faire appel à des fonctions traduisant une simple requete "tous les enfants de ..." en liste d'id_rubrique.

Cela dit, ça fait un moment que ça me démange d'introduire une gestion intervallaire de l'aborescence. Je n'ai pas encore eu le temps car le problème n'est pas simple, d'autant plus que mySQL ne gérant pas les transactions il faut garder une double structure :
- simple pointeur vers le parent qui sert de référence car on est sur que cette info ne peut être corrompue (il est toujours possible de déplacer une branche en une seule requête)
- gestion des bornes intervallaires permettant de faire un selection de branche en une simple requete SQL.

Une fois cette problématique résolue, je ne crois pas qu'on puisse exclure pour autant l'appel à des fonctions php car il restera toujours des cas un peu tordus qu'on imagine pas forcément.

Cédric