From 1058b28ceabcec802932fc33bb79e6ce7814f945 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 15 Apr 2017 00:42:44 +0200 Subject: [PATCH] MySQL ANY_VALUE with fallback to MIN https://github.com/friendica/friendica/issues/3322 --- include/api.php | 13 +++++++------ include/dba.php | 10 ++++++++++ include/notifier.php | 5 +++-- include/photos.php | 8 ++++---- mod/message.php | 16 ++++++++++------ mod/photos.php | 6 ++++-- mod/videos.php | 6 ++++-- 7 files changed, 42 insertions(+), 22 deletions(-) diff --git a/include/api.php b/include/api.php index 477eb94b4e..75f8ab069a 100644 --- a/include/api.php +++ b/include/api.php @@ -3099,13 +3099,14 @@ use \Friendica\Core\Config; $scale = (x($_REQUEST, 'scale') ? intval($_REQUEST['scale']) : false); $scale_sql = ($scale === false ? "" : sprintf("and scale=%d",intval($scale))); - $data_sql = ($scale === false ? "" : "data, "); + $data_sql = ($scale === false ? "" : "ANY_VALUE(data) AS data,"); - $r = q("select %s `resource-id`, `created`, `edited`, `title`, `desc`, `album`, `filename`, - `type`, `height`, `width`, `datasize`, `profile`, min(`scale`) as minscale, max(`scale`) as maxscale - from photo where `uid` = %d and `resource-id` = '%s' %s - group by `resource-id`, `created`, `edited`, `title`, `desc`, `album`, `filename`, - `type`, `height`, `width`, `datasize`, `profile`", + $r = q("select %s ANY_VALUE(`resource-id`) AS `resource-id`, ANY_VALUE(`created`) AS `created`, + ANY_VALUE(`edited`) AS `edited`, ANY_VALUE(`title`) AS `title`, ANY_VALUE(`desc`) AS `desc`, + ANY_VALUE(`album`) AS `album`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`, + ANY_VALUE(`height`) AS `height`, ANY_VALUE(`width`) AS `width`, ANY_VALUE(`datasize`) AS `datasize`, + ANY_VALUE(`profile`) AS `profile`, min(`scale`) as minscale, max(`scale`) as maxscale + from photo where `uid` = %d and `resource-id` = '%s' %s", $data_sql, intval(local_user()), dbesc($_REQUEST['photo_id']), diff --git a/include/dba.php b/include/dba.php index 62728acaed..96df072cfa 100644 --- a/include/dba.php +++ b/include/dba.php @@ -504,6 +504,14 @@ function dbesc($str) { } } +function any_value_fallback($sql) { + //Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5). + //ANY_VALUE() is available from MySQL 5.7 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html + //A standard fallback is to use MIN(), or nothing () in old MySQL 5.6- + //TODO: Skip this line when we know we are on a platform supporting ANY_VALUE() + return str_ireplace('ANY_VALUE(', 'MIN(', $sql); +} + // Function: q($sql,$args); // Description: execute SQL query with printf style args. // Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d", @@ -514,6 +522,7 @@ function q($sql) { unset($args[0]); if ($db && $db->connected) { + $sql = any_value_fallback($sql); $stmt = @vsprintf($sql,$args); // Disabled warnings //logger("dba: q: $stmt", LOGGER_ALL); if ($stmt === false) @@ -550,6 +559,7 @@ function qu($sql) { unset($args[0]); if ($db && $db->connected) { + $sql = any_value_fallback($sql); $stmt = @vsprintf($sql,$args); // Disabled warnings if ($stmt === false) logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG); diff --git a/include/notifier.php b/include/notifier.php index ed34288e8f..370611b4eb 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -516,8 +516,9 @@ function notifier_run(&$argv, &$argc){ $r0 = Diaspora::relay_list(); } - $r1 = q("SELECT DISTINCT(`batch`), `id`, `name`,`network` FROM `contact` WHERE `network` = '%s' - AND `uid` = %d AND `rel` != %d AND NOT `blocked` AND NOT `pending` AND NOT `archive` GROUP BY `batch`, `id` ORDER BY rand()", + $r1 = q("SELECT `batch`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`name`) AS `name`, ANY_VALUE(`network`) AS `network` + FROM `contact` WHERE `network` = '%s' + AND `uid` = %d AND `rel` != %d AND NOT `blocked` AND NOT `pending` AND NOT `archive` GROUP BY `batch` ORDER BY rand()", dbesc(NETWORK_DIASPORA), intval($owner['uid']), intval(CONTACT_IS_SHARING) diff --git a/include/photos.php b/include/photos.php index 02d1b17403..b273c1726b 100644 --- a/include/photos.php +++ b/include/photos.php @@ -48,20 +48,20 @@ function photo_albums($uid, $update = false) { if (!Config::get('system', 'no_count', false)) { /// @todo This query needs to be renewed. It is really slow // At this time we just store the data in the cache - $albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album` + $albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, ANY_VALUE(`created`) AS `created` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra - GROUP BY `album`, `created` ORDER BY `created` DESC", + GROUP BY `album` ORDER BY `created` DESC", intval($uid), dbesc('Contact Photos'), dbesc(t('Contact Photos')) ); } else { // This query doesn't do the count and is much faster - $albums = qu("SELECT DISTINCT(`album`), '' AS `total` + $albums = qu("SELECT DISTINCT(`album`), '' AS `total`, ANY_VALUE(`created`) AS `created` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra - GROUP BY `album`, `created` ORDER BY `created` DESC", + GROUP BY `album` ORDER BY `created` DESC", intval($uid), dbesc('Contact Photos'), dbesc(t('Contact Photos')) diff --git a/mod/message.php b/mod/message.php index 05a8d36f68..dd13d58be6 100644 --- a/mod/message.php +++ b/mod/message.php @@ -349,8 +349,8 @@ function message_content(App $a) { $o .= $header; - $r = q("SELECT count(*) AS `total` FROM `mail` - WHERE `mail`.`uid` = %d GROUP BY `parent-uri`, `created` ORDER BY `created` DESC", + $r = q("SELECT count(*) AS `total` FROM `mail`, ANY_VALUE(`created`) AS `created` + WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `created` DESC", intval(local_user()) ); @@ -528,12 +528,16 @@ function message_content(App $a) { } function get_messages($user, $lstart, $lend) { - + //TODO: rewritte with a sub-query to get the first message of each private thread with certainty return q("SELECT max(`mail`.`created`) AS `mailcreated`, min(`mail`.`seen`) AS `mailseen`, - `mail`.* , `contact`.`name`, `contact`.`url`, `contact`.`thumb` , `contact`.`network`, - count( * ) as count + ANY_VALUE(`mail`.`id`), ANY_VALUE(`mail`.`uid`), ANY_VALUE(`mail`.`guid`), ANY_VALUE(`mail`.`from-name`), + ANY_VALUE(`mail`.`from-photo`), ANY_VALUE(`mail`.`from-url`), ANY_VALUE(`mail`.`contact-id`), + ANY_VALUE(`mail`.`convid`), ANY_VALUE(`mail`.`title`), ANY_VALUE(`mail`.`body`), ANY_VALUE(`mail`.`seen`), + ANY_VALUE(`mail`.`reply`), ANY_VALUE(`mail`.`replied`), ANY_VALUE(`mail`.`unknown`), + ANY_VALUE(`mail`.`uri`), ANY_VALUE(`mail`.`parent-uri`), ANY_VALUE(`mail`.`created`), + ANY_VALUE(`contact`.`name`), ANY_VALUE(`contact`.`url`), ANY_VALUE(`contact`.`thumb`), ANY_VALUE(`contact`.`network`), FROM `mail` LEFT JOIN `contact` ON `mail`.`contact-id` = `contact`.`id` - WHERE `mail`.`uid` = %d GROUP BY `parent-uri`, `mail`.id ORDER BY `mailcreated` DESC LIMIT %d , %d ", + WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `mailcreated` DESC LIMIT %d , %d ", intval($user), intval($lstart), intval($lend) ); } diff --git a/mod/photos.php b/mod/photos.php index a24cee2559..8e47829774 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -1240,8 +1240,10 @@ function photos_content(App $a) { $order = 'DESC'; } - $r = q("SELECT `resource-id`, `id`, `filename`, type, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s' - AND `scale` <= 4 $sql_extra GROUP BY `resource-id`, `id` ORDER BY `created` $order LIMIT %d , %d", + $r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, + ANY_VALUE(`type`) AS `type`, max(`scale`) AS `scale`, ANY_VALUE(`desc`) as `desc` + FROM `photo` WHERE `uid` = %d AND `album` = '%s' + AND `scale` <= 4 $sql_extra GROUP BY `resource-id` ORDER BY `created` $order LIMIT %d , %d", intval($owner_uid), dbesc($album), intval($a->pager['start']), diff --git a/mod/videos.php b/mod/videos.php index ea2e0d4a24..269d537854 100644 --- a/mod/videos.php +++ b/mod/videos.php @@ -356,9 +356,11 @@ function videos_content(App $a) { $a->set_pager_itemspage(20); } - $r = q("SELECT hash, `id`, `filename`, filetype FROM `attach` + $r = q("SELECT hash, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`created`) AS `created`, + ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`filetype`) as `filetype` + FROM `attach` WHERE `uid` = %d AND filetype LIKE '%%video%%' - $sql_extra GROUP BY hash, `id` ORDER BY `created` DESC LIMIT %d , %d", + $sql_extra GROUP BY hash ORDER BY `created` DESC LIMIT %d , %d", intval($a->data['user']['uid']), intval($a->pager['start']), intval($a->pager['itemspage'])