From 200426d1a77bf6ff51bb1abe1170e15c48968485 Mon Sep 17 00:00:00 2001
From: "Committo,Ergo:sum" <esj@rezo.net>
Date: Thu, 16 Mar 2006 20:09:55 +0000
Subject: [PATCH] =?UTF-8?q?Poursuite=20de=20[5974]=C2=A0pour=20pouvoir=20o?=
 =?UTF-8?q?ptimiser=20avant=20l'appel=20au=20serveur=20SQL.=20En=20revanch?=
 =?UTF-8?q?e,=20abandon=20de=20la=20s=C3=A9mantique=20de=205972:=20ne=20pa?=
 =?UTF-8?q?s=20privil=C3=A9gier=20syst=C3=A9matiquement=20la=20cl=C3=A9=20?=
 =?UTF-8?q?primaire=20m=C3=A8ne=20=C3=A0=20des=20aberrations=20(champs=20i?=
 =?UTF-8?q?dx=20ou=20url=5Fpropre=20comme=20cl=C3=A9=20de=20jointures)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ecrire/public/boucles.php       |  8 +++-----
 ecrire/public/calcul-outils.php | 22 +++++++++++++++++++---
 ecrire/public/compilo.php       | 12 +++++++++---
 ecrire/public/criteres.php      | 13 ++++++-------
 4 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/ecrire/public/boucles.php b/ecrire/public/boucles.php
index 1a8cbf04e2..0f7f8d2fb3 100644
--- a/ecrire/public/boucles.php
+++ b/ecrire/public/boucles.php
@@ -168,11 +168,9 @@ function boucle_DOCUMENTS_dist($id_boucle, &$boucles) {
 	// sauf s'ils sont distants (taille inconnue)
 	$boucle->where[]= "($id_table.taille > 0 OR $id_table.distant='oui')";
 
-	$jointure = array_search("spip_types_documents", $boucle->from);
-	if ($jointure) {
-	  $j = $id_table . ".id_type=$jointure" . ".id_type";
-	  if (!in_array($j, $boucle->join)) $boucle->join[]= $j;
-	}
+	$joint = substr(array_search("spip_types_documents", $boucle->from),1);
+	if ($joint AND !isset($boucle->join[$joint]))
+	    $boucle->join[$joint]= array($id_table, 'id_type');
 
 	return calculer_boucle($id_boucle, $boucles);
 }
diff --git a/ecrire/public/calcul-outils.php b/ecrire/public/calcul-outils.php
index 175bd9aea1..f4e87a67f4 100644
--- a/ecrire/public/calcul-outils.php
+++ b/ecrire/public/calcul-outils.php
@@ -551,9 +551,25 @@ function spip_optim_select ($select = array(), $from = array(),
 			    $sousrequete = '', $cpt = '',
 			    $table = '', $id = '', $serveur='') {
 
-	foreach($where as $k => $v) { if (!$v) unset($where[$k]);}
-	$where = array_merge($where, $join);
-
+// retirer les criteres vides:
+// {X ?} avec X absent de l'URL
+// {par #ENV{X}} avec X absent de l'URL
+// IN sur collection vide
+
+	foreach($where as $k => $v) { 
+		if ((!$v) OR ($v==1) OR ($v=='0=0')) {
+			unset($where[$k]);
+		}
+	}
+// Construire les clauses determinant les jointures.
+// Il faudrait retirer celles seulement utiles aux criteres finalement absents
+// (et nettoyer $from en consequence)
+// mais la condition necessaire et suffisante n'est pas triviale
+
+	foreach($join as $k => $v) {
+		list($t,$c) = $v;
+		$where[]= "$t.$c=L$k.$c";
+	}
 	return spip_abstract_select($select, $from, $where,
 		  $groupby, array_filter($orderby), $limit,
 		  $sousrequete, $cpt,
diff --git a/ecrire/public/compilo.php b/ecrire/public/compilo.php
index 990c78f0cd..40fc942679 100644
--- a/ecrire/public/compilo.php
+++ b/ecrire/public/compilo.php
@@ -268,9 +268,8 @@ function calculer_requete_sql(&$boucle)
 		array(' .
 		($boucle->where  ? ('"'. join('", "', $boucle->where) . '"') : '') .
 		'), # WHERE
-		array(' .
-		($boucle->join  ? ('"'. join('", "', $boucle->join) . '"') : '') .
-		'), # WHERE pour jointure
+		' . calculer_dump_array($boucle->join)
+		. ', # WHERE pour jointure
 		' . (!$boucle->group ? "''" : 
 		     ('"' . join(", ", $boucle->group)) . '"') .
 		', # GROUP
@@ -288,6 +287,13 @@ function calculer_requete_sql(&$boucle)
 }
 
 
+function calculer_dump_array($a)
+{
+  $res = "";
+  foreach($a as $k => $v) $res .= ", $k => array('$v[0]', '$v[1]')";
+  return 'array(' . substr($res,2) . ')';
+}
+
 function calculer_from(&$boucle)
 {
   $res = "";
diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php
index 17a73b5973..d6d4bb1c02 100644
--- a/ecrire/public/criteres.php
+++ b/ecrire/public/criteres.php
@@ -591,7 +591,7 @@ function calculer_critere_externe_init(&$boucle, $col, $desc, $crit)
 			_T('zbug_boucle') .
 			" $idb " .
 			_T('zbug_critere_inconnu', 
-			    array('critere' => $crit->op)));
+			    array('critere' => $col)));
 }
 
 // deduction automatique des jointures 
@@ -611,7 +611,7 @@ function calculer_jointure(&$boucle, $depart, $arrivee, $col='')
   foreach($res as $r) {
     list($d, $a, $j) = $r;
     $num++;
-    $boucle->join[]= ($id_table ? $id_table : $d) . ".$j=L$num." . $j;
+    $boucle->join[$num]= array(($id_table ? $id_table : $d), $j);
     $boucle->from[$id_table = "L$num"] = $a[0];    
   }
 
@@ -646,10 +646,9 @@ function calculer_chaine_jointures(&$boucle, $depart, $arrivee, $vu=array())
 
   $keys = $ddesc['key'];
 
-  if ($v = $keys['PRIMARY KEY']) {
-    unset($keys['PRIMARY KEY']);
-    $keys = array_merge(split(', *', $v), $keys);
-  }
+  // priorite a la primaire, qui peut etre multiple
+  if ($v = (split(', *', $keys['PRIMARY KEY'])))
+    $keys = $v;
   $v = array_intersect($keys, $adesc['key']); 
   if ($v)
     return array(array($dnom, $arrivee, array_shift($v)));
@@ -659,7 +658,7 @@ function calculer_chaine_jointures(&$boucle, $depart, $arrivee, $vu=array())
 	if ($v && (!in_array($v,$vu)) && 
 	    ($def = trouver_def_table($v, $boucle))) {
 	  list($table,$join) = $def;
-	  $milieu = array_intersect($keys, trouver_cles_table($join['key']));
+	  $milieu = array_intersect($ddesc['key'], trouver_cles_table($join['key']));
 	  foreach ($milieu as $k)
 	    {
 	      $new[] = $v;
-- 
GitLab