Index: drupal-6.x-dev/includes/cache.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/cache.inc,v
retrieving revision 1.14
diff -u -p -r1.14 cache.inc
--- drupal-6.x-dev/includes/cache.inc	26 Aug 2007 09:33:49 -0000	1.14
+++ drupal-6.x-dev/includes/cache.inc	6 Nov 2007 17:27:54 -0000
@@ -105,9 +105,17 @@ function cache_set($cid, $data, $table =
     $serialized = 1;
   }
   $created = time();
-  db_query("UPDATE {". $table ."} SET data = %b, created = %d, expire = %d, headers = '%s', serialized = %d WHERE cid = '%s'", $data, $created, $expire, $headers, $serialized, $cid);
+  $values = array(
+    array('field' => 'data', 'placeholder' => '%b', 'data' => $data),
+    array('field' => 'created', 'placeholder' => '%d', 'data' => $created),
+    array('field' => 'expire', 'placeholder' => '%d', 'data' => $expire),
+    array('field' => 'headers', 'placeholder' => "'%s'", 'data' => $headers),
+    array('field' => 'serialized', 'placeholder' => '%d', 'data' => $serialized),
+  );
+  db_query_update("{". $table . "}", $values, "cid = '%s'", $cid);
   if (!db_affected_rows()) {
-    @db_query("INSERT INTO {". $table ."} (cid, data, created, expire, headers, serialized) VALUES ('%s', %b, %d, %d, '%s', %d)", $cid, $data, $created, $expire, $headers, $serialized);
+    $values[] = array('field' => 'cid', 'placeholder' => "'%s'", 'data' => $cid);
+    db_query_insert("{". $table ."}", $values);
   }
 }
 
