Anomie has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/358054 )

Change subject: DB: Add join conditions to selectField, selectFieldValues, and 
insertSelect
......................................................................

DB: Add join conditions to selectField, selectFieldValues, and insertSelect

selectField() and selectFieldValues() are trivial, they just need to
pass it through to select(). In fact, selectFieldValues() was already
doing it, just no one ever updated IDatabase.

insertSelect() is a little more work. nativeInsertSelect() was
originally written as largely a copy-paste of select() and has since
gotten well out of sync. Now that we have selectSQLText(), we should be
able to just use that. DatabasePostgres's implementation can wrap the
parent implementation instead of being another copy-paste, but
DatabaseOracle seems to still need to be special.

Change-Id: I0e6a9e6daa510639d3212641606047a5db96c500
---
M includes/db/DatabaseOracle.php
M includes/libs/rdbms/database/DBConnRef.php
M includes/libs/rdbms/database/Database.php
M includes/libs/rdbms/database/DatabaseMssql.php
M includes/libs/rdbms/database/DatabasePostgres.php
M includes/libs/rdbms/database/IDatabase.php
6 files changed, 48 insertions(+), 80 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/54/358054/1

diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php
index b728786..556fe75 100644
--- a/includes/db/DatabaseOracle.php
+++ b/includes/db/DatabaseOracle.php
@@ -558,19 +558,9 @@
        }
 
        function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds, 
$fname = __METHOD__,
-               $insertOptions = [], $selectOptions = []
+               $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        ) {
                $destTable = $this->tableName( $destTable );
-               if ( !is_array( $selectOptions ) ) {
-                       $selectOptions = [ $selectOptions ];
-               }
-               list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) =
-                       $this->makeSelectOptions( $selectOptions );
-               if ( is_array( $srcTable ) ) {
-                       $srcTable = implode( ',', array_map( [ $this, 
'tableName' ], $srcTable ) );
-               } else {
-                       $srcTable = $this->tableName( $srcTable );
-               }
 
                $sequenceData = $this->getSequenceData( $destTable );
                if ( $sequenceData !== false &&
@@ -585,13 +575,16 @@
                        $val = $val . ' field' . ( $i++ );
                }
 
