From 4b4a0a24cb90c4e9ffcab7f9614fc57da70aac32 Mon Sep 17 00:00:00 2001
From: "Committo,Ergo:sum" <esj@rezo.net>
Date: Thu, 22 Nov 2007 22:46:00 +0000
Subject: [PATCH] =?UTF-8?q?La=20d=C3=A9tection=20des=20GroupBy=20superflus?=
 =?UTF-8?q?=20mise=20au=20point=20en=20[5949]=C2=A0pour=20une=20optimisati?=
 =?UTF-8?q?on=20colossale=20(cf=20[http://article.gmane.org/gmane.comp.web?=
 =?UTF-8?q?.spip.devel/30555])=20ne=20se=20faisait=20plus=20depuis=20la=20?=
 =?UTF-8?q?1.9.=20C'est=20r=C3=A9par=C3=A9=20pour=20MySQL,=20mais=20PG=20n?=
 =?UTF-8?q?'en=20profite=20pas=20et=20c'est=20en=20fait=20la=20cl=C3=A9=20?=
 =?UTF-8?q?(c'est=20le=20cas=20de=20le=20dire)=20de=20la=20subtitlit=C3=A9?=
 =?UTF-8?q?=20tournant=20autour=20de=20son=20message=20aga=C3=A7ant=20(cf?=
 =?UTF-8?q?=20[9831])=20demandant=20syst=C3=A9matiquement=20un=20GroupBy:?=
 =?UTF-8?q?=20=20pour=20y=20=C3=A9chapper,=20il=20ne=20faut=20pas=20utilis?=
 =?UTF-8?q?er=20la=20syntaxe=20{{{FROM=20a,b}}}=20mais=20{{{a=20LEFT=20JOI?=
 =?UTF-8?q?N=20b}}}=20qui=20n'impose=20pas=20de=20GroupBy=20(car=20c'est?=
 =?UTF-8?q?=20parfois=20bien=20ce=20qu'on=20veut,=20=C3=A7a=20vient=20de?=
 =?UTF-8?q?=20m'arriver=20et=20tout=20s'est=20=C3=A9clair=C3=A9).?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Le traducteur Mysql->PG ne rajoute plus de GroupBy systématiquement dans le cas d'un LEFT JOIN, ce qui devrait accéléer les qq requêtes les utilisant dans l'espace privé.Mais:

	*  pour l'espace privé, il faudrait examiner ses 600 appels à select voir s'il y a un {{{FROM a,b}} transformable. On laisse tomber, mais il faut à présent y penser quand on écrit des nouveautés.

	* pour l'espace public, il n'y a pas beaucoup d'endroits où on produit cette forme, il faut donc poser la question: est-ce que tous les critères peuvent se compiler par un LEFT JOIN, et sinon qu'est-ce qui caractérise les exceptions ? L'enjeu est important.

Aussi dans ce dépot: traduction MySQL->PG de la fonction CONV (utile pour faire un CAST dans un critère), et prise en compte dès maintenant d'un LEFT JOIN dans les fonctions d'interface, ça servira tôt (le pb du jour) ou tard.
---
 ecrire/public/criteres.php |  2 +-
 ecrire/req/mysql.php       |  3 ++-
 ecrire/req/pg.php          | 11 ++++++++---
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php
index 9a9e49e3e2..19476263ee 100644
--- a/ecrire/public/criteres.php
+++ b/ecrire/public/criteres.php
@@ -867,7 +867,7 @@ function calculer_jointure(&$boucle, $depart, $arrivee, $col='', $cond=false)
   // de l'index principal et de l'index de jointure (non conditionnel! [6031])
   // et operateur d'egalite (http://trac.rezo.net/trac/spip/ticket/477)
 
-  if ($pk = (count($boucle->from) == 1) && !$cond) {
+  if ($pk = (count($boucle->from) == 2) && !$cond) {
   	if ($pk = $a[1]['key']['PRIMARY KEY']) {
 		$id_primary = $ddesc['key']['PRIMARY KEY'];
 		$pk = preg_match("/^$id_primary, *$col$/", $pk) OR
diff --git a/ecrire/req/mysql.php b/ecrire/req/mysql.php
index 26259a5109..412a2401d8 100644
--- a/ecrire/req/mysql.php
+++ b/ecrire/req/mysql.php
@@ -219,7 +219,8 @@ function spip_select_as($args)
 {
 	$argsas = "";
 	foreach($args as $k => $v) {
-		$argsas .= ', ' . $v . (is_numeric($k) ? '' : " AS `$k`");
+		if (strpos($v, 'JOIN') === false)  $argsas .= ', ';
+		$argsas .= $v . (is_numeric($k) ? '' : " AS `$k`");
 	}
 	return substr($argsas,2);
 }
diff --git a/ecrire/req/pg.php b/ecrire/req/pg.php
index 852c5c5a7c..769f70b7b2 100644
--- a/ecrire/req/pg.php
+++ b/ecrire/req/pg.php
@@ -329,7 +329,7 @@ function spip_pg_orderby($order, $select)
 function spip_pg_groupby($groupby, $from, $select)
 {
 	$join = is_array($from) ? (count($from) > 1) : 
-	  (strpos($from, ",") OR strpos($from, "JOIN"));
+	  (strpos($from, ","));
 	if ($join OR $groupby) $join = !is_array($select) ? $select : join(", ", $select);
 	if ($join) {
 	  $join = str_replace('DISTINCT ','',$join);
@@ -368,13 +368,17 @@ function spip_pg_frommysql($arg)
 
 	$res = spip_pg_fromfield($arg);
 
-	$res = preg_replace('/\brand[(][)]/','random()', $res);
+	$res = preg_replace('/\brand[(][)]/i','random()', $res);
+
 	$res = preg_replace('/\b0\.0[+]([a-zA-Z0-9_.]+)\s*/',
 			    'CAST(substring(\1, \'^ *[0-9.]+\') as float)',
 			    $res);
 	$res = preg_replace('/\b0[+]([a-zA-Z0-9_.]+)\s*/',
 			    'CAST(substring(\1, \'^ *[0-9]+\') as int)',
 			    $res);
+	$res = preg_replace('/\bconv[(]([^,]*)[^)]*[)]/i',
+			    'CAST(substring(\1, \'^ *[0-9]+\') as int)',
+			    $res);
 	$res = preg_replace('/UNIX_TIMESTAMP\s*[(]\s*[)]/',
 			    'EXTRACT(\'epoch\' FROM NOW())', $res);
 
@@ -463,7 +467,8 @@ function spip_pg_select_as($args)
 				$v = $k;
 			elseif ($v != $k) $as = " AS $k"; 
 		}
-		$argsas .= ', ' . $v . $as; 
+		if (strpos($v, 'JOIN') === false)  $argsas .= ', ';
+		$argsas .= $v . $as; 
 	}
 	return substr($argsas,2);
 }
-- 
GitLab