Index: trunk/src/wp-includes/wp-db.php
===================================================================
--- trunk/src/wp-includes/wp-db.php	(revision 31255)
+++ trunk/src/wp-includes/wp-db.php	(working copy)
@@ -81,6 +81,14 @@
 	public $last_error = '';
 
 	/**
+	 * The last error code during query
+	 *
+	 * @since 4.2.0
+	 * @var int
+	 */
+	public $last_error_no = 0;
+
+	/**
 	 * Amount of queries made
 	 *
 	 * @since 1.2.0
@@ -1233,6 +1241,81 @@
 	}
 
 	/**
+	 * Handle SQL/DB error.
+	 *
+	 * This function adds the possibility to react to specific database errors
+	 * Initial problem had to do with accidentally removed WP tables (causes: bad backup, user fault, etc)
+	 * This allows for a check to verify all core tables are in place
+	 *
+	 * @since 4.2.0
+	 * @access public
+	 *
+	 */
+	public function handle_error() {
+		if ( $this->suppress_errors || 0 == $this->last_error_no ) {
+			return;
+		}
+
+		// Make sure the error is logged and optionally printed.
+		$this->print_error();
+
+
+		/*
+		 * Check for missing tables; only once per execution.
+		 * If this passes, some custom table is missing and we can't really do anything about that.
+		 */
+		static $wp_tables_verified = false;
+
+		/**
+		 * For all MySQL Error codes see:
+		 * http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
+		 *
+		 * Implemented
+		 *  Error: 1146 SQLSTATE: 42S02 (ER_NO_SUCH_TABLE)
+		 *
+		 */
+		if ( false === $wp_tables_verified && 1146 == $this->last_error_no ) {
+			$suppress = $this->suppress_errors();
+
+			/*
+			 * Loop over the WP tables.
+			 * If one or more are missing, suggest table repair.
+			 *
+			 * Because we got this far, the global is_blog_installed() passed, so options table should be there.
+			 */
+			$wp_tables = $this->tables();
+
+			foreach ( $wp_tables as $table ) {
+				// The existence of custom user tables shouldn't suggest an insane state or prevent a clean install.
+				if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table )
+					continue;
+				if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table )
+					continue;
+
+				// If we have results, the table exists
+				$sql_check = $this->prepare( "SHOW TABLES LIKE %s", $table );
+				$table_exists = ( $this->get_var( $sql_check ) != null );
+				if ( $table_exists ) {
+					continue;
+				}
+
+				// Recreate missing tables.
+				require(ABSPATH . 'wp-admin/includes/upgrade.php');
+				// Make sure we have the latest (and all) tables
+				dbDelta();
+
+				// We're done now, all missing tables should be restored
+				break;
+			}
+
+			$this->suppress_errors( $suppress );
+
+			$wp_tables_verified = true;
+		}
+
+	}
+
+	/**
 	 * Print SQL/DB error.
 	 *
 	 * @since 0.71
@@ -1352,6 +1435,7 @@
 		$this->last_query  = null;
 		$this->rows_affected = $this->num_rows = 0;
 		$this->last_error  = '';
+		$this->last_error_no = 0;
 
 		if ( $this->use_mysqli && $this->result instanceof mysqli_result ) {
 			mysqli_free_result( $this->result );
@@ -1642,12 +1726,14 @@
 			$this->last_error = mysql_error( $this->dbh );
 		}
 
+		$this->last_error_no = $mysql_errno;
+
 		if ( $this->last_error ) {
 			// Clear insert_id on a subsequent failed insert.
 			if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
 				$this->insert_id = 0;
 
-			$this->print_error();
+			$this->handle_error();
 			return false;
 		}
 
