Index: database/database.mysql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.mysql,v
retrieving revision 1.200
diff -u -F^f -r1.200 database.mysql
--- database/database.mysql	27 Sep 2005 15:54:39 -0000	1.200
+++ database/database.mysql	29 Sep 2005 21:58:59 -0000
@@ -244,16 +244,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.139
diff -u -F^f -r1.139 database.pgsql
--- database/database.pgsql	27 Sep 2005 15:54:39 -0000	1.139
+++ database/database.pgsql	29 Sep 2005 21:59:00 -0000
@@ -240,17 +240,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.138
diff -u -F^f -r1.138 updates.inc
--- database/updates.inc	27 Sep 2005 15:54:39 -0000	1.138
+++ database/updates.inc	29 Sep 2005 21:59:00 -0000
@@ -66,7 +66,8 @@
   "2005-08-25" => "update_146",
   "2005-09-07" => "update_147",
   "2005-09-18" => "update_148",
-  "2005-09-27" => "update_149"
+  "2005-09-27" => "update_149",
+  "2005-09-29" => "update_150"
 );
 
 function update_110() {
@@ -846,6 +847,40 @@ function update_149() {
   return $ret;
 }
 
+function update_150() {
+  $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;
+}
+
 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.52
diff -u -F^f -r1.52 upload.module
--- modules/upload.module	27 Sep 2005 15:54:39 -0000	1.52
+++ modules/upload.module	29 Sep 2005 21:59:03 -0000
@@ -321,7 +321,7 @@ function upload_nodeapi(&$node, $op, $ar
  *   The ammount 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));
 }
 
 /**
@@ -331,7 +331,7 @@ function upload_space_used($uid) {
  *   The ammount 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) {
@@ -343,33 +343,35 @@ 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], $file->description);
+        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], $file->description);
       }
     }
   }
   // Remove or update existing files:
   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);
       }
     }
   }
   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);
     }
   }
   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, $file->list, $file->description);
+        $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, $file->list, $file->description);
       }
     }
   }
@@ -381,7 +383,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) {
@@ -429,7 +435,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;
     }
