[SPIP Zone] jointure conditionnelle dans un critère

Hello,
je coince sur un besoin qui me semble pourtant assez classique (c'est du spip 1.9.2)
je voulais faire une petite amélioration au critère tri_donnee de Forms&Tables pour gérer les tris sur les champs de type mot (que le tri soit fait sur le titre du mot et pas sur l'id_mot)
pour ca, il faut ajouter une jointure, mais uniquement quand le champ est de type mot_X.
Jusqu'ici, ca va, je sais faire, mettre une clause where uniquement dans ce cas, ca marche, pour le select, il suffit de mettre un truc bidon quand on est dans les autres cas (genre ", 1 as xxx") mais pas contre, je ne sais pas comment faire pour ne pas avoir de jointure dans les autres cas.
Voici ou j'en suis :

function critere_tri_donnee_dist($idb, &$boucles, $crit) {
        global $table_des_tables;
        $boucle = &$boucles[$idb];
        $t = $boucle->id_table;
        if ($t=='forms_donnees'){
            $not = $crit->not;
            $_quoi = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
               $k = count($boucle->join)+1;
            $boucle->join[$k]= array($t,'id_donnee');
            $boucle->from["L$k"]= 'spip_forms_donnees_champs';

/*
             //gestion des mots champs de type mot
            $l = $k+1;
             //ajout de la table dans le from si necessaire : bug car ajoute ', AS L2' dans les autres cas.
            $boucle->from["L$l"]= "'.(strncmp($_quoi,'mot_',4)==0?'spip_mots':'').'";
            //ajout de la clause pour la jointure
            $opl = array("'='", "'L$k.valeur'", "'L$l.id_mot'");
            $boucle->where[]= array("'?'","(strncmp($_quoi,'mot_',4)==0)",$opl,"''");
             //ajout du order
            $boucle->order[]= "(strncmp($_quoi,'mot_',4)==0?'L$l.titre':'')";
            //ajout du titre du mot au select (interet ?)
            $boucle->select[]= '".(strncmp('.$_quoi.',\'mot_\',4)==0?\'L'.$l.'.titre AS titre_mot\':\'0 as xxx\')."';
    */
                       $op = array("'='", "'L$k.champ'", "_q(".$_quoi.")");
            $boucle->where[]= array("'?'","!in_array($_quoi,array('rang','date','id_donnee','url'))",$op,"''");
            $boucle->order[]= "(in_array($_quoi,array('rang','date','id_donnee','url'))?'$t.'.$_quoi:(strncmp($_quoi,'date_',5)==0?'STR_TO_DATE(L$k.valeur,\'%d/%m/%Y\')':'L$k.valeur'))".($not?".' DESC'":"");
        }
    }
    // {date_compare champ operateur valeur}
    function critere_date_valeur_future_dist($idb, &$boucles, $crit) {
        global $table_des_tables;
        $boucle = &$boucles[$idb];
        $t = $boucle->id_table;
        if ($t=='forms_donnees_champs' OR $t=='forms_donnees'){
            $boucle->where[]= array("'>='","'STR_TO_DATE(valeur,\'%d/%m/%Y\')'","'NOW()'");
        }
    }

Queqlu'un aurait une idée pour contourner ce probleme ?
comment faire $boucle->from["L$l"]= "'.(strncmp($_quoi,'mot_',4)==0?'spip_mots':'').'";
sans se retrouver avec le fameux ", AS L2" dans le le FROM ?
J'ai creusé pas mal de pistes mais elles dégradent toutes les perf.

@++

Le 9 avril 2009 11:35, Stephane <stephane@rezo.net> a écrit :

Hello,
je coince sur un besoin qui me semble pourtant assez classique (c’est du spip 1.9.2)
je voulais faire une petite amélioration au critère tri_donnee de Forms&Tables pour gérer les tris sur les champs de type mot (que le tri soit fait sur le titre du mot et pas sur l’id_mot)
pour ca, il faut ajouter une jointure, mais uniquement quand le champ est de type mot_X.
Jusqu’ici, ca va, je sais faire, mettre une clause where uniquement dans ce cas, ca marche, pour le select, il suffit de mettre un truc bidon quand on est dans les autres cas (genre « , 1 as xxx ») mais pas contre, je ne sais pas comment faire pour ne pas avoir de jointure dans les autres cas.
Voici ou j’en suis :

Queqlu’un aurait une idée pour contourner ce probleme ?
comment faire $boucle->from[« L$l »]= « ‹ .(strncmp($quoi,'mot ›,4)==0?‹ spip_mots ›:‹  ›).' »;
sans se retrouver avec le fameux « , AS L2 » dans le le FROM ?
J’ai creusé pas mal de pistes mais elles dégradent toutes les perf.

En 1.9.2 je ne suis pas sur que ce soit possible.
En SPIP 2.0, le compilateur optimise la requete en virant les jointures qui ne servent pas (ie qui n’apparaissent nulle part dans le reste de la requete). Cela permettrait de s’en sortir.

Cédric

Cédric Morin a écrit :

    Queqlu'un aurait une idée pour contourner ce probleme ?
    comment faire $boucle->from["L$l"]=
    "'.(strncmp($_quoi,'mot_',4)==0?'spip_mots':'').'";
    sans se retrouver avec le fameux ", AS L2" dans le le FROM ?
    J'ai creusé pas mal de pistes mais elles dégradent toutes les perf.

En 1.9.2 je ne suis pas sur que ce soit possible.
En SPIP 2.0, le compilateur optimise la requete en virant les jointures qui ne servent pas (ie qui n'apparaissent nulle part dans le reste de la requete). Cela permettrait de s'en sortir.

dans ce cas, pour spip 2.0, il suffit de faire :
            //gestion des mots champs de type mot
           $l = $k+1;
            //ajout de la table dans le from .
           $boucle->from["L$l"]= 'spip_mots';
           //ajout de la clause pour la jointure
           $opl = array("'='", "'L$k.valeur'", "'L$l.id_mot'");
           $boucle->where= array("'?'","(strncmp($_quoi,'mot_',4)==0)",$opl,"''");
            //ajout du order
           $boucle->order= "(strncmp($_quoi,'mot_',4)==0?'L$l.titre':'')";
           //ajout du titre du mot au select (interet ?)
           $boucle->select= '".(strncmp('.$_quoi.',\'mot_\',4)==0?\'L'.$l.'.titre AS titre_mot\':\'0 as xxx\')."';

et ca devrait marcher.

sais-tu ou je pourrais trafiquer en 1.9.2 pour eliminer des requetes les eventuels ", AS xxx" parasites (un genre d'optimisation sauvage pour rattraper les where vides malencontreux) ?
à part traite_query, je vois pas trop.

@++