Index: src/wp-admin/includes/upgrade.php
===================================================================
--- src/wp-admin/includes/upgrade.php	(revision 37574)
+++ src/wp-admin/includes/upgrade.php	(working copy)
@@ -2185,9 +2185,10 @@
 
 		// For every field line specified in the query.
 		foreach ($flds as $fld) {
+			$fld = trim( $fld, " \t\n\r\0\x0B," ); // Default trim characters, plus ','
 
 			// Extract the field name.
-			preg_match("|^([^ ]*)|", trim($fld), $fvals);
+			preg_match("|^([^ ]*)|", $fld, $fvals);
 			$fieldname = trim( $fvals[1], '`' );
 			$fieldname_lowercased = strtolower( $fieldname );
 
@@ -2202,14 +2203,28 @@
 				case 'key':
 				case 'spatial':
 					$validfield = false;
-					$indices[] = trim(trim($fld), ", \n");
+
+					// Normalize the index so it matches the table index structure from the database.
+					preg_match( '/^(?P<index_type>PRIMARY\s+KEY|(?:UNIQUE|FULLTEXT|SPATIAL)\s+(?:KEY|INDEX)|KEY|INDEX)\s+(?:`?(?P<index_name>\w+)`?\s+)*\((?P<column_names>.+?)\)$/im', $fld, $index_matches );
+					$index_type = strtoupper( preg_replace( '/\s+/', ' ', trim( $index_matches['index_type'] ) ) );
+					$index_type = str_replace( 'INDEX', 'KEY', $index_type );
+					$index_name = ( 'PRIMARY KEY' == $index_matches['index_type'] ) ? '' : '`' . $index_matches['index_name'] . '`';
+					$index_columns = array_map( 'trim', explode( ',', $index_matches['column_names'] ) );
+					foreach ( $index_columns as &$index_column ) {
+						preg_match( '/`?(?P<column_name>\w+)`?(?:\s*\(\s*(?P<sub_part>\d+)\s*\))?/i', $index_column, $index_column_matches );
+						$index_column = '`' . $index_column_matches['column_name'] . '`';
+						if ( isset( $index_column_matches['sub_part'] ) ) {
+							$index_column .= '(' . $index_column_matches['sub_part'] . ')';
+						}
+					}
+
+					$indices[] = "{$index_type} {$index_name} (" . implode( ',', $index_columns ) . ")";
 					break;
 			}
-			$fld = trim( $fld );
 
 			// If it's a valid field, add it to the field array.
 			if ( $validfield ) {
-				$cfields[ $fieldname_lowercased ] = trim( $fld, ", \n" );
+				$cfields[ $fieldname_lowercased ] = $fld;
 			}
 		}
 
@@ -2243,7 +2258,7 @@
 
 					if ( $do_change ) {
 						// Add a query to change the column type.
-						$cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[ $tablefield_field_lowercased ];
+						$cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN `{$tablefield->Field}` " . $cfields[ $tablefield_field_lowercased ];
 						$for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
 					}
 				}
@@ -2253,7 +2268,7 @@
 					$default_value = $matches[1];
 					if ($tablefield->Default != $default_value) {
 						// Add a query to change the column's default value
-						$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
+						$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN `{$tablefield->Field}` SET DEFAULT '{$default_value}'";
 						$for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
 					}
 				}
@@ -2306,17 +2321,19 @@
 					$index_string .= 'SPATIAL ';
 				}
 				$index_string .= 'KEY ';
