Database: Allow selectFieldValues() to accept SQL fragments
authorBrad Jorsch <bjorsch@wikimedia.org>
Wed, 17 Oct 2018 15:26:51 +0000 (11:26 -0400)
committerLegoktm <legoktm@member.fsf.org>
Sun, 21 Oct 2018 15:41:01 +0000 (15:41 +0000)
The documentation says "This must be a valid SQL fragment", but as
written it breaks if given anything other than a field name. It's easy
enough to fix by adding an alias to the internal select() call.

Bug: T201781
Change-Id: I76428af6d3aadc266254fdb24109a0ac2db3761f
(cherry picked from commit c5a5b022400318e52638a4d34369ddbb74d7a21b)

includes/libs/rdbms/database/Database.php
tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php

index 896774f..2b5aaf5 100644 (file)
@@ -1503,14 +1503,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $options = [ $options ];
                }
 
-               $res = $this->select( $table, $var, $cond, $fname, $options, $join_conds );
+               $res = $this->select( $table, [ 'value' => $var ], $cond, $fname, $options, $join_conds );
                if ( $res === false ) {
                        return false;
                }
 
                $values = [];
                foreach ( $res as $row ) {
-                       $values[] = $row->$var;
+                       $values[] = $row->value;
                }
 
                return $values;
index cf10801..ab2f11b 100644 (file)
@@ -2047,4 +2047,21 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                $this->assertLastSql( 'BEGIN; SELECT 1; COMMIT' );
                $this->assertEquals( 0, $this->database->trxLevel() );
        }
+
+       /**
+        * @covers Wikimedia\Rdbms\Database::selectFieldValues()
+        */
+       public function testSelectFieldValues() {
+               $this->database->forceNextResult( [
+                       (object)[ 'value' => 'row1' ],
+                       (object)[ 'value' => 'row2' ],
+                       (object)[ 'value' => 'row3' ],
+               ] );
+
+               $this->assertSame(
+                       [ 'row1', 'row2', 'row3' ],
+                       $this->database->selectFieldValues( 'table', 'table.field', 'conds', __METHOD__ )
+               );
+               $this->assertLastSql( 'SELECT table.field AS value FROM table WHERE conds' );
+       }
 }
index e328cba..444a946 100644 (file)
@@ -609,4 +609,5 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
                $this->db->dbSchema( $old );
                $this->assertNotEquals( 'xxx', $this->db->dbSchema() );
        }
+
 }