diff --git a/ecrire/base/abstract_sql.php b/ecrire/base/abstract_sql.php index 583036c01da509aa406197b66b5f11ddd982081c..990afc764521113c7acd6c7a49b488a086ee3da3 100644 --- a/ecrire/base/abstract_sql.php +++ b/ecrire/base/abstract_sql.php @@ -319,32 +319,6 @@ function sql_version($serveur='') { return ($row['n']); } -// -// IN (...) est limite a 255 elements, d'ou cette fonction assistante -// -// http://doc.spip.org/@calcul_mysql_in -function calcul_mysql_in($val, $valeurs, $not='') { - if (is_array($valeurs)) - $valeurs = join(',', array_map('_q', $valeurs)); - if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); - - $n = $i = 0; - $in_sql =""; - while ($n = strpos($valeurs, ',', $n+1)) { - if ((++$i) >= 255) { - $in_sql .= "($val $not IN (" . - substr($valeurs, 0, $n) . - "))\n" . - ($not ? "AND\t" : "OR\t"); - $valeurs = substr($valeurs, $n+1); - $i = $n = 0; - } - } - $in_sql .= "($val $not IN ($valeurs))"; - - return "($in_sql)"; -} - // prend une chaine sur l'aphabet hexa // et retourne sa representation numerique: // FF ==> 0xFF en MySQL mais x'FF' en PG @@ -355,8 +329,13 @@ function sql_hex($val, $serveur='') return $f($val); } +function sql_in($val, $valeurs, $not='', $serveur='') { + $f = sql_serveur('in', $serveur); + return $f($val, $valeurs, $not, $serveur); +} + // http://doc.spip.org/@test_sql_int -function test_sql_int($type) +function sql_test_int($type) { return (preg_match('/^bigint/i',$type) OR preg_match('/^int/i',$type) @@ -364,7 +343,7 @@ function test_sql_int($type) } // http://doc.spip.org/@test_sql_date -function test_sql_date($type) +function sql_test_date($type) { return (preg_match('/^datetime/i',$type) OR preg_match('/^timestamp/i',$type)); diff --git a/ecrire/exec/auteurs.php b/ecrire/exec/auteurs.php index ce16a498e7118714e2ae1d9da4ccc0c739c3945c..8df4fe26659410670a8e976981ac108d0ff7d31f 100644 --- a/ecrire/exec/auteurs.php +++ b/ecrire/exec/auteurs.php @@ -267,7 +267,7 @@ function requete_auteurs($tri, $statut, $recherche=NULL) $tables = array('auteur'=>$tables['auteur']); $results = recherche_en_base($recherche, $tables); $in_auteurs = $results['auteur'] - ? calcul_mysql_in('aut.id_auteur',array_keys($results['auteur'])) + ? sql_in('aut.id_auteur',array_keys($results['auteur'])) : '0=1'; } diff --git a/ecrire/exec/recherche.php b/ecrire/exec/recherche.php index 2a1fca4ec0521df38a818898fcf27bbaec2fae56..031a0951b2c353ece769d4dc8feca6054e91165a 100644 --- a/ecrire/exec/recherche.php +++ b/ecrire/exec/recherche.php @@ -111,7 +111,7 @@ function exec_recherche_dist() { array( // gasp: la requete spip_articles exige AS articles... 'FROM' => table_objet_sql($table).' AS '.$table.'s', - 'WHERE' => calcul_mysql_in( + 'WHERE' => sql_in( $table.'s.'.id_table_objet($table), array_keys($r) ), diff --git a/ecrire/genie/optimiser.php b/ecrire/genie/optimiser.php index f554ef9675ffbb5238dabb902295e9fa591e88c9..f6d5f2c1a2fb02c78ddf49cf2fb1edd4dabe40ed 100644 --- a/ecrire/genie/optimiser.php +++ b/ecrire/genie/optimiser.php @@ -73,7 +73,7 @@ function optimiser_sansref($table, $id, $sel) if ($in) { $in = join(',', array_keys($in)); - sql_delete($table, calcul_mysql_in($id,$in)); + sql_delete($table, sql_in($id,$in)); spip_log("Numeros des entrees $id supprimees dans la table $table: $in"); } return count($in); diff --git a/ecrire/genie/visites.php b/ecrire/genie/visites.php index 585fd71e86eb76533c3cace55088ffdd62a6a5d6..e68621367312cd4a4044e1f97bf2e7dfd9ffc0f9 100644 --- a/ecrire/genie/visites.php +++ b/ecrire/genie/visites.php @@ -111,7 +111,7 @@ function calculer_visites($t) { } else $ar[$n][] = $id_article; } foreach ($ar as $n => $liste) { - $tous = calcul_mysql_in('id_article', $liste); + $tous = sql_in('id_article', $liste); sql_update('spip_visites_articles', array('visites' => "visites+$n"), "date='$date' AND $tous"); @@ -127,14 +127,14 @@ function calculer_visites($t) { array('visites' => "visites+$n", 'popularite' => "popularite+$n", 'maj' => 'maj'), - calcul_mysql_in('id_article',$noref)); + sql_in('id_article',$noref)); if ($ref) sql_update('spip_articles', array('visites' => "visites+".($n+1), 'popularite' => "popularite+$n", 'maj' => 'maj'), - calcul_mysql_in('id_article',$ref)); + sql_in('id_article',$ref)); ## Ajouter un JOIN sur le statut de l'article ? } @@ -162,10 +162,10 @@ function calculer_visites($t) { } // appliquer les increments sur les anciens - // attention on appelle calcul_mysql_in en mode texte et pas array + // attention on appelle sql_in en mode texte et pas array // pour ne pas passer _q() sur les '0x1234' de referer_md5, cf #849 foreach ($ar as $num => $liste) { - sql_update('spip_referers', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"), calcul_mysql_in('referer_md5',join(', ', $liste))); + sql_update('spip_referers', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"), sql_in('referer_md5',join(', ', $liste))); } } diff --git a/ecrire/inc/documents.php b/ecrire/inc/documents.php index 1ce3943e8ab037a541d1c137588286438b3406f7..15479322b07c603d85e39e0245c2cd43133e14d2 100644 --- a/ecrire/inc/documents.php +++ b/ecrire/inc/documents.php @@ -498,7 +498,7 @@ function supprimer_documents($liste = array()) { if (!count($liste)) return; - $in = calcul_mysql_in('id_document', $liste); + $in = sql_in('id_document', $liste); // Supprimer les fichiers locaux et les copies locales // des docs distants diff --git a/ecrire/inc/forum.php b/ecrire/inc/forum.php index 5b6e96aea1bce3b898749c55307b3af60232b64d..0bf35a3aa7fc9be3dca50235016ec3a81aa9e99a 100644 --- a/ecrire/inc/forum.php +++ b/ecrire/inc/forum.php @@ -212,7 +212,7 @@ function critere_statut_controle_forum($type, $id_rubrique=0, $recherche='') { if ($recherche) { include_spip('inc/rechercher'); if ($a = recherche_en_base($recherche, 'forum')) - $and .= " AND ".calcul_mysql_in('id_forum', + $and .= " AND ".sql_in('id_forum', array_keys(array_pop($a))); else $and .= " 0=1"; diff --git a/ecrire/inc/modifier.php b/ecrire/inc/modifier.php index 6d157ffbf0f4ab7bc3c447a6f7dc9b3ffe2aa297..085b02a0fa839623538a3a6d0918595ac96673f3 100644 --- a/ecrire/inc/modifier.php +++ b/ecrire/inc/modifier.php @@ -119,7 +119,7 @@ function marquer_doublons_documents($champs,$id,$id_table_objet,$table_objet){ sql_updateq("spip_documents_$table_objet", array("vu" => 'non'), "$id_table_objet=$id"); if (count($GLOBALS['doublons_documents_inclus'])){ // on repasse par une requete sur spip_documents pour verifier que les documents existent bien ! - $in_liste = calcul_mysql_in('id_document', + $in_liste = sql_in('id_document', $GLOBALS['doublons_documents_inclus']); $res = sql_select("id_document", "spip_documents", $in_liste); while ($row = sql_fetch($res)) { diff --git a/ecrire/inc/prepare_recherche.php b/ecrire/inc/prepare_recherche.php index 26914a0cc2633ea69a379cfdc6d48ddee4d4acac..6fe019afa805fddf7ef8fa23ad34cd3105c7b532 100644 --- a/ecrire/inc/prepare_recherche.php +++ b/ecrire/inc/prepare_recherche.php @@ -59,7 +59,7 @@ function inc_prepare_recherche_dist($recherche, $table='articles', $cond=false) # Pour les forums, unifier par id_thread et forcer statut='publie' if ($x == 'forum' AND $points) { $p2 = array(); - $s = sql_select("id_thread, id_forum", "spip_forum", "statut='publie' AND ".calcul_mysql_in('id_forum', array_keys($points))); + $s = sql_select("id_thread, id_forum", "spip_forum", "statut='publie' AND ".sql_in('id_forum', array_keys($points))); while ($t = sql_fetch($s)) $p2[intval($t['id_thread'])]['score'] += $points[intval($t['id_forum'])]['score']; @@ -77,11 +77,11 @@ function inc_prepare_recherche_dist($recherche, $table='articles', $cond=false) $listes_ids[$p['score']] .= ','.$id; foreach ($listes_ids as $p => $liste_ids) $select .= "+$p*(". - calcul_mysql_in("$table.$primary", substr($liste_ids, 1)) + sql_in("$table.$primary", substr($liste_ids, 1)) .") "; $cache[$recherche][$table] = array($select, - '('.calcul_mysql_in("$table.$primary", + '('.sql_in("$table.$primary", array_keys($points)).')' ); } diff --git a/ecrire/inc/rechercher.php b/ecrire/inc/rechercher.php index ede8ef5048c9a84766c7021e7b2163d173261e58..dd93ef67ba25eda472a125bc3d93a4d61c07b957 100644 --- a/ecrire/inc/rechercher.php +++ b/ecrire/inc/rechercher.php @@ -246,7 +246,7 @@ function recherche_en_base($recherche='', $tables=NULL, $options=array()) { foreach ($joints as $jtable => $jj) { $it = id_table_objet($table); $ij = id_table_objet($jtable); - $s = sql_select("$it,$ij", "spip_${jtable}s_${table}s", calcul_mysql_in('id_'.${jtable}, array_keys($jj))); + $s = sql_select("$it,$ij", "spip_${jtable}s_${table}s", sql_in('id_'.${jtable}, array_keys($jj))); while ($t = sql_fetch($s)) { $id = $t[$it]; $joint = $jj[$t[$ij]]; diff --git a/ecrire/inc/rubriques.php b/ecrire/inc/rubriques.php index d408eb2baa022177a5cffd6fdb1c3b88901b98d0..9b50f65f326a6f840eb0ef87c31e7734a8a185b0 100644 --- a/ecrire/inc/rubriques.php +++ b/ecrire/inc/rubriques.php @@ -290,7 +290,7 @@ function calcul_generation ($generation) { $lesfils = array(); $result = sql_select(array('id_rubrique'), array('spip_rubriques AS rubriques'), - array(calcul_mysql_in('id_parent', $generation))); + array(sql_in('id_parent', $generation))); while ($row = sql_fetch($result)) $lesfils[] = $row['id_rubrique']; return join(",",$lesfils); diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php index 2fb7c2aba11caeb2ae21538740c2eed15ba9534e..b888073c2a509cc5890b23b36fa0f76b6054efc8 100644 --- a/ecrire/public/criteres.php +++ b/ecrire/public/criteres.php @@ -59,7 +59,7 @@ function critere_doublons_dist($idb, &$boucles, $crit) { erreur_squelette(_T('zbug_doublon_table_sans_index'), "BOUCLE$idb"); $nom = !isset($crit->param[0]) ? "''" : calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent); // mettre un tableau pour que ce ne soit pas vu comme une constante - $boucle->where[]= array("calcul_mysql_in('".$boucle->id_table . '.' . $boucle->primary . + $boucle->where[]= array("sql_in('".$boucle->id_table . '.' . $boucle->primary . "', " . '"0".$doublons[' . ($crit->not ? '' : ($boucle->doublons . "[]= ")) . @@ -248,7 +248,7 @@ function critere_branche_dist($idb, &$boucles, $crit) { $cle = calculer_jointure($boucle, array($boucle->id_table, $desc), $cle, false); } - $c = "calcul_mysql_in('" . + $c = "sql_in('" . ($cle ? "L$cle" : $boucle->id_table) . ".id_rubrique', calcul_branche($arg), '')"; if ($crit->cond) $c = "($arg ? $c : 1)"; @@ -266,7 +266,7 @@ function critere_logo_dist($idb, &$boucles, $crit) { $not = $crit->not; $boucle = &$boucles[$idb]; - $c = "calcul_mysql_in('" . + $c = "sql_in('" . $boucle->id_table . '.' . $boucle->primary . "', lister_objets_avec_logos('". $boucle->primary ."'), '')"; if ($crit->cond) $c = "($arg ? $c : 1)"; @@ -739,7 +739,7 @@ function calculer_critere_infixe($idb, &$boucles, $crit) { // la valeur comparee doit etre munie ou non d'apostrophes if ($op == '=' OR in_array($op, $table_criteres_infixes)) { if (strpos($val[0], '_q(') === 0 - AND $desc AND test_sql_int($desc['field'][$col])) + AND $desc AND sql_test_int($desc['field'][$col])) $val[0] = 'intval' . substr($val[0],2); } // tag du critere pour permettre aux boucles de modifier leurs requetes par defaut en fonction de ca @@ -1023,7 +1023,6 @@ function calculer_critere_infixe_ops($idb, &$boucles, $crit) $val = 'id_parent'; // un critere conditionnel sur date est traite a part // car la date est mise d'office par SPIP, - // il faut if ($crit->cond AND tester_param_date('articles', $col)) $val ='@$Pile["env"][\'' . $col ."']"; else $val = calculer_argument_precedent($idb, $val, $boucles); diff --git a/ecrire/public/vertebrer.php b/ecrire/public/vertebrer.php index f8456b3ddeed2148abc48d3ddc3bca1d75c75f3d..43af1a063fd15380ef70fee4981dc749c39af671 100755 --- a/ecrire/public/vertebrer.php +++ b/ecrire/public/vertebrer.php @@ -32,7 +32,7 @@ function vertebrer_sort($fields, $direction) $res = ''; foreach($fields as $n => $t) { $tri = $direction - . ((test_sql_int($t) OR test_sql_date($r)) ? 'tri_n' : 'tri'); + . ((sql_test_int($t) OR sql_test_date($r)) ? 'tri_n' : 'tri'); $url = vertebrer_sanstri($tri) . "|parametre_url{" . $tri . ",'" . $n . "'}"; @@ -59,7 +59,7 @@ function vertebrer_form($fields) $url = join('|', array_keys($fields)); $url = "#SELF|\n\t\t\tparametre_url{'$url',''}"; foreach($fields as $n => $t) { - $s = test_sql_int($t) ? 11 + $s = sql_test_int($t) ? 11 : (preg_match('/char\s*\((\d)\)/i', $t, $r) ? $r[1] : ''); $res .= "\n\t\t<td><form action='./' method='get'>" @@ -98,7 +98,7 @@ function vertebrer_cell($fields) $url = "[(#SELF|parametre_url{page,'" . $r[1] . "'})]"; $texte = "<a href='$url'>" . $texte . "</a>"; } - $s = test_sql_int($t) ? " style='text-align: right;'" : ''; + $s = sql_test_int($t) ? " style='text-align: right;'" : ''; $res .= "\n\t\t<td$s>$texte</td>"; } } diff --git a/ecrire/req/mysql.php b/ecrire/req/mysql.php index 727f148d5d5c1e09d26eba89babd8dc534fcdaf5..d643f9f7180b2ac89ca3d9340c08e9b20dc74e11 100644 --- a/ecrire/req/mysql.php +++ b/ecrire/req/mysql.php @@ -47,6 +47,7 @@ function req_mysql_dist($host, $port, $login, $pass, $db='', $prefixe='', $ldap= 'fetch' => 'spip_mysql_fetch', 'free' => 'spip_mysql_free', 'hex' => 'spip_mysql_hex', + 'in' => 'spip_mysql_in', 'insert' => 'spip_mysql_insert', 'insertq' => 'spip_mysql_insertq', 'listdbs' => 'spip_mysql_listdbs', @@ -524,10 +525,41 @@ function spip_mysql_hex($v) return "0x" . $v; } +// pour compatibilite +function spip_mysql_in($val, $valeurs, $not='', $serveur='') { + return calcul_mysql_in($val, $valeurs, $not); +} + +// +// IN (...) est limite a 255 elements, d'ou cette fonction assistante +// +// http://doc.spip.org/@calcul_mysql_in +function calcul_mysql_in($val, $valeurs, $not='') { + if (is_array($valeurs)) + $valeurs = join(',', array_map('_q', $valeurs)); + if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); + + $n = $i = 0; + $in_sql =""; + while ($n = strpos($valeurs, ',', $n+1)) { + if ((++$i) >= 255) { + $in_sql .= "($val $not IN (" . + substr($valeurs, 0, $n) . + "))\n" . + ($not ? "AND\t" : "OR\t"); + $valeurs = substr($valeurs, $n+1); + $i = $n = 0; + } + } + $in_sql .= "($val $not IN ($valeurs))"; + + return "($in_sql)"; +} + // http://doc.spip.org/@spip_mysql_cite function spip_mysql_cite($v, $type) { - if (test_sql_date($type) AND preg_match('/^\w+\(/', $v) - OR (test_sql_int($type) + if (sql_test_date($type) AND preg_match('/^\w+\(/', $v) + OR (sql_test_int($type) AND (is_numeric($v) OR (ctype_xdigit(substr($v,2)) AND $v[0]=='0' AND $v[1]=='x')))) diff --git a/ecrire/req/pg.php b/ecrire/req/pg.php index a367ca85a798da3ba2a0dee0b3c288644fb80587..656ac8a7a9e8ae75de4916b6c2f698d59c86f1d5 100644 --- a/ecrire/req/pg.php +++ b/ecrire/req/pg.php @@ -57,6 +57,7 @@ function req_pg_dist($addr, $port, $login, $pass, $db='', $prefixe='', $ldap='') 'fetch' => 'spip_pg_fetch', 'free' => 'spip_pg_free', 'hex' => 'spip_pg_hex', + 'in' => 'spip_pg_in', 'insert' => 'spip_pg_insert', 'insertq' => 'spip_pg_insertq', 'listdbs' => 'spip_pg_listdbs', @@ -642,7 +643,7 @@ function spip_pg_sequence($table) // http://doc.spip.org/@spip_pg_cite function spip_pg_cite($v, $t) { - if (test_sql_date($t)) { + if (sql_test_date($t)) { if (strpos("0123456789", $v[0]) === false) return spip_pg_frommysql($v); else { @@ -651,7 +652,7 @@ function spip_pg_cite($v, $t) return "date '$v'"; } } - elseif (test_sql_int($t) + elseif (sql_test_int($t) AND (is_numeric($v) OR (strpos($v, 'CAST(') === 0) OR ($v[0]== 'x' ? @@ -667,6 +668,33 @@ function spip_pg_hex($v) return "CAST(x'" . $v . "' as bigint)"; } +// http://doc.spip.org/@calcul_pg_in +function spip_pg_in($val, $valeurs, $not='', $serveur) { +// +// IN (...) souvent limite a 255 elements, d'ou cette fonction assistante +// + if (is_array($valeurs)) + $valeurs = join(',', array_map('_q', $valeurs)); + if (!strlen(trim($valeurs))) return ($not ? "0=0" : '0=1'); + if (strpos($valeurs, "CAST(x'") !== false) + return "($val=" . join("OR $val=", explode(',',$valeurs)).')'; + $n = $i = 0; + $in_sql =""; + while ($n = strpos($valeurs, ',', $n+1)) { + if ((++$i) >= 255) { + $in_sql .= "($val $not IN (" . + substr($valeurs, 0, $n) . + "))\n" . + ($not ? "AND\t" : "OR\t"); + $valeurs = substr($valeurs, $n+1); + $i = $n = 0; + } + } + $in_sql .= "($val $not IN ($valeurs))"; + + return "($in_sql)"; +} + // http://doc.spip.org/@spip_pg_error function spip_pg_error($query) { $s = str_replace('ERROR', 'errcode: 1000 ', pg_last_error()); @@ -725,23 +753,6 @@ function spip_pg_showtable($nom_table, $serveur='') return array('field' => $fields, 'key' => $keys); } -// http://doc.spip.org/@calcul_pg_in -function calcul_pg_in($val, $valeurs, $not='') { -// -// IN (...) souvent limite a 255 elements, d'ou cette fonction assistante -// - if (!$valeurs) return '0=0'; - $s = split(',', $valeurs, 255); - if (count($s) < 255) { - return ("($val $not IN ($valeurs))"); - } else { - $valeurs = array_pop($s); - return ("($val $not IN (" . join(',',$s) . "))\n" . - ($not ? "AND\t" : "OR\t") . - calcul_pgsql_in($val, $valeurs, $not)); - } -} - // Fonction de creation d'une table SQL nommee $nom // a partir de 2 tableaux PHP : // champs: champ => type