-               $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( 
$varMap ) ) . ')' .
-                       " SELECT $startOpts " . implode( ',', $varMap ) .
-                       " FROM $srcTable $useIndex $ignoreIndex ";
-               if ( $conds != '*' ) {
-                       $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
-               }
-               $sql .= " $tailOpts";
+               $selectSql = $this->selectSQLText(
+                       $srcTable,
+                       array_values( $varMap ),
+                       $conds,
+                       $fname,
+                       $selectOptions,
+                       $selectJoinConds
+               );
+
+               $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( 
$varMap ) ) . ') ' . $selectSql;
 
                if ( in_array( 'IGNORE', $insertOptions ) ) {
                        $this->ignoreDupValOnIndex = true;
diff --git a/includes/libs/rdbms/database/DBConnRef.php 
b/includes/libs/rdbms/database/DBConnRef.php
index b6167aa..c4aeab7 100644
--- a/includes/libs/rdbms/database/DBConnRef.php
+++ b/includes/libs/rdbms/database/DBConnRef.php
@@ -243,13 +243,13 @@
        }
 
        public function selectField(
-               $table, $var, $cond = '', $fname = __METHOD__, $options = []
+               $table, $var, $cond = '', $fname = __METHOD__, $options = [], 
$join_conds = []
        ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
        public function selectFieldValues(
-               $table, $var, $cond = '', $fname = __METHOD__, $options = []
+               $table, $var, $cond = '', $fname = __METHOD__, $options = [], 
$join_conds = []
        ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -407,7 +407,7 @@
 
        public function insertSelect(
                $destTable, $srcTable, $varMap, $conds,
-               $fname = __METHOD__, $insertOptions = [], $selectOptions = []
+               $fname = __METHOD__, $insertOptions = [], $selectOptions = [], 
$selectJoinConds = []
        ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
diff --git a/includes/libs/rdbms/database/Database.php 
b/includes/libs/rdbms/database/Database.php
index ee7644f..2021c86 100644
--- a/includes/libs/rdbms/database/Database.php
+++ b/includes/libs/rdbms/database/Database.php
@@ -1140,7 +1140,7 @@
        }
 
        public function selectField(
-               $table, $var, $cond = '', $fname = __METHOD__, $options = []
+               $table, $var, $cond = '', $fname = __METHOD__, $options = [], 
$join_conds = []
        ) {
                if ( $var === '*' ) { // sanity
                        throw new DBUnexpectedError( $this, "Cannot use a * 
field: got '$var'" );
@@ -1152,7 +1152,7 @@
 
                $options['LIMIT'] = 1;
 
-               $res = $this->select( $table, $var, $cond, $fname, $options );
+               $res = $this->select( $table, $var, $cond, $fname, $options, 
$join_conds );
                if ( $res === false || !$this->numRows( $res ) ) {
                        return false;
                }
@@ -2346,7 +2346,7 @@
 
        public function insertSelect(
                $destTable, $srcTable, $varMap, $conds,
-               $fname = __METHOD__, $insertOptions = [], $selectOptions = []
+               $fname = __METHOD__, $insertOptions = [], $selectOptions = [], 
$selectJoinConds = []
        ) {
                if ( $this->cliMode ) {
                        // For massive migrations with downtime, we don't want 
to select everything
@@ -2358,7 +2358,8 @@
                                $conds,
                                $fname,
                                $insertOptions,
-                               $selectOptions
+                               $selectOptions,
+                               $selectJoinConds
                        );
                }
 
@@ -2370,7 +2371,9 @@
                        $fields[] = $this->fieldNameWithAlias( 
$sourceColumnOrSql, $dstColumn );
                }
                $selectOptions[] = 'FOR UPDATE';
-               $res = $this->select( $srcTable, implode( ',', $fields ), 
$conds, $fname, $selectOptions );
+               $res = $this->select(
+                       $srcTable, implode( ',', $fields ), $conds, $fname, 
$selectOptions, $selectJoinConds
+               );
                if ( !$res ) {
                        return false;
                }
@@ -2391,7 +2394,7 @@
         */
        protected function nativeInsertSelect( $destTable, $srcTable, $varMap, 
$conds,
                $fname = __METHOD__,
-               $insertOptions = [], $selectOptions = []
+               $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        ) {
                $destTable = $this->tableName( $destTable );
 
@@ -2401,32 +2404,18 @@
 
                $insertOptions = $this->makeInsertOptions( $insertOptions );
 
-               if ( !is_array( $selectOptions ) ) {
-                       $selectOptions = [ $selectOptions ];
-               }
-
-               list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) = 
$this->makeSelectOptions(
-                       $selectOptions );
-
-               if ( is_array( $srcTable ) ) {
-                       $srcTable = implode( ',', array_map( [ $this, 
'tableName' ], $srcTable ) );
-               } else {
-                       $srcTable = $this->tableName( $srcTable );
-               }
+               $selectSql = $this->selectSQLText(
+                       $srcTable,
+                       array_values( $varMap ),
+                       $conds,
+                       $fname,
+                       $selectOptions,
+                       $selectJoinConds
+               );
 
                $sql = "INSERT $insertOptions" .
-                       " INTO $destTable (" . implode( ',', array_keys( 
$varMap ) ) . ')' .
-                       " SELECT $startOpts " . implode( ',', $varMap ) .
-                       " FROM $srcTable $useIndex $ignoreIndex ";
-
-               if ( $conds != '*' ) {
-                       if ( is_array( $conds ) ) {
-                               $conds = $this->makeList( $conds, 
self::LIST_AND );
-                       }
-                       $sql .= " WHERE $conds";
-               }
-
-               $sql .= " $tailOpts";
+                       " INTO $destTable (" . implode( ',', array_keys( 
$varMap ) ) . ') ' .
+                       $selectSql;
 
                return $this->query( $sql, $fname );
        }
diff --git a/includes/libs/rdbms/database/DatabaseMssql.php 
b/includes/libs/rdbms/database/DatabaseMssql.php
index 782727a..8f3cab8 100644
--- a/includes/libs/rdbms/database/DatabaseMssql.php
+++ b/includes/libs/rdbms/database/DatabaseMssql.php
@@ -717,11 +717,12 @@
         * @param string $fname
         * @param array $insertOptions
         * @param array $selectOptions
+        * @param array $selectJoinConds
         * @return null|ResultWrapper
         * @throws Exception
         */
        public function nativeInsertSelect( $destTable, $srcTable, $varMap, 
$conds, $fname = __METHOD__,
-               $insertOptions = [], $selectOptions = []
+               $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        ) {
                $this->mScrollableCursor = false;
                try {
@@ -732,7 +733,8 @@
                                $conds,
                                $fname,
                                $insertOptions,
-                               $selectOptions
+                               $selectOptions,
+                               $selectJoinConds
                        );
                } catch ( Exception $e ) {
                        $this->mScrollableCursor = true;
diff --git a/includes/libs/rdbms/database/DatabasePostgres.php 
b/includes/libs/rdbms/database/DatabasePostgres.php
index 2fe275b..fe5cfa1 100644
--- a/includes/libs/rdbms/database/DatabasePostgres.php
+++ b/includes/libs/rdbms/database/DatabasePostgres.php
@@ -681,14 +681,13 @@
         * @param string $fname
         * @param array $insertOptions
         * @param array $selectOptions
+        * @param array $selectJoinConds
         * @return bool
         */
        public function nativeInsertSelect(
                $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
-               $insertOptions = [], $selectOptions = []
+               $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        ) {
-               $destTable = $this->tableName( $destTable );
-
                if ( !is_array( $insertOptions ) ) {
                        $insertOptions = [ $insertOptions ];
                }
@@ -705,28 +704,9 @@
                        $savepoint->savepoint();
                }
 
-               if ( !is_array( $selectOptions ) ) {
-                       $selectOptions = [ $selectOptions ];
-               }
-               list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) =
-                       $this->makeSelectOptions( $selectOptions );
-               if ( is_array( $srcTable ) ) {
-                       $srcTable = implode( ',', array_map( [ $this, 
'tableName' ], $srcTable ) );
-               } else {
-                       $srcTable = $this->tableName( $srcTable );
-               }
+               $res = parent::nativeInsertSelect( $destTable, $srcTable, 
$varMap, $conds, $fname,
+                       $insertOptions, $selectOptions, $selectJoinConds );
 
-               $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( 
$varMap ) ) . ')' .
-                       " SELECT $startOpts " . implode( ',', $varMap ) .
-                       " FROM $srcTable $useIndex $ignoreIndex ";
-
-               if ( $conds != '*' ) {
-                       $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
-               }
-
-               $sql .= " $tailOpts";
-
-               $res = (bool)$this->query( $sql, $fname, $savepoint );
                if ( $savepoint ) {
                        $bar = pg_result_error( $this->mLastResult );
                        if ( $bar != false ) {
diff --git a/includes/libs/rdbms/database/IDatabase.php 
b/includes/libs/rdbms/database/IDatabase.php
index bec26a6..d3c365c 100644
--- a/includes/libs/rdbms/database/IDatabase.php
+++ b/includes/libs/rdbms/database/IDatabase.php
@@ -560,11 +560,12 @@
         * @param string|array $cond The condition array. See 
IDatabase::select() for details.
         * @param string $fname The function name of the caller.
         * @param string|array $options The query options. See 
IDatabase::select() for details.
+        * @param string|array $join_conds The query join conditions. See 
IDatabase::select() for details.
         *
         * @return bool|mixed The value from the field, or false on failure.
         */
        public function selectField(
-               $table, $var, $cond = '', $fname = __METHOD__, $options = []
+               $table, $var, $cond = '', $fname = __METHOD__, $options = [], 
$join_conds = []
        );
 
        /**
@@ -581,12 +582,13 @@
         * @param string|array $cond The condition array. See 
IDatabase::select() for details.
         * @param string $fname The function name of the caller.
         * @param string|array $options The query options. See 
IDatabase::select() for details.
+        * @param string|array $join_conds The query join conditions. See 
IDatabase::select() for details.
         *
         * @return bool|array The values from the field, or false on failure
         * @since 1.25
         */
        public function selectFieldValues(
-               $table, $var, $cond = '', $fname = __METHOD__, $options = []
+               $table, $var, $cond = '', $fname = __METHOD__, $options = [], 
$join_conds = []
        );
 
        /**
@@ -1239,12 +1241,14 @@
         *    IDatabase::insert() for details.
         * @param array $selectOptions Options for the SELECT part of the 
query, see
         *    IDatabase::select() for details.
+        * @param array $selectJoinConds Join conditions for the SELECT part of 
the query, see
+        *    IDatabase::select() for details.
         *
         * @return IResultWrapper
         */
        public function insertSelect( $destTable, $srcTable, $varMap, $conds,
                $fname = __METHOD__,
-               $insertOptions = [], $selectOptions = []
+               $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        );
 
        /**

-- 
To view, visit https://gerrit.wikimedia.org/r/358054
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0e6a9e6daa510639d3212641606047a5db96c500
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Anomie <bjor...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to