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