MySQL ANY_VALUE with fallback to MIN
https://github.com/friendica/friendica/issues/3322
This commit is contained in:
		
					parent
					
						
							
								38e7a0f793
							
						
					
				
			
			
				commit
				
					
						1058b28cea
					
				
			
		
					 7 changed files with 42 additions and 22 deletions
				
			
		|  | @ -3099,13 +3099,14 @@ use \Friendica\Core\Config; | ||||||
| 
 | 
 | ||||||
| 		$scale = (x($_REQUEST, 'scale') ? intval($_REQUEST['scale']) : false); | 		$scale = (x($_REQUEST, 'scale') ? intval($_REQUEST['scale']) : false); | ||||||
| 		$scale_sql = ($scale === false ? "" : sprintf("and scale=%d",intval($scale))); | 		$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`,
 | 		$r = q("select %s ANY_VALUE(`resource-id`) AS `resource-id`, ANY_VALUE(`created`) AS `created`,
 | ||||||
| 					`type`, `height`, `width`, `datasize`, `profile`, min(`scale`) as minscale, max(`scale`) as maxscale | 				ANY_VALUE(`edited`) AS `edited`, ANY_VALUE(`title`) AS `title`, ANY_VALUE(`desc`) AS `desc`, | ||||||
| 				from photo where `uid` = %d and `resource-id` = '%s' %s | 				ANY_VALUE(`album`) AS `album`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`, | ||||||
| 				group by `resource-id`, `created`, `edited`, `title`, `desc`, `album`, `filename`, | 				ANY_VALUE(`height`) AS `height`, ANY_VALUE(`width`) AS `width`, ANY_VALUE(`datasize`) AS `datasize`, | ||||||
| 					`type`, `height`, `width`, `datasize`, `profile`",
 | 				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, | 			$data_sql, | ||||||
| 			intval(local_user()), | 			intval(local_user()), | ||||||
| 			dbesc($_REQUEST['photo_id']), | 			dbesc($_REQUEST['photo_id']), | ||||||
|  |  | ||||||
|  | @ -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);
 | // Function: q($sql,$args);
 | ||||||
| // Description: execute SQL query with printf style args.
 | // Description: execute SQL query with printf style args.
 | ||||||
| // Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
 | // Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
 | ||||||
