Index: database/database.mysql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.mysql,v
retrieving revision 1.204
diff -u -F^f -r1.204 database.mysql
--- database/database.mysql	14 Nov 2005 22:23:11 -0000	1.204
+++ database/database.mysql	22 Nov 2005 23:38:46 -0000
@@ -248,16 +248,24 @@
 
 CREATE TABLE files (
   fid int(10) unsigned NOT NULL default '0',
-  nid int(10) unsigned NOT NULL default '0',
-  vid int(10) unsigned NOT NULL default '0',
   filename varchar(255) NOT NULL default '',
-  description varchar(255) NOT NULL default '',
   filepath varchar(255) NOT NULL default '',
   filemime varchar(255) NOT NULL default '',
   filesize int(10) unsigned NOT NULL default '0',
+  PRIMARY KEY (fid)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table 'files'
+--
+
+CREATE TABLE file_revisions (
+  fid int(10) unsigned NOT NULL default '0',
+  nid int(10) unsigned NOT NULL default '0',
+  vid int(10) unsigned NOT NULL default '0',
+  description varchar(255) NOT NULL default '',
   list tinyint(1) unsigned NOT NULL default '0',
-  KEY vid (vid),
-  KEY fid (fid)
+  PRIMARY KEY (fid, vid)
 ) TYPE=MyISAM;
 
 --
Index: database/database.pgsql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.pgsql,v
retrieving revision 1.146
diff -u -F^f -r1.146 database.pgsql
--- database/database.pgsql	14 Nov 2005 22:23:11 -0000	1.146
+++ database/database.pgsql	22 Nov 2005 23:38:47 -0000
@@ -243,17 +243,25 @@
 
 CREATE TABLE files (
   fid SERIAL,
-  nid integer NOT NULL default '0',
-  vid integer NOT NULL default '0',
-  description varchar(255) NOT NULL default '',
   filename varchar(255) NOT NULL default '',
   filepath varchar(255) NOT NULL default '',
   filemime varchar(255) NOT NULL default '',
   filesize integer NOT NULL default '0',
-  list smallint NOT NULL default '0'
+  PRIMARY KEY (fid)
+);
+
+--
+-- Table structure for table 'file_revisions'
+--
+
+CREATE TABLE file_revisions (
+  fid integer NOT NULL default '0',
+  nid integer NOT NULL default '0',
+  vid integer NOT NULL default '0',
+  description varchar(255) NOT NULL default '',
+  list smallint NOT NULL default '0',
+  PRIMARY KEY (fid, vid)
 );
-CREATE INDEX files_fid_idx ON files(fid);
-CREATE INDEX files_vid_idx ON files(vid);
 
 --
 -- Table structure for table 'filter_formats'
Index: database/updates.inc
===================================================================
RCS file: /cvs/drupal/drupal/database/updates.inc,v
retrieving revision 1.148
diff -u -F^f -r1.148 updates.inc
--- database/updates.inc	18 Nov 2005 14:05:38 -0000	1.148
+++ database/updates.inc	22 Nov 2005 23:38:47 -0000
@@ -104,7 +104,8 @@
   "2005-10-23" => "update_151",
   "2005-10-28" => "update_152",
   "2005-11-03" => "update_153",
-  "2005-11-14" => "update_154"
+  "2005-11-14" => "update_154",
+  "2005-11-23" => "update_155"
 );
 
 function update_110() {
@@ -1159,7 +1160,39 @@ function update_154() {
   return $ret;
 }
 
+function update_155() {
+  $ret = array();
 
+  switch ($GLOBALS['db_type']) {
+    case 'pgsql':
+      // create file_revisions table
+      $ret[] = update_sql("CREATE TABLE {file_revisions} AS SELECT nid, vid, fid, list, description FROM {files}");
+
+      // fix files table
+      $ret[] = update_sql("ALTER TABLE {files} DROP nid");
+      $ret[] = update_sql("ALTER TABLE {files} DROP vid");
+      $ret[] = update_sql("ALTER TABLE {files} DROP list");
+      $ret[] = update_sql("ALTER TABLE {files} DROP description");
+      break;
+    case 'mysqli':
+    case 'mysql':
+      // create file_revisions table
+      $ret[] = update_sql("CREATE TABLE {file_revisions} AS SELECT nid, vid, fid, list, description FROM {files}");
+      $ret[] = update_sql("ALTER TABLE {file_revisions} ADD PRIMARY KEY (fid, vid)");
+
+      // fix files table
+      $ret[] = update_sql("ALTER TABLE {files} DROP KEY vid");
+      $ret[] = update_sql("ALTER TABLE {files} DROP KEY fid");
+      $ret[] = update_sql("ALTER TABLE {files} ADD PRIMARY KEY (fid)");
+      $ret[] = update_sql("ALTER TABLE {files} DROP nid");
+      $ret[] = update_sql("ALTER TABLE {files} DROP vid");
+      $ret[] = update_sql("ALTER TABLE {files} DROP list");
+      $ret[] = update_sql("ALTER TABLE {files} DROP description");
+      break;
+  }
+
+  return $ret;
+}
 
 /**
  * Adds a column to a database. Uses syntax appropriate for PostgreSQL.
@@ -1258,7 +1291,6 @@ function db_change_column(&$ret, $table,
   // $ret[] = update_sql("ALTER TABLE {". $table ."} DROP ". $column ."_old");
 }
 
-
 function update_sql($sql) {
   $edit = $_POST["edit"];
   $result = db_query($sql);
Index: modules/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload.module,v
retrieving revision 1.60
diff -u -F^f -r1.60 upload.module
--- modules/upload.module	21 Nov 2005 15:36:53 -0000	1.60
+++ modules/upload.module	22 Nov 2005 23:38:50 -0000
@@ -1,4 +1,4 @@
-<?php
+*<?php
 // $Id: upload.module,v 1.60 2005/11/21 15:36:53 dries Exp $
 
 /**
@@ -334,20 +334,20 @@ function upload_nodeapi(&$node, $op, $ar
  * @param $uid
  *   The integer user id of a user.
  * @return
- *   The ammount of disk space used by the user in bytes.
+ *   The amount of disk space used by the user in bytes.
  */
 function upload_space_used($uid) {
-  return db_result(db_query('SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node_revisions} n ON f.vid = n.vid WHERE uid = %d', $uid));
+  return db_result(db_query('SELECT SUM(filesize) FROM {files} f INNER JOIN {file_revisions} r ON f.fid = r.fid INNER JOIN {node} n ON r.nid = n.nid WHERE n.uid = %d', $uid));
 }
 
 /**
  * Determine how much disk space is occupied by uploaded files.
  *
  * @return
- *   The ammount of disk space used by uploaded files in bytes.
+ *   The amount of disk space used by uploaded files in bytes.
  */
 function upload_total_space_used() {
-  return db_result(db_query('SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node_revisions} n ON f.vid = n.vid'));
+  return db_result(db_query('SELECT SUM(filesize) FROM {files}'));
 }
 
 function upload_save($node) {
@@ -359,18 +359,21 @@ function upload_save($node) {
       // Insert new files:
       if ($file = file_save_upload($file, $file->filename)) {
         $fid = db_next_id('{files}_fid');
-        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list, description) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d, '%s')",
-                 $fid, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key], $node->description[$key]);
+        db_query("INSERT INTO {files} (fid, filename, filepath, filemime, filesize) VALUES (%d, '%s', '%s', '%s', %d)",
+                 $fid, $file->filename, $file->filepath, $file->filemime, $file->filesize);
+        db_query("INSERT INTO {file_revisions} (fid, nid, vid, list, description) VALUES (%d, %d, %d, %d, '%s')", 
+                 $fid, $node->nid, $node->vid, $node->list[$key], $node->description[$key]);
       }
     }
   }
   // Remove existing files, as needed
   foreach ((array)$node->remove as $key => $value) {
     if ($node->remove[$key]) {
-      db_query('DELETE FROM {files} WHERE fid = %d AND vid = %d', $key, $node->vid);
+      db_query('DELETE FROM {file_revisions} WHERE fid = %d AND vid = %d', $key, $node->vid);
       // We only delete a file if it isn't used anymore by any revision.
-      $count = db_result(db_query('SELECT COUNT(fid) FROM {files} WHERE fid = %d', $key));
+      $count = db_result(db_query('SELECT COUNT(fid) FROM {file_revisions} WHERE fid = %d', $key));
       if (!($count > 0)) {
+        db_query('DELETE FROM {files} WHERE fid = %d', $key);
         file_delete($file->filepath);
       }
     }
@@ -379,9 +382,9 @@ function upload_save($node) {
   if ($node->old_vid) {
     foreach ((array)$node->remove as $key => $remove) {
       if (!$remove) {
-        $file = db_fetch_object(db_query('SELECT * FROM {files} WHERE vid = %d AND fid = %d', $node->old_vid, $key));
-        db_query("INSERT INTO {files} (fid, nid, vid, filename, filepath, filemime, filesize, list, description) VALUES (%d, %d, %d, '%s', '%s', '%s', %d, %d, '%s')",
-                 $key, $node->nid, $node->vid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key], $node->description[$key]);
+        $file = db_fetch_object(db_query('SELECT list, description FROM {file_revisions} WHERE vid = %d AND fid = %d', $node->old_vid, $key));
+        db_query("INSERT INTO {file_revisions} (fid, nid, vid, list, description) VALUES (%d, %d, %d, %d, '%s')",
+                 $key, $node->nid, $node->vid, $node->list[$key], $node->description[$key]);
       }
     }
   }
@@ -389,7 +392,7 @@ function upload_save($node) {
   else {
     foreach ((array)$node->list as $key => $value) {
       if (!$node->remove[$key]) {
-        db_query('UPDATE {files} SET list = %d, description = \'%s\' WHERE fid = %d AND vid = %d', $node->list[$key], $node->description[$key], $key, $node->vid);
+        db_query("UPDATE {file_revisions} SET list = %d, description = '%s' WHERE fid = %d AND vid = %d", $node->list[$key], $node->description[$key], $key, $node->vid);
       }
     }
   }
@@ -402,7 +405,11 @@ function upload_delete($node) {
   foreach ($node->files as $file) {
     file_delete($file->filepath);
   }
-  db_query("DELETE FROM {files} WHERE nid = %d", $node->nid);
+  $result = db_query("SELECT DISTINCT fid FROM {file_revisions} WHERE nid = %d", $node->nid);
+  db_query("DELETE FROM {file_revisions} WHERE nid = %d", $node->nid);
+  while ($file = db_fetch_object($result)) {
+    db_query("DELETE FROM {files} WHERE fid = %d", $file->fid);
+  }
 }
 
 function upload_form($node) {
@@ -484,7 +491,7 @@ function upload_load($node) {
   $files = array();
 
   if ($node->vid) {
-    $result = db_query("SELECT * FROM {files} WHERE vid = %d", $node->vid);
+    $result = db_query("SELECT * FROM {files} f INNER JOIN {file_revisions} r ON f.fid = r.fid WHERE r.vid = %d", $node->vid);
     while ($file = db_fetch_object($result)) {
       $files[$file->fid] = $file;
     }
