@@ -281,15 +281,60 @@ public function testDeleteWithAliasAndLimit() {
281281 }
282282
283283 public function testCastAsBinary () {
284- $ this ->assertQuery (
285- // Use a confusing alias to make sure it replaces only the correct token
286- "SELECT CAST('ABC' AS BINARY) as `binary`; "
287- );
284+ // Use a confusing alias to make sure it replaces only the correct token
285+ $ this ->assertQuery ( "SELECT CAST('ABC' AS BINARY) as `binary` " );
288286 $ results = $ this ->engine ->get_query_results ();
289287 $ this ->assertCount ( 1 , $ results );
290288 $ this ->assertEquals ( 'ABC ' , $ results [0 ]->binary );
291289 }
292290
291+ public function testBinaryOperator () {
292+ // Use a NOCASE column so plain "=" is case-insensitive. This makes the
293+ // BINARY operator's effect (forcing byte-by-byte comparison) visible.
294+ $ this ->assertQuery ( 'CREATE TABLE t (name TEXT COLLATE NOCASE NOT NULL) ' );
295+ $ this ->assertQuery ( "INSERT INTO t (name) VALUES ('abc'), ('ABC') " );
296+
297+ // Sanity: with NOCASE, plain "=" matches both rows.
298+ $ result = $ this ->assertQuery ( "SELECT name FROM t WHERE name = 'abc' ORDER BY name " );
299+ $ this ->assertCount ( 2 , $ result );
300+
301+ // "= BINARY 'x'" forces byte-by-byte equality.
302+ $ result = $ this ->assertQuery ( "SELECT name FROM t WHERE name = BINARY 'abc' " );
303+ $ this ->assertCount ( 1 , $ result );
304+ $ this ->assertEquals ( 'abc ' , $ result [0 ]->name );
305+
306+ // "BINARY x = 'X'" is symmetric.
307+ $ result = $ this ->assertQuery ( "SELECT name FROM t WHERE BINARY name = 'ABC' " );
308+ $ this ->assertCount ( 1 , $ result );
309+ $ this ->assertEquals ( 'ABC ' , $ result [0 ]->name );
310+
311+ // "ORDER BY BINARY" sorts by byte value ('ABC' before 'abc').
312+ $ result = $ this ->assertQuery ( 'SELECT name FROM t ORDER BY BINARY name ' );
313+ $ this ->assertEquals ( 'ABC ' , $ result [0 ]->name );
314+ $ this ->assertEquals ( 'abc ' , $ result [1 ]->name );
315+
316+ // CAST(expr AS BINARY) = expr
317+ $ result = $ this ->assertQuery ( "SELECT CAST('abc' AS BINARY) = 'abc' AS r " );
318+ $ this ->assertEquals ( 1 , $ result [0 ]->r );
319+
320+ // CONVERT(expr, BINARY) = expr
321+ $ result = $ this ->assertQuery ( "SELECT CONVERT('abc', BINARY) = 'abc' AS r " );
322+ $ this ->assertEquals ( 1 , $ result [0 ]->r );
323+
324+ // The "information_schema.TABLES.TABLE_NAME" column uses COLLATE NOCASE.
325+ // Let's verify that the BINARY override works for this scenario as well.
326+ $ this ->assertQuery ( 'CREATE TABLE CaseSensitive (id INT) ' );
327+
328+ $ result = $ this ->assertQuery ( "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = 'casesensitive' " );
329+ $ this ->assertCount ( 1 , $ result );
330+
331+ $ result = $ this ->assertQuery ( "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = BINARY 'casesensitive' " );
332+ $ this ->assertCount ( 0 , $ result );
333+
334+ $ result = $ this ->assertQuery ( "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = BINARY 'CaseSensitive' " );
335+ $ this ->assertCount ( 1 , $ result );
336+ }
337+
293338 public function testSelectFromDual () {
294339 $ result = $ this ->assertQuery (
295340 'SELECT 1 as output FROM DUAL '
0 commit comments