Browse Source

Retour sur d711e9c740 et fix #4465 :

l'absence de clause where sur les jointures objet/id_objet permet en effet d'optimiser les boucles de type
`<BOUCLE(ARTICLES){id_document ?}>`
mais a contrario comme indique par #4465 l'optimisation d'une boucle
`<BOUCLE(DEPOTS){id_mot=1}>#ID_DEPOT</BOUCLE> est trop forte car la jointure saute du fait que la table principale est enlevee du from  et on a plus le where sur objet.

On s'en tire on reinserant de nouveau le where en doublon de la clause de jointure,
mais en le pointant d'une cle qui l'associe a la jointure,
ce qui permet a calculer_select de savoir que ce where saute si la jointure saute et de faire correctement son travail dans les 2 cas

Il faut esperer que ca ne nous cree pas un nouveau cas limite, ou pas avant 12 ans en tout cas :p
issue_4465
Cerdic 2 months ago
parent
commit
3828abd23c
  1. 5
      ecrire/public/compiler.php
  2. 7
      ecrire/public/composer.php
  3. 7
      ecrire/public/jointures.php

5
ecrire/public/compiler.php

@ -812,8 +812,9 @@ function calculer_dump_array($a) {
" : " . calculer_dump_array($a[3]) .
")");
} else {
foreach ($a as $v) {
$res .= ", " . calculer_dump_array($v);
foreach ($a as $k => $v) {
$showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
$res .= ", " . $showk . calculer_dump_array($v);
}
return "\n\t\t\tarray(" . substr($res, 2) . ')';

7
ecrire/public/composer.php

@ -779,12 +779,13 @@ function calculer_select(
if (is_numeric($cle)) {
$cle = "L$k";
}
$cle_where_lie = "JOIN-$cle";
if (!$menage
or isset($afrom[$cle])
or calculer_jointnul($cle, $select)
or calculer_jointnul($cle, array_diff_key($join, array($cle => $join[$cle])))
or calculer_jointnul($cle, $having)
or calculer_jointnul($cle, $where_simples)
or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
) {
// corriger les references non explicites dans select
// ou groupby
@ -822,6 +823,10 @@ function calculer_select(
$equiv[] = $carr;
} else {
unset($join[$cledef]);
if (isset($where_simples[$cle_where_lie])) {
unset($where_simples[$cle_where_lie]);
unset($where[$cle_where_lie]);
}
}
unset($from[$cle]);
$k--;

7
ecrire/public/jointures.php

@ -171,9 +171,10 @@ function fabrique_jointures(&$boucle, $res, $cond = false, $desc = array(), $nom
} else {
$obj = "L$n.$obj";
}
// le where complementaire est envoye dans la jointure pour pouvoir etre elimine avec la jointure
// en cas d'optimisation
//$boucle->where[] = array("'='","'$obj'","sql_quote('$type')");
// le where complementaire est envoye dans la jointure et dans le where
// on utilise une clé qui le relie a la jointure pour que l'optimiseur
// sache qu'il peut enlever ce where si il enleve la jointure
$boucle->where["JOIN-L$n"] = array("'='","'$obj'","sql_quote('$type')");
$boucle->join["L$n"] =
$echap ?
array("'$id_table'", "'$j2'", "'$j1'", "'$obj='.sql_quote('$type')")

Loading…
Cancel
Save