Produce proper `CAST` for `DECIMAL` and `NUMERIC` in Meta Query. Adds a bunch of unit tests.

Props ericlewis.
Fixes #23033.



git-svn-id: https://develop.svn.wordpress.org/trunk@26055 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Scott Taylor 2013-11-08 23:10:41 +00:00
parent 8ee904343b
commit 047f7fb8bd
3 changed files with 168 additions and 2 deletions

View File

@ -707,7 +707,7 @@ class WP_Meta_Query {
$meta_type = strtoupper( $type );
if ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED', 'NUMERIC' ) ) )
if ( ! preg_match( '/^(?:BINARY|CHAR|DATE|DATETIME|SIGNED|UNSIGNED|TIME|NUMERIC(?:\(\d+(?:,\s?\d+)?\))?|DECIMAL(?:\(\d+(?:,\s?\d+)?\))?)$/', $meta_type ) )
return 'CHAR';
if ( 'NUMERIC' == $meta_type )

View File

@ -108,7 +108,7 @@ class Tests_Meta_Query extends WP_UnitTestCase {
/**
* @ticket 22967
*/
*/
function test_null_value_sql() {
global $wpdb;
@ -119,4 +119,37 @@ class Tests_Meta_Query extends WP_UnitTestCase {
$this->assertEquals( 1, substr_count( $sql['where'], "CAST($wpdb->postmeta.meta_value AS CHAR) = '')" ) );
}
/**
* @ticket 23033
*/
function test_get_cast_for_type() {
$query = new WP_Meta_Query();
$this->assertEquals( 'BINARY', $query->get_cast_for_type( 'BINARY' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'CHAR' ) );
$this->assertEquals( 'DATE', $query->get_cast_for_type( 'DATE' ) );
$this->assertEquals( 'DATETIME', $query->get_cast_for_type( 'DATETIME' ) );
$this->assertEquals( 'SIGNED', $query->get_cast_for_type( 'SIGNED' ) );
$this->assertEquals( 'UNSIGNED', $query->get_cast_for_type( 'UNSIGNED' ) );
$this->assertEquals( 'TIME', $query->get_cast_for_type( 'TIME' ) );
$this->assertEquals( 'SIGNED', $query->get_cast_for_type( 'NUMERIC' ) );
$this->assertEquals( 'NUMERIC(10)', $query->get_cast_for_type( 'NUMERIC(10)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'NUMERIC( 10)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'NUMERIC( 10 )' ) );
$this->assertEquals( 'NUMERIC(10, 5)', $query->get_cast_for_type( 'NUMERIC(10, 5)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'NUMERIC(10, 5)' ) );
$this->assertEquals( 'NUMERIC(10,5)', $query->get_cast_for_type( 'NUMERIC(10,5)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'NUMERIC( 10, 5 )' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'NUMERIC(10, 5 )' ) );
$this->assertEquals( 'DECIMAL', $query->get_cast_for_type( 'DECIMAL' ) );
$this->assertEquals( 'DECIMAL(10)', $query->get_cast_for_type( 'DECIMAL(10)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'DECIMAL( 10 )' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'DECIMAL( 10)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'DECIMAL(10 )' ) );
$this->assertEquals( 'DECIMAL(10, 5)', $query->get_cast_for_type( 'DECIMAL(10, 5)' ) );
$this->assertEquals( 'DECIMAL(10,5)', $query->get_cast_for_type( 'DECIMAL(10,5)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'DECIMAL(10, 5)' ) );
$this->assertEquals( 'CHAR', $query->get_cast_for_type( 'ANYTHING ELSE' ) );
}
}

View File

@ -199,6 +199,139 @@ class Tests_Post_Query extends WP_UnitTestCase {
$this->assertEquals( 0, count( $posts ) );
}
/**
* @ticket 23033
*/
function test_meta_query_decimal_results() {
$post_1 = $this->factory->post->create();
$post_2 = $this->factory->post->create();
$post_3 = $this->factory->post->create();
$post_4 = $this->factory->post->create();
update_post_meta( $post_1, 'decimal_value', '-0.3' );
update_post_meta( $post_2, 'decimal_value', '0.23409844' );
update_post_meta( $post_3, 'decimal_value', '0.3' );
update_post_meta( $post_4, 'decimal_value', '0.4' );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => '.300',
'compare' => '=',
'type' => 'DECIMAL(10,2)'
)
),
) );
$this->assertEquals( array( $post_3 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => '0.35',
'compare' => '>',
'type' => 'DECIMAL(10,2)'
)
),
) );
$this->assertEquals( array( $post_4 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => '0.3',
'compare' => '>=',
'type' => 'DECIMAL(10,2)'
)
),
) );
$this->assertEquals( array( $post_3, $post_4 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => '0',
'compare' => '<',
'type' => 'DECIMAL(10,2)'
)
),
) );
$this->assertEquals( array( $post_1 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => '0.3',
'compare' => '<=',
'type' => 'DECIMAL(10,2)'
)
),
) );
$this->assertEquals( array( $post_1, $post_2, $post_3 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => array( 0.23409845, .31 ),
'compare' => 'BETWEEN',
'type' => 'DECIMAL(10, 10)'
)
),
) );
$this->assertEquals( array( $post_3 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => array( 0.23409845, .31 ),
'compare' => 'NOT BETWEEN',
'type' => 'DECIMAL(10,10)'
)
),
) );
$this->assertEquals( array( $post_1, $post_2, $post_4 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => '.3',
'compare' => 'LIKE',
'type' => 'DECIMAL(10,2)'
)
),
) );
$this->assertEquals( array( $post_1, $post_3 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'decimal_value',
'value' => '.3',
'compare' => 'NOT LIKE',
'type' => 'DECIMAL(10,2)'
)
),
) );
$this->assertEquals( array( $post_2, $post_4 ), wp_list_pluck( $query->posts, 'ID' ) );
$query = new WP_Query( array(
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_key' => 'decimal_value',
'meta_type' => 'DECIMAL(10, 2)'
) );
$this->assertEquals( array( $post_4, $post_3, $post_2, $post_1 ), wp_list_pluck( $query->posts, 'ID' ) );
}
/**
* @ticket 20604
*/