Properly handle the 'IGNORE' option passed to the insert funtion:
authorGreg Sabino Mullane <greg@users.mediawiki.org>
Fri, 4 Jul 2008 15:57:44 +0000 (15:57 +0000)
committerGreg Sabino Mullane <greg@users.mediawiki.org>
Fri, 4 Jul 2008 15:57:44 +0000 (15:57 +0000)
rather than just turning off errors, do some savepoint trickery
so we end at the same state as when we started, to emulate
MySQL's INSERT...IGNORE. Bug 14708.

RELEASE-NOTES
includes/db/DatabasePostgres.php

index b578d15..c5d7544 100644 (file)
@@ -412,6 +412,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
   generates a log entry.
 * (bug 14088) Excessively long block expiry times are rejected as invalid,
   keeps the log page from being distorted.
+* (bug 14708) Emulate INSERT...IGNORE with standard SQL for Postgres backend.
 
 === API changes in 1.13 ===
 
index a0d3d69..14714c6 100644 (file)
@@ -747,10 +747,16 @@ class DatabasePostgres extends Database {
                        $keys = array_keys( $args );
                }
 
-               $ignore = in_array( 'IGNORE', $options ) ? 1 : 0;
-               if ( $ignore )
+               $ignore = in_array( 'IGNORE', $options ) ? 'mw' : '';
+               if ( $ignore ) {
+                       $didbegin = 0;
+                       if (! $this->mTrxLevel) {
+                               $this->begin();
+                               $didbegin = 1;
+                       }
+                       pg_query($this->mConn, "SAVEPOINT $ignore");
                        $olde = error_reporting( 0 );
-
+               }
                $sql = "INSERT INTO $table (" . implode( ',', $keys ) . ') VALUES ';
 
                if ( $multi ) {
@@ -785,6 +791,17 @@ class DatabasePostgres extends Database {
 
                if ( $ignore ) {
                        $olde = error_reporting( $olde );
+                       $bar = pg_last_error();
+                       if ($bar !== FALSE) {
+                               pg_query( $this->mConn, "ROLLBACK TO $ignore" );
+                       }
+                       else {
+                               pg_query( $this->mConn, "RELEASE $ignore" );
+                       }
+                       if ($didbegin) {
+                               $this->commit();
+                       }
+                       ## IGNORE always returns true
                        return true;
                }