User tests: Successful: Unsuccessful:
Since Pdo driver has process limit in setQuery(), we don't need to process it twice.
See https://github.com/joomla/joomla-cms/blob/staging/libraries/joomla/database/driver/pdo.php#L714
Open any Joomla page with pagination or rows limit in debug mode. You will see double LIMIT in SQL debug console if driver is pdomysql, after this patch, the LIMIT keyword will only appear one.
| Status | New | ⇒ | Pending |
| Labels |
Added:
?
|
||
| Category | ⇒ | SQL |
There is a case will make LIMIT appear 3 times. If someone try to override limit by setQuery() with a query (object or string) which has set limit value. However this issue has exists a long time before this PR. see:
try
{
$db->setQuery($db->getQuery(true)->select('*')->from('#__content')->setLimit(20, 10), 100, 50)->execute();
}
catch (\Exception $e)
{
echo @end($db->getLog());
}SELECT *
FROM fan_content LIMIT 10, 20 LIMIT 100, 50 LIMIT 100, 50This PR can only remove the last 2 LIMIT which set by setQuery(), but the first one which set from query object is still not overridable.
Here is a simple test of this PR:
$db = JFactory::getDbo();
// set string by setQuery()
$db->setQuery('SELECT * FROM #__content', 10, 20)->execute();
echo @end($db->getLog());
echo '<br>';
// set query object by setQuery()
$db->setQuery($db->getQuery(true)->select('*')->from('#__content'), 10, 20)->execute();
echo @end($db->getLog());
echo '<br>';
// set query object with limit
$db->setQuery($db->getQuery(true)->select('*')->from('#__content')->setLimit(20, 10))->execute();
echo @end($db->getLog());
echo '<br>';
// set query object and setQuery() both with limit
try
{
$db->setQuery($db->getQuery(true)->select('*')->from('#__content')->setLimit(20, 10), 100, 50)->execute();
}
catch (\Exception $e)
{
echo @end($db->getLog());
echo '<br>';
}Before patch
SELECT * FROM fan_content LIMIT 10, 20 LIMIT 10, 20
SELECT * FROM fan_content LIMIT 10, 20 LIMIT 10, 20
SELECT * FROM fan_content LIMIT 10, 20
SELECT * FROM fan_content LIMIT 10, 20 LIMIT 100, 50 LIMIT 100, 50After patch
SELECT * FROM fan_content LIMIT 10, 20
SELECT * FROM fan_content LIMIT 10, 20
SELECT * FROM fan_content LIMIT 10, 20
SELECT * FROM fan_content LIMIT 10, 20 LIMIT 100, 50This is still an improvement but something in my gut tells me there's still something being handled incorrectly. I just can't figure out a way to deal with it.
I also think so, maybe we need unittest to make sure everything works correctly, this PR just a begining.
But I need more suggestion about how to continue work for this fix.
I have tested this item
I have tested it and patch removes the double LIMIT keyword from the SQL when using MySQL PDO driver.
Before Patch:
After Patch:
| Category | SQL | ⇒ | SQL Unit Tests |
I have tested this item
| Status | Pending | ⇒ | Ready to Commit |
| Labels |
Added:
?
|
||
| Category | SQL Unit Tests | ⇒ | Libraries |
| Status | Ready to Commit | ⇒ | Fixed in Code Base |
| Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2016-09-05 18:14:20 |
| Closed_By | ⇒ | rdeutz |
| Labels |
Removed:
?
|
||
Something about this feels like a major code smell to me.
JDatabaseDriverPdo::setQuery()ignores the limit and offset values that can be set in both the database driver and the query object and relies on values passed when you callsetQuery(). Plus, this change doesn't account for the fact that casting a query object to string would still runproessLimit()if values are set in the query object.Something definitely needs to be fixed, but at a first glance, this doesn't feel like the "right" fix.