From 2bbd21f543aee73edd0b55bd23623eb1dd6199e9 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Mon, 20 Apr 2015 04:46:25 +0000 Subject: [PATCH] WPDB: When sanity checking read queries, there are some collations we can skip, for improved performance. Props pento, nacin. See #21212. Built from https://develop.svn.wordpress.org/trunk@32162 git-svn-id: http://core.svn.wordpress.org/trunk@32137 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/version.php | 2 +- wp-includes/wp-db.php | 68 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/wp-includes/version.php b/wp-includes/version.php index db7eb70880..b4ea6adb5c 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.2-RC1-32161'; +$wp_version = '4.2-RC1-32162'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. diff --git a/wp-includes/wp-db.php b/wp-includes/wp-db.php index 08fc3e5565..cdb9eda8c8 100644 --- a/wp-includes/wp-db.php +++ b/wp-includes/wp-db.php @@ -170,6 +170,16 @@ class wpdb { */ protected $check_current_query = true; + /** + * Flag to ensure we don't run into recursion problems when checking the collation. + * + * @since 4.2.0 + * @access private + * @see wpdb::check_safe_collation() + * @var boolean + */ + private $checking_collation = false; + /** * Saved info on the table column * @@ -2038,6 +2048,10 @@ class wpdb { public function get_var( $query = null, $x = 0, $y = 0 ) { $this->func_call = "\$db->get_var(\"$query\", $x, $y)"; + if ( $this->check_safe_collation( $query ) ) { + $this->check_current_query = false; + } + if ( $query ) { $this->query( $query ); } @@ -2066,6 +2080,11 @@ class wpdb { */ public function get_row( $query = null, $output = OBJECT, $y = 0 ) { $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; + + if ( $this->check_safe_collation( $query ) ) { + $this->check_current_query = false; + } + if ( $query ) { $this->query( $query ); } else { @@ -2103,6 +2122,10 @@ class wpdb { * @return array Database query result. Array indexed from 0 by SQL result row number. */ public function get_col( $query = null , $x = 0 ) { + if ( $this->check_safe_collation( $query ) ) { + $this->check_current_query = false; + } + if ( $query ) { $this->query( $query ); } @@ -2131,6 +2154,10 @@ class wpdb { public function get_results( $query = null, $output = OBJECT ) { $this->func_call = "\$db->get_results(\"$query\", $output)"; + if ( $this->check_safe_collation( $query ) ) { + $this->check_current_query = false; + } + if ( $query ) { $this->query( $query ); } else { @@ -2358,6 +2385,47 @@ class wpdb { return false; } + /** + * Check if the query is accessing a collation considered safe on the current version of MySQL. + * + * @since 4.2.0 + * @access protected + * + * @param string $query The query to check. + * @return bool True if the collation is safe, false if it isn't. + */ + protected function check_safe_collation( $query ) { + if ( $this->checking_collation ) { + return true; + } + + $table = $this->get_table_from_query( $query ); + if ( ! $table ) { + return false; + } + + $this->checking_collation = true; + $this->get_table_charset( $table ); + $this->checking_collation = false; + + $table = strtolower( $table ); + if ( empty( $this->col_meta[ $table ] ) ) { + return false; + } + + foreach( $this->col_meta[ $table ] as $col ) { + if ( empty( $col->Collation ) ) { + continue; + } + + if ( ! in_array( $col->Collation, array( 'utf8_general_ci', 'utf8_bin', 'utf8mb4_general_ci', 'utf8mb4_bin' ), true ) ) { + return false; + } + } + + return true; + } + /** * Strips any invalid characters based on value/charset pairs. *