|  | @ -514,6 +522,7 @@ function q($sql) { | ||||||
| 	unset($args[0]); | 	unset($args[0]); | ||||||
| 
 | 
 | ||||||
| 	if ($db && $db->connected) { | 	if ($db && $db->connected) { | ||||||
|  | 		$sql = any_value_fallback($sql); | ||||||
| 		$stmt = @vsprintf($sql,$args); // Disabled warnings
 | 		$stmt = @vsprintf($sql,$args); // Disabled warnings
 | ||||||
| 		//logger("dba: q: $stmt", LOGGER_ALL);
 | 		//logger("dba: q: $stmt", LOGGER_ALL);
 | ||||||
| 		if ($stmt === false) | 		if ($stmt === false) | ||||||
|  | @ -550,6 +559,7 @@ function qu($sql) { | ||||||
| 	unset($args[0]); | 	unset($args[0]); | ||||||
| 
 | 
 | ||||||
| 	if ($db && $db->connected) { | 	if ($db && $db->connected) { | ||||||
|  | 		$sql = any_value_fallback($sql); | ||||||
| 		$stmt = @vsprintf($sql,$args); // Disabled warnings
 | 		$stmt = @vsprintf($sql,$args); // Disabled warnings
 | ||||||
| 		if ($stmt === false) | 		if ($stmt === false) | ||||||
| 			logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG); | 			logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG); | ||||||
|  |  | ||||||
|  | @ -516,8 +516,9 @@ function notifier_run(&$argv, &$argc){ | ||||||
| 				$r0 = Diaspora::relay_list(); | 				$r0 = Diaspora::relay_list(); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			$r1 = q("SELECT DISTINCT(`batch`), `id`, `name`,`network` FROM `contact` WHERE `network` = '%s'
 | 			$r1 = q("SELECT `batch`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`name`) AS `name`, ANY_VALUE(`network`) AS `network`
 | ||||||
| 				AND `uid` = %d AND `rel` != %d AND NOT `blocked` AND NOT `pending` AND NOT `archive` GROUP BY `batch`, `id` ORDER BY rand()",
 | 				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), | 				dbesc(NETWORK_DIASPORA), | ||||||
| 				intval($owner['uid']), | 				intval($owner['uid']), | ||||||
| 				intval(CONTACT_IS_SHARING) | 				intval(CONTACT_IS_SHARING) | ||||||
|  |  | ||||||
|  | @ -48,20 +48,20 @@ function photo_albums($uid, $update = false) { | ||||||
| 		if (!Config::get('system', 'no_count', false)) { | 		if (!Config::get('system', 'no_count', false)) { | ||||||
| 			/// @todo This query needs to be renewed. It is really slow
 | 			/// @todo This query needs to be renewed. It is really slow
 | ||||||
| 			// At this time we just store the data in the cache
 | 			// 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` | 				FROM `photo` | ||||||
| 				WHERE `uid` = %d  AND `album` != '%s' AND `album` != '%s' $sql_extra | 				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), | 				intval($uid), | ||||||
| 				dbesc('Contact Photos'), | 				dbesc('Contact Photos'), | ||||||
| 				dbesc(t('Contact Photos')) | 				dbesc(t('Contact Photos')) | ||||||
| 			); | 			); | ||||||
| 		} else { | 		} else { | ||||||
| 			// This query doesn't do the count and is much faster
 | 			// 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` | 				FROM `photo` | ||||||
| 				WHERE `uid` = %d  AND `album` != '%s' AND `album` != '%s' $sql_extra | 				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), | 				intval($uid), | ||||||
| 				dbesc('Contact Photos'), | 				dbesc('Contact Photos'), | ||||||
| 				dbesc(t('Contact Photos')) | 				dbesc(t('Contact Photos')) | ||||||
|  |  | ||||||
|  | @ -349,8 +349,8 @@ function message_content(App $a) { | ||||||
| 
 | 
 | ||||||
| 		$o .= $header; | 		$o .= $header; | ||||||
| 
 | 
 | ||||||
| 		$r = q("SELECT count(*) AS `total` FROM `mail`
 | 		$r = q("SELECT count(*) AS `total` FROM `mail`, ANY_VALUE(`created`) AS `created`
 | ||||||
| 			WHERE `mail`.`uid` = %d GROUP BY `parent-uri`, `created` ORDER BY `created` DESC",
 | 			WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `created` DESC",
 | ||||||
| 			intval(local_user()) | 			intval(local_user()) | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  | @ -528,12 +528,16 @@ function message_content(App $a) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function get_messages($user, $lstart, $lend) { | 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`,
 | 	return q("SELECT max(`mail`.`created`) AS `mailcreated`, min(`mail`.`seen`) AS `mailseen`,
 | ||||||
| 		`mail`.* , `contact`.`name`, `contact`.`url`, `contact`.`thumb` , `contact`.`network`, | 		ANY_VALUE(`mail`.`id`), ANY_VALUE(`mail`.`uid`), ANY_VALUE(`mail`.`guid`), ANY_VALUE(`mail`.`from-name`), | ||||||
| 		count( * ) as count | 		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` | 		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) | 		intval($user), intval($lstart), intval($lend) | ||||||
| 	); | 	); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1240,8 +1240,10 @@ function photos_content(App $a) { | ||||||
| 			$order = 'DESC'; | 			$order = 'DESC'; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		$r = q("SELECT `resource-id`, `id`, `filename`, type, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s'
 | 		$r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`,
 | ||||||
| 			AND `scale` <= 4 $sql_extra GROUP BY `resource-id`, `id` ORDER BY `created` $order LIMIT %d , %d",
 | 			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), | 			intval($owner_uid), | ||||||
| 			dbesc($album), | 			dbesc($album), | ||||||
| 			intval($a->pager['start']), | 			intval($a->pager['start']), | ||||||
|  |  | ||||||
|  | @ -356,9 +356,11 @@ function videos_content(App $a) { | ||||||
| 		$a->set_pager_itemspage(20); | 		$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%%' | 		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->data['user']['uid']), | ||||||
| 		intval($a->pager['start']), | 		intval($a->pager['start']), | ||||||
| 		intval($a->pager['itemspage']) | 		intval($a->pager['itemspage']) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue