X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryAllRevisions.php;h=5343c337477ef4f4ed7cc921ef4ea3b58a2b2713;hb=746fa545f0047ec7bcf18f773c224369e6b3172b;hp=6a26eff7f57f0a61b101352e078bcc186d66fb3c;hpb=ac0ab2c03a12756b0965f250c174e228348ec459;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryAllRevisions.php b/includes/api/ApiQueryAllRevisions.php index 6a26eff7f5..5343c33747 100644 --- a/includes/api/ApiQueryAllRevisions.php +++ b/includes/api/ApiQueryAllRevisions.php @@ -40,6 +40,8 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase { * @return void */ protected function run( ApiPageSet $resultPageSet = null ) { + global $wgActorTableSchemaMigrationStage; + $db = $this->getDB(); $params = $this->extractRequestParams( false ); $revisionStore = MediaWikiServices::getInstance()->getRevisionStore(); @@ -48,6 +50,19 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase { $this->requireMaxOneParameter( $params, 'user', 'excludeuser' ); + $tsField = 'rev_timestamp'; + $idField = 'rev_id'; + $pageField = 'rev_page'; + if ( $params['user'] !== null && + ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) + ) { + // The query is probably best done using the actor_timestamp index on + // revision_actor_temp. Use the denormalized fields from that table. + $tsField = 'revactor_timestamp'; + $idField = 'revactor_rev'; + $pageField = 'revactor_page'; + } + // Namespace check is likely to be desired, but can't be done // efficiently in SQL. $miser_ns = null; @@ -70,54 +85,71 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase { $revQuery = $revisionStore->getQueryInfo( $this->fetchContent ? [ 'page', 'text' ] : [ 'page' ] ); - $this->addTables( $revQuery['tables'] ); - $this->addFields( $revQuery['fields'] ); - $this->addJoinConds( $revQuery['joins'] ); - - // Review this depeneding on the outcome of T113901 - $this->addOption( 'STRAIGHT_JOIN' ); } else { $this->limit = $this->getParameter( 'limit' ) ?: 10; - $this->addTables( 'revision' ); - $this->addFields( [ 'rev_timestamp', 'rev_id' ] ); + $revQuery = [ + 'tables' => [ 'revision' ], + 'fields' => [ 'rev_timestamp', 'rev_id' ], + 'joins' => [], + ]; + if ( $params['generatetitles'] ) { - $this->addFields( [ 'rev_page' ] ); + $revQuery['fields'][] = 'rev_page'; } - if ( $needPageTable ) { - $this->addTables( 'page' ); - $this->addJoinConds( - [ 'page' => [ 'INNER JOIN', [ 'rev_page = page_id' ] ] ] - ); - $this->addFieldsIf( [ 'page_namespace' ], (bool)$miser_ns ); + if ( $params['user'] !== null || $params['excludeuser'] !== null ) { + $actorQuery = ActorMigration::newMigration()->getJoin( 'rev_user' ); + $revQuery['tables'] += $actorQuery['tables']; + $revQuery['joins'] += $actorQuery['joins']; + } - // Review this depeneding on the outcome of T113901 - $this->addOption( 'STRAIGHT_JOIN' ); + if ( $needPageTable ) { + $revQuery['tables'][] = 'page'; + $revQuery['joins']['page'] = [ 'INNER JOIN', [ "$pageField = page_id" ] ]; + if ( (bool)$miser_ns ) { + $revQuery['fields'][] = 'page_namespace'; + } } } + // If we're going to be using actor_timestamp, we need to swap the order of `revision` + // and `revision_actor_temp` in the query (for the straight join) and adjust some field aliases. + if ( $idField !== 'rev_id' && isset( $revQuery['tables']['temp_rev_user'] ) ) { + $aliasFields = [ 'rev_id' => $idField, 'rev_timestamp' => $tsField, 'rev_page' => $pageField ]; + $revQuery['fields'] = array_merge( + $aliasFields, + array_diff( $revQuery['fields'], array_keys( $aliasFields ) ) + ); + unset( $revQuery['tables']['temp_rev_user'] ); + $revQuery['tables'] = array_merge( + [ 'temp_rev_user' => 'revision_actor_temp' ], + $revQuery['tables'] + ); + $revQuery['joins']['revision'] = $revQuery['joins']['temp_rev_user']; + unset( $revQuery['joins']['temp_rev_user'] ); + } + + $this->addTables( $revQuery['tables'] ); + $this->addFields( $revQuery['fields'] ); + $this->addJoinConds( $revQuery['joins'] ); + + // Seems to be needed to avoid a planner bug (T113901) + $this->addOption( 'STRAIGHT_JOIN' ); + $dir = $params['dir']; - $this->addTimestampWhereRange( 'rev_timestamp', $dir, $params['start'], $params['end'] ); + $this->addTimestampWhereRange( $tsField, $dir, $params['start'], $params['end'] ); if ( $this->fld_tags ) { - $this->addTables( 'tag_summary' ); - $this->addJoinConds( - [ 'tag_summary' => [ 'LEFT JOIN', [ 'rev_id=ts_rev_id' ] ] ] - ); - $this->addFields( 'ts_tags' ); + $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'revision' ) ] ); } if ( $params['user'] !== null ) { $actorQuery = ActorMigration::newMigration() ->getWhere( $db, 'rev_user', User::newFromName( $params['user'], false ) ); - $this->addTables( $actorQuery['tables'] ); - $this->addJoinConds( $actorQuery['joins'] ); $this->addWhere( $actorQuery['conds'] ); } elseif ( $params['excludeuser'] !== null ) { $actorQuery = ActorMigration::newMigration() ->getWhere( $db, 'rev_user', User::newFromName( $params['excludeuser'], false ) ); - $this->addTables( $actorQuery['tables'] ); - $this->addJoinConds( $actorQuery['joins'] ); $this->addWhere( 'NOT(' . $actorQuery['conds'] . ')' ); } @@ -142,17 +174,17 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase { $ts = $db->addQuotes( $db->timestamp( $cont[0] ) ); $rev_id = (int)$cont[1]; $this->dieContinueUsageIf( strval( $rev_id ) !== $cont[1] ); - $this->addWhere( "rev_timestamp $op $ts OR " . - "(rev_timestamp = $ts AND " . - "rev_id $op= $rev_id)" ); + $this->addWhere( "$tsField $op $ts OR " . + "($tsField = $ts AND " . + "$idField $op= $rev_id)" ); } $this->addOption( 'LIMIT', $this->limit + 1 ); $sort = ( $dir == 'newer' ? '' : ' DESC' ); $orderby = []; - // Targeting index rev_timestamp, user_timestamp, or usertext_timestamp - // But 'user' is always constant for the latter two, so it doesn't matter here. + // Targeting index rev_timestamp, user_timestamp, usertext_timestamp, or actor_timestamp. + // But 'user' is always constant for the latter three, so it doesn't matter here. $orderby[] = "rev_timestamp $sort"; $orderby[] = "rev_id $sort"; $this->addOption( 'ORDER BY', $orderby );