Skip to content
Extraits de code Groupes Projets
Valider 5105a66b rédigé par esj's avatar esj
Parcourir les fichiers

mauvais retour de boucles récursives (nic;o & paolo); code gourmand, mort ou...

mauvais retour de boucles récursives (nic;o & paolo); code gourmand, mort ou mal structuré dans le calcul des champs SQL par le compilateur
parent edd704fb
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -617,25 +617,19 @@ function prepare_recherche($recherche, $type = 'id_article', $table='articles') ...@@ -617,25 +617,19 @@ function prepare_recherche($recherche, $type = 'id_article', $table='articles')
arsort($points, SORT_NUMERIC); arsort($points, SORT_NUMERIC);
# calculer le {id_article IN()} et le {... as points} # calculer le {id_article IN()} et le {... as points}
if (count($points)) { if (!count($points)) {
$cache[$type][$recherche] = array('', '');
} else {
$ids = array(); $ids = array();
$expr = ''; $select = '0';
foreach ($points as $id => $p) foreach ($points as $id => $p)
$listes_ids[$p] .= ','.$id; $listes_ids[$p] .= ','.$id;
foreach ($listes_ids as $p => $liste_ids) foreach ($listes_ids as $p => $liste_ids)
$expr .= "+$p*(".calcul_mysql_in("$table.$type", substr($liste_ids, 1)).") "; $select .= "+$p*(".calcul_mysql_in("$table.$type", substr($liste_ids, 1)).") ";
if ($expr = substr($expr,1))
$select = "$expr as points";
else
$select = "0 as points";
$where = '('.calcul_mysql_in("$table.$type", join(',',array_keys($points))).')'; $cache[$type][$recherche] = array($select,
} else { '('.calcul_mysql_in("$table.$type", join(',',array_keys($points))).')');
$select = '';
$where = '';
} }
$cache[$type][$recherche] = array($select, $where);
} }
return $cache[$type][$recherche]; return $cache[$type][$recherche];
......
...@@ -280,8 +280,6 @@ function boucle_SYNDIC_ARTICLES_dist($id_boucle, &$boucles) { ...@@ -280,8 +280,6 @@ function boucle_SYNDIC_ARTICLES_dist($id_boucle, &$boucles) {
$boucle->where['statut'] = "$id_table.statut IN ('publie','prop')"; $boucle->where['statut'] = "$id_table.statut IN ('publie','prop')";
} }
$boucle->select[]='syndic.nom_site AS nom_site'; # derogation zarbi
$boucle->select[]='syndic.url_site AS url_site'; # idem
return calculer_boucle($id_boucle, $boucles); return calculer_boucle($id_boucle, $boucles);
} }
......
...@@ -62,7 +62,7 @@ class Boucle { ...@@ -62,7 +62,7 @@ class Boucle {
var $order = ''; var $order = '';
var $default_order = ''; var $default_order = '';
var $date = 'date' ; var $date = 'date' ;
var $hash = false ; var $hash = "" ;
var $lien = false; var $lien = false;
var $sous_requete = false; var $sous_requete = false;
var $hierarchie = ''; var $hierarchie = '';
......
...@@ -90,8 +90,10 @@ function index_pile($idb, $nom_champ, &$boucles, $explicite='') { ...@@ -90,8 +90,10 @@ function index_pile($idb, $nom_champ, &$boucles, $explicite='') {
// On l'a trouve // On l'a trouve
if ($e) { if ($e) {
$boucles[$idb]->select[] = $t . "." . $e; $t .= ".$e";
return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']'; if (!in_array($t, $boucles[$idb]->select))
$boucles[$idb]->select[] = $t;
return '$Pile[$SP' . ($i ? "-$i" : "") . '][\'' . $c . '\']';
} }
# spip_log("On remonte vers $i"); # spip_log("On remonte vers $i");
// Sinon on remonte d'un cran // Sinon on remonte d'un cran
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
if (defined("_INC_COMPILO")) return; if (defined("_INC_COMPILO")) return;
define("_INC_COMPILO", "1"); define("_INC_COMPILO", "1");
// reperer un code ne calculant rien, meme avec commentaire
define('CODE_MONOTONE', "^(\n//[^\n]*\n)?\(?'([^'])*'\)?$");
// Definition de la structure $p, et fonctions de recherche et de reservation // Definition de la structure $p, et fonctions de recherche et de reservation
// dans l'arborescence des boucles // dans l'arborescence des boucles
...@@ -83,20 +85,16 @@ function calculer_inclure($struct, $descr, &$boucles, $id_boucle) { ...@@ -83,20 +85,16 @@ function calculer_inclure($struct, $descr, &$boucles, $id_boucle) {
// //
function calculer_boucle($id_boucle, &$boucles) { function calculer_boucle($id_boucle, &$boucles) {
$boucle = &$boucles[$id_boucle]; $boucle = &$boucles[$id_boucle];
$return = $boucle->return; $return = $boucle->return;
$type_boucle = $boucle->type_requete; $type_boucle = $boucle->type_requete;
if ($type_boucle == 'boucle')
return "\n \$t0 = " . $return . ";";
if ($type_boucle == 'boucle') {
$corps = "\n \$t0 = " . $return . ";";
$init = "";
} else {
$id_table = $boucle->id_table; $id_table = $boucle->id_table;
$primary = $boucle->primary; $primary = $boucle->primary;
if($p = strpos($primary, ',')) {
$id_field = $id_table . "." . substr($primary, 0, $p);
} else {
$id_field = $id_table . "." . $primary;
}
// La boucle doit-elle selectionner la langue ? // La boucle doit-elle selectionner la langue ?
// 1. par defaut, les boucles suivantes le font // 1. par defaut, les boucles suivantes le font
...@@ -114,33 +112,26 @@ function calculer_boucle($id_boucle, &$boucles) { ...@@ -114,33 +112,26 @@ function calculer_boucle($id_boucle, &$boucles) {
if ($boucle->lang_select == 'oui') $lang_select = 'oui'; if ($boucle->lang_select == 'oui') $lang_select = 'oui';
if ($boucle->lang_select == 'non') $lang_select = false; if ($boucle->lang_select == 'non') $lang_select = false;
// Penser a demander le champ lang // Penser a demander le champ lang au serveur SQL
if ($lang_select) if ($lang_select)
$boucle->select[] = index_pile($id_boucle, 'lang', $boucles);
// cas des tables SPIP
($id_table ? $id_table.'.' : '')
// cas general ({lang_select} sur une table externe)
. 'lang';
// Calculer les invalideurs si c'est une boucle non constante // Calculer les invalideurs si c'est une boucle non constante
$constant = ereg("^\(?'[^']*'\)?$",$return); $constant = ereg(CODE_MONOTONE,$return);
if ((!$primary) || $constant) if ((!$primary) || $constant)
$invalide = ''; $invalide = '';
else { else {
$boucle->select[] = $id_field; $invalide = "\n \$Cache['$primary'][" .
(($primary != 'id_forum') ?
$invalide = "\n \$Cache['$primary']"; index_pile($id_boucle, $primary, $boucles) :
if ($primary != 'id_forum') ("calcul_index_forum(" .
$invalide .= "[\$Pile[\$SP]['$primary']] = 1;"; // Retournera 4 [$SP] mais force la demande du champ a MySQL
else index_pile($id_boucle, 'id_article', $boucles) . ',' .
$invalide .= "[calcul_index_forum(" . index_pile($id_boucle, 'id_breve', $boucles) . ',' .
// Retournera 4 [$SP] mais force la demande du champ a MySQL index_pile($id_boucle, 'id_rubrique', $boucles) .',' .
index_pile($id_boucle, 'id_article', $boucles) . ',' . index_pile($id_boucle, 'id_syndic', $boucles) .
index_pile($id_boucle, 'id_breve', $boucles) . ',' . ")")) .
index_pile($id_boucle, 'id_rubrique', $boucles) .',' . '] = 1; // invalideurs';
index_pile($id_boucle, 'id_syndic', $boucles) . ")] = 1;";
$invalide .= ' // invalideurs';
} }
// Cas {1/3} {1,4} {n-2,1}... // Cas {1/3} {1,4} {n-2,1}...
...@@ -181,7 +172,6 @@ function calculer_boucle($id_boucle, &$boucles) { ...@@ -181,7 +172,6 @@ function calculer_boucle($id_boucle, &$boucles) {
$code_sep = ("'" . ereg_replace("'","\'",join('',$boucle->separateur)) . "'"); $code_sep = ("'" . ereg_replace("'","\'",join('',$boucle->separateur)) . "'");
// gestion optimale des separateurs et des boucles constantes // gestion optimale des separateurs et des boucles constantes
$corps = $debut . $corps = $debut .
((!$boucle->separateur) ? ((!$boucle->separateur) ?
(($constant && !$debut) ? $return : (($constant && !$debut) ? $return :
...@@ -197,29 +187,27 @@ function calculer_boucle($id_boucle, &$boucles) { ...@@ -197,29 +187,27 @@ function calculer_boucle($id_boucle, &$boucles) {
if ($boucle->mode_partie) if ($boucle->mode_partie)
$corps .= "\n }\n"; $corps .= "\n }\n";
$texte = ''; $init = '';
// Gestion de la hierarchie (voir inc-boucles.php3) // Gestion de la hierarchie (voir inc-boucles.php3)
if ($boucle->hierarchie) if ($boucle->hierarchie)
$texte .= "\n ".$boucle->hierarchie; $init .= "\n ".$boucle->hierarchie;
// si le corps est une constante, ne pas appeler le serveur N fois! // si le corps est une constante, ne pas appeler le serveur N fois!
if (ereg("^\(?'[^']*'\)?$",$corps)) { if (ereg(CODE_MONOTONE,$corps, $r)) {
// vide ? if (!$r[2]) {
if (($corps == "''") || ($corps == "('')")) {
if (!$boucle->numrows) if (!$boucle->numrows)
return 'return "";'; return 'return "";';
else else
$corps = ""; $corps = "";
} else { } else {
$boucle->numrows = true; $boucle->numrows = true;
$corps = "\n ".'for($x=$Numrows["'.$id_boucle.'"]["total"];$x>0;$x--) $corps = "\n ".'for($x=$Numrows["'.$id_boucle.'"]["total"];$x>0;$x--)
$t0 .= ' . $corps .';'; $t0 .= ' . $corps .';';
} }
} else { } else {
$corps = ' $corps = '
// RESULTATS // RESULTATS
while ($Pile[$SP] = @spip_abstract_fetch($result,"' . while ($Pile[$SP] = @spip_abstract_fetch($result,"' .
...@@ -229,7 +217,7 @@ function calculer_boucle($id_boucle, &$boucles) { ...@@ -229,7 +217,7 @@ function calculer_boucle($id_boucle, &$boucles) {
// Memoriser la langue avant la boucle pour la restituer apres // Memoriser la langue avant la boucle pour la restituer apres
if ($lang_select) { if ($lang_select) {
$texte .= "\n \$old_lang = \$GLOBALS['spip_lang'];"; $init .= "\n \$old_lang = \$GLOBALS['spip_lang'];";
$corps .= "\n \$GLOBALS['spip_lang'] = \$old_lang;"; $corps .= "\n \$GLOBALS['spip_lang'] = \$old_lang;";
} }
} }
...@@ -238,26 +226,21 @@ function calculer_boucle($id_boucle, &$boucles) { ...@@ -238,26 +226,21 @@ function calculer_boucle($id_boucle, &$boucles) {
// Requete // Requete
// //
// hack critere recherche : ignorer la requete en cas de hash vide
// Recherche : recuperer les hash a partir de la chaine de recherche
if ($boucle->hash)
$init = '
// RECHERCHE
list($rech_select, $rech_where) = prepare_recherche($GLOBALS["recherche"], "'.$boucle->primary.'", "'.$boucle->id_table.'");
if ($rech_select) ';
if (!$order = $boucle->order if (!$order = $boucle->order
AND !$order = $boucle->default_order) AND !$order = $boucle->default_order)
$order = "''"; $order = "''";
$init .= "\n\n // REQUETE $init .= $boucle->hash .
"\n\n // REQUETE
\$result = spip_abstract_select(\n\t\tarray(\"". \$result = spip_abstract_select(\n\t\tarray(\"".
# En absence de champ c'est un decompte : # En absence de champ c'est un decompte :
# prendre la primary pour avoir qqch # prendre la primary pour avoir qqch
# (COUNT incompatible avec le cas general # (COUNT incompatible avec le cas general
(($boucle->select) ? ($boucle->select ?
join("\",\n\t\t\"", array_unique($boucle->select)) : join("\",\n\t\t\"", $boucle->select) :
$id_field) . ($id_table . "." .
(($p = strpos($primary, ',')) ?
substr($primary, 0, $p) : $primary))) .
'"), # SELECT '"), # SELECT
array("' . array("' .
join('","', array_unique($boucle->from)) . join('","', array_unique($boucle->from)) .
...@@ -297,15 +280,18 @@ function calculer_boucle($id_boucle, &$boucles) { ...@@ -297,15 +280,18 @@ function calculer_boucle($id_boucle, &$boucles) {
// //
// Conclusion et retour // Conclusion et retour
// //
$conclusion = "\n @spip_abstract_free(\$result,'" . $corps .= "\n @spip_abstract_free(\$result,'" .
$boucle->sql_serveur . "');" . $boucle->sql_serveur . "');";
}
return $init . $corps .
## inserer le code d'envoi au debusqueur du resultat de la fonction ## inserer le code d'envoi au debusqueur du resultat de la fonction
(($GLOBALS['var_mode_affiche'] != 'resultat') ? "" : " (($GLOBALS['var_mode_affiche'] != 'resultat') ? "" : "
boucle_debug_resultat('$id_boucle', 'resultat', \$t0);") . boucle_debug_resultat('$id_boucle', 'resultat', \$t0);") .
"\n return \$t0;"; "\n return \$t0;";
return $texte . $init . $corps . $conclusion;
} }
......
...@@ -94,18 +94,18 @@ function critere_recherche_dist($idb, &$boucles, $crit) { ...@@ -94,18 +94,18 @@ function critere_recherche_dist($idb, &$boucles, $crit) {
$boucle = &$boucles[$idb]; $boucle = &$boucles[$idb];
$table = $boucle->id_table; #articles // Ne pas executer la requete en cas de hash vide
$id_table = 'id_'.preg_replace('/s$/', '', $table); #id_article $boucle->hash = '
// RECHERCHE
list($rech_select, $rech_where) = prepare_recherche($GLOBALS["recherche"], "'.$boucle->primary.'", "'.$boucle->id_table.'");
if ($rech_where) ';
// horrible hack du aux id_forum = spip_forum et id_article=spip_articleS $boucle->select[]= $boucle->id_table . '.' . $boucle->primary; # pour postgres, neuneu ici
// en fait il faudrait la fonction inverse de table_objet() $boucle->select[]= '$rech_select as points';
$id = 'id_'.preg_replace('/s$/', '', $boucle->id_table);
$boucle->select[] = $boucle->id_table . '.' . $boucle->primary; # pour postgres, neuneu ici
$boucle->select[] = '$rech_select'; # pour les ... as points
// et la recherche trouve // et la recherche trouve
$boucle->where[] = '$rech_where'; $boucle->where[] = '$rech_where';
} }
// {inverse} // {inverse}
...@@ -216,12 +216,12 @@ function critere_par_dist($idb, &$boucles, $crit) { ...@@ -216,12 +216,12 @@ function critere_par_dist($idb, &$boucles, $crit) {
// tester si cette version de MySQL accepte la commande RAND() // tester si cette version de MySQL accepte la commande RAND()
// sinon faire un gloubi-boulga maison avec de la mayonnaise. // sinon faire un gloubi-boulga maison avec de la mayonnaise.
if (spip_query("SELECT RAND()")) if (spip_query("SELECT RAND()"))
$boucle->select[] = "RAND() AS alea"; $tri = "RAND()";
else else
$boucle->select[] = "MOD(".$boucle->id_table.'.'.$boucle->primary $tri = "MOD(".$boucle->id_table.'.'.$boucle->primary
." * UNIX_TIMESTAMP(),32767) & UNIX_TIMESTAMP() AS alea"; ." * UNIX_TIMESTAMP(),32767) & UNIX_TIMESTAMP()";
$boucle->select[]= $tri . " AS alea";
$order = "'alea'"; $order = "'alea'";
} }
// par titre_mot // par titre_mot
...@@ -559,8 +559,7 @@ function calculer_critere_DEFAUT($idb, &$boucles, $crit) { ...@@ -559,8 +559,7 @@ function calculer_critere_DEFAUT($idb, &$boucles, $crit) {
$where = "NOT ($where)"; $where = "NOT ($where)";
} else { } else {
$boucle->default_order = 'rang'; $boucle->default_order = 'rang';
$boucle->select[] = $boucle->select[]= "FIND_IN_SET($ct, \\\"'\" . " . $val . ' . "\'\\") AS rang';
"FIND_IN_SET($ct, \\\"'\" . " . $val . ' . "\'\\") AS rang';
} }
} else { } else {
if ($op == '==') $op = 'REGEXP'; if ($op == '==') $op = 'REGEXP';
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter