Short answer:
Use CAST(... AS DATE)
Long answer:
From MySQL DATE type:
A “relaxed” syntax is allowed: Any
punctuation character may be used as
the delimiter between date parts or
time parts. For example, '98-12-31
11:30:45', '98.12.31 11+30+45',
'98/12/31 11*30*45', and '98@12@31
11^30^45' are equivalent.
In your examples 1 and 2 you're using ADDDATE... this will always return a date with a '-' separator, no matter what the input format:
+-----------------------------------------------+
| ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY) |
+-----------------------------------------------+
| 2008-11-01 23:59:59 |
+-----------------------------------------------+
You're also using IFNULL, which loses the type information, so when you compare this it's comparing as strings.
What you can do is cast this back to a date:
mysql> SELECT IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) > '2008/10/31 23:59:59';
+-------------------------------------------------------------------------------------+
| IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) > '2008/10/31 23:59:59' |
+-------------------------------------------------------------------------------------+
| 0 |
+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CAST(IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) AS DATE) > '2008/10/31 23:59:59';
+---------------------------------------------------------------------------------------------------+
| CAST(IFNULL(null, ADDDATE('2008/10/31 23:59:59',INTERVAL 1 DAY)) AS DATE) > '2008/10/31 23:59:59' |
+---------------------------------------------------------------------------------------------------+
| 1 |
+---------------------------------------------------------------------------------------------------+