diff --git a/lib/Database.php b/lib/Database.php index 87a3c56f..68cc43df 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -813,7 +813,8 @@ class Database { public function subscriptionList(string $user, $folder = null, bool $recursive = true, int $id = null): Db\Result { // validate inputs $folder = $this->folderValidateId($user, $folder)['id']; - // create a complex query + // compile the query + $integerType = $this->db->sqlToken("integer"); $q = new Query( "WITH RECURSIVE topmost(f_id, top) as ( @@ -834,7 +835,7 @@ class Database { i.url as icon_url, folder, t.top as top_folder, d.name as folder_name, dt.name as top_folder_name, coalesce(s.title, f.title) as title, - coalesce((articles - hidden - marked), coalesce(articles,0)) as unread + cast(coalesce((articles - hidden - marked), coalesce(articles,0)) as $integerType) as unread -- this cast is required for MySQL for unclear reasons from arsse_subscriptions as s join arsse_feeds as f on f.id = s.feed left join topmost as t on t.f_id = s.folder @@ -2209,13 +2210,14 @@ class Database { * @param boolean $includeEmpty Whether to include (true) or supress (false) labels which have no articles assigned to them */ public function labelList(string $user, bool $includeEmpty = true): Db\Result { + $integerType = $this->db->sqlToken("integer"); return $this->db->prepareArray( "SELECT * FROM ( SELECT id, name, - coalesce(articles - coalesce(hidden, 0), 0) as articles, - coalesce(marked, 0) as \"read\" + cast(coalesce(articles - coalesce(hidden, 0), 0) as $integerType) as articles, -- this cast is required for MySQL for unclear reasons + cast(coalesce(marked, 0) as $integerType) as \"read\" -- this cast is required for MySQL for unclear reasons from arsse_labels left join ( SELECT label, sum(assigned) as articles from arsse_label_members group by label diff --git a/lib/Db/MySQL/Driver.php b/lib/Db/MySQL/Driver.php index 532d05d3..10bc766d 100644 --- a/lib/Db/MySQL/Driver.php +++ b/lib/Db/MySQL/Driver.php @@ -83,6 +83,8 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { return '"utf8mb4_unicode_ci"'; case "asc": return ""; + case "integer": + return "signed integer"; default: return $token; } diff --git a/tests/cases/Db/BaseDriver.php b/tests/cases/Db/BaseDriver.php index 0999d3a7..fe7f344c 100644 --- a/tests/cases/Db/BaseDriver.php +++ b/tests/cases/Db/BaseDriver.php @@ -384,6 +384,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest { $greatest = $this->drv->sqlToken("GrEatESt"); $nocase = $this->drv->sqlToken("noCASE"); $like = $this->drv->sqlToken("liKe"); + $integer = $this->drv->sqlToken("InTEGer"); $asc = $this->drv->sqlToken("asc"); $desc = $this->drv->sqlToken("desc"); $least = $this->drv->sqlToken("leASt"); @@ -394,6 +395,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest { $this->assertSame("Z", $this->drv->query("SELECT $greatest('Z', 'A')")->getValue()); $this->assertSame("Z", $this->drv->query("SELECT 'Z' collate $nocase")->getValue()); $this->assertSame("Z", $this->drv->query("SELECT 'Z' where 'Z' $like 'z'")->getValue()); + $this->assertEquals(1, $this->drv->query("SELECT CAST((1=1) as $integer)")->getValue()); $this->assertEquals([null, 1, 2], array_column($this->drv->query("SELECT 1 as t union select null as t union select 2 as t order by t $asc")->getAll(), "t")); $this->assertEquals([2, 1, null], array_column($this->drv->query("SELECT 1 as t union select null as t union select 2 as t order by t $desc")->getAll(), "t")); } diff --git a/tests/lib/AbstractTest.php b/tests/lib/AbstractTest.php index d352bd6d..a22913df 100644 --- a/tests/lib/AbstractTest.php +++ b/tests/lib/AbstractTest.php @@ -518,10 +518,6 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase { // stringify our expectations if necessary if (static::$stringOutput ?? false) { $expected = $this->stringify($expected); - // MySQL is extra-special and mixes strings and integers, so we cast the data, too - if ((static::$implementation ?? "") === "MySQL") { - $data = $this->stringify($data); - } } $this->assertCount(sizeof($expected), $data, "Number of result rows (".sizeof($data).") differs from number of expected rows (".sizeof($expected).")"); if (sizeof($expected)) {