Project

General

Profile

Backport(バックポート) #4067

検索時の日付の範囲指定にて存在しない日付を設定してしまう場合がある

Added by kaoru n almost 3 years ago. Updated almost 3 years ago.

Status:
Pending Testing(テスト待ち)
Priority:
Normal(通常)
Assignee:
Target version:
Start date:
2016-12-12
Due date:
% Done:

70%


Description

Overview (現象)

日記が存在する場合に、カレンダーの日付にリンクが設定されるが12月だけリンクが設定されない。

Causes (原因)

https://github.com/tejimaya/opDiaryPlugin/blob/dev-1.5.x/lib/model/doctrine/PluginDiaryTable.class.php#L202-L217
上記箇所 addDateQuery() にて期間指定の where句 の生成を行っているが、$end に 引数の 日 または 月 に 1 を加算したものを設定しているため、$end が存在しない日付になることがある。

例: 引数の $month が 12 であった場合、 $end に 13 月 として設定される。

なお、下記のように MySQL の場合は存在しない日付を指定しても意図した結果が返却される(Warningが発生)が、MariaDB の場合は意図した結果が返却されない。
確認環境: MySQL 5.7.11 Homebrew, MariaDB 10.0.28

MySQLの場合

mysql> SELECT id, created_at FROM diary WHERE (member_id = 1 AND created_at >= '2015-12-01 00:00:00' AND created_at < '2015-13-01 00:00:00');
+----+---------------------+
| id | created_at          |
+----+---------------------+
|  3 | 2015-12-06 09:54:52 |
+----+---------------------+
1 row in set, 3 warnings (0.00 sec)

MariaDBの場合

MariaDB [openpne]> SELECT id, created_at FROM diary WHERE (member_id = 1 AND created_at >= '2015-12-01 00:00:00' AND created_at < '2015-13-01 00:00:00');
Empty set, 1 warning (0.00 sec)

Way to fix (修正内容)

http://php.net/manual/ja/function.strtotime.php
strtotime を使用して計算するようにする。

(補足)
https://github.com/openpne/OpenPNE3/blob/master/doc/ja/OpenPNE3_Setup_Guide.txt#L25-L26
OpenPNEでは、MySQL で動作させることを想定しているため、MySQL で動作するのであれば修正対象とならないかもしれないが、
不正な日付が設定されてしまうと考えると、DBの種類にかかわらず修正すべきだと思います。
なお、 sql_mode に STRICT_ALL_TABLES を設定した場合でも、現在のところ特に影響はないようです。

・sql_mode に STRICT_ALL_TABLES が設定されていない場合

mysql> SHOW GLOBAL VARIABLES LIKE 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+
1 row in set (0.00 sec)

mysql> SELECT id, created_at FROM diary WHERE (member_id = 1 AND created_at >= '2015-12-01 00:00:00' AND created_at < '2015-13-01 00:00:00');
+----+---------------------+
| id | created_at          |
+----+---------------------+
|  3 | 2015-12-06 09:54:52 |
+----+---------------------+
1 row in set, 3 warnings (0.01 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1292
Message: Incorrect datetime value: '2015-13-01 00:00:00' for column 'created_at' at row 1
*************************** 2. row ***************************
  Level: Warning
   Code: 1292
Message: Incorrect datetime value: '2015-13-01 00:00:00' for column 'created_at' at row 1
*************************** 3. row ***************************
  Level: Warning
   Code: 1292
Message: Incorrect datetime value: '2015-13-01 00:00:00' for column 'created_at' at row 1
3 rows in set (0.00 sec)

・sql_mode に STRICT_ALL_TABLES が設定されている場合

mysql> SET GLOBAL sql_mode=STRICT_ALL_TABLES;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE 'sql_mode';
+---------------+-------------------+
| Variable_name | Value             |
+---------------+-------------------+
| sql_mode      | STRICT_ALL_TABLES |
+---------------+-------------------+
1 row in set (0.00 sec)

mysql> SELECT id, created_at FROM diary WHERE (member_id = 1 AND created_at >= '2015-12-01 00:00:00' AND created_at < '2015-13-01 00:00:00');
+----+---------------------+
| id | created_at          |
+----+---------------------+
|  3 | 2015-12-06 09:54:52 |
+----+---------------------+
1 row in set, 3 warnings (0.00 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1292
Message: Incorrect datetime value: '2015-13-01 00:00:00' for column 'created_at' at row 1
*************************** 2. row ***************************
  Level: Warning
   Code: 1292
Message: Incorrect datetime value: '2015-13-01 00:00:00' for column 'created_at' at row 1
*************************** 3. row ***************************
  Level: Warning
   Code: 1292
Message: Incorrect datetime value: '2015-13-01 00:00:00' for column 'created_at' at row 1
3 rows in set (0.00 sec)

・MariaDBの場合

MariaDB [openpne]> set @sql_mode = 'ALLOW_INVALID_DATES';
Query OK, 0 rows affected (0.00 sec)

MariaDB [openpne]> select @sql_mode;
+---------------------+
| @sql_mode           |
+---------------------+
| ALLOW_INVALID_DATES |
+---------------------+
1 row in set (0.00 sec)

MariaDB [openpne]> SELECT id, created_at FROM diary WHERE (member_id = 1 AND created_at >= '2015-12-01 00:00:00' AND created_at < '2015-13-01 00:00:00');
Empty set, 1 warning (0.00 sec)

Warning (Code 1292): Incorrect datetime value: '2015-13-01 00:00:00'

参考:
MySQLのStrict Modeを有効にした場合に生じる問題を調査
https://redmine.openpne.jp/issues/4033


Related issues

Copied from opDiaryPlugin - Bug(バグ) #4066: 検索時の日付の範囲指定にて存在しない日付を設定してしまう場合がある Pending Testing(テスト待ち) 2016-12-12

History

#1 Updated by kaoru n almost 3 years ago

  • Copied from Bug(バグ) #4066: 検索時の日付の範囲指定にて存在しない日付を設定してしまう場合がある added

#2 Updated by kaoru n almost 3 years ago

  • Description updated (diff)

#3 Updated by kaoru n almost 3 years ago

  • Tracker changed from Bug(バグ) to Backport(バックポート)

#4 Updated by kaoru n almost 3 years ago

  • Status changed from New(新規) to Pending Review(レビュー待ち)
  • % Done changed from 0 to 50

https://github.com/tejimaya/opDiaryPlugin/pull/4
にてプルリクエストしました

#5 Updated by Rimpei Ogawa almost 3 years ago

  • Status changed from Pending Review(レビュー待ち) to Pending Testing(テスト待ち)
  • % Done changed from 50 to 70

Also available in: Atom PDF