-				if ($index_name != 'PRIMARY') {
-					$index_string .= $index_name;
+				if ( $index_name != 'PRIMARY' ) {
+					$index_string .= '`' . $index_name . '`';
 				}
 				$index_columns = '';
 
 				// For each column in the index.
 				foreach ($index_data['columns'] as $column_data) {
-					if ($index_columns != '') $index_columns .= ',';
+					if ( $index_columns != '' ) {
+						$index_columns .= ',';
+					}
 
 					// Add the field to the column list string.
-					$index_columns .= $column_data['fieldname'];
+					$index_columns .= '`' . $column_data['fieldname'] . '`';
 					if ($column_data['subpart'] != '') {
 						$index_columns .= '('.$column_data['subpart'].')';
 					}
Index: tests/phpunit/tests/dbdelta.php
===================================================================
--- tests/phpunit/tests/dbdelta.php	(revision 37574)
+++ tests/phpunit/tests/dbdelta.php	(working copy)
@@ -531,9 +531,299 @@
 
 		$this->assertSame( array(
 			"{$wpdb->prefix}spatial_index_test.spatial_value2" => "Added column {$wpdb->prefix}spatial_index_test.spatial_value2",
-			"Added index {$wpdb->prefix}spatial_index_test SPATIAL KEY spatial_key2 (spatial_value2)"
+			"Added index {$wpdb->prefix}spatial_index_test SPATIAL KEY `spatial_key2` (`spatial_value2`)"
 			), $updates );
 
 		$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}spatial_index_test" );
 	}
