diff -u b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php --- b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php @@ -31,7 +31,7 @@ /** * Set the created column. */ - protected $createdColumn = 'created'; + protected $createdColumn = 'node_property_data-created'; /** * Set default values for the path field options. @@ -67,7 +67,7 @@ public function getAvailableSorts() { // You can't execute functions in properties, so override the method return array( - 'title:DESC' => t('Title') + 'node_property_data-title:DESC' => t('Title') ); } interdiff impossible; taking evasive action reverted: --- b/core/modules/node/node.install +++ a/core/modules/node/node.install @@ -27,7 +27,7 @@ // Defaults to NULL in order to avoid a brief period of potential // deadlocks on the index. 'vid' => array( + 'description' => 'The current {node_revision}.vid version identifier.', - 'description' => 'The current {node_property_revision}.vid version identifier.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, @@ -47,68 +47,6 @@ 'not null' => TRUE, 'default' => '', ), - 'tnid' => array( - 'description' => 'The translation set id for this node, which equals the node id of the source post in each set.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'translate' => array( - 'description' => 'A boolean indicating whether this translation page needs to be updated.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'indexes' => array( - 'node_type' => array(array('type', 4)), - 'tnid' => array('tnid'), - 'translate' => array('translate'), - ), - 'unique keys' => array( - 'vid' => array('vid'), - 'uuid' => array('uuid'), - ), - 'foreign keys' => array( - 'node_revision' => array( - 'table' => 'node_revision', - 'columns' => array('vid' => 'vid'), - ), - ), - 'primary key' => array('nid'), - ); - - // Node property storage. - $schema['node_property_data'] = array( - 'description' => 'Base table for node properties.', - 'fields' => array( - 'nid' => array( - 'description' => 'The primary identifier for a node.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'vid' => array( - 'description' => 'The current {node_property_revision}.vid version identifier.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this node.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - 'default_langcode' => array( - 'description' => 'The default {language}.langcode of this node.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), 'title' => array( 'description' => 'The title of this node, always treated as non-markup plain text.', 'type' => 'varchar', @@ -159,187 +97,187 @@ 'not null' => TRUE, 'default' => 0, ), + 'tnid' => array( + 'description' => 'The translation set id for this node, which equals the node id of the source post in each set.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'translate' => array( + 'description' => 'A boolean indicating whether this translation page needs to be updated.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), ), 'indexes' => array( + 'node_changed' => array('changed'), + 'node_created' => array('created'), + 'node_frontpage' => array('promote', 'status', 'sticky', 'created'), + 'node_status_type' => array('status', 'type', 'nid'), + 'node_title_type' => array('title', array('type', 4)), + 'node_type' => array(array('type', 4)), + 'uid' => array('uid'), + 'tnid' => array('tnid'), + 'translate' => array('translate'), - 'node_created' => array('created'), - 'node_changed' => array('changed'), - 'node_frontpage' => array('promote', 'status', 'sticky', 'changed'), - 'node_status' => array('status', 'nid'), - 'node_title' => array('title'), - 'uid' => array('uid'), ), 'unique keys' => array( 'vid' => array('vid'), + 'uuid' => array('uuid'), ), 'foreign keys' => array( + 'node_revision' => array( + 'table' => 'node_revision', + 'columns' => array('vid' => 'vid'), - 'node_base' => array( - 'table' => 'node', - 'columns' => array('nid' => 'nid'), ), 'node_author' => array( 'table' => 'users', 'columns' => array('uid' => 'uid'), ), ), + 'primary key' => array('nid'), - 'primary key' => array('nid', 'vid', 'langcode'), ); + $schema['node_access'] = array( + 'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.', - // Node property revision storage. - $schema['node_property_revision'] = array( - 'description' => 'Stores information about each saved version of a {node}.', 'fields' => array( 'nid' => array( + 'description' => 'The {node}.nid this record affects.', - 'description' => 'The {node} this version belongs to.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, + 'default' => 0, ), + 'gid' => array( + 'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.", + 'type' => 'int', - 'vid' => array( - 'description' => 'The primary identifier for this version.', - 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, + 'default' => 0, ), + 'realm' => array( + 'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.', - 'langcode' => array( - 'description' => 'The {language}.langcode of this version.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - 'default_langcode' => array( - 'description' => 'The default {language}.langcode of this version.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - 'title' => array( - 'description' => 'The title of this version, always treated as non-markup plain text.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', ), + 'grant_view' => array( + 'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.', - 'uid' => array( - 'description' => 'The {users}.uid that created this version.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, + 'size' => 'tiny', ), + 'grant_update' => array( + 'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.', - 'status' => array( - 'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 1, - ), - 'comment' => array( - 'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).', 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, + 'size' => 'tiny', ), + 'grant_delete' => array( + 'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.', - 'promote' => array( - 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'sticky' => array( - 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'log' => array( - 'description' => 'The log entry explaining the changes in this version.', - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'big', - ), - 'timestamp' => array( - 'description' => 'The Unix timestamp when this revision was saved.', 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, + 'size' => 'tiny', ), ), + 'primary key' => array('nid', 'gid', 'realm'), - 'indexes' => array( - 'nid' => array('nid'), - 'uid' => array('uid'), - ), - 'unique keys' => array( - 'vid' => array('vid'), - ), 'foreign keys' => array( + 'affected_node' => array( - 'versioned_node' => array( 'table' => 'node', 'columns' => array('nid' => 'nid'), ), + ), - 'version_author' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ), - 'primary key' => array('nid', 'vid', 'langcode'), ); + $schema['node_revision'] = array( + 'description' => 'Stores information about each saved version of a {node}.', - $schema['node_access'] = array( - 'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.', 'fields' => array( 'nid' => array( + 'description' => 'The {node} this version belongs to.', - 'description' => 'The {node}.nid this record affects.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), + 'vid' => array( + 'description' => 'The primary identifier for this version.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'uid' => array( + 'description' => 'The {users}.uid that created this version.', - 'gid' => array( - 'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), + 'title' => array( + 'description' => 'The title of this version.', - 'realm' => array( - 'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', ), + 'log' => array( + 'description' => 'The log entry explaining the changes in this version.', + 'type' => 'text', + 'not null' => TRUE, + 'size' => 'big', + ), + 'timestamp' => array( + 'description' => 'A Unix timestamp indicating when this version was created.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'status' => array( + 'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 1, + ), + 'comment' => array( + 'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).', - 'grant_view' => array( - 'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.', 'type' => 'int', - 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'size' => 'tiny', ), + 'promote' => array( + 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.', - 'grant_update' => array( - 'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.', 'type' => 'int', - 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'size' => 'tiny', ), + 'sticky' => array( + 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.', - 'grant_delete' => array( - 'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.', 'type' => 'int', - 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'size' => 'tiny', ), ), + 'indexes' => array( + 'nid' => array('nid'), + 'uid' => array('uid'), + ), + 'primary key' => array('vid'), - 'primary key' => array('nid', 'gid', 'realm'), 'foreign keys' => array( + 'versioned_node' => array( - 'affected_node' => array( 'table' => 'node', 'columns' => array('nid' => 'nid'), ), + 'version_author' => array( + 'table' => 'users', + 'columns' => array('uid' => 'uid'), + ), ), ); @@ -427,7 +365,7 @@ 'type' => 'int', 'not null' => TRUE, 'default' => 0, + 'size' => 'tiny' - 'size' => 'tiny', ), 'orig_type' => array( 'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.', @@ -754,160 +692,6 @@ } /** - * Add dedicated tables for node properties. - */ -function node_update_8008() { - $schema = node_schema(); - // Create property table if necessary. - if (!db_table_exists('node_property_data')) { - db_create_table('node_property_data', $schema['node_property_data']); - } - - // Create property revision table if necessary. - if (!db_table_exists('node_property_revision')) { - db_create_table('node_property_revision', $schema['node_property_revision']); - } -} - -/** - * Move property data to dedicated table. - */ -function node_update_8009(&$sandbox) { - if (!isset($sandbox['progress'])) { - $sandbox['progress'] = 0; - $sandbox['last'] = (int) db_query('SELECT npd.nid FROM {node_property_data npd} ORDER BY nid DESC')->fetchField(); - $sandbox['max'] = db_query('SELECT COUNT(*) FROM {node} n LEFT JOIN {node_property_data} npd ON npd.nid = n.nid WHERE npd.nid IS NULL')->fetchField(); - } - - // Create initial property data set if necessary. - if (!empty($sandbox['max'])) { - $source_query = db_select('node') - ->fields('node', array( - 'nid', - 'vid', - 'langcode', - 'title', - 'uid', - 'status', - 'created', - 'changed', - 'comment', - 'promote', - 'sticky', - )) - ->range(0, 10) - ->condition('nid', $sandbox['last'], '>') - ->orderBy('nid'); - $source_query->addField('node', 'langcode', 'default_langcode'); - db_insert('node_property_data')->from($source_query)->execute(); - $sandbox['last'] = db_query('SELECT npd.nid FROM {node_property_data} npd ORDER BY nid DESC')->fetchField(); - $sandbox['progress'] += 10; - } - - $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); -} - -/** - * Move property revisions to dedicated table. - */ -function node_update_8010(&$sandbox) { - if (!isset($sandbox['progress'])) { - $sandbox['progress'] = 0; - $sandbox['last'] = (int) db_query('SELECT npr.vid FROM {node_property_revision} npr ORDER BY vid DESC')->fetchField(); - $sandbox['max'] = db_query('SELECT COUNT(*) FROM {node_revision} nr LEFT JOIN {node_property_revision} npr ON npr.vid = nr.vid WHERE npr.vid IS NULL')->fetchField(); - } - - // Create initial revision set if necessary. - if (!empty($sandbox['max'])) { - $source_query = db_select('node_revision', 'nr') - ->fields('nr', array( - 'nid', - 'vid', - 'uid', - 'title', - 'status', - 'comment', - 'promote', - 'sticky', - 'log', - 'timestamp', - )) - ->range(0, 10) - ->condition('nr.vid', $sandbox['last'], '>') - ->orderBy('nr.vid'); - $source_query->innerJoin('node_property_data', 'npd', 'npd.nid = nr.nid'); - $source_query->addField('npd', 'langcode'); - $source_query->addField('npd', 'default_langcode'); - - db_insert('node_property_revision')->from($source_query)->execute(); - $sandbox['last'] = db_query('SELECT npr.vid FROM {node_property_revision} npr ORDER BY vid DESC')->fetchField(); - $sandbox['progress'] += 10; - } - - $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); -} - -/** - * Cleanup old tables after finishing switch to dedicated property tables. - */ -function node_update_8011() { - $old_base_table_fields = array( - 'title', - 'uid', - 'status', - 'created', - 'changed', - 'comment', - 'promote', - 'sticky', - ); - $old_base_table_indexes = array( - 'node_created', - 'node_changed', - 'node_frontpage', - 'node_status_type', - 'node_title_type', - 'node_type', - 'uid', - ); - - $node_count = db_select('node')->countQuery()->execute()->fetchColumn(); - $node_revision_count = db_select('node_revision')->countQuery()->execute()->fetchColumn(); - $node_property_count = db_select('node_property_data')->countQuery()->execute()->fetchColumn(); - $node_property_revision_count = db_select('node_property_revision')->countQuery()->execute()->fetchColumn(); - - // Modify original tables if possible and necessary. - if ($node_property_count == $node_count) { - // Drop deprecated indexes. - foreach ($old_base_table_indexes as $old_index) { - if (db_index_exists('node', $old_index)) { - db_drop_index('node', $old_index); - } - } - // Recreate index. - if (!db_index_exists('node', 'node_type')) { - db_add_index('node', 'node_type', array(array('type', 4))); - } - // Drop deprecated fields. - foreach ($old_base_table_fields as $deprecated_base_field) { - if (db_field_exists('node', $deprecated_base_field)) { - db_drop_field('node', $deprecated_base_field); - } - } - } - else { - throw new DrupalUpdateException('The data migration from the node to the new node_property_data table seems to be inconsistent.'); - } - - if (db_table_exists('node_revision') && $node_revision_count == $node_property_revision_count) { - db_drop_table('node_revision'); - } - else { - throw new DrupalUpdateException('The data migration from the node_revision to the new node_property_revision table seems to be inconsistent.'); - } -} - -/** * @} End of "addtogroup updates-7.x-to-8.x" * The next series of updates should start at 9000. */ unchanged: --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -27,7 +27,7 @@ function node_schema() { // Defaults to NULL in order to avoid a brief period of potential // deadlocks on the index. 'vid' => array( - 'description' => 'The current {node_revision}.vid version identifier.', + 'description' => 'The current {node_property_revision}.vid version identifier.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, @@ -47,6 +47,68 @@ function node_schema() { 'not null' => TRUE, 'default' => '', ), + 'tnid' => array( + 'description' => 'The translation set id for this node, which equals the node id of the source post in each set.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'translate' => array( + 'description' => 'A boolean indicating whether this translation page needs to be updated.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'indexes' => array( + 'node_type' => array(array('type', 4)), + 'tnid' => array('tnid'), + 'translate' => array('translate'), + ), + 'unique keys' => array( + 'vid' => array('vid'), + 'uuid' => array('uuid'), + ), + 'foreign keys' => array( + 'node_revision' => array( + 'table' => 'node_revision', + 'columns' => array('vid' => 'vid'), + ), + ), + 'primary key' => array('nid'), + ); + + // Node property storage. + $schema['node_property_data'] = array( + 'description' => 'Base table for node properties.', + 'fields' => array( + 'nid' => array( + 'description' => 'The primary identifier for a node.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'vid' => array( + 'description' => 'The current {node_property_revision}.vid version identifier.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of this node.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + 'default_langcode' => array( + 'description' => 'The default {language}.langcode of this node.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), 'title' => array( 'description' => 'The title of this node, always treated as non-markup plain text.', 'type' => 'varchar', @@ -97,187 +159,187 @@ function node_schema() { 'not null' => TRUE, 'default' => 0, ), - 'tnid' => array( - 'description' => 'The translation set id for this node, which equals the node id of the source post in each set.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'translate' => array( - 'description' => 'A boolean indicating whether this translation page needs to be updated.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), ), 'indexes' => array( - 'node_changed' => array('changed'), - 'node_created' => array('created'), - 'node_frontpage' => array('promote', 'status', 'sticky', 'created'), - 'node_status_type' => array('status', 'type', 'nid'), - 'node_title_type' => array('title', array('type', 4)), - 'node_type' => array(array('type', 4)), - 'uid' => array('uid'), - 'tnid' => array('tnid'), - 'translate' => array('translate'), + 'node_created' => array('created'), + 'node_changed' => array('changed'), + 'node_frontpage' => array('promote', 'status', 'sticky', 'changed'), + 'node_status' => array('status', 'nid'), + 'node_title' => array('title'), + 'uid' => array('uid'), ), 'unique keys' => array( 'vid' => array('vid'), - 'uuid' => array('uuid'), ), 'foreign keys' => array( - 'node_revision' => array( - 'table' => 'node_revision', - 'columns' => array('vid' => 'vid'), + 'node_base' => array( + 'table' => 'node', + 'columns' => array('nid' => 'nid'), ), 'node_author' => array( 'table' => 'users', 'columns' => array('uid' => 'uid'), ), ), - 'primary key' => array('nid'), + 'primary key' => array('nid', 'vid', 'langcode'), ); - $schema['node_access'] = array( - 'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.', + // Node property revision storage. + $schema['node_property_revision'] = array( + 'description' => 'Stores information about each saved version of a {node}.', 'fields' => array( 'nid' => array( - 'description' => 'The {node}.nid this record affects.', + 'description' => 'The {node} this version belongs to.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, - 'default' => 0, ), - 'gid' => array( - 'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.", - 'type' => 'int', + 'vid' => array( + 'description' => 'The primary identifier for this version.', + 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, - 'default' => 0, ), - 'realm' => array( - 'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.', + 'langcode' => array( + 'description' => 'The {language}.langcode of this version.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + 'default_langcode' => array( + 'description' => 'The default {language}.langcode of this version.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + 'title' => array( + 'description' => 'The title of this version, always treated as non-markup plain text.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', ), - 'grant_view' => array( - 'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.', + 'uid' => array( + 'description' => 'The {users}.uid that created this version.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'size' => 'tiny', ), - 'grant_update' => array( - 'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.', + 'status' => array( + 'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 1, + ), + 'comment' => array( + 'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).', 'type' => 'int', - 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'size' => 'tiny', ), - 'grant_delete' => array( - 'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.', + 'promote' => array( + 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'sticky' => array( + 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'log' => array( + 'description' => 'The log entry explaining the changes in this version.', + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ), + 'timestamp' => array( + 'description' => 'The Unix timestamp when this revision was saved.', 'type' => 'int', - 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, - 'size' => 'tiny', ), ), - 'primary key' => array('nid', 'gid', 'realm'), + 'indexes' => array( + 'nid' => array('nid'), + 'uid' => array('uid'), + ), + 'unique keys' => array( + 'vid' => array('vid'), + ), 'foreign keys' => array( - 'affected_node' => array( + 'versioned_node' => array( 'table' => 'node', 'columns' => array('nid' => 'nid'), ), - ), + 'version_author' => array( + 'table' => 'users', + 'columns' => array('uid' => 'uid'), + ), + ), + 'primary key' => array('nid', 'vid', 'langcode'), ); - $schema['node_revision'] = array( - 'description' => 'Stores information about each saved version of a {node}.', + $schema['node_access'] = array( + 'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.', 'fields' => array( 'nid' => array( - 'description' => 'The {node} this version belongs to.', + 'description' => 'The {node}.nid this record affects.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), - 'vid' => array( - 'description' => 'The primary identifier for this version.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'uid' => array( - 'description' => 'The {users}.uid that created this version.', + 'gid' => array( + 'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), - 'title' => array( - 'description' => 'The title of this version.', + 'realm' => array( + 'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', ), - 'log' => array( - 'description' => 'The log entry explaining the changes in this version.', - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - ), - 'timestamp' => array( - 'description' => 'A Unix timestamp indicating when this version was created.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'status' => array( - 'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 1, - ), - 'comment' => array( - 'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).', + 'grant_view' => array( + 'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.', 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, + 'size' => 'tiny', ), - 'promote' => array( - 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.', + 'grant_update' => array( + 'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.', 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, + 'size' => 'tiny', ), - 'sticky' => array( - 'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.', + 'grant_delete' => array( + 'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.', 'type' => 'int', + 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, + 'size' => 'tiny', ), ), - 'indexes' => array( - 'nid' => array('nid'), - 'uid' => array('uid'), - ), - 'primary key' => array('vid'), + 'primary key' => array('nid', 'gid', 'realm'), 'foreign keys' => array( - 'versioned_node' => array( + 'affected_node' => array( 'table' => 'node', 'columns' => array('nid' => 'nid'), ), - 'version_author' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), ), ); @@ -365,7 +427,7 @@ function node_schema() { 'type' => 'int', 'not null' => TRUE, 'default' => 0, - 'size' => 'tiny' + 'size' => 'tiny', ), 'orig_type' => array( 'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.', @@ -712,6 +774,160 @@ function node_update_8008() { } /** + * Add dedicated tables for node properties. + */ +function node_update_8009() { + $schema = node_schema(); + // Create property table if necessary. + if (!db_table_exists('node_property_data')) { + db_create_table('node_property_data', $schema['node_property_data']); + } + + // Create property revision table if necessary. + if (!db_table_exists('node_property_revision')) { + db_create_table('node_property_revision', $schema['node_property_revision']); + } +} + +/** + * Move property data to dedicated table. + */ +function node_update_8010(&$sandbox) { + if (!isset($sandbox['progress'])) { + $sandbox['progress'] = 0; + $sandbox['last'] = (int) db_query('SELECT npd.nid FROM {node_property_data npd} ORDER BY nid DESC')->fetchField(); + $sandbox['max'] = db_query('SELECT COUNT(*) FROM {node} n LEFT JOIN {node_property_data} npd ON npd.nid = n.nid WHERE npd.nid IS NULL')->fetchField(); + } + + // Create initial property data set if necessary. + if (!empty($sandbox['max'])) { + $source_query = db_select('node') + ->fields('node', array( + 'nid', + 'vid', + 'langcode', + 'title', + 'uid', + 'status', + 'created', + 'changed', + 'comment', + 'promote', + 'sticky', + )) + ->range(0, 10) + ->condition('nid', $sandbox['last'], '>') + ->orderBy('nid'); + $source_query->addField('node', 'langcode', 'default_langcode'); + db_insert('node_property_data')->from($source_query)->execute(); + $sandbox['last'] = db_query('SELECT npd.nid FROM {node_property_data} npd ORDER BY nid DESC')->fetchField(); + $sandbox['progress'] += 10; + } + + $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); +} + +/** + * Move property revisions to dedicated table. + */ +function node_update_8011(&$sandbox) { + if (!isset($sandbox['progress'])) { + $sandbox['progress'] = 0; + $sandbox['last'] = (int) db_query('SELECT npr.vid FROM {node_property_revision} npr ORDER BY vid DESC')->fetchField(); + $sandbox['max'] = db_query('SELECT COUNT(*) FROM {node_revision} nr LEFT JOIN {node_property_revision} npr ON npr.vid = nr.vid WHERE npr.vid IS NULL')->fetchField(); + } + + // Create initial revision set if necessary. + if (!empty($sandbox['max'])) { + $source_query = db_select('node_revision', 'nr') + ->fields('nr', array( + 'nid', + 'vid', + 'uid', + 'title', + 'status', + 'comment', + 'promote', + 'sticky', + 'log', + 'timestamp', + )) + ->range(0, 10) + ->condition('nr.vid', $sandbox['last'], '>') + ->orderBy('nr.vid'); + $source_query->innerJoin('node_property_data', 'npd', 'npd.nid = nr.nid'); + $source_query->addField('npd', 'langcode'); + $source_query->addField('npd', 'default_langcode'); + + db_insert('node_property_revision')->from($source_query)->execute(); + $sandbox['last'] = db_query('SELECT npr.vid FROM {node_property_revision} npr ORDER BY vid DESC')->fetchField(); + $sandbox['progress'] += 10; + } + + $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); +} + +/** + * Cleanup old tables after finishing switch to dedicated property tables. + */ +function node_update_8012() { + $old_base_table_fields = array( + 'title', + 'uid', + 'status', + 'created', + 'changed', + 'comment', + 'promote', + 'sticky', + ); + $old_base_table_indexes = array( + 'node_created', + 'node_changed', + 'node_frontpage', + 'node_status_type', + 'node_title_type', + 'node_type', + 'uid', + ); + + $node_count = db_select('node')->countQuery()->execute()->fetchColumn(); + $node_revision_count = db_select('node_revision')->countQuery()->execute()->fetchColumn(); + $node_property_count = db_select('node_property_data')->countQuery()->execute()->fetchColumn(); + $node_property_revision_count = db_select('node_property_revision')->countQuery()->execute()->fetchColumn(); + + // Modify original tables if possible and necessary. + if ($node_property_count == $node_count) { + // Drop deprecated indexes. + foreach ($old_base_table_indexes as $old_index) { + if (db_index_exists('node', $old_index)) { + db_drop_index('node', $old_index); + } + } + // Recreate index. + if (!db_index_exists('node', 'node_type')) { + db_add_index('node', 'node_type', array(array('type', 4))); + } + // Drop deprecated fields. + foreach ($old_base_table_fields as $deprecated_base_field) { + if (db_field_exists('node', $deprecated_base_field)) { + db_drop_field('node', $deprecated_base_field); + } + } + } + else { + throw new DrupalUpdateException('The data migration from the node to the new node_property_data table seems to be inconsistent.'); + } + + if (db_table_exists('node_revision') && $node_revision_count == $node_property_revision_count) { + db_drop_table('node_revision'); + } + else { + throw new DrupalUpdateException('The data migration from the node_revision to the new node_property_revision table seems to be inconsistent.'); + } +} + +/** * @} End of "addtogroup updates-7.x-to-8.x" * The next series of updates should start at 9000. */ diff -u b/core/modules/node/node.views.inc b/core/modules/node/node.views.inc --- b/core/modules/node/node.views.inc +++ b/core/modules/node/node.views.inc @@ -658,7 +658,7 @@ // Explain how this table joins to others. $data['history']['table']['join'] = array( // Directly links to node table. - 'node' => array( + 'node_property_data' => array( 'table' => 'history', 'left_field' => 'nid', 'field' => 'nid', diff -u b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php --- b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -240,7 +240,7 @@ $node->save(); // Small hack to link revisions to our test user. - db_update('node_property_revision') + db_update('node_revision') ->fields(array('uid' => $node->uid)) ->condition('vid', $node->vid) ->execute(); @@ -273,7 +273,7 @@ $node->save(); // Small hack to link revisions to our test user. - db_update('node_revision') + db_update('node_property_revision') ->fields(array('uid' => $node->uid)) ->condition('vid', $node->vid) ->execute(); diff -u b/core/modules/user/user.views.inc b/core/modules/user/user.views.inc --- b/core/modules/user/user.views.inc +++ b/core/modules/user/user.views.inc @@ -48,7 +48,7 @@ 'title' => t('Content authored'), 'help' => t('Relate content to the user who created it. This relationship will create one record for each content item created by the user.'), 'id' => 'standard', - 'base' => 'node', + 'base' => 'node_property_data', 'base field' => 'uid', 'field' => 'uid', 'label' => t('nodes'), diff -u b/core/modules/views/config/views.view.comments_recent.yml b/core/modules/views/config/views.view.comments_recent.yml --- b/core/modules/views/config/views.view.comments_recent.yml +++ b/core/modules/views/config/views.view.comments_recent.yml @@ -49,8 +49,8 @@ label: '' date_format: 'time ago' sorts: - timestamp: - id: timestamp + changed: + id: changed table: comment field: changed order: DESC only in patch2: unchanged: --- a/core/modules/comment/lib/Drupal/comment/Plugin/views/wizard/Comment.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/wizard/Comment.php @@ -58,7 +58,7 @@ class Comment extends WizardPluginBase { ), 'status_node' => array( 'value' => TRUE, - 'table' => 'node', + 'table' => 'node_property', 'field' => 'status', 'relationship' => 'nid' ) only in patch2: unchanged: --- a/core/modules/views/lib/Drupal/views/Tests/Comment/DefaultViewRecentComments.php +++ b/core/modules/views/lib/Drupal/views/Tests/Comment/DefaultViewRecentComments.php @@ -84,6 +84,8 @@ public function setUp() { $comment->node_type = 'comment_node_' . $this->node->type; $comment->comment_body[LANGUAGE_NOT_SPECIFIED][0]['value'] = 'Test body ' . $i; $comment->comment_body[LANGUAGE_NOT_SPECIFIED][0]['format'] = 'full_html'; + // Sets a descending changed time, so the order works as expected. + $comment->changed = REQUEST_TIME - $i; comment_save($comment); } @@ -135,7 +137,6 @@ public function testPageDisplay() { 'comment_nid' => 'nid', 'comment_subject' => 'subject', 'comment_changed' => 'changed', - 'comment_changed' => 'created', 'cid' => 'cid' ); $expected_result = array(); @@ -143,7 +144,6 @@ public function testPageDisplay() { $expected_result[$key]['nid'] = $comment->nid; $expected_result[$key]['subject'] = $comment->subject; $expected_result[$key]['changed'] = $comment->changed; - $expected_result[$key]['created'] = $comment->created; $expected_result[$key]['cid'] = $comment->cid; } $this->assertIdenticalResultset($view, $expected_result, $map); only in patch2: unchanged: --- a/core/modules/views/lib/Drupal/views/Tests/Comment/WizardTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Comment/WizardTest.php @@ -78,7 +78,7 @@ public function testCommentWizard() { $this->assertEqual($view->filter['status']->table, 'comment'); $this->assertEqual($view->filter['status']->field, 'status'); $this->assertTrue($view->filter['status']->value); - $this->assertEqual($view->filter['status_node']->table, 'node'); + $this->assertEqual($view->filter['status_node']->table, 'node_property'); $this->assertEqual($view->filter['status_node']->field, 'status'); $this->assertTrue($view->filter['status_node']->value); only in patch2: unchanged: --- a/core/modules/views/lib/Drupal/views/Tests/Field/ApiDataTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Field/ApiDataTest.php @@ -94,7 +94,7 @@ function testViewsData() { $this->assertTrue(isset($data[$revision_table])); // The node field should join against node. $this->assertTrue(isset($data[$current_table]['table']['join']['node'])); - $this->assertTrue(isset($data[$revision_table]['table']['join']['node_revision'])); + $this->assertTrue(isset($data[$revision_table]['table']['join']['node_property_revision'])); $expected_join = array( 'left_field' => 'nid', @@ -113,7 +113,7 @@ function testViewsData() { array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), ), ); - $this->assertEqual($expected_join, $data[$revision_table]['table']['join']['node_revision']); + $this->assertEqual($expected_join, $data[$revision_table]['table']['join']['node_property_revision']); // Check the table and the joins of the second field. // Attached to both node and user. @@ -125,7 +125,7 @@ function testViewsData() { $this->assertTrue(isset($data[$revision_table_2])); // The second field should join against both node and users. $this->assertTrue(isset($data[$current_table_2]['table']['join']['node'])); - $this->assertTrue(isset($data[$revision_table_2]['table']['join']['node_revision'])); + $this->assertTrue(isset($data[$revision_table_2]['table']['join']['node_property_revision'])); $this->assertTrue(isset($data[$current_table_2]['table']['join']['users'])); $expected_join = array( @@ -145,7 +145,7 @@ function testViewsData() { array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), ) ); - $this->assertEqual($expected_join, $data[$revision_table_2]['table']['join']['node_revision']); + $this->assertEqual($expected_join, $data[$revision_table_2]['table']['join']['node_property_revision']); $expected_join = array( 'left_field' => 'uid', 'field' => 'entity_id', only in patch2: unchanged: --- a/core/modules/views/lib/Drupal/views/Tests/Handler/ArgumentStringTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/ArgumentStringTest.php @@ -40,13 +40,13 @@ function testGlossary() { $count_field = 'nid'; foreach ($view->result as &$row) { - if (strpos($row->node_title, 'a') === 0) { + if (strpos($view->field['title']->get_value($row), 'a') === 0) { $this->assertEqual(1, $row->{$count_field}); } - if (strpos($row->node_title, 'b') === 0) { + if (strpos($view->field['title']->get_value($row), 'b') === 0) { $this->assertEqual(2, $row->{$count_field}); } - if (strpos($row->node_title, 'c') === 0) { + if (strpos($view->field['title']->get_value($row), 'c') === 0) { $this->assertEqual(3, $row->{$count_field}); } } only in patch2: unchanged: --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/ItemsPerPageTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/ItemsPerPageTest.php @@ -45,7 +45,7 @@ function testItemsPerPage() { $view['description'] = $this->randomName(16); $view['show[wizard_key]'] = 'node'; $view['show[type]'] = 'article'; - $view['show[sort]'] = 'created:DESC'; + $view['show[sort]'] = 'node_property_data-created:DESC'; $view['page[create]'] = 1; $view['page[title]'] = $this->randomName(16); $view['page[path]'] = $this->randomName(16); only in patch2: unchanged: --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/SortingTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/SortingTest.php @@ -35,7 +35,7 @@ function testSorting() { $view1['human_name'] = $this->randomName(16); $view1['name'] = strtolower($this->randomName(16)); $view1['description'] = $this->randomName(16); - $view1['show[sort]'] = 'created:ASC'; + $view1['show[sort]'] = 'node_property_data-created:ASC'; $view1['page[create]'] = 1; $view1['page[title]'] = $this->randomName(16); $view1['page[path]'] = $this->randomName(16); @@ -59,7 +59,7 @@ function testSorting() { $view2['human_name'] = $this->randomName(16); $view2['name'] = strtolower($this->randomName(16)); $view2['description'] = $this->randomName(16); - $view2['show[sort]'] = 'created:DESC'; + $view2['show[sort]'] = 'node_property_data-created:DESC'; $view2['page[create]'] = 1; $view2['page[title]'] = $this->randomName(16); $view2['page[path]'] = $this->randomName(16);