diff options
author | jenkins-bot <jenkins-bot@gerrit.wikimedia.org> | 2022-07-22 10:31:46 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@wikimedia.org> | 2022-07-22 10:31:46 +0000 |
commit | 6f2441edce64d3a39132be8d573579da955f1e78 (patch) | |
tree | c195d4bf9253b0a3a9e39450df218cf909204698 /includes/libs | |
parent | 916466b209b48b1db1177b0582e9ddb9491a9f05 (diff) | |
parent | 9ec6cd73818efca283c81c396a8272aa71f5e982 (diff) | |
download | mediawikicore-6f2441edce64d3a39132be8d573579da955f1e78.tar.gz mediawikicore-6f2441edce64d3a39132be8d573579da955f1e78.zip |
Merge "rdbms: Move DatabasePostgres::selectSQLText to PostgresPlatform"
Diffstat (limited to 'includes/libs')
-rw-r--r-- | includes/libs/rdbms/database/DatabasePostgres.php | 55 | ||||
-rw-r--r-- | includes/libs/rdbms/platform/PostgresPlatform.php | 55 |
2 files changed, 55 insertions, 55 deletions
diff --git a/includes/libs/rdbms/database/DatabasePostgres.php b/includes/libs/rdbms/database/DatabasePostgres.php index 8ad9cc97db82..f9dbe123d402 100644 --- a/includes/libs/rdbms/database/DatabasePostgres.php +++ b/includes/libs/rdbms/database/DatabasePostgres.php @@ -459,61 +459,6 @@ __INDEXATTR__; return $res->numRows() > 0; } - public function selectSQLText( - $table, $vars, $conds = '', $fname = __METHOD__, $options = [], $join_conds = [] - ) { - if ( is_string( $options ) ) { - $options = [ $options ]; - } - - // Change the FOR UPDATE option as necessary based on the join conditions. Then pass - // to the parent function to get the actual SQL text. - // In Postgres when using FOR UPDATE, only the main table and tables that are inner joined - // can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to - // do so causes a DB error. This wrapper checks which tables can be locked and adjusts it - // accordingly. - // MySQL uses "ORDER BY NULL" as an optimization hint, but that is illegal in PostgreSQL. - if ( is_array( $options ) ) { - $forUpdateKey = array_search( 'FOR UPDATE', $options, true ); - if ( $forUpdateKey !== false && $join_conds ) { - unset( $options[$forUpdateKey] ); - $options['FOR UPDATE'] = []; - - $toCheck = $table; - reset( $toCheck ); - while ( $toCheck ) { - $alias = key( $toCheck ); - $name = $toCheck[$alias]; - unset( $toCheck[$alias] ); - - $hasAlias = !is_numeric( $alias ); - if ( !$hasAlias && is_string( $name ) ) { - $alias = $name; - } - - if ( !isset( $join_conds[$alias] ) || - !preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_conds[$alias][0] ) - ) { - if ( is_array( $name ) ) { - // It's a parenthesized group, process all the tables inside the group. - $toCheck = array_merge( $toCheck, $name ); - } else { - // Quote alias names so $this->tableName() won't mangle them - $options['FOR UPDATE'][] = $hasAlias ? - $this->platform->addIdentifierQuotes( $alias ) : $alias; - } - } - } - } - - if ( isset( $options['ORDER BY'] ) && $options['ORDER BY'] == 'NULL' ) { - unset( $options['ORDER BY'] ); - } - } - - return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); - } - public function doInsertNonConflicting( $table, array $rows, $fname ) { // Postgres 9.5 supports "ON CONFLICT" if ( $this->getServerVersion() >= 9.5 ) { diff --git a/includes/libs/rdbms/platform/PostgresPlatform.php b/includes/libs/rdbms/platform/PostgresPlatform.php index 771322b72418..4681a289ff0e 100644 --- a/includes/libs/rdbms/platform/PostgresPlatform.php +++ b/includes/libs/rdbms/platform/PostgresPlatform.php @@ -60,6 +60,61 @@ class PostgresPlatform extends SQLPlatform { $this->coreSchema = $coreSchema; } + public function selectSQLText( + $table, $vars, $conds = '', $fname = __METHOD__, $options = [], $join_conds = [] + ) { + if ( is_string( $options ) ) { + $options = [ $options ]; + } + + // Change the FOR UPDATE option as necessary based on the join conditions. Then pass + // to the parent function to get the actual SQL text. + // In Postgres when using FOR UPDATE, only the main table and tables that are inner joined + // can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to + // do so causes a DB error. This wrapper checks which tables can be locked and adjusts it + // accordingly. + // MySQL uses "ORDER BY NULL" as an optimization hint, but that is illegal in PostgreSQL. + if ( is_array( $options ) ) { + $forUpdateKey = array_search( 'FOR UPDATE', $options, true ); + if ( $forUpdateKey !== false && $join_conds ) { + unset( $options[$forUpdateKey] ); + $options['FOR UPDATE'] = []; + + $toCheck = $table; + reset( $toCheck ); + while ( $toCheck ) { + $alias = key( $toCheck ); + $name = $toCheck[$alias]; + unset( $toCheck[$alias] ); + + $hasAlias = !is_numeric( $alias ); + if ( !$hasAlias && is_string( $name ) ) { + $alias = $name; + } + + if ( !isset( $join_conds[$alias] ) || + !preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_conds[$alias][0] ) + ) { + if ( is_array( $name ) ) { + // It's a parenthesized group, process all the tables inside the group. + $toCheck = array_merge( $toCheck, $name ); + } else { + // Quote alias names so $this->tableName() won't mangle them + $options['FOR UPDATE'][] = $hasAlias ? + $this->addIdentifierQuotes( $alias ) : $alias; + } + } + } + } + + if ( isset( $options['ORDER BY'] ) && $options['ORDER BY'] == 'NULL' ) { + unset( $options['ORDER BY'] ); + } + } + + return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); + } + protected function makeSelectOptions( array $options ) { $preLimitTail = $postLimitTail = ''; $startOpts = $useIndex = $ignoreIndex = ''; |