+
+	/**
+	 * @ticket 20263
+	 */
+	function test_query_with_backticks_does_not_cause_a_query_to_alter_all_columns_and_indices_to_run_even_if_none_have_changed() {
+		global $wpdb;
+
+		$schema = "
+			CREATE TABLE {$wpdb->prefix}dbdelta_test2 (
+				`id` bigint(20) NOT NULL AUTO_INCREMENT,
+				`references` varchar(255) NOT NULL,
+				PRIMARY KEY  (`id`),
+				KEY `compound_key` (`id`,`references`)
+			)
+		";
+
+		$wpdb->query( $schema );
+
+		$updates = dbDelta( $schema );
+
+		$table_indices = $wpdb->get_results( "SHOW INDEX FROM {$wpdb->prefix}dbdelta_test2" );
+		$compound_key_index = wp_list_filter( $table_indices, array( 'Key_name' => 'compound_key' ) );
+
+		$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}dbdelta_test2" );
+
+		$this->assertCount( 2, $compound_key_index );
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 20263
+	 */
+	function test_index_with_reserved_keywords_can_be_created() {
+		global $wpdb;
+
+		$updates = dbDelta(
+			"
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				`references` varchar(255) NOT NULL,
+				PRIMARY KEY  (id),
+				KEY key_1 (column_1),
+				KEY compound_key (id , column_1),
+				KEY compound_key2 (id,`references`),
+				FULLTEXT KEY fulltext_key (column_1)
+			) ENGINE=MyISAM
+			"
+		);
+
+		$table_indices = $wpdb->get_results( "SHOW INDEX FROM {$wpdb->prefix}dbdelta_test" );
+
+		$this->assertCount( 2, wp_list_filter( $table_indices, array( 'Key_name' => 'compound_key2' ) , 'AND' ) );
+
+		$this->assertSame(
+			array(
+				"{$wpdb->prefix}dbdelta_test.references" => "Added column {$wpdb->prefix}dbdelta_test.references",
+				0 => "Added index {$wpdb->prefix}dbdelta_test KEY `compound_key2` (`id`,`references`)",
+			),
+			$updates
+		);
+	}
+
+	/**
+	 * @ticket 20263
+	 */
+	function test_wp_get_db_schema_does_no_alter_queries_on_existing_install() {
+		$updates = dbDelta( wp_get_db_schema() );
+
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 20263
+	 */
+	function test_all_possible_index_types_are_supported() {
+		global $wpdb;
+
+		$schema = "
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY  (id),
+				KEY key_1 (column_1),
+				KEY compound_key (id,column_1),
+				FULLTEXT KEY fulltext_key (column_1),
+				INDEX key_2 (column_1),
+				UNIQUE KEY key_3 (column_1),
+				UNIQUE INDEX key_4 (column_1),
+				FULLTEXT INDEX key_5 (column_1),
+			) ENGINE=MyISAM
+		";
+
+		$creates = dbDelta( $schema );
+		$this->assertSame(
+			array(
+				0 => "Added index {$wpdb->prefix}dbdelta_test KEY `key_2` (`column_1`)",
+				1 => "Added index {$wpdb->prefix}dbdelta_test UNIQUE KEY `key_3` (`column_1`)",
+				2 => "Added index {$wpdb->prefix}dbdelta_test UNIQUE KEY `key_4` (`column_1`)",
+				3 => "Added index {$wpdb->prefix}dbdelta_test FULLTEXT KEY `key_5` (`column_1`)",
+			),
+			$creates
+		);
+
+		$updates = dbDelta( $schema );
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 20263
+	 */
+	function test_index_and_key_is_the_same_and_does_not_recreate_index() {
+		global $wpdb;
+
+		$updates = dbDelta(
+			"
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY  (id),
+				INDEX key_1 (column_1),
+				INDEX compound_key (id,column_1),
+				FULLTEXT INDEX fulltext_key (column_1)
+			) ENGINE=MyISAM
+			"
+		);
+
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 20263
+	 */
+	function test_indices_with_prefix_limits_are_created_and_do_not_cause_an_index_recreate() {
+		global $wpdb;
+
+		$schema = "
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY  (id),
+				KEY key_1 (column_1),
+				KEY compound_key (id,column_1),
+				FULLTEXT KEY fulltext_key (column_1),
+				KEY key_2 (column_1(10)),
+				KEY key_3 (column_2(100),column_1(10)),
+			) ENGINE=MyISAM
+		";
+
+		$creates = dbDelta( $schema );
+		$this->assertSame(
+			array(
+				0 => "Added index {$wpdb->prefix}dbdelta_test KEY `key_2` (`column_1`(10))",
+				1 => "Added index {$wpdb->prefix}dbdelta_test KEY `key_3` (`column_2`(100),`column_1`(10))",
+			),
+			$creates
+		);
+
+		$updates = dbDelta( $schema );
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 34959
+	 */
+	function test_index_col_name_with_order_does_not_recreate_index() {
+		global $wpdb;
+
+		$updates = dbDelta(
+			"
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY  (id),
+				KEY key_1 (column_1 DESC),
+				KEY compound_key (id,column_1 ASC),
+				FULLTEXT KEY fulltext_key (column_1)
+			) ENGINE=MyISAM
+			"
+		);
+
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 34873
+	 */
+	function test_primary_key_with_single_space_does_not_recreate_index() {
+		global $wpdb;
+
+		$updates = dbDelta(
+			"
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY (id),
+				KEY key_1 (column_1),
+				KEY compound_key (id,column_1),
+				FULLTEXT KEY fulltext_key (column_1)
+			) ENGINE=MyISAM
+			"
+		);
+
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 34869
+	 */
+	function test_index_definitions_with_spaces_do_not_recreate_indices() {
+		global $wpdb;
+
+		$updates = dbDelta(
+			"
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY  (id),
+				KEY key_1 (column_1),
+				KEY compound_key (id,      column_1),
+				FULLTEXT KEY fulltext_key (column_1)
+			) ENGINE=MyISAM
+			"
+		);
+
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 34871
+	 */
+	function test_index_types_are_not_case_sensitive_and_do_not_recreate_indices() {
+		global $wpdb;
+
+		$updates = dbDelta(
+			"
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY  (id),
+				key key_1 (column_1),
+				key compound_key (id,column_1),
+				FULLTEXT KEY fulltext_key (column_1)
+			) ENGINE=MyISAM
+			"
+		);
+
+		$this->assertEmpty( $updates );
+	}
+
+	/**
+	 * @ticket 34874
+	 */
+	function test_index_names_are_not_case_sensitive_and_do_not_recreate_indices() {
+		$this->markTestSkipped();
+		global $wpdb;
+
+		$updates = dbDelta(
+			"
+			CREATE TABLE {$wpdb->prefix}dbdelta_test (
+				id bigint(20) NOT NULL AUTO_INCREMENT,
+				column_1 varchar(255) NOT NULL,
+				column_2 text,
+				column_3 blob,
+				PRIMARY KEY  (id),
+				KEY key_1 (column_1),
+				KEY COMPOUND_KEY (id,column_1),
+				FULLTEXT KEY fulltext_key (column_1)
+			) ENGINE=MyISAM
+			"
+		);
+
+		$this->assertEmpty( $updates );
+	}
 }
