@@ -2586,6 +2586,91 @@ public function testZeroInDateInUpdateRejectedWhenNoZeroInDateAndStrictModeAreOn
25862586 );
25872587 }
25882588
2589+ /**
2590+ * Test that stored zero dates can be selected and compared.
2591+ *
2592+ * In MySQL, zero dates are regular values for reads — they can appear in
2593+ * WHERE, ORDER BY, and comparisons regardless of the current SQL mode.
2594+ */
2595+ public function testSelectZeroDatesComparison () {
2596+ $ this ->assertQuery ( "SET sql_mode = 'STRICT_TRANS_TABLES' " );
2597+
2598+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('zero', '0000-00-00 00:00:00'); " );
2599+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('real', '2022-01-15 14:30:00'); " );
2600+
2601+ // Zero dates compare as less than real dates.
2602+ $ this ->assertQuery ( "SELECT option_name FROM _dates WHERE option_value < '2000-01-01 00:00:00' ORDER BY option_value; " );
2603+ $ results = $ this ->engine ->get_query_results ();
2604+ $ this ->assertCount ( 1 , $ results );
2605+ $ this ->assertEquals ( 'zero ' , $ results [0 ]->option_name );
2606+
2607+ // Equality match on zero date.
2608+ $ this ->assertQuery ( "SELECT option_name FROM _dates WHERE option_value = '0000-00-00 00:00:00'; " );
2609+ $ results = $ this ->engine ->get_query_results ();
2610+ $ this ->assertCount ( 1 , $ results );
2611+ $ this ->assertEquals ( 'zero ' , $ results [0 ]->option_name );
2612+ }
2613+
2614+ /**
2615+ * Test ORDER BY with a mix of zero and non-zero dates.
2616+ */
2617+ public function testSelectZeroDatesOrderBy () {
2618+ $ this ->assertQuery ( "SET sql_mode = 'STRICT_TRANS_TABLES' " );
2619+
2620+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('b', '2022-06-01 00:00:00'); " );
2621+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('a', '0000-00-00 00:00:00'); " );
2622+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('c', '2023-01-01 00:00:00'); " );
2623+
2624+ $ this ->assertQuery ( 'SELECT option_name FROM _dates ORDER BY option_value ASC; ' );
2625+ $ results = $ this ->engine ->get_query_results ();
2626+ $ this ->assertCount ( 3 , $ results );
2627+ $ this ->assertEquals ( 'a ' , $ results [0 ]->option_name );
2628+ $ this ->assertEquals ( 'b ' , $ results [1 ]->option_name );
2629+ $ this ->assertEquals ( 'c ' , $ results [2 ]->option_name );
2630+ }
2631+
2632+ /**
2633+ * Test that zero-in-dates stored in the database can be read back
2634+ * and filtered in SELECT statements.
2635+ */
2636+ public function testSelectZeroInDates () {
2637+ $ this ->assertQuery ( "SET sql_mode = 'STRICT_TRANS_TABLES' " );
2638+
2639+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('zero-month', '2020-00-15 00:00:00'); " );
2640+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('zero-day', '2020-01-00 00:00:00'); " );
2641+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('normal', '2020-01-15 00:00:00'); " );
2642+
2643+ // All three rows are readable.
2644+ $ this ->assertQuery ( 'SELECT option_name, option_value FROM _dates ORDER BY option_value ASC; ' );
2645+ $ results = $ this ->engine ->get_query_results ();
2646+ $ this ->assertCount ( 3 , $ results );
2647+ $ this ->assertEquals ( '2020-00-15 00:00:00 ' , $ results [0 ]->option_value );
2648+ $ this ->assertEquals ( '2020-01-00 00:00:00 ' , $ results [1 ]->option_value );
2649+ $ this ->assertEquals ( '2020-01-15 00:00:00 ' , $ results [2 ]->option_value );
2650+
2651+ // Filtering by a zero-in-date value works.
2652+ $ this ->assertQuery ( "SELECT option_name FROM _dates WHERE option_value = '2020-00-15 00:00:00'; " );
2653+ $ results = $ this ->engine ->get_query_results ();
2654+ $ this ->assertCount ( 1 , $ results );
2655+ $ this ->assertEquals ( 'zero-month ' , $ results [0 ]->option_name );
2656+ }
2657+
2658+ /**
2659+ * Test date functions on zero dates — YEAR(), MONTH(), DAY() all return 0.
2660+ */
2661+ public function testDateFunctionsOnZeroDates () {
2662+ $ this ->assertQuery ( "SET sql_mode = 'STRICT_TRANS_TABLES' " );
2663+
2664+ $ this ->assertQuery ( "INSERT INTO _dates (option_name, option_value) VALUES ('zero', '0000-00-00 00:00:00'); " );
2665+
2666+ $ this ->assertQuery ( "SELECT YEAR(option_value) as y, MONTH(option_value) as m, DAY(option_value) as d FROM _dates; " );
2667+ $ results = $ this ->engine ->get_query_results ();
2668+ $ this ->assertCount ( 1 , $ results );
2669+ $ this ->assertEquals ( 0 , $ results [0 ]->y );
2670+ $ this ->assertEquals ( 0 , $ results [0 ]->m );
2671+ $ this ->assertEquals ( 0 , $ results [0 ]->d );
2672+ }
2673+
25892674 public function testCaseInsensitiveSelect () {
25902675 $ this ->assertQuery (
25912676 "CREATE TABLE _tmp_table (
0 commit comments