Index: drupal-6.x-dev/includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.710
diff -u -p -r1.710 common.inc
--- drupal-6.x-dev/includes/common.inc	4 Nov 2007 21:24:09 -0000	1.710
+++ drupal-6.x-dev/includes/common.inc	6 Nov 2007 17:27:55 -0000
@@ -3106,7 +3106,7 @@ function drupal_schema_fields_sql($table
  *   The object to write. This is a reference, as defaults according to
  *   the schema may be filled in on the object, as well as ID on the serial
  *   type(s). Both array an object types may be passed.
- * @param update
+ * @param primary_keys
  *   If this is an update, specify the primary keys' field names. It is the
  *   caller's responsibility to know if a record for this object already
  *   exists in the database. If there is only 1 key, you may pass a simple string.
@@ -3115,19 +3115,15 @@ function drupal_schema_fields_sql($table
  *   fields defined by the $table. For example, $object->nid will be populated
  *   after inserting a new node.
  */
-function drupal_write_record($table, &$object, $update = array()) {
-  // Standardize $update to an array.
-  if (is_string($update)) {
-    $update = array($update);
+function drupal_write_record($table, &$object, $primary_keys = array()) {
+  // Standardize $primary_keys to an array.
+  if (!is_array($primary_keys)) {
+    $primary_keys = array($primary_keys);
   }
 
   // Convert to an object if needed.
-  if (is_array($object)) {
+  if ($array = is_array($object)) {
     $object = (object) $object;
-    $array = TRUE;
-  }
-  else {
-    $array = FALSE;
   }
 
   $schema = drupal_get_schema($table);
@@ -3135,18 +3131,18 @@ function drupal_write_record($table, &$o
     return FALSE;
   }
 
-  $fields = $defs = $values = $serials = array();
-
+  $values = array();
+  $serials = array();
   // Go through our schema, build SQL, and when inserting, fill in defaults for
   // fields that are not set.
   foreach ($schema['fields'] as $field => $info) {
     // Special case -- skip serial types if we are updating.
-    if ($info['type'] == 'serial' && count($update)) {
+    if ($info['type'] == 'serial' && count($primary_keys)) {
       continue;
     }
 
     // For inserts, populate defaults from Schema if not already provided
-    if (!isset($object->$field)  && !count($update) && isset($info['default'])) {
+    if (!isset($object->$field) && !count($primary_keys) && isset($info['default'])) {
       $object->$field = $info['default'];
     }
 
@@ -3159,42 +3155,33 @@ function drupal_write_record($table, &$o
 
     // Build arrays for the fields, placeholders, and values in our query.
     if (isset($object->$field)) {
-      $fields[] = $field;
-      $placeholders[] = db_type_placeholder($info['type']);
+      $value['field'] = $field;
+      $value['placeholder'] = db_type_placeholder($info['type']);
 
       if (empty($info['serialize'])) {
-        $values[] = $object->$field;
+        $value['data'] = $object->$field;
       }
       else {
-        $values[] = serialize($object->$field);
+        $value['data'] = serialize($object->$field);
       }
+
+      $values[] = $value;
     }
   }
 
   // Build the SQL.
-  $query = '';
-  if (!count($update)) {
-    $query = "INSERT INTO {". $table ."} (". implode(', ', $fields) .') VALUES ('. implode(', ', $placeholders) .')';
+  if (!count($primary_keys)) {
+    db_query_insert("{". $table ."}", $values);
     $return = SAVED_NEW;
   }
   else {
-    $query = '';
-    foreach ($fields as $id => $field) {
-      if ($query) {
-        $query .= ', ';
-      }
-      $query .= $field .' = '. $placeholders[$id];
-    }
-
-    foreach ($update as $key){
+    foreach ($primary_keys as $key){
       $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']);
-      $values[] = $object->$key;
+      $args[] = $object->$key;
     }
-
-    $query = "UPDATE {". $table ."} SET $query WHERE ". implode(' AND ', $conditions);
+    db_query_update("{". $table ."}", $values, implode(' AND ', $conditions), $args);
     $return = SAVED_UPDATED;
   }
-  db_query($query, $values);
 
   if ($serials) {
     // Get last insert ids and fill them in.
@@ -3202,16 +3189,57 @@ function drupal_write_record($table, &$o
       $object->$field = db_last_insert_id($table, $field);
     }
   }
-
+  
   // If we began with an array, convert back so we don't surprise the caller.
   if ($array) {
-    $object = (array)$object;
+    $object = (array) $object;
   }
 
   return $return;
 }
 
 /**
+ * Drop a record from the database based upon the schema.
+ *
+ * @param $table
+ *   The name of the table; this must exist in schema API.
+ * @param $object
+ *   The object to drop. This is a reference, as defaults according to
+ *   the schema may be filled in on the object, as well as ID on the serial
+ *   type(s). Both array an object types may be passed.
+ * @param primary_keys
+ *   Specify the primary keys' field names. If there is only 1 key, you may
+ *   pass a simple string.
+ * @return (boolean) Failure to write a record will return FALSE. Otherwise,
+ *   TRUE is returned.
+ */
+function drupal_drop_record($table, $object, $primary_keys = array()) {
+  // Standardize $primary_keys to an array.
+  if (!is_array($primary_keys)) {
+    $primary_keys = array($primary_keys);
+  }
+
+  // Convert to an object if needed.
+  if ($array = is_array($object)) {
+    $object = (object) $object;
+  }
+
+  $schema = drupal_get_schema($table);
+  if (empty($schema)) {
+    return FALSE;
+  }
+
+  // Execute the request.
+  foreach ($primary_keys as $key){
+    $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']);
+    $args[] = $object->$key;
+  }
+  db_query_delete("{". $table ."}", implode(' AND ', $conditions), $args);
+
+  return SAVED_DELETED;
+}
+
+/**
  * @} End of "ingroup schemaapi".
  */
 
Index: drupal-6.x-dev/includes/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.inc,v
retrieving revision 1.84
diff -u -p -r1.84 database.inc
--- drupal-6.x-dev/includes/database.inc	12 Oct 2007 14:19:44 -0000	1.84
+++ drupal-6.x-dev/includes/database.inc	6 Nov 2007 17:27:55 -0000
@@ -176,14 +176,16 @@ function _db_query_callback($match, $ini
   switch ($match[1]) {
     case '%d': // We must use type casting to int to convert FALSE/NULL/(TRUE?)
       return (int) array_shift($args); // We don't need db_escape_string as numbers are db-safe
+    case '%f':
+      return (float) array_shift($args);
     case '%s':
       return db_escape_string(array_shift($args));
+    case '%b': // Binary Large OBject.
+      return db_encode_blob(array_shift($args));  
+    case '%c': // Character Large OBject.
+      return db_encode_clob(array_shift($args));
     case '%%':
       return '%';
-    case '%f':
-      return (float) array_shift($args);
-    case '%b': // binary data
-      return db_encode_blob(array_shift($args));
   }
 }
 
@@ -206,7 +208,7 @@ function db_placeholders($arguments, $ty
 /**
  * Indicates the place holders that should be replaced in _db_query_callback().
  */
-define('DB_QUERY_REGEXP', '/(%d|%s|%%|%f|%b)/');
+define('DB_QUERY_REGEXP', '/(%d|%f|%s|%b|%c|%%)/');
 
 /**
  * Helper function for db_rewrite_sql.
@@ -512,6 +514,9 @@ function db_type_placeholder($type) {
 
     case 'blob':
       return '%b';
+
+    case 'clob':
+      return '%c';
   }
 
   // There is no safe value to return here, so return something that
Index: drupal-6.x-dev/includes/database.mysql-common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.mysql-common.inc,v
retrieving revision 1.13
diff -u -p -r1.13 database.mysql-common.inc
--- drupal-6.x-dev/includes/database.mysql-common.inc	2 Oct 2007 16:15:56 -0000	1.13
+++ drupal-6.x-dev/includes/database.mysql-common.inc	6 Nov 2007 17:27:55 -0000
@@ -7,6 +7,81 @@
  */
 
 /**
+ * @ingroup database
+ * @{
+ */
+
+/**
+ * Indicates the concatenation operator.
+ */
+define('DB_CONCAT_OPERATOR', '+');
+
+/**
+ * Indicates the name of the SQL strtoupper function.
+ */
+define('DB_UPPER', 'UPPER');
+
+/**
+ * Indicates the SQL to generate a random number between 0.00 and 1.00.
+ */
+define('DB_RAND', 'RAND()');
+
+/**
+ * Indicates the name of the SQL strlen function.
+ */
+define('DB_STRLEN', 'LENGTH');
+
+/**
+ * Indicates the name of the SQL substring function.
+ */
+define('DB_SUBSTR', 'SUBSTRING');
+
+/**
+ * Portable SQL generating function.
+ *
+ * @param ...
+ *   Variable number of string parameters.
+ * @return
+ *   Portably concatenate strings.
+ */
+function db_concat() {
+  $args = func_get_args();
+  $return = implode(', ', $args);
+  return (strlen($return) > 0) ? "CONCAT($return)" : '';
+}
+
+/**
+ * Returns a string that is the equivalent of MySQL IFNULL or Oracle NVL.
+ *
+ * @return
+ *   If $expr1 is not NULL, returns $expr1; otherwise it returns $expr2.
+ */
+function db_if_null($expr1, $expr2) {
+  return " IFNULL($expr1, $expr2) ";
+}
+
+/**
+ * Report database status.
+ */
+function db_status_report($phase) {
+  $t = get_t();
+
+  $version = db_version();
+
+  $form['mysql'] = array(
+    'title' => $t('MySQL database'),
+    'value' => ($phase == 'runtime') ? l($version, 'admin/reports/status/sql') : $version,
+  );
+
+  if (version_compare($version, DRUPAL_MINIMUM_MYSQL) < 0) {
+    $form['mysql']['severity'] = REQUIREMENT_ERROR;
+    $form['mysql']['description'] = $t('Your MySQL Server is too old. Drupal requires at least MySQL %version.', array('%version' => DRUPAL_MINIMUM_MYSQL));
+  }
+
+  return $form;
+}
+
+/**
  * Runs a basic query in the active database.
  *
  * User-supplied arguments to the query should be passed in as separate
@@ -43,11 +118,353 @@ function db_query($query) {
 }
 
 /**
+ * Insert a row of record into database.
+ *
+ * @param $table
+ *   Table to insert.
+ * @param $values
+ *   An array containing the insert values. Each element of the array
+ *   should be an associatie array with the following keys:
+ *   - "field": The database field represented in the table column.
+ *   - "placeholder": The placeholder of the table column, using printf()
+ *     syntax. Valid %-modifiers are: %d, %f, %s and %b.
+ *   - "data": The data to insert into the table column.
+ * @return
+ *   A database query result resource, or FALSE if the query was not
+ *   executed correctly.
+ */
+function db_query_insert($table, $values) {
+  $fields = array();
+  $placeholders = array();
+  $data = array();
+  foreach ($values as $value) {
+    $fields[] = $value['field'];
+    $placeholders[] = $value['placeholder'];
+    $data[] = $value['data'];
+  }
+
+  if (count($fields)) {
+    $query = "INSERT INTO ". $table ." (". implode(', ', $fields) .") VALUES (". implode(', ', $placeholders) .")";
+    return db_query($query, $data);
+  }
+}
+
+/**
+ * Update a row of record in database.
+ *
+ * @param $table
+ *   Table to update.
+ * @param $values
+ *   An array containing the update values. Each element of the array
+ *   should be an associatie array with the following keys:
+ *   - "field": The database field represented in the table column.
+ *   - "placeholder": The placeholder of the table column, using printf()
+ *     syntax. Valid %-modifiers are: %d, %f, %s and %b.
+ *   - "data": The data to insert into the table column.
+ * @param $where_clause
+ *   A string containing an update condition query (where clause).
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   WHERE condition, using printf() syntax. Instead of a variable number
+ *   of query arguments, you may also pass a single array containing the
+ *   query arguments.
+ *
+ *   Valid %-modifiers are: %d, %f and %s.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @return
+ *   A database query result resource, or FALSE if the query was not
+ *   executed correctly.
+ */
+function db_query_update($table, $values, $where_clause = NULL) {
+  $args = func_get_args();
+  $args = array_slice($args, 3);
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+
+  $fields = array();
+  $data = array();
+  foreach ($values as $value) {
+    $fields[] = $value['field'] .'='. $value['placeholder'];
+    $data[] = $value['data'];
+  }
+
+  if (count($fields)) {
+    $query = "UPDATE ". $table ." SET ". implode(', ', $fields);
+    if ($where_clause) {
+      $query .= " WHERE ". $where_clause;
+      $data = array_merge($data, $args);
+    }
+    return db_query($query, $data);
+  }
+}
+
+/**
+ * Delete a row of record from database.
+ *
+ * @param $table
+ *   Table to delete.
+ * @param $where_clause
+ *   A string containing an update condition query (where clause).
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   WHERE condition, using printf() syntax. Instead of a variable number
+ *   of query arguments, you may also pass a single array containing the
+ *   query arguments.
+ *
+ *   Valid %-modifiers are: %d, %f and %s.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @return
+ *   A database query result resource, or FALSE if the query was not
+ *   executed correctly.
+ */
+function db_query_delete($table, $where_clause = NULL) {
+  $args = func_get_args();
+  $args = array_slice($args, 2);
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+
+  $data = array();
+
+  $query = "DELETE FROM ". $table;
+  if ($where_clause) {
+    $query .= " WHERE ". $where_clause;
+    $data = $args;
+  }
+  return db_query($query, $data);
+}
+
+/**
+ * Returns the last insert id.
+ *
+ * @param $table
+ *   The name of the table you inserted into.
+ * @param $field
+ *   The name of the autoincrement field.
+ */
+function db_last_insert_id($table, $field) {
+  return db_result(db_query('SELECT LAST_INSERT_ID()'));
+}
+
+/**
+ * Runs a limited-range query in the active database.
+ *
+ * Use this as a substitute for db_query() when a subset of the query is to be
+ * returned.
+ * User-supplied arguments to the query should be passed in as separate parameters
+ * so that they can be properly escaped to avoid SQL injection attacks.
+ *
+ * @param $query
+ *   A string containing an SQL query.
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   using printf() syntax. The query arguments can be enclosed in one
+ *   array instead.
+ *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
+ *   in '') and %%.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @param $from
+ *   The first result row to return.
+ * @param $count
+ *   The maximum number of result rows to return.
+ * @return
+ *   A database query result resource, or FALSE if the query was not executed
+ *   correctly.
+ */
+function db_query_range($query) {
+  $args = func_get_args();
+  $count = array_pop($args);
+  $from = array_pop($args);
+  array_shift($args);
+
+  $query .= ' LIMIT '. (int) $from .', '. (int) $count;
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+  return db_query($query, $args);
+}
+
+/**
+ * Runs a SELECT query and stores its results in a temporary table.
+ *
+ * Use this as a substitute for db_query() when the results need to stored
+ * in a temporary table. Temporary tables exist for the duration of the page
+ * request.
+ * User-supplied arguments to the query should be passed in as separate parameters
+ * so that they can be properly escaped to avoid SQL injection attacks.
+ *
+ * Note that if you need to know how many results were returned, you should do
+ * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() does
+ * not give consistent result across different database types in this case.
+ *
+ * @param $query
+ *   A string containing a normal SELECT SQL query.
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   using printf() syntax. The query arguments can be enclosed in one
+ *   array instead.
+ *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
+ *   in '') and %%.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @param $table
+ *   The name of the temporary table to select into. This name will not be
+ *   prefixed as there is no risk of collision.
+ * @return
+ *   A database query result resource, or FALSE if the query was not executed
+ *   correctly.
+ */
+function db_query_temporary($query) {
+  $args = func_get_args();
+  $tablename = array_pop($args);
+  array_shift($args);
+
+  $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' Engine=HEAP SELECT', $query);
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+  return db_query($query, $args);
+}
+
+/**
+ * Returns text from a Binary Large Object value.
+ *
+ * @param $data
+ *   Data to decode.
+ * @return
+ *  Decoded data.
+ */
+function db_decode_blob($data) {
+  return $data;
+}
+
+/**
+ * Returns text from a Character Large Object value.
+ *
+ * @param $data
+ *   Data to decode.
+ * @return
+ *  Decoded data.
+ */
+function db_decode_clob($data) {
+  return $data;
+}
+
+/**
+ * Lock a table.
+ */
+function db_lock_table($table) {
+  db_query('LOCK TABLES {'. db_escape_table($table) .'} WRITE');
+}
+
+/**
+ * Unlock all locked tables.
+ */
+function db_unlock_tables() {
+  db_query('UNLOCK TABLES');
+}
+
+/**
+ * Check if a table exists.
+ */
+function db_table_exists($table) {
+  return db_fetch_object(db_query("SHOW TABLES LIKE '{". db_escape_table($table) ."}'")) ? TRUE : FALSE;
+}
+
+/**
+ * Check if a column exists in the given table.
+ */
+function db_column_exists($table, $column) {
+  return db_fetch_object(db_query("SHOW COLUMNS FROM {%s} LIKE '%s'", $table, $column)) ? TRUE : FALSE;
+}
+
+/**
+ * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to
+ * the SELECT list entry of the given query and the resulting query is returned.
+ * This function only applies the wrapper if a DISTINCT doesn't already exist in
+ * the query.
+ *
+ * @param $table Table containing the field to set as DISTINCT
+ * @param $field Field to set as DISTINCT
+ * @param $query Query to apply the wrapper to
+ * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
+ */
+function db_distinct_field($table, $field, $query) {
+  $field_to_select = 'DISTINCT('. $table .'.'. $field .')';
+  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
+  return preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query);
+}
+
+/**
+ * @} End of "ingroup database".
+ */
+
+/**
  * @ingroup schemaapi
  * @{
  */
 
 /**
+ * This maps a generic data type in combination with its data size
+ * to the engine-specific data type.
+ */
+function db_type_map() {
+  // Put :normal last so it gets preserved by array_flip.  This makes
+  // it much easier for modules (such as schema.module) to map
+  // database types back into schema types.
+  $map = array(
+    'varchar:normal'  => 'VARCHAR',
+
+    'text:tiny'       => 'SMALLTEXT',
+    'text:small'      => 'SMALLTEXT',
+    'text:medium'     => 'MEDIUMTEXT',
+    'text:big'        => 'LONGTEXT',
+    'text:normal'     => 'TEXT',
+
+    'serial:tiny'     => 'TINYINT',
+    'serial:small'    => 'SMALLINT',
+    'serial:medium'   => 'MEDIUMINT',
+    'serial:big'      => 'BIGINT',
+    'serial:normal'   => 'INT',
+
+    'int:tiny'        => 'TINYINT',
+    'int:small'       => 'SMALLINT',
+    'int:medium'      => 'MEDIUMINT',
+    'int:big'         => 'BIGINT',
+    'int:normal'      => 'INT',
+
+    'float:tiny'      => 'FLOAT',
+    'float:small'     => 'FLOAT',
+    'float:medium'    => 'FLOAT',
+    'float:big'       => 'DOUBLE',
+    'float:normal'    => 'FLOAT',
+
+    'numeric:normal'  => 'NUMERIC',
+
+    'blob:big'        => 'LONGBLOB',
+    'blob:normal'     => 'BLOB',
+
+    'clob:big'        => 'LONGTEXT',
+    'clob:normal'     => 'TEXT',
+
+    'datetime:normal' => 'DATETIME',
+  );
+  return $map;
+}
+
+/**
  * Generate SQL to create a new table from a Drupal schema definition.
  *
  * @param $name
@@ -71,7 +488,7 @@ function db_create_table_sql($name, $tab
   }
 
   // Process keys & indexes.
-  $keys = _db_create_keys_sql($table);
+  $keys = _db_create_keys($table);
   if (count($keys)) {
     $sql .= implode(", \n", $keys) .", \n";
   }
@@ -84,7 +501,20 @@ function db_create_table_sql($name, $tab
   return array($sql);
 }
 
-function _db_create_keys_sql($spec) {
+function _db_create_key_sql($fields) {
+  $ret = array();
+  foreach ($fields as $field) {
+    if (is_array($field)) {
+      $ret[] = $field[0] .'('. $field[1] .')';
+    }
+    else {
+      $ret[] = $field;
+    }
+  }
+  return implode(', ', $ret);
+}
+
+function _db_create_keys($spec) {
   $keys = array();
 
   if (!empty($spec['primary key'])) {
@@ -104,19 +534,6 @@ function _db_create_keys_sql($spec) {
   return $keys;
 }
 
-function _db_create_key_sql($fields) {
-  $ret = array();
-  foreach ($fields as $field) {
-    if (is_array($field)) {
-      $ret[] = $field[0] .'('. $field[1] .')';
-    }
-    else {
-      $ret[] = $field;
-    }
-  }
-  return implode(', ', $ret);
-}
-
 /**
  * Set database-engine specific properties for a field.
  *
@@ -164,7 +581,7 @@ function _db_create_field_sql($name, $sp
   }
 
   if (!empty($spec['unsigned'])) {
-    $sql .= ' unsigned';
+    $sql .= ' UNSIGNED';
   }
 
   if (!empty($spec['not null'])) {
@@ -172,7 +589,7 @@ function _db_create_field_sql($name, $sp
   }
 
   if (!empty($spec['auto_increment'])) {
-    $sql .= ' auto_increment';
+    $sql .= ' AUTO_INCREMENT';
   }
 
   if (isset($spec['default'])) {
@@ -190,51 +607,6 @@ function _db_create_field_sql($name, $sp
 }
 
 /**
- * This maps a generic data type in combination with its data size
- * to the engine-specific data type.
- */
-function db_type_map() {
-  // Put :normal last so it gets preserved by array_flip.  This makes
-  // it much easier for modules (such as schema.module) to map
-  // database types back into schema types.
-  $map = array(
-    'varchar:normal'  => 'VARCHAR',
-
-    'text:tiny'       => 'SMALLTEXT',
-    'text:small'      => 'SMALLTEXT',
-    'text:medium'     => 'MEDIUMTEXT',
-    'text:big'        => 'LONGTEXT',
-    'text:normal'     => 'TEXT',
-
-    'serial:tiny'     => 'TINYINT',
-    'serial:small'    => 'SMALLINT',
-    'serial:medium'   => 'MEDIUMINT',
-    'serial:big'      => 'BIGINT',
-    'serial:normal'   => 'INT',
-
-    'int:tiny'        => 'TINYINT',
-    'int:small'       => 'SMALLINT',
-    'int:medium'      => 'MEDIUMINT',
-    'int:big'         => 'BIGINT',
-    'int:normal'      => 'INT',
-
-    'float:tiny'      => 'FLOAT',
-    'float:small'     => 'FLOAT',
-    'float:medium'    => 'FLOAT',
-    'float:big'       => 'DOUBLE',
-    'float:normal'    => 'FLOAT',
-
-    'numeric:normal'  => 'NUMERIC',
-
-    'blob:big'        => 'LONGBLOB',
-    'blob:normal'     => 'BLOB',
-
-    'datetime:normal' => 'DATETIME',
-  );
-  return $map;
-}
-
-/**
  * Rename a table.
  *
  * @param $ret
@@ -292,7 +664,7 @@ function db_add_field(&$ret, $table, $fi
   $query = 'ALTER TABLE {'. $table .'} ADD ';
   $query .= _db_create_field_sql($field, _db_process_field($spec));
   if (count($keys_new)) {
-    $query .= ', ADD '. implode(', ADD ', _db_create_keys_sql($keys_new));
+    $query .= ', ADD '. implode(', ADD ', _db_create_keys($keys_new));
   }
   $ret[] = update_sql($query);
   if (isset($spec['initial'])) {
@@ -514,19 +886,11 @@ function db_change_field(&$ret, $table, 
   $sql = 'ALTER TABLE {'. $table .'} CHANGE '. $field .' '.
     _db_create_field_sql($field_new, _db_process_field($spec));
   if (count($keys_new)) {
-    $sql .= ', ADD '.implode(', ADD ', _db_create_keys_sql($keys_new));
+    $sql .= ', ADD '.implode(', ADD ', _db_create_keys($keys_new));
   }
   $ret[] = update_sql($sql);
 }
 
 /**
- * Returns the last insert id.
- *
- * @param $table
- *   The name of the table you inserted into.
- * @param $field
- *   The name of the autoincrement field.
+ * @} End of "ingroup schemaapi".
  */
-function db_last_insert_id($table, $field) {
-  return db_result(db_query('SELECT LAST_INSERT_ID()'));
-}
Index: drupal-6.x-dev/includes/database.mysql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.mysql.inc,v
retrieving revision 1.83
diff -u -p -r1.83 database.mysql.inc
--- drupal-6.x-dev/includes/database.mysql.inc	20 Oct 2007 21:57:49 -0000	1.83
+++ drupal-6.x-dev/includes/database.mysql.inc	6 Nov 2007 17:27:55 -0000
@@ -15,27 +15,6 @@
 require_once './includes/database.mysql-common.inc';
 
 /**
- * Report database status.
- */
-function db_status_report($phase) {
-  $t = get_t();
-
-  $version = db_version();
-
-  $form['mysql'] = array(
-    'title' => $t('MySQL database'),
-    'value' => ($phase == 'runtime') ? l($version, 'admin/reports/status/sql') : $version,
-  );
-
-  if (version_compare($version, DRUPAL_MINIMUM_MYSQL) < 0) {
-    $form['mysql']['severity'] = REQUIREMENT_ERROR;
-    $form['mysql']['description'] = $t('Your MySQL Server is too old. Drupal requires at least MySQL %version.', array('%version' => DRUPAL_MINIMUM_MYSQL));
-  }
-
-  return $form;
-}
-
-/**
  * Returns the version of the database server currently in use.
  *
  * @return Database server version
@@ -238,93 +217,11 @@ function db_affected_rows() {
 }
 
 /**
- * Runs a limited-range query in the active database.
- *
- * Use this as a substitute for db_query() when a subset of the query is to be
- * returned.
- * User-supplied arguments to the query should be passed in as separate parameters
- * so that they can be properly escaped to avoid SQL injection attacks.
- *
- * @param $query
- *   A string containing an SQL query.
- * @param ...
- *   A variable number of arguments which are substituted into the query
- *   using printf() syntax. The query arguments can be enclosed in one
- *   array instead.
- *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
- *   in '') and %%.
- *
- *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
- *   and TRUE values to decimal 1.
- *
- * @param $from
- *   The first result row to return.
- * @param $count
- *   The maximum number of result rows to return.
- * @return
- *   A database query result resource, or FALSE if the query was not executed
- *   correctly.
- */
-function db_query_range($query) {
-  $args = func_get_args();
-  $count = array_pop($args);
-  $from = array_pop($args);
-  array_shift($args);
-
-  $query = db_prefix_tables($query);
-  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
-    $args = $args[0];
-  }
-  _db_query_callback($args, TRUE);
-  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
-  $query .= ' LIMIT '. (int)$from .', '. (int)$count;
-  return _db_query($query);
-}
-
-/**
- * Runs a SELECT query and stores its results in a temporary table.
- *
- * Use this as a substitute for db_query() when the results need to stored
- * in a temporary table. Temporary tables exist for the duration of the page
- * request.
- * User-supplied arguments to the query should be passed in as separate parameters
- * so that they can be properly escaped to avoid SQL injection attacks.
- *
- * Note that if you need to know how many results were returned, you should do
- * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() does
- * not give consistent result across different database types in this case.
- *
- * @param $query
- *   A string containing a normal SELECT SQL query.
- * @param ...
- *   A variable number of arguments which are substituted into the query
- *   using printf() syntax. The query arguments can be enclosed in one
- *   array instead.
- *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
- *   in '') and %%.
- *
- *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
- *   and TRUE values to decimal 1.
- *
- * @param $table
- *   The name of the temporary table to select into. This name will not be
- *   prefixed as there is no risk of collision.
- * @return
- *   A database query result resource, or FALSE if the query was not executed
- *   correctly.
+ * Prepare user input for use in a database query, preventing SQL injection attacks.
  */
-function db_query_temporary($query) {
-  $args = func_get_args();
-  $tablename = array_pop($args);
-  array_shift($args);
-
-  $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' Engine=HEAP SELECT', db_prefix_tables($query));
-  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
-    $args = $args[0];
-  }
-  _db_query_callback($args, TRUE);
-  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
-  return _db_query($query);
+function db_escape_string($data) {
+  global $active_db;
+  return mysql_real_escape_string($data, $active_db);
 }
 
 /**
@@ -341,68 +238,16 @@ function db_encode_blob($data) {
 }
 
 /**
- * Returns text from a Binary Large Object value.
+ * Returns a properly formatted Character Large OBject value.
  *
  * @param $data
- *   Data to decode.
+ *   Data to encode.
  * @return
- *  Decoded data.
- */
-function db_decode_blob($data) {
-  return $data;
-}
-
-/**
- * Prepare user input for use in a database query, preventing SQL injection attacks.
+ *  Encoded data.
  */
-function db_escape_string($text) {
+function db_encode_clob($data) {
   global $active_db;
-  return mysql_real_escape_string($text, $active_db);
-}
-
-/**
- * Lock a table.
- */
-function db_lock_table($table) {
-  db_query('LOCK TABLES {'. db_escape_table($table) .'} WRITE');
-}
-
-/**
- * Unlock all locked tables.
- */
-function db_unlock_tables() {
-  db_query('UNLOCK TABLES');
-}
-
-/**
- * Check if a table exists.
- */
-function db_table_exists($table) {
-  return db_fetch_object(db_query("SHOW TABLES LIKE '{". db_escape_table($table) ."}'")) ? TRUE : FALSE;
-}
-
-/**
- * Check if a column exists in the given table.
- */
-function db_column_exists($table, $column) {
-  return db_fetch_object(db_query("SHOW COLUMNS FROM {%s} LIKE '%s'", $table, $column)) ? TRUE : FALSE;
-}
-
-/**
- * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to
- * the SELECT list entry of the given query and the resulting query is returned.
- * This function only applies the wrapper if a DISTINCT doesn't already exist in
- * the query.
- *
- * @param $table Table containing the field to set as DISTINCT
- * @param $field Field to set as DISTINCT
- * @param $query Query to apply the wrapper to
- * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
- */
-function db_distinct_field($table, $field, $query) {
-  $field_to_select = 'DISTINCT('. $table .'.'. $field .')';
-  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
-  return preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query);
+  return "'". mysql_real_escape_string($data, $active_db) ."'";
 }
 
 /**
Index: drupal-6.x-dev/includes/database.mysqli.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.mysqli.inc,v
retrieving revision 1.48
diff -u -p -r1.48 database.mysqli.inc
--- drupal-6.x-dev/includes/database.mysqli.inc	20 Oct 2007 21:57:49 -0000	1.48
+++ drupal-6.x-dev/includes/database.mysqli.inc	6 Nov 2007 17:27:55 -0000
@@ -19,27 +19,6 @@
 require_once './includes/database.mysql-common.inc';
 
 /**
- * Report database status.
- */
-function db_status_report($phase) {
-  $t = get_t();
-
-  $version = db_version();
-
-  $form['mysql'] = array(
-    'title' => $t('MySQL database'),
-    'value' => ($phase == 'runtime') ? l($version, 'admin/reports/status/sql') : $version,
-  );
-
-  if (version_compare($version, DRUPAL_MINIMUM_MYSQL) < 0) {
-    $form['mysql']['severity'] = REQUIREMENT_ERROR;
-    $form['mysql']['description'] = $t('Your MySQL Server is too old. Drupal requires at least MySQL %version.', array('%version' => DRUPAL_MINIMUM_MYSQL));
-  }
-
-  return $form;
-}
-
-/**
  * Returns the version of the database server currently in use.
  *
  * @return Database server version
@@ -237,93 +216,11 @@ function db_affected_rows() {
 }
 
 /**
- * Runs a limited-range query in the active database.
- *
- * Use this as a substitute for db_query() when a subset of the query is to be
- * returned.
- * User-supplied arguments to the query should be passed in as separate parameters
- * so that they can be properly escaped to avoid SQL injection attacks.
- *
- * @param $query
- *   A string containing an SQL query.
- * @param ...
- *   A variable number of arguments which are substituted into the query
- *   using printf() syntax. The query arguments can be enclosed in one
- *   array instead.
- *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
- *   in '') and %%.
- *
- *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
- *   and TRUE values to decimal 1.
- *
- * @param $from
- *   The first result row to return.
- * @param $count
- *   The maximum number of result rows to return.
- * @return
- *   A database query result resource, or FALSE if the query was not executed
- *   correctly.
- */
-function db_query_range($query) {
-  $args = func_get_args();
-  $count = array_pop($args);
-  $from = array_pop($args);
-  array_shift($args);
-
-  $query = db_prefix_tables($query);
-  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
-    $args = $args[0];
-  }
-  _db_query_callback($args, TRUE);
-  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
-  $query .= ' LIMIT '. (int)$from .', '. (int)$count;
-  return _db_query($query);
-}
-
-/**
- * Runs a SELECT query and stores its results in a temporary table.
- *
- * Use this as a substitute for db_query() when the results need to stored
- * in a temporary table. Temporary tables exist for the duration of the page
- * request.
- * User-supplied arguments to the query should be passed in as separate parameters
- * so that they can be properly escaped to avoid SQL injection attacks.
- *
- * Note that if you need to know how many results were returned, you should do
- * a SELECT COUNT(*) on the temporary table afterwards. db_affected_rows() does
- * not give consistent result across different database types in this case.
- *
- * @param $query
- *   A string containing a normal SELECT SQL query.
- * @param ...
- *   A variable number of arguments which are substituted into the query
- *   using printf() syntax. The query arguments can be enclosed in one
- *   array instead.
- *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
- *   in '') and %%.
- *
- *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
- *   and TRUE values to decimal 1.
- *
- * @param $table
- *   The name of the temporary table to select into. This name will not be
- *   prefixed as there is no risk of collision.
- * @return
- *   A database query result resource, or FALSE if the query was not executed
- *   correctly.
+ * Prepare user input for use in a database query, preventing SQL injection attacks.
  */
-function db_query_temporary($query) {
-  $args = func_get_args();
-  $tablename = array_pop($args);
-  array_shift($args);
-
-  $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' Engine=HEAP SELECT', db_prefix_tables($query));
-  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
-    $args = $args[0];
-  }
-  _db_query_callback($args, TRUE);
-  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
-  return _db_query($query);
+function db_escape_string($data) {
+  global $active_db;
+  return mysqli_real_escape_string($active_db, $data);
 }
 
 /**
@@ -340,71 +237,18 @@ function db_encode_blob($data) {
 }
 
 /**
- * Returns text from a Binary Large OBject value.
+ * Returns a properly formatted Character Large OBject value.
  *
  * @param $data
- *   Data to decode.
+ *   Data to encode.
  * @return
- *  Decoded data.
- */
-function db_decode_blob($data) {
-  return $data;
-}
-
-/**
- * Prepare user input for use in a database query, preventing SQL injection attacks.
+ *  Encoded data.
  */
-function db_escape_string($text) {
+function db_encode_clob($data) {
   global $active_db;
-  return mysqli_real_escape_string($active_db, $text);
-}
-
-/**
- * Lock a table.
- */
-function db_lock_table($table) {
-  db_query('LOCK TABLES {'. db_escape_table($table) .'} WRITE');
-}
-
-/**
- * Unlock all locked tables.
- */
-function db_unlock_tables() {
-  db_query('UNLOCK TABLES');
-}
-
-/**
- * Check if a table exists.
- */
-function db_table_exists($table) {
-  return db_fetch_object(db_query("SHOW TABLES LIKE '{". db_escape_table($table) ."}'")) ? TRUE : FALSE;
-}
-
-/**
- * Check if a column exists in the given table.
- */
-function db_column_exists($table, $column) {
-  return db_fetch_object(db_query("SHOW COLUMNS FROM {%s} LIKE '%s'", $table, $column)) ? TRUE : FALSE;
-}
-
-/**
- * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to
- * the SELECT list entry of the given query and the resulting query is returned.
- * This function only applies the wrapper if a DISTINCT doesn't already exist in
- * the query.
- *
- * @param $table Table containing the field to set as DISTINCT
- * @param $field Field to set as DISTINCT
- * @param $query Query to apply the wrapper to
- * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
- */
-function db_distinct_field($table, $field, $query) {
-  $field_to_select = 'DISTINCT('. $table .'.'. $field .')';
-  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
-  return preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query);
+  return "'". mysqli_real_escape_string($active_db, $data) ."'";
 }
 
 /**
  * @} End of "ingroup database".
  */
-
Index: drupal-6.x-dev/includes/database.pgsql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v
retrieving revision 1.63
diff -u -p -r1.63 database.pgsql.inc
--- drupal-6.x-dev/includes/database.pgsql.inc	17 Oct 2007 12:47:28 -0000	1.63
+++ drupal-6.x-dev/includes/database.pgsql.inc	6 Nov 2007 17:27:55 -0000
@@ -12,6 +12,54 @@
  */
 
 /**
+ * Indicates the concatenation operator.
+ */
+define('DB_CONCAT_OPERATOR', '||');
+
+/**
+ * Indicates the name of the SQL strtoupper function.
+ */
+define('DB_UPPER', 'UPPER');
+
+/**
+ * Indicates the SQL to generate a random number between 0.00 and 1.00.
+ */
+define('DB_RAND', 'RANDOM()');
+
+/**
+ * Indicates the name of the SQL strlen function.
+ */
+define('DB_STRLEN', 'LENGTH');
+
+/**
+ * Indicates the name of the SQL substr function.
+ */
+define('DB_SUBSTR', 'SUBSTRING');
+
+/**
+ * Return a portably concatenate strings.
+ *
+ * @param ...
+ *   Variable number of string parameters.
+ * @return
+ *   Portably concatenate strings.
+ */
+function db_concat() {
+  $args = func_get_args();
+  return implode(DB_CONCAT_OPERATOR, $args);
+}
+
+/**
+ * Returns a string that is the equivalent of MySQL IFNULL or Oracle NVL.
+ *
+ * @return
+ *   If $expr1 is not NULL, returns $expr1; otherwise it returns $expr2.
+ */
+function db_if_null($expr1, $expr2) {
+  return " COALESCE($expr1, $expr2) ";
+}
+
+/**
  * Report database status.
  */
 function db_status_report() {
@@ -291,14 +339,11 @@ function db_query_range($query) {
   $from = array_pop($args);
   array_shift($args);
 
-  $query = db_prefix_tables($query);
+  $query .= ' LIMIT '. (int) $count .' OFFSET '. (int) $from;
   if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
     $args = $args[0];
   }
-  _db_query_callback($args, TRUE);
-  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
-  $query .= ' LIMIT '. (int)$count .' OFFSET '. (int)$from;
-  return _db_query($query);
+  return db_query($query, $args);
 }
 
 /**
@@ -338,13 +383,143 @@ function db_query_temporary($query) {
   $tablename = array_pop($args);
   array_shift($args);
 
-  $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' AS SELECT', db_prefix_tables($query));
+  $query = preg_replace('/^SELECT/i', 'CREATE TEMPORARY TABLE '. $tablename .' AS SELECT', $query);
   if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
     $args = $args[0];
   }
-  _db_query_callback($args, TRUE);
-  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
-  return _db_query($query);
+  return db_query($query, $args);
+}
+
+/**
+ * Insert a row of record into database.
+ *
+ * @param $table
+ *   Table to insert.
+ * @param $values
+ *   An array containing the insert values. Each element of the array
+ *   should be an associatie array with the following keys:
+ *   - "field": The database field represented in the table column.
+ *   - "placeholder": The placeholder of the table column, using printf()
+ *     syntax. Valid %-modifiers are: %d, %f, %s and %b.
+ *   - "data": The data to insert into the table column.
+ * @return
+ *   A database query result resource, or FALSE if the query was not
+ *   executed correctly.
+ */
+function db_query_insert($table, $values) {
+  $fields = array();
+  $placeholders = array();
+  $data = array();
+  foreach ($values as $value) {
+    $fields[] = $value['field'];
+    $placeholders[] = $value['placeholder'];
+    $data[] = $value['data'];
+  }
+
+  if (count($fields)) {
+    $query = "INSERT INTO ". $table ." (". implode(', ', $fields) .") VALUES (". implode(', ', $placeholders) .")";
+    return db_query($query, $data);
+  }
+}
+
+/**
+ * Update a row of record in database.
+ *
+ * @param $table
+ *   Table to update.
+ * @param $values
+ *   An array containing the update values. Each element of the array
+ *   should be an associatie array with the following keys:
+ *   - "field": The database field represented in the table column.
+ *   - "placeholder": The placeholder of the table column, using printf()
+ *     syntax. Valid %-modifiers are: %d, %f, %s and %b.
+ *   - "data": The data to insert into the table column.
+ * @param $where_clause
+ *   A string containing an update condition query (where clause).
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   WHERE condition, using printf() syntax. Instead of a variable number
+ *   of query arguments, you may also pass a single array containing the
+ *   query arguments.
+ *
+ *   Valid %-modifiers are: %d, %f and %s.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @return
+ *   A database query result resource, or FALSE if the query was not
+ *   executed correctly.
+ */
+function db_query_update($table, $values, $where_clause = NULL) {
+  $args = func_get_args();
+  $args = array_slice($args, 3);
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+
+  $fields = array();
+  $data = array();
+  foreach ($values as $value) {
+    $fields[] = $value['field'] .'='. $value['placeholder'];
+    $data[] = $value['data'];
+  }
+
+  if (count($fields)) {
+    $query = "UPDATE ". $table ." SET ". implode(', ', $fields);
+    if ($where_clause) {
+      $query .= " WHERE ". $where_clause;
+      $data = array_merge($data, $args);
+    }
+    return db_query($query, $data);
+  }
+}
+
+/**
+ * Delete a row of record from database.
+ *
+ * @param $table
+ *   Table to delete.
+ * @param $where_clause
+ *   A string containing an update condition query (where clause).
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   WHERE condition, using printf() syntax. Instead of a variable number
+ *   of query arguments, you may also pass a single array containing the
+ *   query arguments.
+ *
+ *   Valid %-modifiers are: %d, %f and %s.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @return
+ *   A database query result resource, or FALSE if the query was not
+ *   executed correctly.
+ */
+function db_query_delete($table, $where_clause = NULL) {
+  $args = func_get_args();
+  $args = array_slice($args, 2);
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+
+  $data = array();
+
+  $query = "DELETE FROM ". $table;
+  if ($where_clause) {
+    $query .= " WHERE ". $where_clause;
+    $data = $args;
+  }
+  return db_query($query, $data);
+}
+
+/**
+ * Prepare user input for use in a database query, preventing SQL injection attacks.
+ * Note: This function requires PostgreSQL 7.2 or later.
+ */
+function db_escape_string($data) {
+  return pg_escape_string($data);
 }
 
 /**
@@ -374,11 +549,30 @@ function db_decode_blob($data) {
 }
 
 /**
- * Prepare user input for use in a database query, preventing SQL injection attacks.
- * Note: This function requires PostgreSQL 7.2 or later.
+ * Returns a properly formatted Character Large OBject value.
+ * In case of PostgreSQL encodes data for insert or update into text field.
+ *
+ * @param $data
+ *   Data to encode.
+ * @return
+ *  Encoded data.
  */
-function db_escape_string($text) {
-  return pg_escape_string($text);
+function db_encode_clob($data) {
+  return "'". pg_escape_string($data) ."'";
+
+}
+
+/**
+ * Returns text from a Character Large OBject value.
+ * In case of PostgreSQL decodes data after select from bytea field.
+ *
+ * @param $data
+ *   Data to decode.
+ * @return
+ *  Decoded data.
+ */
+function db_decode_clob($data) {
+  return $data;
 }
 
 /**
@@ -401,14 +595,14 @@ function db_unlock_tables() {
  * Check if a table exists.
  */
 function db_table_exists($table) {
-  return db_result(db_query("SELECT COUNT(*) FROM pg_class WHERE relname = '{". db_escape_table($table) ."}'"));
+  return db_result(db_query("SELECT COUNT(*) FROM pg_class WHERE relname = '{". db_escape_table($table) ."}'")) ? TRUE : FALSE;
 }
 
 /**
  * Check if a column exists in the given table.
  */
 function db_column_exists($table, $column) {
-  return db_result(db_query("SELECT COUNT(pg_attribute.attname) FROM pg_class, pg_attribute WHERE pg_attribute.attrelid = pg_class.oid AND pg_class.relname = '{". db_escape_table($table) ."}' AND attname='%s'", $column));
+  return db_result(db_query("SELECT COUNT(pg_attribute.attname) FROM pg_class, pg_attribute WHERE pg_attribute.attrelid = pg_class.oid AND pg_class.relname = '{". db_escape_table($table) ."}' AND attname='%s'", $column)) ? TRUE : FALSE;
 }
 
 /**
@@ -460,38 +654,41 @@ function db_type_map() {
   // it much easier for modules (such as schema.module) to map
   // database types back into schema types.
   $map = array(
-    'varchar:normal' => 'varchar',
+    'varchar:normal'  => 'VARCHAR',
+ 
+    'text:tiny'       => 'TEXT',
+    'text:small'      => 'TEXT',
+    'text:medium'     => 'TEXT',
+    'text:big'        => 'TEXT',
+    'text:normal'     => 'TEXT',
+
+    'serial:tiny'     => 'SERIAL',
+    'serial:small'    => 'SERIAL',
+    'serial:medium'   => 'SERIAL',
+    'serial:big'      => 'BIGSERIAL',
+    'serial:normal'   => 'SERIAL',
+
+    'int:tiny'        => 'SMALLINT',
+    'int:small'       => 'SMALLINT',
+    'int:medium'      => 'INT',
+    'int:big'         => 'BIGINT',
+    'int:normal'      => 'INT',
+
+    'float:tiny'      => 'REAL',
+    'float:small'     => 'REAL',
+    'float:medium'    => 'REAL',
+    'float:big'       => 'DOUBLE PRECISION',
+    'float:normal'    => 'REAL',
+
+    'numeric:normal'  => 'NUMERIC',
 
-    'text:tiny' => 'text',
-    'text:small' => 'text',
-    'text:medium' => 'text',
-    'text:big' => 'text',
-    'text:normal' => 'text',
-
-    'int:tiny' => 'smallint',
-    'int:small' => 'smallint',
-    'int:medium' => 'int',
-    'int:big' => 'bigint',
-    'int:normal' => 'int',
-
-    'float:tiny' => 'real',
-    'float:small' => 'real',
-    'float:medium' => 'real',
-    'float:big' => 'double precision',
-    'float:normal' => 'real',
-
-    'numeric:normal'  => 'numeric',
-
-    'blob:big' => 'bytea',
-    'blob:normal' => 'bytea',
-
-    'datetime:normal' => 'timestamp',
-
-    'serial:tiny' => 'serial',
-    'serial:small' => 'serial',
-    'serial:medium' => 'serial',
-    'serial:big' => 'bigserial',
-    'serial:normal' => 'serial',
+    'blob:big'        => 'BYTEA',
+    'blob:normal'     => 'BYTEA',
+
+    'clob:big'        => 'TEXT',
+    'clob:normal'     => 'TEXT',
+
+    'datetime:normal' => 'TIMESTAMP',
   );
   return $map;
 }
@@ -634,7 +831,7 @@ function _db_create_field_sql($name, $sp
   }
   if (isset($spec['default'])) {
     $default = is_string($spec['default']) ? "'". $spec['default'] ."'" : $spec['default'];
-    $sql .= " default $default";
+    $sql .= " DEFAULT $default";
   }
 
   return $sql;
@@ -939,4 +1136,3 @@ function db_change_field(&$ret, $table, 
 /**
  * @} End of "ingroup schemaapi".
  */
-
Index: drupal-6.x-dev/modules/aggregator/aggregator.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.install,v
retrieving revision 1.12
diff -u -p -r1.12 aggregator.install
--- drupal-6.x-dev/modules/aggregator/aggregator.install	4 Nov 2007 14:33:06 -0000	1.12
+++ drupal-6.x-dev/modules/aggregator/aggregator.install	6 Nov 2007 17:27:55 -0000
@@ -214,7 +214,7 @@ function aggregator_schema() {
         'description' => t('Author of the feed item.'),
       ),
       'description' => array(
-        'type' => 'text',
+        'type' => 'clob',
         'not null' => TRUE,
         'size' => 'big',
         'description' => t('Body of the feed item.'),
Index: drupal-6.x-dev/modules/aggregator/aggregator.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.module,v
retrieving revision 1.360
diff -u -p -r1.360 aggregator.module
--- drupal-6.x-dev/modules/aggregator/aggregator.module	25 Oct 2007 15:32:55 -0000	1.360
+++ drupal-6.x-dev/modules/aggregator/aggregator.module	6 Nov 2007 17:27:55 -0000
@@ -806,15 +806,14 @@ function aggregator_parse_feed(&$data, $
 
 function aggregator_save_item($edit) {
   if ($edit['iid'] && $edit['title']) {
-    db_query("UPDATE {aggregator_item} SET title = '%s', link = '%s', author = '%s', description = '%s', guid = '%s', timestamp = %d WHERE iid = %d", $edit['title'], $edit['link'], $edit['author'], $edit['description'], $edit['guid'], $edit['timestamp'], $edit['iid']);
+    drupal_write_record("aggregator_item", $edit, 'iid');
   }
   else if ($edit['iid']) {
     db_query('DELETE FROM {aggregator_item} WHERE iid = %d', $edit['iid']);
     db_query('DELETE FROM {aggregator_category_item} WHERE iid = %d', $edit['iid']);
   }
   else if ($edit['title'] && $edit['link']) {
-    db_query("INSERT INTO {aggregator_item} (fid, title, link, author, description, timestamp, guid) VALUES (%d, '%s', '%s', '%s', '%s', %d, '%s')", $edit['fid'], $edit['title'], $edit['link'], $edit['author'], $edit['description'], $edit['timestamp'], $edit['guid']);
-    $edit['iid'] = db_last_insert_id('aggregator_item', 'iid');
+    drupal_write_record("aggregator_item", $edit);
     // file the items in the categories indicated by the feed
     $categories = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = %d', $edit['fid']);
     while ($category = db_fetch_object($categories)) {
Index: drupal-6.x-dev/modules/aggregator/aggregator.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.pages.inc,v
retrieving revision 1.5
diff -u -p -r1.5 aggregator.pages.inc
--- drupal-6.x-dev/modules/aggregator/aggregator.pages.inc	16 Oct 2007 13:48:11 -0000	1.5
+++ drupal-6.x-dev/modules/aggregator/aggregator.pages.inc	6 Nov 2007 17:27:55 -0000
@@ -202,7 +202,7 @@ function template_preprocess_aggregator_
 
   $variables['feed_url'] = check_url($item->link);
   $variables['feed_title'] = check_plain($item->title);
-  $variables['content'] = aggregator_filter_xss($item->description);
+  $variables['content'] = aggregator_filter_xss(db_decode_clob($item->description));
 
   $variables['source_url'] = '';
   $variables['source_title'] = '';
@@ -312,6 +312,7 @@ function theme_aggregator_page_rss($feed
   $items = '';
   $feed_length = variable_get('feed_item_length', 'teaser');
   foreach ($feeds as $feed) {
+    $feed->description = db_decode_clob($feed->description);
     switch ($feed_length) {
       case 'teaser':
         $teaser = node_teaser($feed->description);
Index: drupal-6.x-dev/modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.9
diff -u -p -r1.9 block.admin.inc
--- drupal-6.x-dev/modules/block/block.admin.inc	5 Oct 2007 09:35:09 -0000	1.9
+++ drupal-6.x-dev/modules/block/block.admin.inc	6 Nov 2007 17:27:55 -0000
@@ -387,8 +387,8 @@ function block_add_block_form_validate($
  * Save the new custom block.
  */
 function block_add_block_form_submit($form, &$form_state) {
-  db_query("INSERT INTO {boxes} (body, info, format) VALUES  ('%s', '%s', %d)", $form_state['values']['body'], $form_state['values']['info'], $form_state['values']['format']);
-  $delta = db_last_insert_id('boxes', 'bid');
+  drupal_write_record('boxes', $form_state['values']);
+  $delta = $form_state['values']['bid'];
 
   foreach (list_themes() as $key => $theme) {
     if ($theme->status) {
Index: drupal-6.x-dev/modules/block/block.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.install,v
retrieving revision 1.5
diff -u -p -r1.5 block.install
--- drupal-6.x-dev/modules/block/block.install	4 Nov 2007 14:33:06 -0000	1.5
+++ drupal-6.x-dev/modules/block/block.install	6 Nov 2007 17:27:55 -0000
@@ -138,7 +138,7 @@ function block_schema() {
         'description' => t("The block's {blocks}.bid."),
       ),
       'body' => array(
-        'type' => 'text',
+        'type' => 'clob',
         'not null' => FALSE,
         'size' => 'big',
         'description' => t('Block contents.'),
Index: drupal-6.x-dev/modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.284
diff -u -p -r1.284 block.module
--- drupal-6.x-dev/modules/block/block.module	21 Oct 2007 18:59:01 -0000	1.284
+++ drupal-6.x-dev/modules/block/block.module	6 Nov 2007 17:27:56 -0000
@@ -207,7 +207,7 @@ function block_block($op = 'list', $delt
 
     case 'view':
       $block = db_fetch_object(db_query('SELECT body, format FROM {boxes} WHERE bid = %d', $delta));
-      $data['content'] = check_markup($block->body, $block->format, FALSE);
+      $data['content'] = check_markup(db_decode_clob($block->body), $block->format, FALSE);
       return $data;
   }
 }
@@ -324,7 +324,8 @@ function block_box_save($edit, $delta) {
     $edit['format'] = FILTER_FORMAT_DEFAULT;
   }
 
-  db_query("UPDATE {boxes} SET body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['body'], $edit['info'], $edit['format'], $delta);
+  $edit['bid'] = $delta;
+  drupal_write_record('boxes', $edit, 'bid');
 
   return TRUE;
 }
Index: drupal-6.x-dev/modules/comment/comment.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.admin.inc,v
retrieving revision 1.1
diff -u -p -r1.1 comment.admin.inc
--- drupal-6.x-dev/modules/comment/comment.admin.inc	31 Oct 2007 17:50:47 -0000	1.1
+++ drupal-6.x-dev/modules/comment/comment.admin.inc	6 Nov 2007 17:27:56 -0000
@@ -58,7 +58,7 @@ function comment_admin_overview($type = 
   while ($comment = db_fetch_object($result)) {
     $comments[$comment->cid] = '';
     $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
-    $form['subject'][$comment->cid] = array('#value' => l($comment->subject, 'node/'. $comment->nid, array('title' => truncate_utf8($comment->comment, 128), 'fragment' => 'comment-'. $comment->cid)));
+    $form['subject'][$comment->cid] = array('#value' => l($comment->subject, 'node/'. $comment->nid, array('title' => truncate_utf8(db_decode_clob($comment->comment), 128), 'fragment' => 'comment-'. $comment->cid)));
     $form['username'][$comment->cid] = array('#value' => theme('username', $comment));
     $form['node_title'][$comment->cid] = array('#value' => l($comment->node_title, 'node/'. $comment->nid));
     $form['timestamp'][$comment->cid] = array('#value' => format_date($comment->timestamp, 'small'));
Index: drupal-6.x-dev/modules/comment/comment.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.install,v
retrieving revision 1.8
diff -u -p -r1.8 comment.install
--- drupal-6.x-dev/modules/comment/comment.install	4 Nov 2007 14:33:06 -0000	1.8
+++ drupal-6.x-dev/modules/comment/comment.install	6 Nov 2007 17:27:56 -0000
@@ -95,7 +95,7 @@ function comment_schema() {
         'description' => t('The comment title.'),
       ),
       'comment' => array(
-        'type' => 'text',
+        'type' => 'clob',
         'not null' => TRUE,
         'size' => 'big',
         'description' => t('The comment body.'),
Index: drupal-6.x-dev/modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.600
diff -u -p -r1.600 comment.module
--- drupal-6.x-dev/modules/comment/comment.module	5 Nov 2007 14:25:58 -0000	1.600
+++ drupal-6.x-dev/modules/comment/comment.module	6 Nov 2007 17:27:57 -0000
@@ -358,9 +358,9 @@ function comment_new_page_count($num_com
       }
       else {
         // Oldest first: find the first thread with new comment
-        $result = db_query('(SELECT thread FROM {comments} WHERE nid = %d  AND status = 0 ORDER BY timestamp DESC LIMIT %d) ORDER BY SUBSTRING(thread, 1, (LENGTH(thread) - 1)) LIMIT 1', $node->nid, $new_replies);
+        $result = db_query('(SELECT thread FROM {comments} WHERE nid = %d  AND status = 0 ORDER BY timestamp DESC LIMIT %d) ORDER BY '. DB_SUBSTR .'(thread, 1, ('. DB_STRLEN .'(thread) - 1)) LIMIT 1', $node->nid, $new_replies);
         $thread = substr(db_result($result), 0, -1);
-        $result_count = db_query("SELECT COUNT(*) FROM {comments} WHERE nid = %d AND status = 0 AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < '". $thread ."'", $node->nid);
+        $result_count = db_query("SELECT COUNT(*) FROM {comments} WHERE nid = %d AND status = 0 AND ". DB_SUBSTR ."(thread, 1, (". DB_STRLEN ."(thread) - 1)) < '". $thread ."'", $node->nid);
       }
       $count = db_result($result_count);
     }
@@ -602,7 +602,7 @@ function comment_nodeapi(&$node, $op, $a
       $text = '';
       $comments = db_query('SELECT subject, comment, format FROM {comments} WHERE nid = %d AND status = %d', $node->nid, COMMENT_PUBLISHED);
       while ($comment = db_fetch_object($comments)) {
-        $text .= '<h2>'. check_plain($comment->subject) .'</h2>'. check_markup($comment->comment, $comment->format, FALSE);
+        $text .= '<h2>'. check_plain($comment->subject) .'</h2>'. check_markup(db_decode_clob($comment->comment), $comment->format, FALSE);
       }
       return $text;
 
@@ -672,7 +672,7 @@ function comment_save($edit) {
       );
       if ($edit['cid']) {
         // Update the comment in the database.
-        db_query("UPDATE {comments} SET status = %d, timestamp = %d, subject = '%s', comment = '%s', format = %d, uid = %d, name = '%s', mail = '%s', homepage = '%s' WHERE cid = %d", $edit['status'], $edit['timestamp'], $edit['subject'], $edit['comment'], $edit['format'], $edit['uid'], $edit['name'], $edit['mail'], $edit['homepage'], $edit['cid']);
+        drupal_write_record('comments', $edit, 'cid');
 
         // Allow modules to respond to the updating of a comment.
         comment_invoke_comment($edit, 'update');
@@ -732,8 +732,9 @@ function comment_save($edit) {
           $edit['name'] = $user->name;
         }
 
-        db_query("INSERT INTO {comments} (nid, pid, uid, subject, comment, format, hostname, timestamp, status, thread, name, mail, homepage) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", $edit['nid'], $edit['pid'], $edit['uid'], $edit['subject'], $edit['comment'], $edit['format'], ip_address(), $edit['timestamp'], $edit['status'], $thread, $edit['name'], $edit['mail'], $edit['homepage']);
-        $edit['cid'] = db_last_insert_id('comments', 'cid');
+        $edit['hostname'] = ip_address();
+        $edit['thread'] = $thread;
+        drupal_write_record('comments', $edit);
 
         // Tell the other modules a new comment has been submitted.
         comment_invoke_comment($edit, 'insert');
@@ -947,7 +948,7 @@ function comment_render($node, $cid = 0)
           ** comment structure.
           */
 
-          $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))';
+          $query .= ' ORDER BY '. DB_SUBSTR .'(c.thread, 1, ('. DB_STRLEN .'(c.thread) - 1))';
         }
       }
       $query = db_rewrite_sql($query, 'c', 'cid');
@@ -1899,7 +1900,7 @@ function comment_unpublish_by_keyword_ac
  */
 function comment_unpublish_by_keyword_action($comment, $context) {
   foreach ($context['keywords'] as $keyword) {
-    if (strstr($comment->comment, $keyword) || strstr($comment->subject, $keyword)) {
+    if (strstr(db_decode_clob($comment->comment), $keyword) || strstr($comment->subject, $keyword)) {
       db_query('UPDATE {comments} SET status = %d WHERE cid = %d', COMMENT_NOT_PUBLISHED, $comment->cid);
       watchdog('action', 'Unpublished comment %subject.', array('%subject' => $comment->subject));
       break;
Index: drupal-6.x-dev/modules/contact/contact.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.admin.inc,v
retrieving revision 1.2
diff -u -p -r1.2 contact.admin.inc
--- drupal-6.x-dev/modules/contact/contact.admin.inc	16 Jul 2007 12:43:05 -0000	1.2
+++ drupal-6.x-dev/modules/contact/contact.admin.inc	6 Nov 2007 17:27:57 -0000
@@ -110,13 +110,13 @@ function contact_admin_edit_submit($form
   }
   $form_state['values']['recipients'] = implode(',', $recipients);
   if (empty($form_state['values']['cid']) || $form_state['values']['contact_op'] == 'add') {
-    db_query("INSERT INTO {contact} (category, recipients, reply, weight, selected) VALUES ('%s', '%s', '%s', %d, %d)", $form_state['values']['category'], $form_state['values']['recipients'], $form_state['values']['reply'], $form_state['values']['weight'], $form_state['values']['selected']);
+    drupal_write_record('contact', $form_state['values']);
     drupal_set_message(t('Category %category has been added.', array('%category' => $form_state['values']['category'])));
     watchdog('mail', 'Contact form: category %category added.', array('%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('view'), 'admin/build/contact'));
 
   }
   else {
-    db_query("UPDATE {contact} SET category = '%s', recipients = '%s', reply = '%s', weight = %d, selected = %d WHERE cid = %d", $form_state['values']['category'], $form_state['values']['recipients'], $form_state['values']['reply'], $form_state['values']['weight'], $form_state['values']['selected'], $form_state['values']['cid']);
+    drupal_write_record('contact', $form_state['values'], 'cid');
     drupal_set_message(t('Category %category has been updated.', array('%category' => $form_state['values']['category'])));
     watchdog('mail', 'Contact form: category %category updated.', array('%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('view'), 'admin/build/contact'));
   }
Index: drupal-6.x-dev/modules/contact/contact.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.install,v
retrieving revision 1.9
diff -u -p -r1.9 contact.install
--- drupal-6.x-dev/modules/contact/contact.install	10 Oct 2007 11:39:32 -0000	1.9
+++ drupal-6.x-dev/modules/contact/contact.install	6 Nov 2007 17:27:57 -0000
@@ -48,7 +48,7 @@ function contact_schema() {
         'description' => t('Comma-separated list of recipient e-mail addresses.'),
       ),
       'reply' => array(
-        'type' => 'text',
+        'type' => 'clob',
         'not null' => TRUE,
         'size' => 'big',
         'description' => t('Text of the auto-reply message.'),
Index: drupal-6.x-dev/modules/contact/contact.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.module,v
retrieving revision 1.97
diff -u -p -r1.97 contact.module
--- drupal-6.x-dev/modules/contact/contact.module	16 Jul 2007 06:37:49 -0000	1.97
+++ drupal-6.x-dev/modules/contact/contact.module	6 Nov 2007 17:27:57 -0000
@@ -171,7 +171,7 @@ function contact_mail($key, &$message, $
     case 'page_autoreply':
       $contact = $params['contact'];
       $message['subject'] .= t('[!category] !subject', array('!category' => $contact['category'], '!subject' => $params['subject']), $language->language);
-      $message['body'][] = $contact['reply'];
+      $message['body'][] = db_decode_clob($contact['reply']);
       break;
     case 'user_mail':
     case 'user_copy':
Index: drupal-6.x-dev/modules/contact/contact.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.pages.inc,v
retrieving revision 1.4
diff -u -p -r1.4 contact.pages.inc
--- drupal-6.x-dev/modules/contact/contact.pages.inc	2 Oct 2007 16:03:17 -0000	1.4
+++ drupal-6.x-dev/modules/contact/contact.pages.inc	6 Nov 2007 17:27:57 -0000
@@ -134,7 +134,7 @@ function contact_mail_page_submit($form,
   }
 
   // Send an auto-reply if necessary using the current language.
-  if ($contact['reply']) {
+  if (db_decode_clob($contact['reply'])) {
     drupal_mail('contact', 'page_autoreply', $from, $language, $values, $contact['recipients']);
   }
 
Index: drupal-6.x-dev/modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.198
diff -u -p -r1.198 locale.module
--- drupal-6.x-dev/modules/locale/locale.module	4 Nov 2007 11:10:09 -0000	1.198
+++ drupal-6.x-dev/modules/locale/locale.module	6 Nov 2007 17:27:57 -0000
@@ -328,7 +328,7 @@ function locale($string = NULL, $langcod
         // Refresh database stored cache of translations for given language.
         // We only store short strings used in current version, to improve
         // performance and consume less memory.
-        $result = db_query("SELECT s.source, t.translation, t.language FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = '%s' WHERE s.textgroup = 'default' AND s.version = '%s' AND LENGTH(s.source) < 75", $langcode, VERSION);
+        $result = db_query("SELECT s.source, t.translation, t.language FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = '%s' WHERE s.textgroup = 'default' AND s.version = '%s' AND ". DB_STRLEN ."(s.source) < 75", $langcode, VERSION);
         while ($data = db_fetch_object($result)) {
           $locale_t[$langcode][$data->source] = (empty($data->translation) ? TRUE : $data->translation);
         }
Index: drupal-6.x-dev/modules/node/node.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.install,v
retrieving revision 1.3
diff -u -p -r1.3 node.install
--- drupal-6.x-dev/modules/node/node.install	4 Nov 2007 14:33:07 -0000	1.3
+++ drupal-6.x-dev/modules/node/node.install	6 Nov 2007 17:27:57 -0000
@@ -214,12 +214,12 @@ function node_schema() {
         'default' => ''),
       'body' => array(
         'description' => t('The body of this version.'),
-        'type' => 'text',
+        'type' => 'clob',
         'not null' => TRUE,
         'size' => 'big'),
       'teaser' => array(
         'description' => t('The teaser of this version.'),
-        'type' => 'text',
+        'type' => 'clob',
         'not null' => TRUE,
         'size' => 'big'),
       'log' => array(
Index: drupal-6.x-dev/modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.898
diff -u -p -r1.898 node.module
--- drupal-6.x-dev/modules/node/node.module	5 Nov 2007 15:14:54 -0000	1.898
+++ drupal-6.x-dev/modules/node/node.module	6 Nov 2007 17:27:57 -0000
@@ -667,6 +667,9 @@ function node_load($param = array(), $re
     $node = db_fetch_object(db_query('SELECT '. $fields .' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond, $arguments));
   }
 
+  $node->body = db_decode_clob($node->body);
+  $node->teaser = db_decode_clob($node->teaser);
+
   if ($node && $node->nid) {
     // Call the node specific callback (if any) and piggy-back the
     // results to the node or overwrite some values.
@@ -843,8 +846,8 @@ function node_delete($nid) {
   $node = node_load($nid);
 
   if (node_access('delete', $node)) {
-    db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
-    db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid);
+    drupal_drop_record('node', $node, 'nid');
+    drupal_drop_record('node_revisions', $node, 'nid');
 
     // Call the node-specific callback (if any):
     node_invoke($node, 'delete');
Index: drupal-6.x-dev/modules/statistics/statistics.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.admin.inc,v
retrieving revision 1.2
diff -u -p -r1.2 statistics.admin.inc
--- drupal-6.x-dev/modules/statistics/statistics.admin.inc	20 Oct 2007 21:57:50 -0000	1.2
+++ drupal-6.x-dev/modules/statistics/statistics.admin.inc	6 Nov 2007 17:27:57 -0000
@@ -82,7 +82,7 @@ function statistics_top_visitors() {
   );
 
   $sql = "SELECT COUNT(a.uid) AS hits, a.uid, u.name, a.hostname, SUM(a.timer) AS total, ac.aid FROM {accesslog} a LEFT JOIN {access} ac ON ac.type = 'host' AND LOWER(a.hostname) LIKE (ac.mask) LEFT JOIN {users} u ON a.uid = u.uid GROUP BY a.hostname, a.uid, u.name, ac.aid". tablesort_sql($header);
-  $sql_cnt = "SELECT COUNT(DISTINCT(CONCAT(uid, hostname))) FROM {accesslog}";
+  $sql_cnt = "SELECT COUNT(DISTINCT(". db_concat('uid', 'hostname') . ")) FROM {accesslog}";
   $result = pager_query($sql, 30, 0, $sql_cnt);
 
   $rows = array();
Index: drupal-6.x-dev/modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.169
diff -u -p -r1.169 system.install
--- drupal-6.x-dev/modules/system/system.install	4 Nov 2007 16:39:59 -0000	1.169
+++ drupal-6.x-dev/modules/system/system.install	6 Nov 2007 17:27:57 -0000
@@ -210,19 +210,6 @@ function system_install() {
       \'SELECT greatest($1, greatest($2, $3));\'
       LANGUAGE \'sql\''
     );
-    if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname = 'rand'"))) {
-      db_query('CREATE OR REPLACE FUNCTION "rand"() RETURNS float AS
-        \'SELECT random();\'
-        LANGUAGE \'sql\''
-      );
-    }
-
-    if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname = 'concat'"))) {
-      db_query('CREATE OR REPLACE FUNCTION "concat"(text, text) RETURNS text AS
-        \'SELECT $1 || $2;\'
-        LANGUAGE \'sql\''
-      );
-    }
     db_query('CREATE OR REPLACE FUNCTION "if"(boolean, text, text) RETURNS text AS
       \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
       LANGUAGE \'sql\''
