Fix selection of related articles for old MySQL versions
authorTim Düsterhus <duesterhus@woltlab.com>
Mon, 24 Aug 2020 09:54:19 +0000 (11:54 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Mon, 24 Aug 2020 10:22:17 +0000 (12:22 +0200)
MySQL < 5.7 and apparently MariaDB up to at least 10.3 is unable to deduce
that there can only be exactly a single row from the `article` table, because
it is functionally dependent on `tag_to_object.objectID`.

Help them out by using `MAX` which effectively does nothing, because we're
taking the `MAX` of a single item.

Fixes #3528.

wcfsetup/install/files/lib/page/AbstractArticlePage.class.php

index 95340a1824c308b217e36ef2f7863bc5c7f44a2a..3b364bbc5cc3cd7ab4f0339ad407b5d7dc24d31d 100644 (file)
@@ -141,7 +141,7 @@ abstract class AbstractArticlePage extends AbstractPage {
                                $conditionBuilder->add('tag_to_object.objectTypeID = ?', [TagEngine::getInstance()->getObjectTypeID('com.woltlab.wcf.article')]);
                                $conditionBuilder->add('tag_to_object.tagID IN (?)', [array_keys($this->tags)]);
                                $conditionBuilder->add('tag_to_object.objectID <> ?', [$this->articleContentID]);
-                               $sql = "SELECT          article.articleID, COUNT(*) AS count
+                               $sql = "SELECT          MAX(article.articleID), COUNT(*) AS count
                                        FROM            wcf" . WCF_N . "_tag_to_object tag_to_object
                                        INNER JOIN      wcf" . WCF_N . "_article_content article_content
                                        ON              tag_to_object.objectID = article_content.articleContentID
@@ -150,7 +150,7 @@ abstract class AbstractArticlePage extends AbstractPage {
                                        " . $conditionBuilder . "
                                        GROUP BY        tag_to_object.objectID
                                        HAVING          COUNT(*) >= " . round(count($this->tags) * ARTICLE_RELATED_ARTICLES_MATCH_THRESHOLD / 100) . "
-                                       ORDER BY        count DESC, article.time DESC";
+                                       ORDER BY        count DESC, MAX(article.time) DESC";
                                $statement = WCF::getDB()->prepareStatement($sql, ARTICLE_RELATED_ARTICLES);
                                $statement->execute($conditionBuilder->getParameters());
                                $articleIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);