In the off chance something called this, it would break all
sorts of code that expects that either query result functions
either succeed or throw an error.
Callers are not expected to have to check if the result of
a query is meaningful or false due to an error.
Change-Id: I0b4fe1403f55a399ffd40817ed12f857087d6f83
The SQL standard supports parenthesized joins like
a JOIN (b JOIN c ON (...)) ON (...)
But it doesn't support parenthesizing a single table name, i.e. a
one-table "join", like
a JOIN (b) ON (...)
Detect the degenerate single-table case and omit the parentheses.
Bug: T181674
Change-Id: I82cacd80465092aa67ff19bdcfd6682001bf12ab
SQL supports parentheses for grouping in the FROM clause.[1] This is
useful when you want to left-join against a join of other tables.
For example, say you have tables 'a', 'b', and 'c'. You want all rows
from 'a', along with rows from 'b' + 'c' only where both of those
exist.
SELECT * FROM a LEFT JOIN b ON (a_b = b_id) JOIN c ON (b_c = c_id)
doesn't work, it'll only give you the rows where 'c' exists.
SELECT * FROM a LEFT JOIN b ON (a_b = b_id) LEFT JOIN c ON (b_c = c_id)
doesn't work either, it'll give you rows from 'b' without a
corresponding row in 'c'. What you need to do is
SELECT * FROM a LEFT JOIN (b JOIN c ON (b_c = c_id)) ON (a_b = b_id)
This patch implements this by extending the syntax for the $table
parameter to IDatabase::select(). When passing an array of tables, if a
value in the array is itself an array that is interpreted as a request
for a parenthesized join. To produce the example above, you'd do
something like
$db->select(
[ 'a', 'nest' => [ 'b', 'c' ] ],
'*',
[],
__METHOD__,
[],
[
'c' => [ 'JOIN', 'b_c = c_id ],
'nest' => [ 'LEFT JOIN', 'a_b = b_id' ],
]
);
[1]: In standards as far back as SQL-1992 (I couldn't find an earlier
version), and it seems to be supported by at least MySQL 5.6, MariaDB
10.1.28, PostgreSQL 9.3, PostgreSQL 10.0, Oracle 11g R2, SQLite 3.20.1,
and MSSQL 2014 (from local testing and sqlfiddle.com).
Change-Id: I1e0a77381e06d885650a94f53847fb82f01c2694
Only missing cases where 'USE INDEX' and 'IGNORE INDEX'.
The test doesn't do much since the underlying methods are no-ops
by default, but at least it ensures there are no PHP errors from
these branches.
We can later re-use some of these test cases in tests specific
to one backend.
Change-Id: Id004a2ae41efaa7a367f964013e25d98ecc591ff
If no writes started a transaction yet, the callback would run
but not commit (by design, joining the request round). Later
writes will then pile on top of it.
The point of this method is to avoid such cases, so this edge
case has been fixed.
Change-Id: I9b44b19261d679de4aff6e44a9cfeb4f684ce02e
* Add case for `$tables[0] == ' '`.
* Add case for `$tables == ''`.
* Add case for 'DISTINCT' option.
* Add case for 'FOR UPDATE' option.
* Add case for 'LOCK IN SHARE MODE' option.
* Add case for 'EXPLAIN' option.
Change-Id: I4a5f4754bc30d31ec35a085f39321fd358b6aa49
Many of the main methods here have, over the years, been split up
into several protected/private methods.
Change-Id: I1b8489b1c61c0294288442a0a0cd28c9fa77f82e
* Move DatabaseTest and DatabaseSQLTest to libs,
and remove MediaWikiTestCase dependency.
* Refactor DatabaseTest to be a test of the Database abstract class,
not of whatever current DB backend is configured by LocalSettings.
- Remove most switches/conditionals and other tests for specific
database backends. Move those to individual test classes for
those backends instead.
- Some tests appear to have been integration tests for the PHP driver
and/or the db backend itself. Moved to a new DatabaseIntegrationTest.
- Now that only the abstract Database is invoked, the test runs a bit
faster (no real connections/queries).
* Add missing @covers tags, and remove or fix broken ones
(follows-up 26e52f0c49).
Change-Id: I9dc4a558e701d00e95789e7eb8e02926783b65ad
Beyond giving a more complete picture, this can be used to adjust
the PostSend criteria to log master queries under the restInPeace()
entry point.
Bug: T166199
Change-Id: If5cf704ba10291d0eba63e66b388666fde3ca649
The default will remain PHPUnit 4.x due to PHP 5.5 support.
But, we should allow developers to run tests with newer PHPUnit
versions which are noticably faster (especially for code coverage
reports).
* <https://github.com/sebastianbergmann/phpunit/wiki/Release-Announcement-for-PHPUnit-5.4.0>
PHPUnit 5 deprecates the getMock() shortcut for getMockBuilder()->getMock().
It instead introduces the shortcut createMock() which has better defaults
than getMockBuilder(). For example, it sets 'disableArgumentCloning' and
other things by default.
Going forward, code should either use getMockBuilder directly and configure
it using the setter methods (instead of the confusing variadic arguments
of getMock) or simply use the new minimalistic createMock method. This patch
backports the createMock method to MediaWikiTestCase so that we can start
using it.
Change-Id: I091c0289b21d2b1c876adba89529dc3e72b99af2
This moves and refactors the ConsistentReadConnectionManager
from Wikibase into the core rdbms lib.
The refactoring also creates a generic ConnectionManager.
This relates to Iff20a22f9f2bc7ceefd6defc0ed9a494a6fe62c0
which introduced a DB factory / connection manager in
an extension revealing the need for this in multiple places.
Change-Id: I0c58e15aed5bed88323d18cb95e5008f8d3381c5
* Add DatabaseDomain class to handle passing domains around.
It also can be cast to and from strings, which are of the same
format as wfWikiId() except with hyphens escaped.
* Make IDatabase::getDomainID() use these IDs so they can be
passed into LoadBalancer::getConnection() and friends without
breaking on sites with a hyphen in the DB name.
* Add more LBFactory unit tests for domains.
Bug: T145840
Change-Id: Icfed62b251af8cef706a899197c3ccdb730ef4d1